Add auto-generated API client and schema files
Some checks failed
Build and Push Docker Images / changes (push) Successful in 5s
Build and Push Docker Images / build-backend (push) Has been skipped
Build and Push Docker Images / build-frontend (push) Failing after 42s

Integrated auto-generated TypeScript client and schemas using @hey-api/openapi-ts for API communication. Includes type definitions, API endpoint handlers, and React Query integration for enhanced type safety and developer experience.
This commit is contained in:
2025-03-05 10:09:48 +01:00
parent a7504f6876
commit ffa3f2ffd3
6 changed files with 903 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
// This file is auto-generated by @hey-api/openapi-ts
import { type Options, rootGet, register, login, loginOauth, refreshToken, changePassword, getCurrentUserInfo } from '../sdk.gen';
import { queryOptions, type UseMutationOptions } from '@tanstack/react-query';
import type { RootGetData, RegisterData, RegisterError, RegisterResponse, LoginData, LoginError, LoginResponse, LoginOauthData, LoginOauthError, LoginOauthResponse, RefreshTokenData, RefreshTokenError, RefreshTokenResponse, ChangePasswordData, ChangePasswordError, GetCurrentUserInfoData } from '../types.gen';
import type { AxiosError } from 'axios';
import { client as _heyApiClient } from '../client.gen';
export type QueryKey<TOptions extends Options> = [
Pick<TOptions, 'baseURL' | 'body' | 'headers' | 'path' | 'query'> & {
_id: string;
_infinite?: boolean;
}
];
const createQueryKey = <TOptions extends Options>(id: string, options?: TOptions, infinite?: boolean): [
QueryKey<TOptions>[0]
] => {
const params: QueryKey<TOptions>[0] = { _id: id, baseURL: (options?.client ?? _heyApiClient).getConfig().baseURL } as QueryKey<TOptions>[0];
if (infinite) {
params._infinite = infinite;
}
if (options?.body) {
params.body = options.body;
}
if (options?.headers) {
params.headers = options.headers;
}
if (options?.path) {
params.path = options.path;
}
if (options?.query) {
params.query = options.query;
}
return [
params
];
};
export const rootGetQueryKey = (options?: Options<RootGetData>) => createQueryKey('rootGet', options);
export const rootGetOptions = (options?: Options<RootGetData>) => {
return queryOptions({
queryFn: async ({ queryKey, signal }) => {
const { data } = await rootGet({
...options,
...queryKey[0],
signal,
throwOnError: true
});
return data;
},
queryKey: rootGetQueryKey(options)
});
};
export const registerQueryKey = (options: Options<RegisterData>) => createQueryKey('register', options);
export const registerOptions = (options: Options<RegisterData>) => {
return queryOptions({
queryFn: async ({ queryKey, signal }) => {
const { data } = await register({
...options,
...queryKey[0],
signal,
throwOnError: true
});
return data;
},
queryKey: registerQueryKey(options)
});
};
export const registerMutation = (options?: Partial<Options<RegisterData>>) => {
const mutationOptions: UseMutationOptions<RegisterResponse, AxiosError<RegisterError>, Options<RegisterData>> = {
mutationFn: async (localOptions) => {
const { data } = await register({
...options,
...localOptions,
throwOnError: true
});
return data;
}
};
return mutationOptions;
};
export const loginQueryKey = (options: Options<LoginData>) => createQueryKey('login', options);
export const loginOptions = (options: Options<LoginData>) => {
return queryOptions({
queryFn: async ({ queryKey, signal }) => {
const { data } = await login({
...options,
...queryKey[0],
signal,
throwOnError: true
});
return data;
},
queryKey: loginQueryKey(options)
});
};
export const loginMutation = (options?: Partial<Options<LoginData>>) => {
const mutationOptions: UseMutationOptions<LoginResponse, AxiosError<LoginError>, Options<LoginData>> = {
mutationFn: async (localOptions) => {
const { data } = await login({
...options,
...localOptions,
throwOnError: true
});
return data;
}
};
return mutationOptions;
};
export const loginOauthQueryKey = (options: Options<LoginOauthData>) => createQueryKey('loginOauth', options);
export const loginOauthOptions = (options: Options<LoginOauthData>) => {
return queryOptions({
queryFn: async ({ queryKey, signal }) => {
const { data } = await loginOauth({
...options,
...queryKey[0],
signal,
throwOnError: true
});
return data;
},
queryKey: loginOauthQueryKey(options)
});
};
export const loginOauthMutation = (options?: Partial<Options<LoginOauthData>>) => {
const mutationOptions: UseMutationOptions<LoginOauthResponse, AxiosError<LoginOauthError>, Options<LoginOauthData>> = {
mutationFn: async (localOptions) => {
const { data } = await loginOauth({
...options,
...localOptions,
throwOnError: true
});
return data;
}
};
return mutationOptions;
};
export const refreshTokenQueryKey = (options: Options<RefreshTokenData>) => createQueryKey('refreshToken', options);
export const refreshTokenOptions = (options: Options<RefreshTokenData>) => {
return queryOptions({
queryFn: async ({ queryKey, signal }) => {
const { data } = await refreshToken({
...options,
...queryKey[0],
signal,
throwOnError: true
});
return data;
},
queryKey: refreshTokenQueryKey(options)
});
};
export const refreshTokenMutation = (options?: Partial<Options<RefreshTokenData>>) => {
const mutationOptions: UseMutationOptions<RefreshTokenResponse, AxiosError<RefreshTokenError>, Options<RefreshTokenData>> = {
mutationFn: async (localOptions) => {
const { data } = await refreshToken({
...options,
...localOptions,
throwOnError: true
});
return data;
}
};
return mutationOptions;
};
export const changePasswordQueryKey = (options: Options<ChangePasswordData>) => createQueryKey('changePassword', options);
export const changePasswordOptions = (options: Options<ChangePasswordData>) => {
return queryOptions({
queryFn: async ({ queryKey, signal }) => {
const { data } = await changePassword({
...options,
...queryKey[0],
signal,
throwOnError: true
});
return data;
},
queryKey: changePasswordQueryKey(options)
});
};
export const changePasswordMutation = (options?: Partial<Options<ChangePasswordData>>) => {
const mutationOptions: UseMutationOptions<unknown, AxiosError<ChangePasswordError>, Options<ChangePasswordData>> = {
mutationFn: async (localOptions) => {
const { data } = await changePassword({
...options,
...localOptions,
throwOnError: true
});
return data;
}
};
return mutationOptions;
};
export const getCurrentUserInfoQueryKey = (options?: Options<GetCurrentUserInfoData>) => createQueryKey('getCurrentUserInfo', options);
export const getCurrentUserInfoOptions = (options?: Options<GetCurrentUserInfoData>) => {
return queryOptions({
queryFn: async ({ queryKey, signal }) => {
const { data } = await getCurrentUserInfo({
...options,
...queryKey[0],
signal,
throwOnError: true
});
return data;
},
queryKey: getCurrentUserInfoQueryKey(options)
});
};

