From 31bdccdbaa42a74bd1b918df986f22db28173b82 Mon Sep 17 00:00:00 2001 From: Leo Developer Date: Mon, 12 May 2025 11:20:59 +0200 Subject: [PATCH] draft typeid support --- packages/openapi-ts/src/ir/types.d.ts | 1 + .../src/openApi/2.0.x/parser/schema.ts | 4 ++ .../src/openApi/3.0.x/parser/schema.ts | 4 ++ .../src/openApi/3.1.x/parser/schema.ts | 4 ++ .../src/plugins/@hey-api/typescript/config.ts | 1 + .../src/plugins/@hey-api/typescript/plugin.ts | 42 +++++++++++++++++++ .../plugins/@hey-api/typescript/types.d.ts | 6 +++ 7 files changed, 62 insertions(+) diff --git a/packages/openapi-ts/src/ir/types.d.ts b/packages/openapi-ts/src/ir/types.d.ts index 3b4f51153..fb2f13c5b 100644 --- a/packages/openapi-ts/src/ir/types.d.ts +++ b/packages/openapi-ts/src/ir/types.d.ts @@ -138,6 +138,7 @@ interface IRSchemaObject | 'pattern' | 'required' | 'title' + | 'example' > { /** * If the schema is intended to be used as an object property, it can be diff --git a/packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts b/packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts index a03d481e5..a1ff77b88 100644 --- a/packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts +++ b/packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts @@ -32,6 +32,10 @@ const parseSchemaJsDoc = ({ irSchema: IR.SchemaObject; schema: SchemaObject; }) => { + if (schema.example) { + irSchema.example = schema.example; + } + if (schema.description) { irSchema.description = schema.description; } diff --git a/packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts b/packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts index f43caaf3e..3fc725b4c 100644 --- a/packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts +++ b/packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts @@ -36,6 +36,10 @@ const parseSchemaJsDoc = ({ irSchema.deprecated = schema.deprecated; } + if (schema.example) { + irSchema.example = schema.example; + } + if (schema.description) { irSchema.description = schema.description; } diff --git a/packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts b/packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts index 51ee9f822..5610f4783 100644 --- a/packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts +++ b/packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts @@ -42,6 +42,10 @@ const parseSchemaJsDoc = ({ irSchema.deprecated = schema.deprecated; } + if (schema.example) { + irSchema.example = schema.example; + } + if (schema.description) { irSchema.description = schema.description; } diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/config.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/config.ts index 797a772a0..e0eb8f26c 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/config.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/config.ts @@ -17,6 +17,7 @@ export const defaultConfig: Plugin.Config = { readableNameBuilder: '{{name}}Readable', style: 'preserve', tree: false, + typeids: false, writableNameBuilder: '{{name}}Writable', }; diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts index f8ea8c584..45861d072 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts @@ -617,10 +617,12 @@ const objectTypeToIdentifier = ({ const stringTypeToIdentifier = ({ context, + plugin, schema, }: { context: IR.Context; namespace: Array; + plugin: Plugin.Instance; schema: SchemaWithType<'string'>; }): ts.TypeNode => { if (schema.const !== undefined) { @@ -649,6 +651,20 @@ const stringTypeToIdentifier = ({ return compiler.typeReferenceNode({ typeName: 'Date' }); } } + + if (schema.format === 'typeid' && schema.example && plugin.typeids) { + const type = String(schema.example).split('_')[0]!; + return compiler.typeReferenceNode({ + typeArguments: [ + compiler.literalTypeNode({ + literal: compiler.stringLiteral({ + text: type, + }), + }), + ], + typeName: 'TypeID', + }); + } } return compiler.keywordTypeNode({ @@ -763,6 +779,7 @@ const schemaTypeToIdentifier = ({ return stringTypeToIdentifier({ context, namespace, + plugin, schema: schema as SchemaWithType<'string'>, }); case 'tuple': @@ -1255,6 +1272,31 @@ export const handler: Plugin.Handler = ({ context, plugin }) => { namespace: 'type', }); + if (plugin.typeids) { + const typeParameter = compiler.typeParameterDeclaration({ + constraint: compiler.keywordTypeNode({ + keyword: 'string', + }), + name: 'T', + }); + const node = compiler.typeAliasDeclaration({ + name: 'TypeID', + type: compiler.templateLiteralType({ + value: [ + compiler.typeReferenceNode({ + typeName: 'T', + }), + '_', + compiler.keywordTypeNode({ + keyword: 'string', + }), + ], + }), + typeParameters: [typeParameter], + }); + file.add(node); + } + context.subscribe('schema', ({ $ref, schema }) => { if ( plugin.readOnlyWriteOnlyBehavior === 'off' || diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/types.d.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/types.d.ts index 515025dc5..c4a2f2793 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/types.d.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/types.d.ts @@ -67,6 +67,12 @@ export interface Config extends Plugin.Name<'@hey-api/typescript'> { * @default '{{name}}Writable' */ writableNameBuilder?: string; + /** + * Generate types for [TypeIDs](https://github.com/jetify-com/typeid/tree/main/spec). + * + * @default false + */ + typeids?: boolean; // DEPRECATED OPTIONS BELOW