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", 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..44d64833 --- /dev/null +++ b/test/documents/asyncapi3.yaml @@ -0,0 +1,62 @@ +asyncapi: 3.1.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..661f1a3b 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 () { @@ -66,8 +68,13 @@ 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() { + const { diagnostics } = await coreParser.parse(inputWithValidAsyncAPI3); + expect(diagnostics).toHaveLength(0); }); it('should validate valid AsyncAPI', async function() { @@ -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 +}