View File

@@ -0,0 +1,18 @@
// This file is auto-generated by @hey-api/openapi-ts
import type { ClientOptions } from './types.gen';
import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from '@hey-api/client-axios';
/**
* The `createClientConfig()` function will be called on client initialization
* and the returned object will become the client's initial configuration.
*
* You may want to initialize your client this way instead of calling
* `setConfig()`. This is useful for example if you're using Next.js
* to ensure your client always has the correct values.
*/
export type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> = (override?: Config<DefaultClientOptions & T>) => Config<Required<DefaultClientOptions> & T>;
export const client = createClient(createConfig<ClientOptions>({
baseURL: 'http://localhost:8000'
}));

View File

@@ -0,0 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './types.gen';
export * from './sdk.gen';

View File

@@ -0,0 +1,290 @@
// This file is auto-generated by @hey-api/openapi-ts
export const Body_change_passwordSchema = {
properties: {
current_password: {
type: 'string',
title: 'Current Password'
},
new_password: {
type: 'string',
title: 'New Password'
}
},
type: 'object',
required: ['current_password', 'new_password'],
title: 'Body_change_password'
} as const;
export const Body_login_oauthSchema = {
properties: {
grant_type: {
anyOf: [
{
type: 'string',
pattern: '^password$'
},
{
type: 'null'
}
],
title: 'Grant Type'
},
username: {
type: 'string',
title: 'Username'
},
password: {
type: 'string',
title: 'Password'
},
scope: {
type: 'string',
title: 'Scope',
default: ''
},
client_id: {
anyOf: [
{
type: 'string'
},
{
type: 'null'
}
],
title: 'Client Id'
},
client_secret: {
anyOf: [
{
type: 'string'
},
{
type: 'null'
}
],
title: 'Client Secret'
}
},
type: 'object',
required: ['username', 'password'],
title: 'Body_login_oauth'
} as const;
export const HTTPValidationErrorSchema = {
properties: {
detail: {
items: {
'$ref': '#/components/schemas/ValidationError'
},
type: 'array',
title: 'Detail'
}
},
type: 'object',
title: 'HTTPValidationError'
} as const;
export const LoginRequestSchema = {
properties: {
email: {
type: 'string',
format: 'email',
title: 'Email'
},
password: {
type: 'string',
title: 'Password'
}
},
type: 'object',
required: ['email', 'password'],
title: 'LoginRequest'
} as const;
export const RefreshTokenRequestSchema = {
properties: {
refresh_token: {
type: 'string',
title: 'Refresh Token'
}
},
type: 'object',
required: ['refresh_token'],
title: 'RefreshTokenRequest'
} as const;
export const TokenSchema = {
properties: {
access_token: {
type: 'string',
title: 'Access Token'
},
refresh_token: {
anyOf: [
{
type: 'string'
},
{
type: 'null'
}
],
title: 'Refresh Token'
},
token_type: {
type: 'string',
title: 'Token Type',
default: 'bearer'
}
},
type: 'object',
required: ['access_token'],
title: 'Token'
} as const;
export const UserCreateSchema = {
properties: {
email: {
type: 'string',
format: 'email',
title: 'Email'
},
first_name: {
type: 'string',
title: 'First Name'
},
last_name: {
anyOf: [
{
type: 'string'
},
{
type: 'null'
}
],
title: 'Last Name'
},
phone_number: {
anyOf: [
{
type: 'string'
},
{
type: 'null'
}
],
title: 'Phone Number'
},
password: {
type: 'string',
title: 'Password'
},
is_superuser: {
type: 'boolean',
title: 'Is Superuser',
default: false
}
},
type: 'object',
required: ['email', 'first_name', 'password'],
title: 'UserCreate'
} as const;
export const UserResponseSchema = {
properties: {
email: {
type: 'string',
format: 'email',
title: 'Email'
},
first_name: {
type: 'string',
title: 'First Name'
},
last_name: {
anyOf: [
{
type: 'string'
},
{
type: 'null'
}
],
title: 'Last Name'
},
phone_number: {
anyOf: [
{
type: 'string'
},
{
type: 'null'
}
],
title: 'Phone Number'
},
id: {
type: 'string',
format: 'uuid',
title: 'Id'
},
is_active: {
type: 'boolean',
title: 'Is Active'
},
is_superuser: {
type: 'boolean',
title: 'Is Superuser'
},
created_at: {
type: 'string',
format: 'date-time',
title: 'Created At'
},
updated_at: {
anyOf: [
{
type: 'string',
format: 'date-time'
},
{
type: 'null'
}
],
title: 'Updated At'
}
},
type: 'object',
required: ['email', 'first_name', 'id', 'is_active', 'is_superuser', 'created_at'],
title: 'UserResponse'
} as const;
export const ValidationErrorSchema = {
properties: {
loc: {
items: {
anyOf: [
{
type: 'string'
},
{
type: 'integer'
}
]
},
type: 'array',
title: 'Location'
},
msg: {
type: 'string',
title: 'Message'
},
type: {
type: 'string',
title: 'Error Type'
}
},
type: 'object',
required: ['loc', 'msg', 'type'],
title: 'ValidationError'
} as const;

