add zod schemas & inferences

This commit is contained in:
thierryverse 2025-11-14 00:25:08 +02:00
parent 0c41e487d8
commit 77d49ca11c
10 changed files with 143 additions and 92 deletions

View file

@ -1,50 +0,0 @@
import { LoginRequest, LoginResponse, RegisterRequest, RegisterResponse } from "./contracts";
export class AuthApiService {
login = async (request: LoginRequest) : Promise<LoginResponse> => {
const requestBody = new URLSearchParams();
requestBody.append("username", request.email);
requestBody.append("password", request.password);
requestBody.append("grant_type", "password");
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/auth/jwt/login`,
{
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: requestBody.toString(),
}
);
const data = await response.json();
if (!response.ok) {
throw new Error(data.detail || `HTTP ${response.status}`);
}
return data;
};
register = async (request: RegisterRequest) : Promise<RegisterResponse> => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/auth/register`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(request),
}
);
const data = await response.json();
if (!response.ok) {
throw new Error(data.detail || `HTTP ${response.status}`);
}
return data;
};
}

View file

@ -1,34 +0,0 @@
/**
* LOGIN
*/
export type LoginRequest = {
email: string;
password: string;
grant_type?: string;
};
export type LoginResponse = {
access_token: string;
token_type: string;
};
/**
* REGISTER
*/
export type RegisterRequest = {
email: string;
password: string;
is_active: boolean;
is_superuser: boolean;
is_verified: boolean;
};
export type RegisterResponse = {
id: number;
email: string;
is_active: boolean;
is_superuser: boolean;
is_verified: boolean;
pages_limit: number;
pages_used: number;
};

View file

@ -33,7 +33,7 @@ export class BaseApiService {
body?: any,
responseSchema?: z.ZodSchema<T>,
options?: RequestOptions
) {
) : Promise<T> {
const defaultOptions: RequestOptions = {
headers: {
"Content-Type": "application/json",
@ -55,7 +55,10 @@ export class BaseApiService {
// Serialize body
if (body) {
if (mergedOptions.headers?.["Content-Type"].toLocaleLowerCase() === "application/json") {
if (
mergedOptions.headers?.["Content-Type"].toLocaleLowerCase() ===
"application/json"
) {
requestBody = JSON.stringify(body);
}
@ -125,7 +128,7 @@ export class BaseApiService {
async get<T>(
url: string,
responseSchema?: z.ZodSchema<T>,
options?: RequestOptions
options?: Omit<RequestOptions, "method">
) {
return this.request(url, undefined, responseSchema, {
...options,
@ -137,7 +140,7 @@ export class BaseApiService {
url: string,
body?: any,
responseSchema?: z.ZodSchema<T>,
options?: RequestOptions
options?: Omit<RequestOptions, "method">
) {
return this.request(url, body, responseSchema, {
...options,
@ -149,7 +152,7 @@ export class BaseApiService {
url: string,
body?: any,
responseSchema?: z.ZodSchema<T>,
options?: RequestOptions
options?: Omit<RequestOptions, "method">
) {
return this.request(url, body, responseSchema, {
...options,
@ -161,7 +164,7 @@ export class BaseApiService {
url: string,
body?: any,
responseSchema?: z.ZodSchema<T>,
options?: RequestOptions
options?: Omit<RequestOptions, "method">
) {
return this.request(url, body, responseSchema, {
...options,
@ -169,3 +172,8 @@ export class BaseApiService {
});
}
}
export const baseApiService = new BaseApiService(
typeof window !== "undefined" ? localStorage.getItem("surfsense_bearer_token") || "" : "",
process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL || ""
);

View file

@ -1 +0,0 @@
// Will contain a ChatApiService class that will be used to make API calls

View file

@ -1 +0,0 @@
// Will contains contracts for all chat related APIs