From 0120641e3aee93d4bef83c9125e6490544110fa0 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Thu, 2 Oct 2025 20:30:02 +0200 Subject: [PATCH] feat: onboarding flow --- .../api-client/@tanstack/react-query.gen.ts | 170 ++++++++++++++++++ apps/client/app/api-client/sdk.gen.ts | 63 +++++++ apps/client/app/api-client/types.gen.ts | 123 +++++++++++++ 3 files changed, 356 insertions(+) diff --git a/apps/client/app/api-client/@tanstack/react-query.gen.ts b/apps/client/app/api-client/@tanstack/react-query.gen.ts index aa9bf19..bc0df28 100644 --- a/apps/client/app/api-client/@tanstack/react-query.gen.ts +++ b/apps/client/app/api-client/@tanstack/react-query.gen.ts @@ -2,6 +2,11 @@ import { type Options, + register, + login, + logout, + getMe, + getStatus, listVolumes, createVolume, testConnection, @@ -15,6 +20,14 @@ import { } from "../sdk.gen"; import { queryOptions, type UseMutationOptions, type DefaultError } from "@tanstack/react-query"; import type { + RegisterData, + RegisterResponse, + LoginData, + LoginResponse, + LogoutData, + LogoutResponse, + GetMeData, + GetStatusData, ListVolumesData, CreateVolumeData, CreateVolumeResponse, @@ -74,6 +87,163 @@ const createQueryKey = ( return [params]; }; +export const registerQueryKey = (options?: Options) => createQueryKey("register", options); + +/** + * Register a new user + */ +export const registerOptions = (options?: Options) => { + return queryOptions({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await register({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: registerQueryKey(options), + }); +}; + +/** + * Register a new user + */ +export const registerMutation = ( + options?: Partial>, +): UseMutationOptions> => { + const mutationOptions: UseMutationOptions> = { + mutationFn: async (localOptions) => { + const { data } = await register({ + ...options, + ...localOptions, + throwOnError: true, + }); + return data; + }, + }; + return mutationOptions; +}; + +export const loginQueryKey = (options?: Options) => createQueryKey("login", options); + +/** + * Login with username and password + */ +export const loginOptions = (options?: Options) => { + return queryOptions({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await login({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: loginQueryKey(options), + }); +}; + +/** + * Login with username and password + */ +export const loginMutation = ( + options?: Partial>, +): UseMutationOptions> => { + const mutationOptions: UseMutationOptions> = { + mutationFn: async (localOptions) => { + const { data } = await login({ + ...options, + ...localOptions, + throwOnError: true, + }); + return data; + }, + }; + return mutationOptions; +}; + +export const logoutQueryKey = (options?: Options) => createQueryKey("logout", options); + +/** + * Logout current user + */ +export const logoutOptions = (options?: Options) => { + return queryOptions({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await logout({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: logoutQueryKey(options), + }); +}; + +/** + * Logout current user + */ +export const logoutMutation = ( + options?: Partial>, +): UseMutationOptions> => { + const mutationOptions: UseMutationOptions> = { + mutationFn: async (localOptions) => { + const { data } = await logout({ + ...options, + ...localOptions, + throwOnError: true, + }); + return data; + }, + }; + return mutationOptions; +}; + +export const getMeQueryKey = (options?: Options) => createQueryKey("getMe", options); + +/** + * Get current authenticated user + */ +export const getMeOptions = (options?: Options) => { + return queryOptions({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await getMe({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: getMeQueryKey(options), + }); +}; + +export const getStatusQueryKey = (options?: Options) => createQueryKey("getStatus", options); + +/** + * Get authentication system status + */ +export const getStatusOptions = (options?: Options) => { + return queryOptions({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await getStatus({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: getStatusQueryKey(options), + }); +}; + export const listVolumesQueryKey = (options?: Options) => createQueryKey("listVolumes", options); /** diff --git a/apps/client/app/api-client/sdk.gen.ts b/apps/client/app/api-client/sdk.gen.ts index dbf3ced..b0e3093 100644 --- a/apps/client/app/api-client/sdk.gen.ts +++ b/apps/client/app/api-client/sdk.gen.ts @@ -2,6 +2,19 @@ import type { Options as ClientOptions, TDataShape, Client } from "./client"; import type { + RegisterData, + RegisterResponses, + RegisterErrors, + LoginData, + LoginResponses, + LoginErrors, + LogoutData, + LogoutResponses, + GetMeData, + GetMeResponses, + GetMeErrors, + GetStatusData, + GetStatusResponses, ListVolumesData, ListVolumesResponses, CreateVolumeData, @@ -48,6 +61,56 @@ export type Options; }; +/** + * Register a new user + */ +export const register = (options?: Options) => { + return (options?.client ?? _heyApiClient).post({ + url: "/api/v1/auth/register", + ...options, + }); +}; + +/** + * Login with username and password + */ +export const login = (options?: Options) => { + return (options?.client ?? _heyApiClient).post({ + url: "/api/v1/auth/login", + ...options, + }); +}; + +/** + * Logout current user + */ +export const logout = (options?: Options) => { + return (options?.client ?? _heyApiClient).post({ + url: "/api/v1/auth/logout", + ...options, + }); +}; + +/** + * Get current authenticated user + */ +export const getMe = (options?: Options) => { + return (options?.client ?? _heyApiClient).get({ + url: "/api/v1/auth/me", + ...options, + }); +}; + +/** + * Get authentication system status + */ +export const getStatus = (options?: Options) => { + return (options?.client ?? _heyApiClient).get({ + url: "/api/v1/auth/status", + ...options, + }); +}; + /** * List all volumes */ diff --git a/apps/client/app/api-client/types.gen.ts b/apps/client/app/api-client/types.gen.ts index e4ee4a2..1949eeb 100644 --- a/apps/client/app/api-client/types.gen.ts +++ b/apps/client/app/api-client/types.gen.ts @@ -1,5 +1,128 @@ // This file is auto-generated by @hey-api/openapi-ts +export type RegisterData = { + body?: never; + path?: never; + query?: never; + url: "/api/v1/auth/register"; +}; + +export type RegisterErrors = { + /** + * Invalid request or username already exists + */ + 400: unknown; +}; + +export type RegisterResponses = { + /** + * User created successfully + */ + 201: { + message: string; + user: { + id: string; + username: string; + }; + }; +}; + +export type RegisterResponse = RegisterResponses[keyof RegisterResponses]; + +export type LoginData = { + body?: never; + path?: never; + query?: never; + url: "/api/v1/auth/login"; +}; + +export type LoginErrors = { + /** + * Invalid credentials + */ + 401: unknown; +}; + +export type LoginResponses = { + /** + * Login successful + */ + 200: { + message: string; + user: { + id: string; + username: string; + }; + }; +}; + +export type LoginResponse = LoginResponses[keyof LoginResponses]; + +export type LogoutData = { + body?: never; + path?: never; + query?: never; + url: "/api/v1/auth/logout"; +}; + +export type LogoutResponses = { + /** + * Logout successful + */ + 200: { + message: string; + }; +}; + +export type LogoutResponse = LogoutResponses[keyof LogoutResponses]; + +export type GetMeData = { + body?: never; + path?: never; + query?: never; + url: "/api/v1/auth/me"; +}; + +export type GetMeErrors = { + /** + * Not authenticated + */ + 401: unknown; +}; + +export type GetMeResponses = { + /** + * Current user information + */ + 200: { + message: string; + user: { + id: string; + username: string; + }; + }; +}; + +export type GetMeResponse = GetMeResponses[keyof GetMeResponses]; + +export type GetStatusData = { + body?: never; + path?: never; + query?: never; + url: "/api/v1/auth/status"; +}; + +export type GetStatusResponses = { + /** + * Authentication system status + */ + 200: { + hasUsers: boolean; + }; +}; + +export type GetStatusResponse = GetStatusResponses[keyof GetStatusResponses]; + export type ListVolumesData = { body?: never; path?: never;