Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add support for long integers #1529

Merged
merged 1 commit into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cool-days-scream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hey-api/openapi-ts': patch
---

fix: add support for long integers
2 changes: 1 addition & 1 deletion .changeset/nasty-comics-smoke.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
'@hey-api/openapi-ts': patch
---

fix: preserve leading indicators in enum keys
fix: preserve leading separators in enum keys
1 change: 1 addition & 0 deletions packages/openapi-ts/src/ir/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const deduplicateSchema = <T extends IR.SchemaObject>({
// no `type` might still include `$ref` or `const`
!item.type ||
item.type === 'boolean' ||
item.type === 'integer' ||
item.type === 'null' ||
item.type === 'number' ||
item.type === 'string' ||
Expand Down
1 change: 1 addition & 0 deletions packages/openapi-ts/src/ir/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ interface IRSchemaObject
| 'array'
| 'boolean'
| 'enum'
| 'integer'
| 'never'
| 'null'
| 'number'
Expand Down
5 changes: 3 additions & 2 deletions packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,12 @@

const parseNumber = ({
irSchema = {},
schema,

Check warning on line 166 in packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts#L166

Added line #L166 was not covered by tests
}: SchemaContext & {
irSchema?: IR.SchemaObject;
schema: SchemaObject;
schema: SchemaWithRequired<SchemaObject, 'type'>;

Check warning on line 169 in packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts#L169

Added line #L169 was not covered by tests
}): IR.SchemaObject => {
irSchema.type = 'number';
irSchema.type = schema.type;

Check warning on line 171 in packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts#L171

Added line #L171 was not covered by tests

return irSchema;
};
Expand Down
5 changes: 3 additions & 2 deletions packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,12 @@

const parseNumber = ({
irSchema = {},
schema,

Check warning on line 173 in packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts#L173

Added line #L173 was not covered by tests
}: SchemaContext & {
irSchema?: IR.SchemaObject;
schema: SchemaObject;
schema: SchemaWithRequired<SchemaObject, 'type'>;

Check warning on line 176 in packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts#L176

Added line #L176 was not covered by tests
}): IR.SchemaObject => {
irSchema.type = 'number';
irSchema.type = schema.type;

Check warning on line 178 in packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts#L178

Added line #L178 was not covered by tests

return irSchema;
};
Expand Down
7 changes: 5 additions & 2 deletions packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,14 @@ const parseNull = ({

const parseNumber = ({
irSchema = {},
schema,
}: SchemaContext & {
irSchema?: IR.SchemaObject;
schema: SchemaObject;
schema: Omit<SchemaObject, 'type'> & {
type: SchemaType<SchemaObject>;
};
}): IR.SchemaObject => {
irSchema.type = 'number';
irSchema.type = schema.type;

return irSchema;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const defaultConfig: Plugin.Config<Config> = {
_handler: handler,
_handlerLegacy: handlerLegacy,
_tags: ['transformer'],
bigInt: true,
dates: true,
name: '@hey-api/transformers',
output: 'transformers',
Expand Down
100 changes: 75 additions & 25 deletions packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,75 @@
id: string;
}

const bigIntExpressions = ({
dataExpression,
}: {
dataExpression?: ts.Expression | string;
}): Array<ts.Expression> => {
const bigIntCallExpression =
dataExpression !== undefined
? compiler.callExpression({
functionName: 'BigInt',
parameters: [
compiler.callExpression({
functionName: compiler.propertyAccessExpression({
expression: dataExpression,
name: 'toString',
}),
}),
],
})
: undefined;

if (bigIntCallExpression) {
if (typeof dataExpression === 'string') {
return [bigIntCallExpression];
}

if (dataExpression) {
return [
compiler.assignment({
left: dataExpression,
right: bigIntCallExpression,
}),
];
}
}

return [];
};

Check warning on line 55 in packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts#L20-L55

Added lines #L20 - L55 were not covered by tests

const dateExpressions = ({
dataExpression,
}: {
dataExpression?: ts.Expression | string;
}): Array<ts.Expression> => {
const identifierDate = compiler.identifier({ text: 'Date' });

if (typeof dataExpression === 'string') {
return [
compiler.newExpression({
argumentsArray: [compiler.identifier({ text: dataExpression })],
expression: identifierDate,
}),
];
}

if (dataExpression) {
return [
compiler.assignment({
left: dataExpression,
right: compiler.newExpression({
argumentsArray: [dataExpression],
expression: identifierDate,
}),
}),
];
}

return [];
};

Check warning on line 86 in packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts#L58-L86

Added lines #L58 - L86 were not covered by tests

export const operationTransformerIrRef = ({
id,
type,
Expand Down Expand Up @@ -147,7 +216,7 @@
parameters: [
{
name: dataVariableName,
// TODO: parser - add types, generate types without transformed dates
// TODO: parser - add types, generate types without transforms

Check warning on line 219 in packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts#L219

Added line #L219 was not covered by tests
type: compiler.keywordTypeNode({ keyword: 'any' }),
},
],
Expand Down Expand Up @@ -293,30 +362,11 @@
schema.type === 'string' &&
(schema.format === 'date' || schema.format === 'date-time')
) {
const identifierDate = compiler.identifier({ text: 'Date' });

if (typeof dataExpression === 'string') {
return [
compiler.newExpression({
argumentsArray: [compiler.identifier({ text: dataExpression })],
expression: identifierDate,
}),
];
}

if (dataExpression) {
return [
compiler.assignment({
left: dataExpression,
right: compiler.newExpression({
argumentsArray: [dataExpression],
expression: identifierDate,
}),
}),
];
}
return dateExpressions({ dataExpression });
}

Check warning on line 366 in packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts#L365-L366

Added lines #L365 - L366 were not covered by tests

return [];
if (plugin.bigInt && schema.type === 'integer' && schema.format === 'int64') {
return bigIntExpressions({ dataExpression });

Check warning on line 369 in packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts#L368-L369

Added lines #L368 - L369 were not covered by tests
}

if (schema.items) {
Expand Down Expand Up @@ -447,7 +497,7 @@
parameters: [
{
name: dataVariableName,
// TODO: parser - add types, generate types without transformed dates
// TODO: parser - add types, generate types without transforms

Check warning on line 500 in packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts#L500

Added line #L500 was not covered by tests
type: compiler.keywordTypeNode({ keyword: 'any' }),
},
],
Expand Down
10 changes: 10 additions & 0 deletions packages/openapi-ts/src/plugins/@hey-api/transformers/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import type { Plugin } from '../../types';

export interface Config extends Plugin.Name<'@hey-api/transformers'> {
/**
* **This feature works only with the [experimental parser](https://heyapi.dev/openapi-ts/configuration#parser)**
*
* Convert long integers into BigInt values?
*
* @default true
*/
bigInt?: boolean;
/**
* Convert date strings into Date objects?
*
* @default true
*/
dates?: boolean;
/**
* Name of the generated file.
*
* @default 'transformers'
*/
output?: string;
Expand Down
23 changes: 16 additions & 7 deletions packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,18 +402,26 @@
};

const numberTypeToIdentifier = ({
context,
schema,
}: {
context: IR.Context;
namespace: Array<ts.Statement>;
schema: SchemaWithType<'number'>;
schema: SchemaWithType<'integer' | 'number'>;
}) => {
if (schema.const !== undefined) {
return compiler.literalTypeNode({
literal: compiler.ots.number(schema.const as number),
});
}

if (schema.type === 'integer' && schema.format === 'int64') {
// TODO: parser - add ability to skip type transformers
if (context.config.plugins['@hey-api/transformers']?.bigInt) {
return compiler.typeReferenceNode({ typeName: 'BigInt' });
}

Check warning on line 422 in packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts#L419-L422

Added lines #L419 - L422 were not covered by tests
}

return compiler.keywordTypeNode({
keyword: 'number',
});
Expand Down Expand Up @@ -605,6 +613,13 @@
plugin,
schema: schema as SchemaWithType<'enum'>,
});
case 'integer':
case 'number':
return numberTypeToIdentifier({
context,
namespace,
schema: schema as SchemaWithType<'integer' | 'number'>,
});
case 'never':
return compiler.keywordTypeNode({
keyword: 'never',
Expand All @@ -613,12 +628,6 @@
return compiler.literalTypeNode({
literal: compiler.null(),
});
case 'number':
return numberTypeToIdentifier({
context,
namespace,
schema: schema as SchemaWithType<'number'>,
});
case 'object':
return objectTypeToIdentifier({
context,
Expand Down
28 changes: 21 additions & 7 deletions packages/openapi-ts/src/plugins/zod/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,28 @@
schema,
}: {
context: IR.Context;
schema: SchemaWithType<'number'>;
schema: SchemaWithType<'integer' | 'number'>;

Check warning on line 244 in packages/openapi-ts/src/plugins/zod/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/zod/plugin.ts#L244

Added line #L244 was not covered by tests
}) => {
const isBigInt = schema.type === 'integer' && schema.format === 'int64';

Check warning on line 247 in packages/openapi-ts/src/plugins/zod/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/zod/plugin.ts#L246-L247

Added lines #L246 - L247 were not covered by tests
let numberExpression = compiler.callExpression({
functionName: compiler.propertyAccessExpression({
expression: zIdentifier,
name: compiler.identifier({ text: schema.type }),
name: isBigInt
? compiler.identifier({ text: 'bigint' })
: compiler.identifier({ text: 'number' }),

Check warning on line 253 in packages/openapi-ts/src/plugins/zod/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/zod/plugin.ts#L251-L253

Added lines #L251 - L253 were not covered by tests
}),
});

if (!isBigInt && schema.type === 'integer') {
numberExpression = compiler.callExpression({
functionName: compiler.propertyAccessExpression({
expression: numberExpression,
name: compiler.identifier({ text: 'int' }),
}),
});
}

Check warning on line 265 in packages/openapi-ts/src/plugins/zod/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/zod/plugin.ts#L257-L265

Added lines #L257 - L265 were not covered by tests
if (schema.const !== undefined) {
// TODO: parser - add constant
// return compiler.literalTypeNode({
Expand Down Expand Up @@ -584,6 +597,12 @@
context,
schema: schema as SchemaWithType<'enum'>,
});
case 'integer':
case 'number':
return numberTypeToZodSchema({
context,
schema: schema as SchemaWithType<'integer' | 'number'>,
});

Check warning on line 605 in packages/openapi-ts/src/plugins/zod/plugin.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/plugins/zod/plugin.ts#L600-L605

Added lines #L600 - L605 were not covered by tests
case 'never':
return neverTypeToZodSchema({
context,
Expand All @@ -594,11 +613,6 @@
context,
schema: schema as SchemaWithType<'null'>,
});
case 'number':
return numberTypeToZodSchema({
context,
schema: schema as SchemaWithType<'number'>,
});
case 'object':
return objectTypeToZodSchema({
context,
Expand Down
10 changes: 5 additions & 5 deletions packages/openapi-ts/test/2.0.x.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import { getFilePaths } from './utils';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const VERSION = '2.0.x';
const version = '2.0.x';

const outputDir = path.join(__dirname, 'generated', VERSION);
const outputDir = path.join(__dirname, 'generated', version);

describe(`OpenAPI ${VERSION}`, () => {
describe(`OpenAPI ${version}`, () => {
const createConfig = (userConfig: UserConfig): UserConfig => ({
client: '@hey-api/client-fetch',
experimentalParser: true,
Expand All @@ -24,7 +24,7 @@ describe(`OpenAPI ${VERSION}`, () => {
input: path.join(
__dirname,
'spec',
VERSION,
version,
typeof userConfig.input === 'string' ? userConfig.input : '',
),
output: path.join(
Expand Down Expand Up @@ -273,7 +273,7 @@ describe(`OpenAPI ${VERSION}`, () => {
path.join(
__dirname,
'__snapshots__',
VERSION,
version,
filePath.slice(outputDir.length + 1),
),
);
Expand Down
Loading
Loading