diff --git a/src/codegen/generators/typescript/headers.ts b/src/codegen/generators/typescript/headers.ts index d630e2ae..8cbfaf31 100644 --- a/src/codegen/generators/typescript/headers.ts +++ b/src/codegen/generators/typescript/headers.ts @@ -67,10 +67,14 @@ export interface ProcessedHeadersData { } // Core generator function that works with processed data -export async function generateTypescriptHeadersCore( - processedData: ProcessedHeadersData, - generator: TypescriptHeadersGeneratorInternal -): Promise> { +export async function generateTypescriptHeadersCore({ + processedData, + context +}: { + processedData: ProcessedHeadersData; + context: TypescriptHeadersContext; +}): Promise> { + const {generator} = context; const modelinaGenerator = new TypeScriptFileGenerator({ ...defaultCodegenTypescriptModelinaOptions, constraints: { @@ -95,7 +99,7 @@ export async function generateTypescriptHeadersCore( return content; } return `${content} -${generateTypescriptValidationCode({model, renderer})}`; +${generateTypescriptValidationCode({model, renderer, context})}`; } } } @@ -150,10 +154,10 @@ export async function generateTypescriptHeaders( } // Generate models using processed data - const channelModels = await generateTypescriptHeadersCore( + const channelModels = await generateTypescriptHeadersCore({ processedData, - generator - ); + context + }); return { channelModels, diff --git a/src/codegen/generators/typescript/payloads.ts b/src/codegen/generators/typescript/payloads.ts index 773f2382..5d21baf5 100644 --- a/src/codegen/generators/typescript/payloads.ts +++ b/src/codegen/generators/typescript/payloads.ts @@ -323,10 +323,14 @@ export async function generateTypescriptPayloadsCore( // Core generator function that works with processed schema data // eslint-disable-next-line sonarjs/cognitive-complexity -export async function generateTypescriptPayloadsCoreFromSchemas( - processedSchemaData: ProcessedPayloadSchemaData, - generator: TypeScriptPayloadGeneratorInternal -): Promise { +export async function generateTypescriptPayloadsCoreFromSchemas({ + context, + processedSchemaData +}: { + processedSchemaData: ProcessedPayloadSchemaData; + context: TypeScriptPayloadContext; +}): Promise { + const generator = context.generator; const modelinaGenerator = new TypeScriptFileGenerator({ ...defaultCodegenTypescriptModelinaOptions, presets: [ @@ -343,7 +347,7 @@ export async function generateTypescriptPayloadsCoreFromSchemas( return content; } return `${content} -${generateTypescriptValidationCode({model, renderer})}`; +${generateTypescriptValidationCode({model, renderer, context})}`; } } }, @@ -356,7 +360,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 +488,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 +515,8 @@ export async function generateTypescriptPayload( } // Generate final result using processed schema data - return generateTypescriptPayloadsCoreFromSchemas( + return generateTypescriptPayloadsCoreFromSchemas({ processedSchemaData, - generator - ); + context + }); } diff --git a/src/codegen/modelina/index.ts b/src/codegen/modelina/index.ts index 93693b30..5fc38107 100644 --- a/src/codegen/modelina/index.ts +++ b/src/codegen/modelina/index.ts @@ -1,5 +1,9 @@ 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 +89,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 +120,11 @@ 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,6 +138,7 @@ ${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; } 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 ]); 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; }