diff --git a/.changeset/poor-queens-crash.md b/.changeset/poor-queens-crash.md new file mode 100644 index 000000000..ec42ae2c5 --- /dev/null +++ b/.changeset/poor-queens-crash.md @@ -0,0 +1,5 @@ +--- +'@hey-api/openapi-ts': patch +--- + +fix: use z.coerce before calling z.bigint diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2f722473d..f913297f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,4 +53,4 @@ jobs: - name: Publish previews if: matrix.node-version == '22.11.0' && matrix.os == 'ubuntu-latest' - run: pnpx pkg-pr-new publish --compact --pnpm './packages/*' + run: pnpx pkg-pr-new publish --pnpm './packages/*' diff --git a/packages/client-axios/src/types.ts b/packages/client-axios/src/types.ts index 6912b7f72..49c0619ff 100644 --- a/packages/client-axios/src/types.ts +++ b/packages/client-axios/src/types.ts @@ -135,46 +135,46 @@ export interface RequestOptions< } export type RequestResult< - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, > = ThrowOnError extends true - ? Promise> + ? Promise> : Promise< - | (AxiosResponse & { error: undefined }) + | (AxiosResponse & { error: undefined }) | (AxiosError & { data: undefined; error: TError }) >; type MethodFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'>, -) => RequestResult; +) => RequestResult; type RequestFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'> & Pick>, 'method'>, -) => RequestResult; +) => RequestResult; export interface Client { /** * Returns the final request URL. This method works only with experimental parser. */ buildUrl: < - Data extends { + TData extends { body?: unknown; path?: Record; query?: Record; url: string; }, >( - options: Pick & Omit, 'axios'>, + options: Pick & Omit, 'axios'>, ) => string; delete: MethodFn; get: MethodFn; @@ -198,22 +198,22 @@ interface DataShape { } export type Options< - Data extends DataShape = DataShape, + TData extends DataShape = DataShape, ThrowOnError extends boolean = boolean, > = OmitKeys, 'body' | 'path' | 'query' | 'url'> & - Omit; + Omit; export type OptionsLegacyParser< - Data = unknown, + TData = unknown, ThrowOnError extends boolean = boolean, -> = Data extends { body?: any } - ? Data extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & Data +> = TData extends { body?: any } + ? TData extends { headers?: any } + ? OmitKeys, 'body' | 'headers' | 'url'> & TData : OmitKeys, 'body' | 'url'> & - Data & + TData & Pick, 'headers'> - : Data extends { headers?: any } + : TData extends { headers?: any } ? OmitKeys, 'headers' | 'url'> & - Data & + TData & Pick, 'body'> - : OmitKeys, 'url'> & Data; + : OmitKeys, 'url'> & TData; diff --git a/packages/client-fetch/src/types.ts b/packages/client-fetch/src/types.ts index f2ed532da..9b8d6d852 100644 --- a/packages/client-fetch/src/types.ts +++ b/packages/client-fetch/src/types.ts @@ -145,18 +145,18 @@ export interface RequestOptions< } export type RequestResult< - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, > = ThrowOnError extends true ? Promise<{ - data: Data; + data: TData; request: Request; response: Response; }> : Promise< ( - | { data: Data; error: undefined } + | { data: TData; error: undefined } | { data: undefined; error: TError } ) & { request: Request; @@ -165,21 +165,21 @@ export type RequestResult< >; type MethodFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'>, -) => RequestResult; +) => RequestResult; type RequestFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'> & Pick>, 'method'>, -) => RequestResult; +) => RequestResult; export interface Client< Req = Request, @@ -191,14 +191,14 @@ export interface Client< * Returns the final request URL. This method works only with experimental parser. */ buildUrl: < - Data extends { + TData extends { body?: unknown; path?: Record; query?: Record; url: string; }, >( - options: Pick & Options, + options: Pick & Options, ) => string; connect: MethodFn; delete: MethodFn; @@ -224,22 +224,22 @@ interface DataShape { } export type Options< - Data extends DataShape = DataShape, + TData extends DataShape = DataShape, ThrowOnError extends boolean = boolean, > = OmitKeys, 'body' | 'path' | 'query' | 'url'> & - Omit; + Omit; export type OptionsLegacyParser< - Data = unknown, + TData = unknown, ThrowOnError extends boolean = boolean, -> = Data extends { body?: any } - ? Data extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & Data +> = TData extends { body?: any } + ? TData extends { headers?: any } + ? OmitKeys, 'body' | 'headers' | 'url'> & TData : OmitKeys, 'body' | 'url'> & - Data & + TData & Pick, 'headers'> - : Data extends { headers?: any } + : TData extends { headers?: any } ? OmitKeys, 'headers' | 'url'> & - Data & + TData & Pick, 'body'> - : OmitKeys, 'url'> & Data; + : OmitKeys, 'url'> & TData; diff --git a/packages/openapi-ts/src/plugins/zod/plugin.ts b/packages/openapi-ts/src/plugins/zod/plugin.ts index a0e36ce63..9c5321ee2 100644 --- a/packages/openapi-ts/src/plugins/zod/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/plugin.ts @@ -22,6 +22,7 @@ interface Result { export const zodId = 'zod'; // frequently used identifiers +const coerceIdentifier = compiler.identifier({ text: 'coerce' }); const defaultIdentifier = compiler.identifier({ text: 'default' }); const intersectionIdentifier = compiler.identifier({ text: 'intersection' }); const lazyIdentifier = compiler.identifier({ text: 'lazy' }); @@ -263,12 +264,18 @@ const numberTypeToZodSchema = ({ } let numberExpression = compiler.callExpression({ - functionName: compiler.propertyAccessExpression({ - expression: zIdentifier, - name: isBigInt - ? compiler.identifier({ text: 'bigint' }) - : compiler.identifier({ text: 'number' }), - }), + functionName: isBigInt + ? compiler.propertyAccessExpression({ + expression: compiler.propertyAccessExpression({ + expression: zIdentifier, + name: coerceIdentifier, + }), + name: compiler.identifier({ text: 'bigint' }), + }) + : compiler.propertyAccessExpression({ + expression: zIdentifier, + name: compiler.identifier({ text: 'number' }), + }), }); if (!isBigInt && schema.type === 'integer') { diff --git a/packages/openapi-ts/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format/zod.gen.ts b/packages/openapi-ts/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format/zod.gen.ts index 30bdf8629..328fe6811 100644 --- a/packages/openapi-ts/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format/zod.gen.ts +++ b/packages/openapi-ts/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format/zod.gen.ts @@ -4,7 +4,7 @@ import { z } from 'zod'; export const zFoo = z.object({ bar: z.number().int().optional(), - foo: z.bigint(), + foo: z.coerce.bigint(), id: z.string() }); diff --git a/packages/openapi-ts/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format/zod.gen.ts b/packages/openapi-ts/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format/zod.gen.ts index 30bdf8629..328fe6811 100644 --- a/packages/openapi-ts/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format/zod.gen.ts +++ b/packages/openapi-ts/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format/zod.gen.ts @@ -4,7 +4,7 @@ import { z } from 'zod'; export const zFoo = z.object({ bar: z.number().int().optional(), - foo: z.bigint(), + foo: z.coerce.bigint(), id: z.string() }); diff --git a/packages/openapi-ts/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format/zod.gen.ts b/packages/openapi-ts/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format/zod.gen.ts index 30bdf8629..328fe6811 100644 --- a/packages/openapi-ts/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format/zod.gen.ts +++ b/packages/openapi-ts/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format/zod.gen.ts @@ -4,7 +4,7 @@ import { z } from 'zod'; export const zFoo = z.object({ bar: z.number().int().optional(), - foo: z.bigint(), + foo: z.coerce.bigint(), id: z.string() }); diff --git a/packages/openapi-ts/test/__snapshots__/3.1.x/schema-const/zod.gen.ts b/packages/openapi-ts/test/__snapshots__/3.1.x/schema-const/zod.gen.ts index 7ffcfc43a..808d0e91b 100644 --- a/packages/openapi-ts/test/__snapshots__/3.1.x/schema-const/zod.gen.ts +++ b/packages/openapi-ts/test/__snapshots__/3.1.x/schema-const/zod.gen.ts @@ -15,5 +15,5 @@ export const zFoo = z.object({ z.literal(true) ]).optional(), corge: z.object({}).optional(), - garply: z.bigint().optional() + garply: z.coerce.bigint().optional() }); \ No newline at end of file diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-axios-bundle/client/types.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-axios-bundle/client/types.ts.snap index 6912b7f72..49c0619ff 100644 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-axios-bundle/client/types.ts.snap +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-axios-bundle/client/types.ts.snap @@ -135,46 +135,46 @@ export interface RequestOptions< } export type RequestResult< - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, > = ThrowOnError extends true - ? Promise> + ? Promise> : Promise< - | (AxiosResponse & { error: undefined }) + | (AxiosResponse & { error: undefined }) | (AxiosError & { data: undefined; error: TError }) >; type MethodFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'>, -) => RequestResult; +) => RequestResult; type RequestFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'> & Pick>, 'method'>, -) => RequestResult; +) => RequestResult; export interface Client { /** * Returns the final request URL. This method works only with experimental parser. */ buildUrl: < - Data extends { + TData extends { body?: unknown; path?: Record; query?: Record; url: string; }, >( - options: Pick & Omit, 'axios'>, + options: Pick & Omit, 'axios'>, ) => string; delete: MethodFn; get: MethodFn; @@ -198,22 +198,22 @@ interface DataShape { } export type Options< - Data extends DataShape = DataShape, + TData extends DataShape = DataShape, ThrowOnError extends boolean = boolean, > = OmitKeys, 'body' | 'path' | 'query' | 'url'> & - Omit; + Omit; export type OptionsLegacyParser< - Data = unknown, + TData = unknown, ThrowOnError extends boolean = boolean, -> = Data extends { body?: any } - ? Data extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & Data +> = TData extends { body?: any } + ? TData extends { headers?: any } + ? OmitKeys, 'body' | 'headers' | 'url'> & TData : OmitKeys, 'body' | 'url'> & - Data & + TData & Pick, 'headers'> - : Data extends { headers?: any } + : TData extends { headers?: any } ? OmitKeys, 'headers' | 'url'> & - Data & + TData & Pick, 'body'> - : OmitKeys, 'url'> & Data; + : OmitKeys, 'url'> & TData; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-axios-bundle_transform/client/types.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-axios-bundle_transform/client/types.ts.snap index 6912b7f72..49c0619ff 100644 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-axios-bundle_transform/client/types.ts.snap +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-axios-bundle_transform/client/types.ts.snap @@ -135,46 +135,46 @@ export interface RequestOptions< } export type RequestResult< - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, > = ThrowOnError extends true - ? Promise> + ? Promise> : Promise< - | (AxiosResponse & { error: undefined }) + | (AxiosResponse & { error: undefined }) | (AxiosError & { data: undefined; error: TError }) >; type MethodFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'>, -) => RequestResult; +) => RequestResult; type RequestFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'> & Pick>, 'method'>, -) => RequestResult; +) => RequestResult; export interface Client { /** * Returns the final request URL. This method works only with experimental parser. */ buildUrl: < - Data extends { + TData extends { body?: unknown; path?: Record; query?: Record; url: string; }, >( - options: Pick & Omit, 'axios'>, + options: Pick & Omit, 'axios'>, ) => string; delete: MethodFn; get: MethodFn; @@ -198,22 +198,22 @@ interface DataShape { } export type Options< - Data extends DataShape = DataShape, + TData extends DataShape = DataShape, ThrowOnError extends boolean = boolean, > = OmitKeys, 'body' | 'path' | 'query' | 'url'> & - Omit; + Omit; export type OptionsLegacyParser< - Data = unknown, + TData = unknown, ThrowOnError extends boolean = boolean, -> = Data extends { body?: any } - ? Data extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & Data +> = TData extends { body?: any } + ? TData extends { headers?: any } + ? OmitKeys, 'body' | 'headers' | 'url'> & TData : OmitKeys, 'body' | 'url'> & - Data & + TData & Pick, 'headers'> - : Data extends { headers?: any } + : TData extends { headers?: any } ? OmitKeys, 'headers' | 'url'> & - Data & + TData & Pick, 'body'> - : OmitKeys, 'url'> & Data; + : OmitKeys, 'url'> & TData; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-fetch-bundle/client/types.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-fetch-bundle/client/types.ts.snap index f2ed532da..9b8d6d852 100644 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-fetch-bundle/client/types.ts.snap +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-fetch-bundle/client/types.ts.snap @@ -145,18 +145,18 @@ export interface RequestOptions< } export type RequestResult< - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, > = ThrowOnError extends true ? Promise<{ - data: Data; + data: TData; request: Request; response: Response; }> : Promise< ( - | { data: Data; error: undefined } + | { data: TData; error: undefined } | { data: undefined; error: TError } ) & { request: Request; @@ -165,21 +165,21 @@ export type RequestResult< >; type MethodFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'>, -) => RequestResult; +) => RequestResult; type RequestFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'> & Pick>, 'method'>, -) => RequestResult; +) => RequestResult; export interface Client< Req = Request, @@ -191,14 +191,14 @@ export interface Client< * Returns the final request URL. This method works only with experimental parser. */ buildUrl: < - Data extends { + TData extends { body?: unknown; path?: Record; query?: Record; url: string; }, >( - options: Pick & Options, + options: Pick & Options, ) => string; connect: MethodFn; delete: MethodFn; @@ -224,22 +224,22 @@ interface DataShape { } export type Options< - Data extends DataShape = DataShape, + TData extends DataShape = DataShape, ThrowOnError extends boolean = boolean, > = OmitKeys, 'body' | 'path' | 'query' | 'url'> & - Omit; + Omit; export type OptionsLegacyParser< - Data = unknown, + TData = unknown, ThrowOnError extends boolean = boolean, -> = Data extends { body?: any } - ? Data extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & Data +> = TData extends { body?: any } + ? TData extends { headers?: any } + ? OmitKeys, 'body' | 'headers' | 'url'> & TData : OmitKeys, 'body' | 'url'> & - Data & + TData & Pick, 'headers'> - : Data extends { headers?: any } + : TData extends { headers?: any } ? OmitKeys, 'headers' | 'url'> & - Data & + TData & Pick, 'body'> - : OmitKeys, 'url'> & Data; + : OmitKeys, 'url'> & TData; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-fetch-bundle_transform/client/types.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-fetch-bundle_transform/client/types.ts.snap index f2ed532da..9b8d6d852 100644 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-fetch-bundle_transform/client/types.ts.snap +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v3-hey-api-client-fetch-bundle_transform/client/types.ts.snap @@ -145,18 +145,18 @@ export interface RequestOptions< } export type RequestResult< - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, > = ThrowOnError extends true ? Promise<{ - data: Data; + data: TData; request: Request; response: Response; }> : Promise< ( - | { data: Data; error: undefined } + | { data: TData; error: undefined } | { data: undefined; error: TError } ) & { request: Request; @@ -165,21 +165,21 @@ export type RequestResult< >; type MethodFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'>, -) => RequestResult; +) => RequestResult; type RequestFn = < - Data = unknown, + TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'> & Pick>, 'method'>, -) => RequestResult; +) => RequestResult; export interface Client< Req = Request, @@ -191,14 +191,14 @@ export interface Client< * Returns the final request URL. This method works only with experimental parser. */ buildUrl: < - Data extends { + TData extends { body?: unknown; path?: Record; query?: Record; url: string; }, >( - options: Pick & Options, + options: Pick & Options, ) => string; connect: MethodFn; delete: MethodFn; @@ -224,22 +224,22 @@ interface DataShape { } export type Options< - Data extends DataShape = DataShape, + TData extends DataShape = DataShape, ThrowOnError extends boolean = boolean, > = OmitKeys, 'body' | 'path' | 'query' | 'url'> & - Omit; + Omit; export type OptionsLegacyParser< - Data = unknown, + TData = unknown, ThrowOnError extends boolean = boolean, -> = Data extends { body?: any } - ? Data extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & Data +> = TData extends { body?: any } + ? TData extends { headers?: any } + ? OmitKeys, 'body' | 'headers' | 'url'> & TData : OmitKeys, 'body' | 'url'> & - Data & + TData & Pick, 'headers'> - : Data extends { headers?: any } + : TData extends { headers?: any } ? OmitKeys, 'headers' | 'url'> & - Data & + TData & Pick, 'body'> - : OmitKeys, 'url'> & Data; + : OmitKeys, 'url'> & TData;