View File

@@ -0,0 +1,145 @@
// This file is auto-generated by @hey-api/openapi-ts
import { type Options as ClientOptions, type TDataShape, type Client, urlSearchParamsBodySerializer } from '@hey-api/client-axios';
import type { RootGetData, RootGetResponse, RegisterData, RegisterResponse, RegisterError, LoginData, LoginResponse, LoginError, LoginOauthData, LoginOauthResponse, LoginOauthError, RefreshTokenData, RefreshTokenResponse, RefreshTokenError, ChangePasswordData, ChangePasswordError, GetCurrentUserInfoData, GetCurrentUserInfoResponse } from './types.gen';
import { client as _heyApiClient } from './client.gen';
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = ClientOptions<TData, ThrowOnError> & {
/**
* You can provide a client instance returned by `createClient()` instead of
* individual options. This might be also useful if you want to implement a
* custom client.
*/
client?: Client;
/**
* You can pass arbitrary values through the `meta` object. This can be
* used to access values that aren't defined as part of the SDK function.
*/
meta?: Record<string, unknown>;
};
/**
* Root
*/
export const rootGet = <ThrowOnError extends boolean = false>(options?: Options<RootGetData, ThrowOnError>) => {
return (options?.client ?? _heyApiClient).get<RootGetResponse, unknown, ThrowOnError>({
responseType: 'text',
url: '/',
...options
});
};
/**
* Register User
* Register a new user.
*
* Returns:
* The created user information.
*/
export const register = <ThrowOnError extends boolean = false>(options: Options<RegisterData, ThrowOnError>) => {
return (options.client ?? _heyApiClient).post<RegisterResponse, RegisterError, ThrowOnError>({
url: '/api/v1/auth/register',
...options,
headers: {
'Content-Type': 'application/json',
...options?.headers
}
});
};
/**
* Login
* Login with username and password.
*
* Returns:
* Access and refresh tokens.
*/
export const login = <ThrowOnError extends boolean = false>(options: Options<LoginData, ThrowOnError>) => {
return (options.client ?? _heyApiClient).post<LoginResponse, LoginError, ThrowOnError>({
url: '/api/v1/auth/login',
...options,
headers: {
'Content-Type': 'application/json',
...options?.headers
}
});
};
/**
* Login Oauth
* OAuth2-compatible login endpoint, used by the OpenAPI UI.
*
* Returns:
* Access and refresh tokens.
*/
export const loginOauth = <ThrowOnError extends boolean = false>(options: Options<LoginOauthData, ThrowOnError>) => {
return (options.client ?? _heyApiClient).post<LoginOauthResponse, LoginOauthError, ThrowOnError>({
...urlSearchParamsBodySerializer,
url: '/api/v1/auth/login/oauth',
...options,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
...options?.headers
}
});
};
/**
* Refresh Token
* Refresh access token using a refresh token.
*
* Returns:
* New access and refresh tokens.
*/
export const refreshToken = <ThrowOnError extends boolean = false>(options: Options<RefreshTokenData, ThrowOnError>) => {
return (options.client ?? _heyApiClient).post<RefreshTokenResponse, RefreshTokenError, ThrowOnError>({
url: '/api/v1/auth/refresh',
...options,
headers: {
'Content-Type': 'application/json',
...options?.headers
}
});
};
/**
* Change Password
* Change current user's password.
*
* Requires authentication.
*/
export const changePassword = <ThrowOnError extends boolean = false>(options: Options<ChangePasswordData, ThrowOnError>) => {
return (options.client ?? _heyApiClient).post<unknown, ChangePasswordError, ThrowOnError>({
security: [
{
scheme: 'bearer',
type: 'http'
}
],
url: '/api/v1/auth/change-password',
...options,
headers: {
'Content-Type': 'application/json',
...options?.headers
}
});
};
/**
* Get Current User Info
* Get current user information.
*
* Requires authentication.
*/
export const getCurrentUserInfo = <ThrowOnError extends boolean = false>(options?: Options<GetCurrentUserInfoData, ThrowOnError>) => {
return (options?.client ?? _heyApiClient).get<GetCurrentUserInfoResponse, unknown, ThrowOnError>({
security: [
{
scheme: 'bearer',
type: 'http'
}
],
url: '/api/v1/auth/me',
...options
});
};

