From 8f519479393c6f3371026d873f5a3642e3e9e0de Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 6 Sep 2025 18:09:59 +0200 Subject: [PATCH 1/2] improve code --- src/codegen/generators/typescript/headers.ts | 17 ++++++++------- src/codegen/generators/typescript/payloads.ts | 21 ++++++++++--------- src/codegen/modelina/index.ts | 10 +++++++-- src/codegen/types.ts | 1 + 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/codegen/generators/typescript/headers.ts b/src/codegen/generators/typescript/headers.ts index d630e2ae..bd20c5a9 100644 --- a/src/codegen/generators/typescript/headers.ts +++ b/src/codegen/generators/typescript/headers.ts @@ -67,10 +67,11 @@ export interface ProcessedHeadersData { } // Core generator function that works with processed data -export async function generateTypescriptHeadersCore( +export async function generateTypescriptHeadersCore({processedData, context}:{ processedData: ProcessedHeadersData, - generator: TypescriptHeadersGeneratorInternal -): Promise> { + context: TypescriptHeadersContext +}): Promise> { + const {generator} = context; const modelinaGenerator = new TypeScriptFileGenerator({ ...defaultCodegenTypescriptModelinaOptions, constraints: { @@ -95,7 +96,7 @@ export async function generateTypescriptHeadersCore( return content; } return `${content} -${generateTypescriptValidationCode({model, renderer})}`; +${generateTypescriptValidationCode({model, renderer, context})}`; } } } @@ -150,13 +151,13 @@ export async function generateTypescriptHeaders( } // Generate models using processed data - const channelModels = await generateTypescriptHeadersCore( + const channelModels = await generateTypescriptHeadersCore({ processedData, - generator - ); + context + }); return { channelModels, generator }; -} +} \ No newline at end of file diff --git a/src/codegen/generators/typescript/payloads.ts b/src/codegen/generators/typescript/payloads.ts index 773f2382..7ade063e 100644 --- a/src/codegen/generators/typescript/payloads.ts +++ b/src/codegen/generators/typescript/payloads.ts @@ -323,10 +323,11 @@ export async function generateTypescriptPayloadsCore( // Core generator function that works with processed schema data // eslint-disable-next-line sonarjs/cognitive-complexity -export async function generateTypescriptPayloadsCoreFromSchemas( +export async function generateTypescriptPayloadsCoreFromSchemas({context, processedSchemaData} :{ processedSchemaData: ProcessedPayloadSchemaData, - generator: TypeScriptPayloadGeneratorInternal -): Promise { + context: TypeScriptPayloadContext +}): Promise { + const generator = context.generator; const modelinaGenerator = new TypeScriptFileGenerator({ ...defaultCodegenTypescriptModelinaOptions, presets: [ @@ -343,7 +344,7 @@ export async function generateTypescriptPayloadsCoreFromSchemas( return content; } return `${content} -${generateTypescriptValidationCode({model, renderer})}`; +${generateTypescriptValidationCode({model, renderer, context})}`; } } }, @@ -356,7 +357,7 @@ ${generateTypescriptValidationCode({model, renderer})}`; ${renderUnionUnmarshal(model, renderer)} ${renderUnionMarshal(model)} ${renderUnionUnmarshalByStatusCode(model)} -${generator.includeValidation ? generateTypescriptValidationCode({model, renderer, asClassMethods: false}) : ''} +${generator.includeValidation ? generateTypescriptValidationCode({model, renderer, asClassMethods: false, context}) : ''} `; } return content; @@ -484,7 +485,7 @@ ${generator.includeValidation ? generateTypescriptValidationCode({model, rendere export async function generateTypescriptPayload( context: TypeScriptPayloadContext ): Promise { - const {asyncapiDocument, openapiDocument, inputType, generator} = context; + const {asyncapiDocument, openapiDocument, inputType} = context; let processedSchemaData: ProcessedPayloadSchemaData; @@ -511,8 +512,8 @@ export async function generateTypescriptPayload( } // Generate final result using processed schema data - return generateTypescriptPayloadsCoreFromSchemas( + return generateTypescriptPayloadsCoreFromSchemas({ processedSchemaData, - generator - ); -} + context + }); +} \ No newline at end of file diff --git a/src/codegen/modelina/index.ts b/src/codegen/modelina/index.ts index 93693b30..5ca7a894 100644 --- a/src/codegen/modelina/index.ts +++ b/src/codegen/modelina/index.ts @@ -1,5 +1,6 @@ import {ConstrainedMetaModel} from '@asyncapi/modelina'; import {TypeScriptRenderer} from '@asyncapi/modelina/lib/types/generators/typescript/TypeScriptRenderer'; +import { TypescriptHeadersContext, TypeScriptPayloadContext } from '../generators'; /** * Safe stringify that removes x- properties and circular references by assuming true @@ -85,11 +86,13 @@ export function safeStringify(value: any): string { export function generateTypescriptValidationCode({ model, renderer, - asClassMethods = true + asClassMethods = true, + context }: { model: ConstrainedMetaModel; renderer: TypeScriptRenderer; asClassMethods?: boolean; + context: TypeScriptPayloadContext | TypescriptHeadersContext }) { renderer.dependencyManager.addTypeScriptDependency( '{Ajv, Options as AjvOptions, ErrorObject, ValidateFunction}', @@ -114,6 +117,8 @@ export function generateTypescriptValidationCode({ ? 'this.theCodeGenSchema' : 'theCodeGenSchema'; + const vocabularies = context.inputType === 'openapi' ? 'ajvInstance.addVocabulary(["xml", "example"])' : ''; + return `${schemaProperty} = ${safeStringify(model.originalInput)}; ${methodPrefix}validate(context?: {data: any, ajvValidatorFunction?: ValidateFunction, ajvInstance?: Ajv, ajvOptions?: AjvOptions}): { valid: boolean; errors?: ErrorObject[]; } { const {data, ajvValidatorFunction} = context ?? {}; @@ -127,8 +132,9 @@ ${methodPrefix}validate(context?: {data: any, ajvValidatorFunction?: ValidateFun ${methodPrefix}createValidator(context?: {ajvInstance?: Ajv, ajvOptions?: AjvOptions}): ValidateFunction { const {ajvInstance} = {...context ?? {}, ajvInstance: new Ajv(context?.ajvOptions ?? {})}; addFormats(ajvInstance); + ${vocabularies} const validate = ajvInstance.compile(${compileCall}); return validate; } `; -} +} \ No newline at end of file diff --git a/src/codegen/types.ts b/src/codegen/types.ts index f32330b3..23ba4346 100644 --- a/src/codegen/types.ts +++ b/src/codegen/types.ts @@ -81,6 +81,7 @@ export const zodOpenAPITypeScriptGenerators = z.discriminatedUnion('preset', [ zodTypescriptParametersGenerator, zodTypescriptHeadersGenerator, zodTypescriptTypesGenerator, + zodTypescriptChannelsGenerator, zodCustomGenerator ]); From 4cd8b3fc1fa0c5cc039e987926454a00447093cb Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Sat, 6 Sep 2025 18:15:45 +0200 Subject: [PATCH 2/2] fix snapts --- src/codegen/generators/typescript/headers.ts | 11 +++++++---- src/codegen/generators/typescript/payloads.ts | 11 +++++++---- src/codegen/modelina/index.ts | 14 ++++++++++---- .../typescript/__snapshots__/headers.spec.ts.snap | 4 ++++ .../typescript/__snapshots__/payload.spec.ts.snap | 3 +++ 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/codegen/generators/typescript/headers.ts b/src/codegen/generators/typescript/headers.ts index bd20c5a9..8cbfaf31 100644 --- a/src/codegen/generators/typescript/headers.ts +++ b/src/codegen/generators/typescript/headers.ts @@ -67,9 +67,12 @@ export interface ProcessedHeadersData { } // Core generator function that works with processed data -export async function generateTypescriptHeadersCore({processedData, context}:{ - processedData: ProcessedHeadersData, - context: TypescriptHeadersContext +export async function generateTypescriptHeadersCore({ + processedData, + context +}: { + processedData: ProcessedHeadersData; + context: TypescriptHeadersContext; }): Promise> { const {generator} = context; const modelinaGenerator = new TypeScriptFileGenerator({ @@ -160,4 +163,4 @@ export async function generateTypescriptHeaders( channelModels, generator }; -} \ No newline at end of file +} diff --git a/src/codegen/generators/typescript/payloads.ts b/src/codegen/generators/typescript/payloads.ts index 7ade063e..5d21baf5 100644 --- a/src/codegen/generators/typescript/payloads.ts +++ b/src/codegen/generators/typescript/payloads.ts @@ -323,9 +323,12 @@ export async function generateTypescriptPayloadsCore( // Core generator function that works with processed schema data // eslint-disable-next-line sonarjs/cognitive-complexity -export async function generateTypescriptPayloadsCoreFromSchemas({context, processedSchemaData} :{ - processedSchemaData: ProcessedPayloadSchemaData, - context: TypeScriptPayloadContext +export async function generateTypescriptPayloadsCoreFromSchemas({ + context, + processedSchemaData +}: { + processedSchemaData: ProcessedPayloadSchemaData; + context: TypeScriptPayloadContext; }): Promise { const generator = context.generator; const modelinaGenerator = new TypeScriptFileGenerator({ @@ -516,4 +519,4 @@ export async function generateTypescriptPayload( processedSchemaData, context }); -} \ No newline at end of file +} diff --git a/src/codegen/modelina/index.ts b/src/codegen/modelina/index.ts index 5ca7a894..5fc38107 100644 --- a/src/codegen/modelina/index.ts +++ b/src/codegen/modelina/index.ts @@ -1,6 +1,9 @@ import {ConstrainedMetaModel} from '@asyncapi/modelina'; import {TypeScriptRenderer} from '@asyncapi/modelina/lib/types/generators/typescript/TypeScriptRenderer'; -import { TypescriptHeadersContext, TypeScriptPayloadContext } from '../generators'; +import { + TypescriptHeadersContext, + TypeScriptPayloadContext +} from '../generators'; /** * Safe stringify that removes x- properties and circular references by assuming true @@ -92,7 +95,7 @@ export function generateTypescriptValidationCode({ model: ConstrainedMetaModel; renderer: TypeScriptRenderer; asClassMethods?: boolean; - context: TypeScriptPayloadContext | TypescriptHeadersContext + context: TypeScriptPayloadContext | TypescriptHeadersContext; }) { renderer.dependencyManager.addTypeScriptDependency( '{Ajv, Options as AjvOptions, ErrorObject, ValidateFunction}', @@ -117,7 +120,10 @@ export function generateTypescriptValidationCode({ ? 'this.theCodeGenSchema' : 'theCodeGenSchema'; - const vocabularies = context.inputType === 'openapi' ? 'ajvInstance.addVocabulary(["xml", "example"])' : ''; + const vocabularies = + context.inputType === 'openapi' + ? 'ajvInstance.addVocabulary(["xml", "example"])' + : ''; return `${schemaProperty} = ${safeStringify(model.originalInput)}; ${methodPrefix}validate(context?: {data: any, ajvValidatorFunction?: ValidateFunction, ajvInstance?: Ajv, ajvOptions?: AjvOptions}): { valid: boolean; errors?: ErrorObject[]; } { @@ -137,4 +143,4 @@ ${methodPrefix}createValidator(context?: {ajvInstance?: Ajv, ajvOptions?: AjvOpt return validate; } `; -} \ No newline at end of file +} diff --git a/test/codegen/generators/typescript/__snapshots__/headers.spec.ts.snap b/test/codegen/generators/typescript/__snapshots__/headers.spec.ts.snap index a12a832c..557baf3c 100644 --- a/test/codegen/generators/typescript/__snapshots__/headers.spec.ts.snap +++ b/test/codegen/generators/typescript/__snapshots__/headers.spec.ts.snap @@ -49,6 +49,7 @@ class DeletePetHeaders { public static createValidator(context?: {ajvInstance?: Ajv, ajvOptions?: AjvOptions}): ValidateFunction { const {ajvInstance} = {...context ?? {}, ajvInstance: new Ajv(context?.ajvOptions ?? {})}; addFormats(ajvInstance); + ajvInstance.addVocabulary(["xml", "example"]) const validate = ajvInstance.compile(this.theCodeGenSchema); return validate; } @@ -106,6 +107,7 @@ class DeletePetHeaders { public static createValidator(context?: {ajvInstance?: Ajv, ajvOptions?: AjvOptions}): ValidateFunction { const {ajvInstance} = {...context ?? {}, ajvInstance: new Ajv(context?.ajvOptions ?? {})}; addFormats(ajvInstance); + ajvInstance.addVocabulary(["xml", "example"]) const validate = ajvInstance.compile(this.theCodeGenSchema); return validate; } @@ -163,6 +165,7 @@ class DeletePetHeaders { public static createValidator(context?: {ajvInstance?: Ajv, ajvOptions?: AjvOptions}): ValidateFunction { const {ajvInstance} = {...context ?? {}, ajvInstance: new Ajv(context?.ajvOptions ?? {})}; addFormats(ajvInstance); + ajvInstance.addVocabulary(["xml", "example"]) const validate = ajvInstance.compile(this.theCodeGenSchema); return validate; } @@ -254,6 +257,7 @@ class SimpleObjectHeaders { public static createValidator(context?: {ajvInstance?: Ajv, ajvOptions?: AjvOptions}): ValidateFunction { const {ajvInstance} = {...context ?? {}, ajvInstance: new Ajv(context?.ajvOptions ?? {})}; addFormats(ajvInstance); + const validate = ajvInstance.compile(this.theCodeGenSchema); return validate; } diff --git a/test/codegen/generators/typescript/__snapshots__/payload.spec.ts.snap b/test/codegen/generators/typescript/__snapshots__/payload.spec.ts.snap index fd48149b..f634d244 100644 --- a/test/codegen/generators/typescript/__snapshots__/payload.spec.ts.snap +++ b/test/codegen/generators/typescript/__snapshots__/payload.spec.ts.snap @@ -129,6 +129,7 @@ export function validate(context?: {data: any, ajvValidatorFunction?: ValidateFu export function createValidator(context?: {ajvInstance?: Ajv, ajvOptions?: AjvOptions}): ValidateFunction { const {ajvInstance} = {...context ?? {}, ajvInstance: new Ajv(context?.ajvOptions ?? {})}; addFormats(ajvInstance); + const validate = ajvInstance.compile(theCodeGenSchema); return validate; } @@ -214,6 +215,7 @@ class SimpleObject2 { public static createValidator(context?: {ajvInstance?: Ajv, ajvOptions?: AjvOptions}): ValidateFunction { const {ajvInstance} = {...context ?? {}, ajvInstance: new Ajv(context?.ajvOptions ?? {})}; addFormats(ajvInstance); + const validate = ajvInstance.compile(this.theCodeGenSchema); return validate; } @@ -305,6 +307,7 @@ class SimpleObject { public static createValidator(context?: {ajvInstance?: Ajv, ajvOptions?: AjvOptions}): ValidateFunction { const {ajvInstance} = {...context ?? {}, ajvInstance: new Ajv(context?.ajvOptions ?? {})}; addFormats(ajvInstance); + const validate = ajvInstance.compile(this.theCodeGenSchema); return validate; }