From 5ba716304c2013438f831de3e708ef38715da514 Mon Sep 17 00:00:00 2001 From: pvdb Date: Thu, 14 Aug 2025 15:14:26 +0200 Subject: [PATCH 1/4] Clone OpenAPI input schemas before transforming them --- src/index.ts | 6 ++-- test/documents/asyncapi3.yaml | 62 +++++++++++++++++++++++++++++++++++ test/parser.spec.ts | 9 ++++- 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 test/documents/asyncapi3.yaml diff --git a/src/index.ts b/src/index.ts index 614ce0d1..ae530efe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -30,7 +30,9 @@ async function validate(input: ValidateSchemaInput): Promise): Promise { - const transformed = toJsonSchema(input.data, { + // cloning input, because input schema is modified during transformation despite setting cloneSchema + const inputSchema = structuredClone(input.data); + const transformed = toJsonSchema(inputSchema, { cloneSchema: true, keepNotSupported: [ 'discriminator', @@ -119,4 +121,4 @@ function getAjvInstance(): Ajv { ajv.addSchema(jsonSchemaV3, 'openapi'); return ajv; -} \ No newline at end of file +} diff --git a/test/documents/asyncapi3.yaml b/test/documents/asyncapi3.yaml new file mode 100644 index 00000000..d846b95b --- /dev/null +++ b/test/documents/asyncapi3.yaml @@ -0,0 +1,62 @@ +asyncapi: 3.0.0 +info: + title: Address change events + version: 1.0.0 +defaultContentType: application/json +channels: + AddressEventsChannel: + messages: + addressAdded: + $ref: '#/components/messages/AddressAddedEvent' + addressUpdated: + $ref: '#/components/messages/AddressUpdatedEvent' +operations: + receiveAddressNotification: + action: receive + channel: + $ref: '#/channels/AddressEventsChannel' +components: + messages: + AddressAddedEvent: + payload: + schemaFormat: application/vnd.oai.openapi+yaml;version=3.0.0 + schema: + $ref: '#/components/schemas/AddressAddedEvent' + AddressUpdatedEvent: + payload: + schemaFormat: application/vnd.oai.openapi+yaml;version=3.0.0 + schema: + $ref: '#/components/schemas/AddressUpdatedEvent' + schemas: + EventBase: + type: object + properties: + time2: + type: string + nullable: true + AddressEvent: + allOf: + - $ref: "#/components/schemas/EventBase" + type: object + properties: + type: + type: string + time: + type: string + nullable: true + required: + - type + AddressAddedEvent: + type: object + allOf: + - $ref: "#/components/schemas/AddressEvent" + properties: + addedAddress: + type: string + AddressUpdatedEvent: + allOf: + - $ref: "#/components/schemas/AddressEvent" + type: object + properties: + updatedAddress: + type: string diff --git a/test/parser.spec.ts b/test/parser.spec.ts index 2cdd7687..a904fd2d 100644 --- a/test/parser.spec.ts +++ b/test/parser.spec.ts @@ -12,6 +12,8 @@ const inputWithInvalidOpenApi3 = toParseInput(fs.readFileSync(path.resolve(__dir const inputWithValidAsyncAPI = fs.readFileSync(path.resolve(__dirname, './documents/valid-asyncapi.yaml'), 'utf8'); +const inputWithValidAsyncAPI3 = fs.readFileSync(path.resolve(__dirname, './documents/asyncapi3.yaml'), 'utf8'); + const inputWithInvalidAsyncAPI = fs.readFileSync(path.resolve(__dirname, './documents/invalid-asyncapi.yaml'), 'utf8'); describe('OpenAPISchemaParser', function () { @@ -70,6 +72,11 @@ describe('OpenAPISchemaParser', function () { doParseCoreTest((document?.json()?.components?.messages?.testMessage as any)?.payload, outputWithValidOpenApi3); }); + it('should parse valid AsyncAPI3', async function() { + const { document, diagnostics } = await coreParser.parse(inputWithValidAsyncAPI3); + expect(diagnostics).toHaveLength(0); + }); + it('should validate valid AsyncAPI', async function() { const diagnostics = await coreParser.validate(inputWithValidAsyncAPI); expect(filterDiagnostics(diagnostics, 'asyncapi2-schemas')).toHaveLength(0); @@ -181,4 +188,4 @@ function filterDiagnostics(diagnostics: Diagnostic[], code: string) { function expectDiagnostics(diagnostics: Diagnostic[], code: string, results: SchemaValidateResult[]) { expect(filterDiagnostics(diagnostics, code)).toEqual(results.map(e => expect.objectContaining(e))); -} \ No newline at end of file +} From a9284901191be307b26b21b493b7b748eaa6146b Mon Sep 17 00:00:00 2001 From: pvdb Date: Tue, 24 Mar 2026 17:52:09 +0100 Subject: [PATCH 2/4] Fix broken test after merge of master - update asyncapi version (avoid warning not latest) - sonar fix (unused constant) --- test/documents/asyncapi3.yaml | 2 +- test/parser.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/documents/asyncapi3.yaml b/test/documents/asyncapi3.yaml index d846b95b..44d64833 100644 --- a/test/documents/asyncapi3.yaml +++ b/test/documents/asyncapi3.yaml @@ -1,4 +1,4 @@ -asyncapi: 3.0.0 +asyncapi: 3.1.0 info: title: Address change events version: 1.0.0 diff --git a/test/parser.spec.ts b/test/parser.spec.ts index a904fd2d..fe1b469b 100644 --- a/test/parser.spec.ts +++ b/test/parser.spec.ts @@ -73,7 +73,7 @@ describe('OpenAPISchemaParser', function () { }); it('should parse valid AsyncAPI3', async function() { - const { document, diagnostics } = await coreParser.parse(inputWithValidAsyncAPI3); + const { diagnostics } = await coreParser.parse(inputWithValidAsyncAPI3); expect(diagnostics).toHaveLength(0); }); From 9f45cbd506ec93f395a8146bc45ee163037b5fa2 Mon Sep 17 00:00:00 2001 From: pvdb Date: Tue, 24 Mar 2026 18:18:53 +0100 Subject: [PATCH 3/4] add missing `await` --- test/parser.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/parser.spec.ts b/test/parser.spec.ts index fe1b469b..661f1a3b 100644 --- a/test/parser.spec.ts +++ b/test/parser.spec.ts @@ -68,8 +68,8 @@ describe('OpenAPISchemaParser', function () { it('should parse valid AsyncAPI', async function() { const { document, diagnostics } = await coreParser.parse(inputWithValidAsyncAPI); expect(filterDiagnostics(diagnostics, 'asyncapi2-schemas')).toHaveLength(0); - doParseCoreTest((document?.json()?.channels?.myChannel?.publish?.message as any)?.payload, outputWithValidOpenApi3); - doParseCoreTest((document?.json()?.components?.messages?.testMessage as any)?.payload, outputWithValidOpenApi3); + await doParseCoreTest((document?.json()?.channels?.myChannel?.publish?.message as any)?.payload, outputWithValidOpenApi3); + await doParseCoreTest((document?.json()?.components?.messages?.testMessage as any)?.payload, outputWithValidOpenApi3); }); it('should parse valid AsyncAPI3', async function() { From ae2224b906535fb5a0deff0c8b0886f8f4d2996e Mon Sep 17 00:00:00 2001 From: pvdb Date: Tue, 24 Mar 2026 18:35:56 +0100 Subject: [PATCH 4/4] require Node version >= 18 structuredClone requires minimum Node 17 --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 100456ec..6c58a546 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,9 @@ "LICENSE", "README.md" ], + "engines" : { + "node" : ">=18" + }, "dependencies": { "@asyncapi/parser": "^3.6.0", "@openapi-contrib/openapi-schema-to-json-schema": "~3.2.0",