From f4ad5c6abea1d42e6d8d5cff9ae5e2fb5566ee7f Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Wed, 25 Mar 2026 21:27:02 +0900 Subject: [PATCH 1/2] Fix refactor --- packages/core/src/additional.ts | 18 +- packages/core/src/api-struct.ts | 52 ++--- packages/core/src/utils.ts | 3 +- packages/hookform/src/types.ts | 69 ++----- packages/react-query/src/query-client.ts | 236 ++++++++++++++--------- packages/zod/src/schema-struct.ts | 60 ++---- 6 files changed, 214 insertions(+), 224 deletions(-) diff --git a/packages/core/src/additional.ts b/packages/core/src/additional.ts index 9d9e093..7726b76 100644 --- a/packages/core/src/additional.ts +++ b/packages/core/src/additional.ts @@ -6,15 +6,10 @@ export type Additional< Target extends object, > = T extends keyof Target ? Target[T] & object : object -export type RequiredOptions = keyof T extends undefined +export type RequiredOptions = ('params' | 'query' | 'body') & + keyof T extends never ? never - : 'params' extends keyof T - ? T - : 'query' extends keyof T - ? T - : 'body' extends keyof T - ? T - : never + : T export type IsCold = keyof DevupApiServers extends never ? true : false export type DevupApiRequestInit = Omit & { body?: object | RequestInit['body'] @@ -40,9 +35,10 @@ export type ExtractValue = V extends keyof T export type BoildApiOption = Omit & Omit -export type ConditionalApiOption = IsCold extends true - ? DevupApiRequestInit - : BoildApiOption +export type ConditionalApiOption< + O, + _Cold extends boolean = IsCold, +> = _Cold extends true ? DevupApiRequestInit : BoildApiOption export type ApiOption = [ RequiredOptions, diff --git a/packages/core/src/api-struct.ts b/packages/core/src/api-struct.ts index 867bcd1..5d2dbf1 100644 --- a/packages/core/src/api-struct.ts +++ b/packages/core/src/api-struct.ts @@ -31,14 +31,13 @@ export interface DevupErrorComponentStruct {} export type DevupObject< R extends 'response' | 'request' | 'error' = 'response', T extends keyof DevupApiServers | (string & {}) = 'openapi.json', -> = ExtractValue< - { - response: ExtractValue - request: ExtractValue - error: ExtractValue - }, - R -> +> = R extends 'response' + ? ExtractValue + : R extends 'request' + ? ExtractValue + : R extends 'error' + ? ExtractValue + : never export type DevupGetApiStructScope = ConditionalScope< DevupGetApiStruct, @@ -91,18 +90,22 @@ export type DevupApiMethodKeys = export type DevupApiMethodScope< S extends string, M extends DevupApiMethodKeys, -> = { - get: DevupGetApiStructScope - post: DevupPostApiStructScope - put: DevupPutApiStructScope - delete: DevupDeleteApiStructScope - patch: DevupPatchApiStructScope - GET: DevupGetApiStructScope - POST: DevupPostApiStructScope - PUT: DevupPutApiStructScope - DELETE: DevupDeleteApiStructScope - PATCH: DevupPatchApiStructScope -}[M] +> = M extends 'get' | 'GET' + ? DevupGetApiStructScope + : M extends 'post' | 'POST' + ? DevupPostApiStructScope + : M extends 'put' | 'PUT' + ? DevupPutApiStructScope + : M extends 'delete' | 'DELETE' + ? DevupDeleteApiStructScope + : M extends 'patch' | 'PATCH' + ? DevupPatchApiStructScope + : never + +export type DevupApiMethodKey< + S extends string, + M extends DevupApiMethodKeys, +> = ConditionalKeys> export type DevupApiStructScope = DevupGetApiStructScope & DevupPostApiStructScope & @@ -110,6 +113,9 @@ export type DevupApiStructScope = DevupGetApiStructScope & DevupDeleteApiStructScope & DevupPatchApiStructScope -export type DevupApiStructKey = ConditionalKeys< - DevupApiStructScope -> +export type DevupApiStructKey = + | DevupGetApiStructKey + | DevupPostApiStructKey + | DevupPutApiStructKey + | DevupDeleteApiStructKey + | DevupPatchApiStructKey diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 631c09f..4da947b 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -1,6 +1,7 @@ import type { ExtractValue } from './additional' +import type { DevupApiServers } from './api-struct' -export type ConditionalKeys = keyof T extends undefined +export type ConditionalKeys = keyof DevupApiServers extends never ? F : keyof T & string export type ConditionalScope = ExtractValue diff --git a/packages/hookform/src/types.ts b/packages/hookform/src/types.ts index 3951013..96ede8a 100644 --- a/packages/hookform/src/types.ts +++ b/packages/hookform/src/types.ts @@ -2,17 +2,9 @@ import type { Additional, ConditionalKeys, DevupApi, + DevupApiMethodKey, + DevupApiMethodScope, DevupApiServers, - DevupDeleteApiStructKey, - DevupDeleteApiStructScope, - DevupGetApiStructKey, - DevupGetApiStructScope, - DevupPatchApiStructKey, - DevupPatchApiStructScope, - DevupPostApiStructKey, - DevupPostApiStructScope, - DevupPutApiStructKey, - DevupPutApiStructScope, ExtractValue, } from '@devup-api/fetch' import type { QueryClient, UseMutationResult } from '@tanstack/react-query' @@ -31,58 +23,22 @@ export type FetchMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' export type MethodApiStructScope< S extends string, M extends HttpMethod, -> = M extends 'post' - ? DevupPostApiStructScope - : M extends 'put' - ? DevupPutApiStructScope - : M extends 'patch' - ? DevupPatchApiStructScope - : M extends 'delete' - ? DevupDeleteApiStructScope - : never +> = DevupApiMethodScope export type MethodApiStructKey< S extends string, M extends HttpMethod, -> = M extends 'post' - ? DevupPostApiStructKey - : M extends 'put' - ? DevupPutApiStructKey - : M extends 'patch' - ? DevupPatchApiStructKey - : M extends 'delete' - ? DevupDeleteApiStructKey - : never +> = DevupApiMethodKey export type FetchMethodApiStructScope< S extends string, M extends FetchMethod, -> = M extends 'get' - ? DevupGetApiStructScope - : M extends 'post' - ? DevupPostApiStructScope - : M extends 'put' - ? DevupPutApiStructScope - : M extends 'patch' - ? DevupPatchApiStructScope - : M extends 'delete' - ? DevupDeleteApiStructScope - : never +> = DevupApiMethodScope export type FetchMethodApiStructKey< S extends string, M extends FetchMethod, -> = M extends 'get' - ? DevupGetApiStructKey - : M extends 'post' - ? DevupPostApiStructKey - : M extends 'put' - ? DevupPutApiStructKey - : M extends 'patch' - ? DevupPatchApiStructKey - : M extends 'delete' - ? DevupDeleteApiStructKey - : never +> = DevupApiMethodKey /** * Configuration for auto-fetching default values @@ -91,10 +47,6 @@ export interface FetchDefaultValuesConfig< S extends ConditionalKeys, FM extends FetchMethod = 'get', FP extends FetchMethodApiStructKey = FetchMethodApiStructKey, - FO extends Additional> = Additional< - FP, - FetchMethodApiStructScope - >, > { /** * HTTP method for fetching default values @@ -108,11 +60,16 @@ export interface FetchDefaultValuesConfig< /** * Request options for fetching (params, query, headers) */ - options?: Omit + options?: Omit>, 'body'> /** * Transform the fetched response to form default values */ - transform?: (response: ExtractValue) => unknown + transform?: ( + response: ExtractValue< + Additional>, + 'response' + >, + ) => unknown } /** diff --git a/packages/react-query/src/query-client.ts b/packages/react-query/src/query-client.ts index 2eec699..6ea3a11 100644 --- a/packages/react-query/src/query-client.ts +++ b/packages/react-query/src/query-client.ts @@ -39,28 +39,30 @@ type UseQueriesTuple = [ queryOptions?: UseQueryOptions, ] +type LowercaseMethodKeys = 'get' | 'post' | 'put' | 'delete' | 'patch' + type UseQueriesEntry> = { - [M in DevupApiMethodKeys]: { - [P in ConditionalKeys>]: UseQueriesTuple< - ResolveScope, - P, - M - > + [M in LowercaseMethodKeys]: { + [P in ConditionalKeys>]: + | UseQueriesTuple, P, M> + | UseQueriesTuple, P, Uppercase> }[ConditionalKeys>] -}[DevupApiMethodKeys] +}[LowercaseMethodKeys] type InferUseQueryResult< S extends ConditionalKeys, Q, -> = Q extends [infer M extends DevupApiMethodKeys, infer P, ...unknown[]] - ? P extends ConditionalKeys> - ? ReturnType< - typeof useQuery< - ExtractValue, 'response'>, - ExtractValue, 'error'> - > +> = Q extends [ + infer M extends DevupApiMethodKeys, + infer P extends string, + ...unknown[], +] + ? ReturnType< + typeof useQuery< + ExtractValue, 'response'>, + ExtractValue, 'error'> > - : ReturnType + > : ReturnType type UseQueriesResults< @@ -87,80 +89,97 @@ export class DevupQueryClient> { useQuery< M extends DevupApiMethodKeys, - ST extends DevupApiMethodScope, - T extends ConditionalKeys, - O extends Additional, - D extends ExtractValue, - E extends ExtractValue, + T extends ConditionalKeys>, >( method: M, path: T, ...options: ApiOption< - O, + ResolveScope, [ - queryOptions?: Omit< - Parameters>[0], - 'queryFn' | 'queryKey' - >, - queryClient?: Parameters>[1], + queryOptions?: UseQueryOptions>, + queryClient?: Parameters[1], ] > - ): ReturnType> & { + ): ReturnType< + typeof useQuery< + ExtractValue, 'response'>, + ExtractValue, 'error'> + > + > & { queryKey: [M, T, ...unknown[]] } { const queryKey = getQueryKey(method, path, options[0]) - const result = useQuery( + // biome-ignore lint/suspicious/noExplicitAny: internal cast - type safety from signature + const result = useQuery( { queryKey, - queryFn: ({ - queryKey: [method, path, ...options], - signal, - }): Promise => + queryFn: ({ queryKey: [method, path, ...options], signal }) => // biome-ignore lint/suspicious/noExplicitAny: can't use method as a function (this.api as any) [method as string](path, { signal, ...(options[0] as DevupApiRequestInit), }) - .then(({ data, error, isError }: DevupApiResponse) => { - if (isError) throw error - return data - }), + .then( + ({ + data, + error, + isError, + }: DevupApiResponse) => { + if (isError) throw error + return data + }, + ), ...options[1], }, options[2], ) - return Object.assign(result, { queryKey }) + // biome-ignore lint/suspicious/noExplicitAny: internal cast - type safety from signature + return Object.assign(result, { queryKey }) as any } useMutation< M extends DevupApiMethodKeys, - ST extends DevupApiMethodScope, - T extends ConditionalKeys, - O extends Additional, - D extends ExtractValue, - E extends ExtractValue, - V extends ApiOption[0], + T extends ConditionalKeys>, >( method: M, path: T, queryOptions?: Omit< - Parameters>[0], + Parameters< + typeof useMutation< + ExtractValue, 'response'>, + ExtractValue, 'error'>, + ApiOption>[0] + > + >[0], 'mutationFn' | 'mutationKey' >, - queryClient?: Parameters>[1], - ): ReturnType> { - return useMutation( + queryClient?: Parameters[1], + ): ReturnType< + typeof useMutation< + ExtractValue, 'response'>, + ExtractValue, 'error'>, + ApiOption>[0] + > + > { + // biome-ignore lint/suspicious/noExplicitAny: internal cast - type safety from signature + return useMutation( { mutationKey: [method, path], - mutationFn: (variables: V, { mutationKey }): Promise => + mutationFn: (variables, { mutationKey }) => // biome-ignore lint/suspicious/noExplicitAny: can't use method as a function (this.api as any) [mutationKey?.[0] as string](mutationKey?.[1] as T, variables) - .then(({ data, error, isError }: DevupApiResponse) => { - if (isError) throw error - return data - }), + .then( + ({ + data, + error, + isError, + }: DevupApiResponse) => { + if (isError) throw error + return data + }, + ), ...queryOptions, }, queryClient, @@ -169,85 +188,116 @@ export class DevupQueryClient> { useSuspenseQuery< M extends DevupApiMethodKeys, - ST extends DevupApiMethodScope, - T extends ConditionalKeys, - O extends Additional, - D extends ExtractValue, - E extends ExtractValue, + T extends ConditionalKeys>, >( method: M, path: T, ...options: ApiOption< - O, + ResolveScope, [ queryOptions?: Omit< - Parameters>[0], + Parameters< + typeof useSuspenseQuery< + ExtractValue, 'response'>, + ExtractValue, 'error'> + > + >[0], 'queryFn' | 'queryKey' >, - queryClient?: Parameters>[1], + queryClient?: Parameters[1], ] > - ): ReturnType> & { + ): ReturnType< + typeof useSuspenseQuery< + ExtractValue, 'response'>, + ExtractValue, 'error'> + > + > & { queryKey: [M, T, ...unknown[]] } { const queryKey = getQueryKey(method, path, options[0]) - const result = useSuspenseQuery( + // biome-ignore lint/suspicious/noExplicitAny: internal cast - type safety from signature + const result = useSuspenseQuery( { queryKey, - queryFn: ({ - queryKey: [method, path, ...options], - signal, - }): Promise => + queryFn: ({ queryKey: [method, path, ...options], signal }) => // biome-ignore lint/suspicious/noExplicitAny: can't use method as a function (this.api as any) [method as string](path, { signal, ...(options[0] as DevupApiRequestInit), }) - .then(({ data, error, isError }: DevupApiResponse) => { - if (isError) throw error - return data - }), + .then( + ({ + data, + error, + isError, + }: DevupApiResponse) => { + if (isError) throw error + return data + }, + ), ...options[1], }, options[2], ) - return Object.assign(result, { queryKey }) + // biome-ignore lint/suspicious/noExplicitAny: internal cast - type safety from signature + return Object.assign(result, { queryKey }) as any } useInfiniteQuery< M extends DevupApiMethodKeys, - ST extends DevupApiMethodScope, - T extends ConditionalKeys, - O extends Additional, - D extends ExtractValue, - E extends ExtractValue, + T extends ConditionalKeys>, >( method: M, path: T, ...options: [ - options: ConditionalApiOption & + options: ConditionalApiOption> & Pick< - Parameters>[0], + Parameters< + typeof useInfiniteQuery< + ExtractValue, 'response'>, + ExtractValue, 'error'> + > + >[0], 'getNextPageParam' | 'initialPageParam' >, queryOptions?: Omit< - Parameters>[0], + Parameters< + typeof useInfiniteQuery< + ExtractValue, 'response'>, + ExtractValue, 'error'> + > + >[0], 'queryFn' | 'queryKey' | 'getNextPageParam' | 'initialPageParam' >, - queryClient?: Parameters>[1], + queryClient?: Parameters[1], ] - ): ReturnType> & { + ): ReturnType< + typeof useInfiniteQuery< + ExtractValue, 'response'>, + ExtractValue, 'error'> + > + > & { queryKey: [M, T, ...unknown[]] } { const { getNextPageParam, initialPageParam, ...apiOptions } = options[0] const queryKey = getQueryKey(method, path, apiOptions) - const result = useInfiniteQuery( + // biome-ignore lint/suspicious/noExplicitAny: internal cast - type safety from signature + const result = useInfiniteQuery( { getNextPageParam, initialPageParam, queryKey, - queryFn: ({ queryKey, pageParam, signal }): Promise => { + queryFn: ({ + queryKey, + pageParam, + signal, + }: { + queryKey: unknown[] + pageParam: unknown + signal: AbortSignal + }) => { const [methodKey, pathKey, ...restOptions] = queryKey const apiOptions = restOptions[0] as DevupApiRequestInit | undefined // biome-ignore lint/suspicious/noExplicitAny: can't use method as a function @@ -263,16 +313,24 @@ export class DevupQueryClient> { }, } as DevupApiRequestInit, ) - .then(({ data, error, isError }: DevupApiResponse) => { - if (isError) throw error - return data as D - }) + .then( + ({ + data, + error, + isError, + }: DevupApiResponse) => { + if (isError) throw error + return data + }, + ) }, ...options[1], - } as Parameters>[0], + // biome-ignore lint/suspicious/noExplicitAny: internal cast - type safety from signature + } as any, options[2], ) - return Object.assign(result, { queryKey }) + // biome-ignore lint/suspicious/noExplicitAny: internal cast - type safety from signature + return Object.assign(result, { queryKey }) as any } useQueries< diff --git a/packages/zod/src/schema-struct.ts b/packages/zod/src/schema-struct.ts index facf9b8..72bfc42 100644 --- a/packages/zod/src/schema-struct.ts +++ b/packages/zod/src/schema-struct.ts @@ -28,23 +28,13 @@ export interface DevupZodErrorSchemas {} export type DevupZodSchema< Category extends 'response' | 'request' | 'error' = 'response', Server extends keyof DevupApiServers | (string & {}) = 'openapi.json', -> = ExtractValue< - { - response: ExtractValue< - DevupZodResponseSchemas, - Server, - Record - > - request: ExtractValue< - DevupZodRequestSchemas, - Server, - Record - > - error: ExtractValue> - }, - Category, - Record -> +> = Category extends 'response' + ? ExtractValue> + : Category extends 'request' + ? ExtractValue> + : Category extends 'error' + ? ExtractValue> + : Record /** * Access Zod schemas by category for a specific server @@ -75,36 +65,18 @@ export type DevupZodAllSchemas = { * @example * type User = DevupZodSchemaTypes['response']['User'] */ +type InferZodSchemaMap = { + [K in keyof ExtractValue>]: z.infer< + ExtractValue>[K] + > +} + export type DevupZodSchemaTypes< T extends keyof DevupApiServers | (string & {}) = 'openapi.json', > = { - response: { - [K in keyof ExtractValue< - DevupZodResponseSchemas, - T, - Record - >]: z.infer< - ExtractValue>[K] - > - } - request: { - [K in keyof ExtractValue< - DevupZodRequestSchemas, - T, - Record - >]: z.infer< - ExtractValue>[K] - > - } - error: { - [K in keyof ExtractValue< - DevupZodErrorSchemas, - T, - Record - >]: z.infer< - ExtractValue>[K] - > - } + response: InferZodSchemaMap + request: InferZodSchemaMap + error: InferZodSchemaMap } // ============================================================================= From 1c441ed9ac5ed73e8554df4dbb00324d9aa8de99 Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Wed, 25 Mar 2026 21:54:59 +0900 Subject: [PATCH 2/2] Refactor --- .../changepack_log_maCvVFhSXg-WSKYfKPVeo.json | 1 + examples/next/app/page.tsx | 5 + packages/core/src/api-struct.ts | 16 +- packages/fetch/src/api.ts | 26 +- .../generate-interface.test.ts.snap | 1120 +++++++++++++++++ packages/generator/src/generate-interface.ts | 50 + packages/react-query/src/query-client.ts | 43 +- 7 files changed, 1232 insertions(+), 29 deletions(-) create mode 100644 .changepacks/changepack_log_maCvVFhSXg-WSKYfKPVeo.json diff --git a/.changepacks/changepack_log_maCvVFhSXg-WSKYfKPVeo.json b/.changepacks/changepack_log_maCvVFhSXg-WSKYfKPVeo.json new file mode 100644 index 0000000..f8db8fb --- /dev/null +++ b/.changepacks/changepack_log_maCvVFhSXg-WSKYfKPVeo.json @@ -0,0 +1 @@ +{"changes":{"packages/zod/package.json":"Patch","packages/core/package.json":"Patch","packages/react-query/package.json":"Patch","packages/hookform/package.json":"Patch","packages/generator/package.json":"Patch","packages/fetch/package.json":"Patch"},"note":"Impl pregen, Fix wrong path issue","date":"2026-03-25T12:54:53.475679Z"} \ No newline at end of file diff --git a/examples/next/app/page.tsx b/examples/next/app/page.tsx index 223e125..90665b4 100644 --- a/examples/next/app/page.tsx +++ b/examples/next/app/page.tsx @@ -39,6 +39,11 @@ export default function Home() { const _object2: DevupObject<'response', 'openapi2.json'>['User'] | undefined = data?.[0] + const _results = queryClient.useQueries([ + ['GET', 'getUsers', { query: { name: 'John Doe' } }], + ['GET', '/users/{id}', { params: { id: 1 }, query: { name: 'John Doe' } }], + ]) + console.info(data, isLoading, error) const { diff --git a/packages/core/src/api-struct.ts b/packages/core/src/api-struct.ts index 5d2dbf1..d20ddac 100644 --- a/packages/core/src/api-struct.ts +++ b/packages/core/src/api-struct.ts @@ -28,6 +28,14 @@ export interface DevupResponseComponentStruct {} // biome-ignore lint/suspicious/noEmptyInterface: empty interface export interface DevupErrorComponentStruct {} +// biome-ignore lint/suspicious/noEmptyInterface: empty interface for augmentation by generator +export interface DevupPrecomputedMethodKeys {} + +// biome-ignore lint/suspicious/noEmptyInterface: empty interface for augmentation by generator +export interface DevupPrecomputedScopes {} + +type LowercaseMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' + export type DevupObject< R extends 'response' | 'request' | 'error' = 'response', T extends keyof DevupApiServers | (string & {}) = 'openapi.json', @@ -105,7 +113,13 @@ export type DevupApiMethodScope< export type DevupApiMethodKey< S extends string, M extends DevupApiMethodKeys, -> = ConditionalKeys> +> = S extends keyof DevupPrecomputedMethodKeys + ? ExtractValue< + ExtractValue, + Lowercase & LowercaseMethod, + never + > + : ConditionalKeys> export type DevupApiStructScope = DevupGetApiStructScope & DevupPostApiStructScope & diff --git a/packages/fetch/src/api.ts b/packages/fetch/src/api.ts index 556e58f..af2f0f3 100644 --- a/packages/fetch/src/api.ts +++ b/packages/fetch/src/api.ts @@ -3,19 +3,15 @@ import type { ApiOption, BoildApiOption, ConditionalKeys, + DevupApiMethodKey, DevupApiRequestInit, DevupApiServers, DevupApiStructKey, DevupApiStructScope, - DevupDeleteApiStructKey, DevupDeleteApiStructScope, - DevupGetApiStructKey, DevupGetApiStructScope, - DevupPatchApiStructKey, DevupPatchApiStructScope, - DevupPostApiStructKey, DevupPostApiStructScope, - DevupPutApiStructKey, DevupPutApiStructScope, ExtractValue, Middleware, @@ -65,7 +61,7 @@ export class DevupApi> { } get< - T extends DevupGetApiStructKey, + T extends DevupApiMethodKey, O extends Additional>, >( path: T, @@ -80,7 +76,7 @@ export class DevupApi> { } GET< - T extends DevupGetApiStructKey, + T extends DevupApiMethodKey, O extends Additional>, >( path: T, @@ -95,7 +91,7 @@ export class DevupApi> { } post< - T extends DevupPostApiStructKey, + T extends DevupApiMethodKey, O extends Additional>, >( path: T, @@ -110,7 +106,7 @@ export class DevupApi> { } POST< - T extends DevupPostApiStructKey, + T extends DevupApiMethodKey, O extends Additional>, >( path: T, @@ -125,7 +121,7 @@ export class DevupApi> { } put< - T extends DevupPutApiStructKey, + T extends DevupApiMethodKey, O extends Additional>, >( path: T, @@ -140,7 +136,7 @@ export class DevupApi> { } PUT< - T extends DevupPutApiStructKey, + T extends DevupApiMethodKey, O extends Additional>, >( path: T, @@ -155,7 +151,7 @@ export class DevupApi> { } delete< - T extends DevupDeleteApiStructKey, + T extends DevupApiMethodKey, O extends Additional>, >( path: T, @@ -170,7 +166,7 @@ export class DevupApi> { } DELETE< - T extends DevupDeleteApiStructKey, + T extends DevupApiMethodKey, O extends Additional>, >( path: T, @@ -185,7 +181,7 @@ export class DevupApi> { } patch< - T extends DevupPatchApiStructKey, + T extends DevupApiMethodKey, O extends Additional>, >( path: T, @@ -200,7 +196,7 @@ export class DevupApi> { } PATCH< - T extends DevupPatchApiStructKey, + T extends DevupApiMethodKey, O extends Additional>, >( path: T, diff --git a/packages/generator/src/__tests__/__snapshots__/generate-interface.test.ts.snap b/packages/generator/src/__tests__/__snapshots__/generate-interface.test.ts.snap index 54ab29a..a831f27 100644 --- a/packages/generator/src/__tests__/__snapshots__/generate-interface.test.ts.snap +++ b/packages/generator/src/__tests__/__snapshots__/generate-interface.test.ts.snap @@ -16,6 +16,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -55,6 +75,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: '/users' | 'createUser'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -110,6 +150,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -146,6 +206,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -174,6 +254,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -250,6 +350,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: '/users' | 'createUser'; + put: '/users' | 'updateUser'; + delete: '/users' | 'deleteUser'; + patch: '/users' | 'patchUser'; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: DevupPostApiStruct['openapi.json']; + put: DevupPutApiStruct['openapi.json']; + delete: DevupDeleteApiStruct['openapi.json']; + patch: DevupPatchApiStruct['openapi.json']; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -284,6 +404,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users/{userId}' | 'getUser'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -320,6 +460,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -360,6 +520,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users/{userId}/posts' | 'getUserPosts'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -396,6 +576,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/users' | 'createUser'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -426,6 +626,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/users' | 'createUser'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct { 'openapi.json': { User: { @@ -461,6 +681,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -496,6 +736,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/users' | 'createUser'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -535,6 +795,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -569,6 +849,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -610,6 +910,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -640,6 +960,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/users' | 'createUser'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct { 'openapi.json': { CreateUserRequest: { @@ -675,6 +1015,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -712,6 +1072,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -747,6 +1127,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -788,6 +1188,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users/{userId}' | 'getUserById'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -813,6 +1233,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -849,6 +1289,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/users' | 'createUser'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -885,6 +1345,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/users' | 'createUser'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -919,6 +1399,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -953,6 +1453,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -985,6 +1505,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -1008,6 +1548,26 @@ declare module "@devup-api/fetch" { 'openapi.json': never } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1042,6 +1602,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users/{userId}' | 'getUser'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1076,6 +1656,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/users' | 'createUser'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1100,6 +1700,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1163,6 +1783,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users/{userId}/posts/{postId}' | 'getUserPost'; + post: never; + put: '/users/{userId}/posts/{postId}' | 'updateUserPost'; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: DevupPutApiStruct['openapi.json']; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct { 'openapi.json': { UpdatePostRequest: { @@ -1213,6 +1853,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -1251,6 +1911,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -1290,6 +1970,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/users' | 'createUser'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct { 'openapi.json': { CreateUserRequest: { @@ -1320,6 +2020,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -1356,6 +2076,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/users' | 'createUser'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1384,6 +2124,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1414,6 +2174,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1442,6 +2222,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1472,6 +2272,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1502,6 +2322,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1537,6 +2377,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1565,6 +2425,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/users' | 'getUsers'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1620,6 +2500,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/items' | 'listItems' | '/other-items' | 'listOtherItems'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -1659,6 +2559,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/nodes' | 'listNodes'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -1699,6 +2619,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/items' | 'createItem'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct { 'openapi.json': { CreateItemRequest: { @@ -1738,6 +2678,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/files/{id}' | 'downloadFile'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1768,6 +2728,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/items' | 'listItems'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct { @@ -1807,6 +2787,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: '/items' | 'getItems'; + post: never; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: DevupGetApiStruct['openapi.json']; + post: Record; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1848,6 +2848,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/form' | 'subscribe'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct { 'openapi.json': { SubscribeRequest: { @@ -1893,6 +2913,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/form/contact' | 'contact'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -1927,6 +2967,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/typed-form' | 'createFileUpload'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct { 'openapi.json': { CreateFileUploadRequest: { @@ -1970,6 +3030,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/form/upload' | 'upload'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct {} interface DevupResponseComponentStruct {} @@ -2025,6 +3105,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: never; + put: '/typed-form/{id}' | 'updateFileUpload'; + delete: never; + patch: '/typed-form/{id}' | 'patchFileUpload'; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: Record; + put: DevupPutApiStruct['openapi.json']; + delete: Record; + patch: DevupPatchApiStruct['openapi.json']; + } + } + interface DevupRequestComponentStruct { 'openapi.json': { UpdateFileUploadRequest: { @@ -2082,6 +3182,26 @@ declare module "@devup-api/fetch" { } } + interface DevupPrecomputedMethodKeys { + 'openapi.json': { + get: never; + post: '/users' | 'createUser' | '/form' | 'subscribe' | '/form/upload' | 'upload'; + put: never; + delete: never; + patch: never; + } + } + + interface DevupPrecomputedScopes { + 'openapi.json': { + get: Record; + post: DevupPostApiStruct['openapi.json']; + put: Record; + delete: Record; + patch: Record; + } + } + interface DevupRequestComponentStruct { 'openapi.json': { CreateUserRequest: { diff --git a/packages/generator/src/generate-interface.ts b/packages/generator/src/generate-interface.ts index bfc0266..dc493c3 100644 --- a/packages/generator/src/generate-interface.ts +++ b/packages/generator/src/generate-interface.ts @@ -738,10 +738,60 @@ export function generateInterface( enumTypeAliases.push(` type ${enumName} = ${values}`) } + // Generate DevupPrecomputedMethodKeys interface + const precomputedEntries: string[] = [] + for (const serverName of serverNames) { + const methodKeyEntries: string[] = [] + for (const method of methods) { + const endpoints = serverEndpoints[serverName]?.[method] + const keys = endpoints ? Object.keys(endpoints) : [] + if (keys.length > 0) { + const keyUnion = keys.map((k) => `'${k}'`).join(' | ') + methodKeyEntries.push(` ${method}: ${keyUnion}`) + } else { + methodKeyEntries.push(` ${method}: never`) + } + } + const serverKey = wrapInterfaceKeyGuard(serverName) + precomputedEntries.push( + ` ${serverKey}: {\n${methodKeyEntries.join(';\n')};\n }`, + ) + } + const precomputedInterface = + precomputedEntries.length > 0 + ? ` interface DevupPrecomputedMethodKeys {\n${precomputedEntries.join(';\n')}\n }` + : '' + + // Generate DevupPrecomputedScopes interface (direct struct references per server+method) + const precomputedScopeEntries: string[] = [] + for (const serverName of serverNames) { + const methodScopeEntries: string[] = [] + for (const method of methods) { + const endpoints = serverEndpoints[serverName]?.[method] + if (endpoints && Object.keys(endpoints).length > 0) { + const structName = `Devup${toPascal(method)}ApiStruct` + const serverKey = wrapInterfaceKeyGuard(serverName) + methodScopeEntries.push(` ${method}: ${structName}[${serverKey}]`) + } else { + methodScopeEntries.push(` ${method}: Record`) + } + } + const serverKey = wrapInterfaceKeyGuard(serverName) + precomputedScopeEntries.push( + ` ${serverKey}: {\n${methodScopeEntries.join(';\n')};\n }`, + ) + } + const precomputedScopeInterface = + precomputedScopeEntries.length > 0 + ? ` interface DevupPrecomputedScopes {\n${precomputedScopeEntries.join(';\n')}\n }` + : '' + // Combine all interfaces const allInterfaces = [ serversInterface, ...methodInterfaces, + ...(precomputedInterface ? [precomputedInterface] : []), + ...(precomputedScopeInterface ? [precomputedScopeInterface] : []), requestComponentInterface, responseComponentInterface, errorComponentInterface, diff --git a/packages/react-query/src/query-client.ts b/packages/react-query/src/query-client.ts index 6ea3a11..9bf2980 100644 --- a/packages/react-query/src/query-client.ts +++ b/packages/react-query/src/query-client.ts @@ -4,11 +4,13 @@ import type { ConditionalApiOption, ConditionalKeys, DevupApi, + DevupApiMethodKey, DevupApiMethodKeys, DevupApiMethodScope, DevupApiRequestInit, DevupApiResponse, DevupApiServers, + DevupPrecomputedScopes, ExtractValue, } from '@devup-api/fetch' import { @@ -19,11 +21,32 @@ import { useSuspenseQuery, } from '@tanstack/react-query' +type LowercaseMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' + +type ResolveScopePrecomputed< + S extends string, + M extends string, + P extends string, +> = S extends keyof DevupPrecomputedScopes + ? P extends keyof ExtractValue< + ExtractValue, + M & LowercaseMethod + > + ? ExtractValue< + ExtractValue, + M & LowercaseMethod + >[P] & + object + : object + : never + type ResolveScope< S extends ConditionalKeys, M extends DevupApiMethodKeys, P extends string, -> = Additional> +> = S extends keyof DevupPrecomputedScopes + ? ResolveScopePrecomputed, P> + : Additional> type UseQueryOptions = Omit< Parameters< @@ -43,10 +66,10 @@ type LowercaseMethodKeys = 'get' | 'post' | 'put' | 'delete' | 'patch' type UseQueriesEntry> = { [M in LowercaseMethodKeys]: { - [P in ConditionalKeys>]: + [P in DevupApiMethodKey]: | UseQueriesTuple, P, M> | UseQueriesTuple, P, Uppercase> - }[ConditionalKeys>] + }[DevupApiMethodKey] }[LowercaseMethodKeys] type InferUseQueryResult< @@ -87,10 +110,7 @@ export class DevupQueryClient> { this.api = api } - useQuery< - M extends DevupApiMethodKeys, - T extends ConditionalKeys>, - >( + useQuery>( method: M, path: T, ...options: ApiOption< @@ -138,10 +158,7 @@ export class DevupQueryClient> { return Object.assign(result, { queryKey }) as any } - useMutation< - M extends DevupApiMethodKeys, - T extends ConditionalKeys>, - >( + useMutation>( method: M, path: T, queryOptions?: Omit< @@ -188,7 +205,7 @@ export class DevupQueryClient> { useSuspenseQuery< M extends DevupApiMethodKeys, - T extends ConditionalKeys>, + T extends DevupApiMethodKey, >( method: M, path: T, @@ -247,7 +264,7 @@ export class DevupQueryClient> { useInfiniteQuery< M extends DevupApiMethodKeys, - T extends ConditionalKeys>, + T extends DevupApiMethodKey, >( method: M, path: T,