Refactor auto-generated schemas and types formatting
Updated the formatting for auto-generated schemas, types, and related files to adhere to consistent coding standards (e.g., double quotes, indentation). No functional changes were made, ensuring behavior remains identical.
This commit is contained in:
@@ -1,227 +1,292 @@
|
||||
// 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';
|
||||
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;
|
||||
}
|
||||
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
|
||||
];
|
||||
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 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)
|
||||
});
|
||||
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 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)
|
||||
});
|
||||
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;
|
||||
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 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)
|
||||
});
|
||||
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;
|
||||
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 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)
|
||||
});
|
||||
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 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 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)
|
||||
});
|
||||
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 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 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)
|
||||
});
|
||||
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 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 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)
|
||||
});
|
||||
};
|
||||
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),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
// 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';
|
||||
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
|
||||
@@ -11,8 +16,13 @@ import { type Config, type ClientOptions as DefaultClientOptions, createClient,
|
||||
* `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 type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> =
|
||||
(
|
||||
override?: Config<DefaultClientOptions & T>,
|
||||
) => Config<Required<DefaultClientOptions> & T>;
|
||||
|
||||
export const client = createClient(createConfig<ClientOptions>({
|
||||
baseURL: 'http://localhost:8000'
|
||||
}));
|
||||
export const client = createClient(
|
||||
createConfig<ClientOptions>({
|
||||
baseURL: "http://localhost:8000",
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
export * from './types.gen';
|
||||
export * from './sdk.gen';
|
||||
export * from "./types.gen";
|
||||
export * from "./sdk.gen";
|
||||
|
||||
@@ -1,290 +1,297 @@
|
||||
// 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'
|
||||
}
|
||||
properties: {
|
||||
current_password: {
|
||||
type: "string",
|
||||
title: "Current Password",
|
||||
},
|
||||
type: 'object',
|
||||
required: ['current_password', 'new_password'],
|
||||
title: 'Body_change_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'
|
||||
properties: {
|
||||
grant_type: {
|
||||
anyOf: [
|
||||
{
|
||||
type: "string",
|
||||
pattern: "^password$",
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
title: 'Username'
|
||||
{
|
||||
type: "null",
|
||||
},
|
||||
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'
|
||||
}
|
||||
],
|
||||
title: "Grant Type",
|
||||
},
|
||||
type: 'object',
|
||||
required: ['username', 'password'],
|
||||
title: 'Body_login_oauth'
|
||||
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'
|
||||
}
|
||||
properties: {
|
||||
detail: {
|
||||
items: {
|
||||
$ref: "#/components/schemas/ValidationError",
|
||||
},
|
||||
type: "array",
|
||||
title: "Detail",
|
||||
},
|
||||
type: 'object',
|
||||
title: 'HTTPValidationError'
|
||||
},
|
||||
type: "object",
|
||||
title: "HTTPValidationError",
|
||||
} as const;
|
||||
|
||||
export const LoginRequestSchema = {
|
||||
properties: {
|
||||
email: {
|
||||
type: 'string',
|
||||
format: 'email',
|
||||
title: 'Email'
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
title: 'Password'
|
||||
}
|
||||
properties: {
|
||||
email: {
|
||||
type: "string",
|
||||
format: "email",
|
||||
title: "Email",
|
||||
},
|
||||
type: 'object',
|
||||
required: ['email', 'password'],
|
||||
title: 'LoginRequest'
|
||||
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'
|
||||
}
|
||||
properties: {
|
||||
refresh_token: {
|
||||
type: "string",
|
||||
title: "Refresh Token",
|
||||
},
|
||||
type: 'object',
|
||||
required: ['refresh_token'],
|
||||
title: 'RefreshTokenRequest'
|
||||
},
|
||||
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'
|
||||
}
|
||||
properties: {
|
||||
access_token: {
|
||||
type: "string",
|
||||
title: "Access Token",
|
||||
},
|
||||
type: 'object',
|
||||
required: ['access_token'],
|
||||
title: '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
|
||||
}
|
||||
properties: {
|
||||
email: {
|
||||
type: "string",
|
||||
format: "email",
|
||||
title: "Email",
|
||||
},
|
||||
type: 'object',
|
||||
required: ['email', 'first_name', 'password'],
|
||||
title: 'UserCreate'
|
||||
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'
|
||||
}
|
||||
properties: {
|
||||
email: {
|
||||
type: "string",
|
||||
format: "email",
|
||||
title: "Email",
|
||||
},
|
||||
type: 'object',
|
||||
required: ['email', 'first_name', 'id', 'is_active', 'is_superuser', 'created_at'],
|
||||
title: 'UserResponse'
|
||||
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'
|
||||
}
|
||||
properties: {
|
||||
loc: {
|
||||
items: {
|
||||
anyOf: [
|
||||
{
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
type: "integer",
|
||||
},
|
||||
],
|
||||
},
|
||||
type: "array",
|
||||
title: "Location",
|
||||
},
|
||||
type: 'object',
|
||||
required: ['loc', 'msg', 'type'],
|
||||
title: 'ValidationError'
|
||||
} as const;
|
||||
msg: {
|
||||
type: "string",
|
||||
title: "Message",
|
||||
},
|
||||
type: {
|
||||
type: "string",
|
||||
title: "Error Type",
|
||||
},
|
||||
},
|
||||
type: "object",
|
||||
required: ["loc", "msg", "type"],
|
||||
title: "ValidationError",
|
||||
} as const;
|
||||
|
||||
@@ -1,32 +1,65 @@
|
||||
// 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';
|
||||
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>;
|
||||
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
|
||||
});
|
||||
export const rootGet = <ThrowOnError extends boolean = false>(
|
||||
options?: Options<RootGetData, ThrowOnError>,
|
||||
) => {
|
||||
return (options?.client ?? _heyApiClient).get<
|
||||
RootGetResponse,
|
||||
unknown,
|
||||
ThrowOnError
|
||||
>({
|
||||
responseType: "text",
|
||||
url: "/",
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -36,15 +69,21 @@ export const rootGet = <ThrowOnError extends boolean = false>(options?: Options<
|
||||
* 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
|
||||
}
|
||||
});
|
||||
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,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -54,15 +93,21 @@ export const register = <ThrowOnError extends boolean = false>(options: Options<
|
||||
* 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
|
||||
}
|
||||
});
|
||||
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,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -72,16 +117,22 @@ export const login = <ThrowOnError extends boolean = false>(options: Options<Log
|
||||
* 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
|
||||
}
|
||||
});
|
||||
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,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -91,15 +142,21 @@ export const loginOauth = <ThrowOnError extends boolean = false>(options: Option
|
||||
* 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
|
||||
}
|
||||
});
|
||||
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,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -108,21 +165,27 @@ export const refreshToken = <ThrowOnError extends boolean = false>(options: Opti
|
||||
*
|
||||
* 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
|
||||
}
|
||||
});
|
||||
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,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -131,15 +194,21 @@ export const changePassword = <ThrowOnError extends boolean = false>(options: Op
|
||||
*
|
||||
* 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
|
||||
});
|
||||
};
|
||||
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,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,220 +1,223 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
|
||||
export type BodyChangePassword = {
|
||||
current_password: string;
|
||||
new_password: string;
|
||||
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;
|
||||
grant_type?: string | null;
|
||||
username: string;
|
||||
password: string;
|
||||
scope?: string;
|
||||
client_id?: string | null;
|
||||
client_secret?: string | null;
|
||||
};
|
||||
|
||||
export type HttpValidationError = {
|
||||
detail?: Array<ValidationError>;
|
||||
detail?: Array<ValidationError>;
|
||||
};
|
||||
|
||||
export type LoginRequest = {
|
||||
email: string;
|
||||
password: string;
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
export type RefreshTokenRequest = {
|
||||
refresh_token: string;
|
||||
refresh_token: string;
|
||||
};
|
||||
|
||||
export type Token = {
|
||||
access_token: string;
|
||||
refresh_token?: string | null;
|
||||
token_type?: string;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
loc: Array<string | number>;
|
||||
msg: string;
|
||||
type: string;
|
||||
};
|
||||
|
||||
export type RootGetData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: '/';
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/";
|
||||
};
|
||||
|
||||
export type RootGetResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: string;
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: string;
|
||||
};
|
||||
|
||||
export type RootGetResponse = RootGetResponses[keyof RootGetResponses];
|
||||
|
||||
export type RegisterData = {
|
||||
body: UserCreate;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: '/api/v1/auth/register';
|
||||
body: UserCreate;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/api/v1/auth/register";
|
||||
};
|
||||
|
||||
export type RegisterErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type RegisterError = RegisterErrors[keyof RegisterErrors];
|
||||
|
||||
export type RegisterResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
201: UserResponse;
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
201: UserResponse;
|
||||
};
|
||||
|
||||
export type RegisterResponse = RegisterResponses[keyof RegisterResponses];
|
||||
|
||||
export type LoginData = {
|
||||
body: LoginRequest;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: '/api/v1/auth/login';
|
||||
body: LoginRequest;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/api/v1/auth/login";
|
||||
};
|
||||
|
||||
export type LoginErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type LoginError = LoginErrors[keyof LoginErrors];
|
||||
|
||||
export type LoginResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: Token;
|
||||
/**
|
||||
* 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';
|
||||
body: BodyLoginOauth;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/api/v1/auth/login/oauth";
|
||||
};
|
||||
|
||||
export type LoginOauthErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type LoginOauthError = LoginOauthErrors[keyof LoginOauthErrors];
|
||||
|
||||
export type LoginOauthResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: Token;
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: Token;
|
||||
};
|
||||
|
||||
export type LoginOauthResponse = LoginOauthResponses[keyof LoginOauthResponses];
|
||||
|
||||
export type RefreshTokenData = {
|
||||
body: RefreshTokenRequest;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: '/api/v1/auth/refresh';
|
||||
body: RefreshTokenRequest;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/api/v1/auth/refresh";
|
||||
};
|
||||
|
||||
export type RefreshTokenErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type RefreshTokenError = RefreshTokenErrors[keyof RefreshTokenErrors];
|
||||
|
||||
export type RefreshTokenResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: Token;
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: Token;
|
||||
};
|
||||
|
||||
export type RefreshTokenResponse = RefreshTokenResponses[keyof RefreshTokenResponses];
|
||||
export type RefreshTokenResponse =
|
||||
RefreshTokenResponses[keyof RefreshTokenResponses];
|
||||
|
||||
export type ChangePasswordData = {
|
||||
body: BodyChangePassword;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: '/api/v1/auth/change-password';
|
||||
body: BodyChangePassword;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/api/v1/auth/change-password";
|
||||
};
|
||||
|
||||
export type ChangePasswordErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type ChangePasswordError = ChangePasswordErrors[keyof ChangePasswordErrors];
|
||||
export type ChangePasswordError =
|
||||
ChangePasswordErrors[keyof ChangePasswordErrors];
|
||||
|
||||
export type ChangePasswordResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: unknown;
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: unknown;
|
||||
};
|
||||
|
||||
export type GetCurrentUserInfoData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: '/api/v1/auth/me';
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/api/v1/auth/me";
|
||||
};
|
||||
|
||||
export type GetCurrentUserInfoResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: UserResponse;
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: UserResponse;
|
||||
};
|
||||
|
||||
export type GetCurrentUserInfoResponse = GetCurrentUserInfoResponses[keyof GetCurrentUserInfoResponses];
|
||||
export type GetCurrentUserInfoResponse =
|
||||
GetCurrentUserInfoResponses[keyof GetCurrentUserInfoResponses];
|
||||
|
||||
export type ClientOptions = {
|
||||
baseURL: 'http://localhost:8000' | (string & {});
|
||||
};
|
||||
baseURL: "http://localhost:8000" | (string & {});
|
||||
};
|
||||
|
||||
@@ -1,45 +1,53 @@
|
||||
'use client';
|
||||
"use client";
|
||||
|
||||
import React, {createContext, useContext, useState, useEffect, ReactNode, useCallback, useMemo} from 'react';
|
||||
import {useRouter, usePathname} from 'next/navigation';
|
||||
import {jwtDecode} from 'jwt-decode';
|
||||
import {client} from '@/client/client.gen';
|
||||
import {useMutation, useQueryClient, useQuery, type UseQueryOptions} from '@tanstack/react-query';
|
||||
import {loginMutation, getCurrentUserInfoOptions} from '@/client/@tanstack/react-query.gen';
|
||||
import {LoginRequest, UserResponse, Token} from '@/client/types.gen';
|
||||
import React, {
|
||||
createContext,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
import { client } from "@/client/client.gen";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
getCurrentUserInfoOptions,
|
||||
loginMutation,
|
||||
} from "@/client/@tanstack/react-query.gen";
|
||||
import { LoginRequest, Token, UserResponse } from "@/client/types.gen";
|
||||
|
||||
// JWT token payload interface
|
||||
interface TokenPayload {
|
||||
sub: string;
|
||||
exp: number;
|
||||
role?: string;
|
||||
sub: string;
|
||||
exp: number;
|
||||
role?: string;
|
||||
|
||||
[key: string]: any;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
// Auth context state interface
|
||||
interface AuthContextState {
|
||||
user: UserResponse | null;
|
||||
isAuthenticated: boolean;
|
||||
isLoading: boolean;
|
||||
error: Error | null;
|
||||
login: (credentials: LoginRequest) => Promise<void>;
|
||||
logout: () => void;
|
||||
refreshToken: () => Promise<void>;
|
||||
user: UserResponse | null;
|
||||
isAuthenticated: boolean;
|
||||
isLoading: boolean;
|
||||
error: Error | null;
|
||||
login: (credentials: LoginRequest) => Promise<void>;
|
||||
logout: () => void;
|
||||
refreshToken: () => Promise<void>;
|
||||
}
|
||||
|
||||
// Default context state
|
||||
const defaultAuthState: AuthContextState = {
|
||||
user: null,
|
||||
isAuthenticated: false,
|
||||
isLoading: true,
|
||||
error: null,
|
||||
login: async () => {
|
||||
},
|
||||
logout: () => {
|
||||
},
|
||||
refreshToken: async () => {
|
||||
},
|
||||
user: null,
|
||||
isAuthenticated: false,
|
||||
isLoading: true,
|
||||
error: null,
|
||||
login: async () => {},
|
||||
logout: () => {},
|
||||
refreshToken: async () => {},
|
||||
};
|
||||
|
||||
// Create context
|
||||
@@ -47,255 +55,256 @@ const AuthContext = createContext<AuthContextState>(defaultAuthState);
|
||||
|
||||
// Custom hook to use the auth context
|
||||
export const useAuth = () => {
|
||||
const context = useContext(AuthContext);
|
||||
if (!context) {
|
||||
throw new Error('useAuth must be used within an AuthProvider');
|
||||
}
|
||||
return context;
|
||||
const context = useContext(AuthContext);
|
||||
if (!context) {
|
||||
throw new Error("useAuth must be used within an AuthProvider");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
// Token management
|
||||
const TOKEN_KEY = 'accessToken';
|
||||
const REFRESH_TOKEN_KEY = 'refreshToken';
|
||||
const TOKEN_KEY = "accessToken";
|
||||
const REFRESH_TOKEN_KEY = "refreshToken";
|
||||
|
||||
// Get token from storage
|
||||
const getStoredToken = (): string | null => {
|
||||
if (typeof window === 'undefined') return null;
|
||||
return localStorage.getItem(TOKEN_KEY);
|
||||
if (typeof window === "undefined") return null;
|
||||
return localStorage.getItem(TOKEN_KEY);
|
||||
};
|
||||
|
||||
// Store token in storage
|
||||
const storeToken = (token: string | null, refreshToken: string | null = null): void => {
|
||||
if (typeof window === 'undefined') return;
|
||||
const storeToken = (
|
||||
token: string | null,
|
||||
refreshToken: string | null = null,
|
||||
): void => {
|
||||
if (typeof window === "undefined") return;
|
||||
|
||||
if (token) {
|
||||
localStorage.setItem(TOKEN_KEY, token);
|
||||
if (refreshToken) {
|
||||
localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);
|
||||
}
|
||||
} else {
|
||||
localStorage.removeItem(TOKEN_KEY);
|
||||
localStorage.removeItem(REFRESH_TOKEN_KEY);
|
||||
if (token) {
|
||||
localStorage.setItem(TOKEN_KEY, token);
|
||||
if (refreshToken) {
|
||||
localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);
|
||||
}
|
||||
} else {
|
||||
localStorage.removeItem(TOKEN_KEY);
|
||||
localStorage.removeItem(REFRESH_TOKEN_KEY);
|
||||
}
|
||||
};
|
||||
|
||||
// Check if token is expired
|
||||
const isTokenExpired = (token: string): boolean => {
|
||||
try {
|
||||
const decoded = jwtDecode<TokenPayload>(token);
|
||||
const currentTime = Date.now() / 1000;
|
||||
// Add a buffer of 10 seconds to prevent edge cases
|
||||
return decoded.exp < currentTime - 10;
|
||||
} catch (error) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
const decoded = jwtDecode<TokenPayload>(token);
|
||||
const currentTime = Date.now() / 1000;
|
||||
// Add a buffer of 10 seconds to prevent edge cases
|
||||
return decoded.exp < currentTime - 10;
|
||||
} catch (error) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Auth Provider Props
|
||||
interface AuthProviderProps {
|
||||
children: ReactNode;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
// Auth Provider Component
|
||||
export const AuthProvider: React.FC<AuthProviderProps> = ({children}: AuthProviderProps) => {
|
||||
const [isInitializing, setIsInitializing] = useState(true);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const queryClient = useQueryClient();
|
||||
export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
|
||||
const [isInitializing, setIsInitializing] = useState(true);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// Set up login mutation
|
||||
const loginMutationHook = useMutation(loginMutation());
|
||||
// Set up login mutation
|
||||
const loginMutationHook = useMutation(loginMutation());
|
||||
|
||||
// Configure API client with token if available
|
||||
useEffect(() => {
|
||||
const token = getStoredToken();
|
||||
if (token) {
|
||||
client.setConfig({
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
// Configure API client with token if available
|
||||
useEffect(() => {
|
||||
const token = getStoredToken();
|
||||
if (token) {
|
||||
client.setConfig({
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
const hasValidToken = useCallback((): boolean => {
|
||||
const token = getStoredToken();
|
||||
return Boolean(token && !isTokenExpired(token));
|
||||
}, []);
|
||||
// Check if current token is valid (not expired)
|
||||
const hasValidToken = useCallback((): boolean => {
|
||||
const token = getStoredToken();
|
||||
return Boolean(token && !isTokenExpired(token));
|
||||
}, []);
|
||||
|
||||
// Create query options
|
||||
const userQueryOptions = {
|
||||
...getCurrentUserInfoOptions(),
|
||||
enabled: hasValidToken(),
|
||||
retry: false,
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
} as UseQueryOptions;
|
||||
// Create query options
|
||||
const userQueryOptions = {
|
||||
...getCurrentUserInfoOptions(),
|
||||
enabled: hasValidToken(),
|
||||
retry: false,
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
};
|
||||
|
||||
// Use the query without onError in the options
|
||||
const {data: user, isLoading, error, refetch} = useQuery(userQueryOptions);
|
||||
// Use the query without onError in the options
|
||||
const { data: user, isLoading, error, refetch } = useQuery(userQueryOptions);
|
||||
|
||||
// Handle error with a separate effect
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
// Clear tokens on error (unauthorized)
|
||||
storeToken(null);
|
||||
}
|
||||
}, [error]);
|
||||
// Handle error with a separate effect
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
// Clear tokens on error (unauthorized)
|
||||
storeToken(null);
|
||||
}
|
||||
}, [error]);
|
||||
|
||||
// Login function
|
||||
const login = useCallback(async (credentials: LoginRequest): Promise<void> => {
|
||||
try {
|
||||
const response = await loginMutationHook.mutateAsync({
|
||||
body: credentials
|
||||
});
|
||||
// Login function
|
||||
const login = useCallback(
|
||||
async (credentials: LoginRequest): Promise<void> => {
|
||||
try {
|
||||
const response = await loginMutationHook.mutateAsync({
|
||||
body: credentials,
|
||||
});
|
||||
|
||||
// Store tokens
|
||||
storeToken(response.access_token, response.refresh_token || null);
|
||||
// Store tokens
|
||||
storeToken(response.access_token, response.refresh_token || null);
|
||||
|
||||
// Configure client with new token
|
||||
client.setConfig({
|
||||
headers: {
|
||||
Authorization: `Bearer ${response.access_token}`
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger user data fetch
|
||||
await refetch();
|
||||
|
||||
// Redirect after login
|
||||
if (pathname === '/login') {
|
||||
router.push('/dashboard');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Login failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}, [loginMutationHook, refetch, router, pathname]);
|
||||
|
||||
// Logout function
|
||||
const logout = useCallback((): void => {
|
||||
// Clear tokens
|
||||
storeToken(null);
|
||||
|
||||
// Remove auth headers
|
||||
// Configure client with new token
|
||||
client.setConfig({
|
||||
headers: {
|
||||
Authorization: undefined
|
||||
}
|
||||
headers: {
|
||||
Authorization: `Bearer ${response.access_token}`,
|
||||
},
|
||||
});
|
||||
|
||||
// Clear user from cache
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: getCurrentUserInfoOptions().queryKey
|
||||
// Trigger user data fetch
|
||||
await refetch();
|
||||
|
||||
// Redirect after login
|
||||
if (pathname === "/login") {
|
||||
router.push("/dashboard");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Login failed:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[loginMutationHook, refetch, router, pathname],
|
||||
);
|
||||
|
||||
// Logout function
|
||||
const logout = useCallback((): void => {
|
||||
// Clear tokens
|
||||
storeToken(null);
|
||||
|
||||
// Remove auth headers
|
||||
client.setConfig({
|
||||
headers: {
|
||||
Authorization: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
// Clear user from cache
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: getCurrentUserInfoOptions().queryKey,
|
||||
});
|
||||
|
||||
// Redirect to login page
|
||||
router.push("/login");
|
||||
}, [router, queryClient]);
|
||||
|
||||
// Refresh token function
|
||||
const refreshToken = useCallback(async (): Promise<void> => {
|
||||
const refreshTokenValue = localStorage.getItem(REFRESH_TOKEN_KEY);
|
||||
|
||||
if (!refreshTokenValue) {
|
||||
logout();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await client.post<Token>({
|
||||
url: "/api/v1/auth/refresh",
|
||||
body: { refresh_token: refreshTokenValue },
|
||||
});
|
||||
|
||||
const newTokens = response.data;
|
||||
|
||||
if (newTokens) {
|
||||
// Store new tokens
|
||||
storeToken(newTokens.access_token, newTokens.refresh_token || null);
|
||||
|
||||
// Update client headers
|
||||
client.setConfig({
|
||||
headers: {
|
||||
Authorization: `Bearer ${newTokens.access_token}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
// Refetch user data
|
||||
await refetch();
|
||||
} catch (error) {
|
||||
console.error("Token refresh failed:", error);
|
||||
logout();
|
||||
}
|
||||
}, [logout, refetch]);
|
||||
|
||||
// Redirect to login page
|
||||
router.push('/login');
|
||||
}, [router, queryClient]);
|
||||
// Check token validity and refresh if needed on route changes
|
||||
useEffect(() => {
|
||||
const token = getStoredToken();
|
||||
|
||||
// Refresh token function
|
||||
const refreshToken = useCallback(async (): Promise<void> => {
|
||||
const refreshTokenValue = localStorage.getItem(REFRESH_TOKEN_KEY);
|
||||
if (token && isTokenExpired(token)) {
|
||||
refreshToken();
|
||||
}
|
||||
|
||||
if (!refreshTokenValue) {
|
||||
logout();
|
||||
return;
|
||||
}
|
||||
setIsInitializing(false);
|
||||
}, [pathname, refreshToken]);
|
||||
|
||||
try {
|
||||
const response = await client.post<Token>({
|
||||
url: '/api/v1/auth/refresh',
|
||||
body: {refresh_token: refreshTokenValue},
|
||||
});
|
||||
// Protected routes logic
|
||||
useEffect(() => {
|
||||
if (isInitializing) return;
|
||||
|
||||
const newTokens = response.data;
|
||||
const protectedRoutes = [
|
||||
"/admin",
|
||||
"/dashboard",
|
||||
"/events/create",
|
||||
"/events/edit",
|
||||
"/profile",
|
||||
];
|
||||
|
||||
if (newTokens) {
|
||||
// Store new tokens
|
||||
storeToken(newTokens.access_token, newTokens.refresh_token || null);
|
||||
const publicOnlyRoutes = ["/login", "/register"];
|
||||
|
||||
// Update client headers
|
||||
client.setConfig({
|
||||
headers: {
|
||||
Authorization: `Bearer ${newTokens.access_token}`
|
||||
}
|
||||
});
|
||||
const publicRoutes = ["/", "/invite", "/rsvp"];
|
||||
|
||||
}
|
||||
// Refetch user data
|
||||
await refetch();
|
||||
} catch (error) {
|
||||
console.error('Token refresh failed:', error);
|
||||
logout();
|
||||
}
|
||||
}, [logout, refetch]);
|
||||
|
||||
// Check token validity and refresh if needed on route changes
|
||||
useEffect(() => {
|
||||
const token = getStoredToken();
|
||||
|
||||
if (token && isTokenExpired(token)) {
|
||||
refreshToken();
|
||||
}
|
||||
|
||||
setIsInitializing(false);
|
||||
}, [pathname, refreshToken]);
|
||||
|
||||
// Protected routes logic
|
||||
useEffect(() => {
|
||||
if (isInitializing) return;
|
||||
|
||||
const protectedRoutes = [
|
||||
'/admin',
|
||||
'/dashboard',
|
||||
'/events/create',
|
||||
'/events/edit',
|
||||
'/profile',
|
||||
];
|
||||
|
||||
const publicOnlyRoutes = [
|
||||
'/login',
|
||||
'/register',
|
||||
];
|
||||
|
||||
const publicRoutes = [
|
||||
'/',
|
||||
'/invite',
|
||||
'/rsvp',
|
||||
];
|
||||
|
||||
const isProtectedRoute = protectedRoutes.some(route => pathname?.startsWith(route));
|
||||
const isPublicOnlyRoute = publicOnlyRoutes.some(route => pathname === route);
|
||||
|
||||
// Handle loading state
|
||||
if (isLoading && isProtectedRoute) return;
|
||||
|
||||
// Redirect to login if not authenticated but trying to access protected route
|
||||
if (isProtectedRoute && !user) {
|
||||
router.push(`/login?redirect=${encodeURIComponent(pathname || '')}`);
|
||||
}
|
||||
|
||||
// Redirect to dashboard if authenticated but trying to access public-only route
|
||||
if (isPublicOnlyRoute && user) {
|
||||
router.push('/dashboard');
|
||||
}
|
||||
}, [user, isLoading, pathname, router, isInitializing]);
|
||||
|
||||
// Create the context value
|
||||
const value = useMemo<AuthContextState>(() => ({
|
||||
user: user as UserResponse | null,
|
||||
isAuthenticated: !!user,
|
||||
isLoading: isInitializing || isLoading,
|
||||
error: error as Error | null,
|
||||
login,
|
||||
logout,
|
||||
refreshToken,
|
||||
}), [user, isInitializing, isLoading, error, login, logout, refreshToken]);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={value}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
const isProtectedRoute = protectedRoutes.some((route) =>
|
||||
pathname?.startsWith(route),
|
||||
);
|
||||
const isPublicOnlyRoute = publicOnlyRoutes.some(
|
||||
(route) => pathname === route,
|
||||
);
|
||||
};
|
||||
|
||||
// Handle loading state
|
||||
if (isLoading && isProtectedRoute) return;
|
||||
|
||||
// Redirect to login if not authenticated but trying to access protected route
|
||||
if (isProtectedRoute && !user) {
|
||||
router.push(`/login?redirect=${encodeURIComponent(pathname || "")}`);
|
||||
}
|
||||
|
||||
// Redirect to dashboard if authenticated but trying to access public-only route
|
||||
if (isPublicOnlyRoute && user) {
|
||||
router.push("/dashboard");
|
||||
}
|
||||
}, [user, isLoading, pathname, router, isInitializing]);
|
||||
|
||||
// Create the context value
|
||||
const value = useMemo<AuthContextState>(
|
||||
() => ({
|
||||
user: user as UserResponse | null,
|
||||
isAuthenticated: !!user,
|
||||
isLoading: isInitializing || isLoading,
|
||||
error: error as Error | null,
|
||||
login,
|
||||
logout,
|
||||
refreshToken,
|
||||
}),
|
||||
[user, isInitializing, isLoading, error, login, logout, refreshToken],
|
||||
);
|
||||
|
||||
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
||||
};
|
||||
|
||||
10
frontend/src/types/api.d.ts
vendored
10
frontend/src/types/api.d.ts
vendored
@@ -1,7 +1,7 @@
|
||||
declare namespace API {
|
||||
interface ErrorResponse {
|
||||
detail: string;
|
||||
}
|
||||
interface ErrorResponse {
|
||||
detail: string;
|
||||
}
|
||||
|
||||
// Add more types as you develop your API
|
||||
}
|
||||
// Add more types as you develop your API
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user