View File

@@ -0,0 +1,220 @@
// This file is auto-generated by @hey-api/openapi-ts
export type BodyChangePassword = {
current_password: string;
new_password: string;
};
export type BodyLoginOauth = {
grant_type?: string | null;
username: string;
password: string;
scope?: string;
client_id?: string | null;
client_secret?: string | null;
};
export type HttpValidationError = {
detail?: Array<ValidationError>;
};
export type LoginRequest = {
email: string;
password: string;
};
export type RefreshTokenRequest = {
refresh_token: string;
};
export type Token = {
access_token: string;
refresh_token?: string | null;
token_type?: string;
};
export type UserCreate = {
email: string;
first_name: string;
last_name?: string | null;
phone_number?: string | null;
password: string;
is_superuser?: boolean;
};
export type UserResponse = {
email: string;
first_name: string;
last_name?: string | null;
phone_number?: string | null;
id: string;
is_active: boolean;
is_superuser: boolean;
created_at: string;
updated_at?: string | null;
};
export type ValidationError = {
loc: Array<string | number>;
msg: string;
type: string;
};
export type RootGetData = {
body?: never;
path?: never;
query?: never;
url: '/';
};
export type RootGetResponses = {
/**
* Successful Response
*/
200: string;
};
export type RootGetResponse = RootGetResponses[keyof RootGetResponses];
export type RegisterData = {
body: UserCreate;
path?: never;
query?: never;
url: '/api/v1/auth/register';
};
export type RegisterErrors = {
/**
* Validation Error
*/
422: HttpValidationError;
};
export type RegisterError = RegisterErrors[keyof RegisterErrors];
export type RegisterResponses = {
/**
* Successful Response
*/
201: UserResponse;
};
export type RegisterResponse = RegisterResponses[keyof RegisterResponses];
export type LoginData = {
body: LoginRequest;
path?: never;
query?: never;
url: '/api/v1/auth/login';
};
export type LoginErrors = {
/**
* Validation Error
*/
422: HttpValidationError;
};
export type LoginError = LoginErrors[keyof LoginErrors];
export type LoginResponses = {
/**
* Successful Response
*/
200: Token;
};
export type LoginResponse = LoginResponses[keyof LoginResponses];
export type LoginOauthData = {
body: BodyLoginOauth;
path?: never;
query?: never;
url: '/api/v1/auth/login/oauth';
};
export type LoginOauthErrors = {
/**
* Validation Error
*/
422: HttpValidationError;
};
export type LoginOauthError = LoginOauthErrors[keyof LoginOauthErrors];
export type LoginOauthResponses = {
/**
* Successful Response
*/
200: Token;
};
export type LoginOauthResponse = LoginOauthResponses[keyof LoginOauthResponses];
export type RefreshTokenData = {
body: RefreshTokenRequest;
path?: never;
query?: never;
url: '/api/v1/auth/refresh';
};
export type RefreshTokenErrors = {
/**
* Validation Error
*/
422: HttpValidationError;
};
export type RefreshTokenError = RefreshTokenErrors[keyof RefreshTokenErrors];
export type RefreshTokenResponses = {
/**
* Successful Response
*/
200: Token;
};
export type RefreshTokenResponse = RefreshTokenResponses[keyof RefreshTokenResponses];
export type ChangePasswordData = {
body: BodyChangePassword;
path?: never;
query?: never;
url: '/api/v1/auth/change-password';
};
export type ChangePasswordErrors = {
/**
* Validation Error
*/
422: HttpValidationError;
};
export type ChangePasswordError = ChangePasswordErrors[keyof ChangePasswordErrors];
export type ChangePasswordResponses = {
/**
* Successful Response
*/
200: unknown;
};
export type GetCurrentUserInfoData = {
body?: never;
path?: never;
query?: never;
url: '/api/v1/auth/me';
};
export type GetCurrentUserInfoResponses = {
/**
* Successful Response
*/
200: UserResponse;
};
export type GetCurrentUserInfoResponse = GetCurrentUserInfoResponses[keyof GetCurrentUserInfoResponses];
export type ClientOptions = {
baseURL: 'http://localhost:8000' | (string & {});
};