From 1d8b4a0a24e7f1e6999deee2dde7fa3c27b3f2c3 Mon Sep 17 00:00:00 2001 From: Dieter Stinglhamber Date: Thu, 4 Jan 2024 21:16:43 +0100 Subject: [PATCH] feat: add support for openapi schemas --- package.json | 1 + pnpm-lock.yaml | 18 +++++++ src/index.ts | 6 ++- .../fixtures/valid-schema-openapi-2.4.0.yaml | 44 ++++++++++++++++ .../fixtures/valid-schema-openapi-3.0.0.yaml | 51 +++++++++++++++++++ tests/from-file.test.ts | 24 +++++++++ tests/from-schema.test.ts | 28 ++++++++++ 7 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/valid-schema-openapi-2.4.0.yaml create mode 100644 tests/fixtures/valid-schema-openapi-3.0.0.yaml diff --git a/package.json b/package.json index 35af06b..7f3b1a3 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "author": "Elhebert", "license": "MIT", "dependencies": { + "@asyncapi/openapi-schema-parser": "^3.0.10", "@asyncapi/parser": "^3.0.0", "ajv": "^8.12.0", "ajv-formats": "^2.1.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04c6447..7934ae3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + '@asyncapi/openapi-schema-parser': + specifier: ^3.0.10 + version: 3.0.10 '@asyncapi/parser': specifier: ^3.0.0 version: 3.0.2 @@ -103,6 +106,21 @@ packages: '@jridgewell/trace-mapping': 0.3.20 dev: true + /@asyncapi/openapi-schema-parser@3.0.10: + resolution: + { + integrity: sha512-kaLeYLicn65iLCKnjrmOYEybjFgxrKBOc2ZjwloCMRahyWX3hQHPU9IqL54JxEQ2R9AGznROPhrKz4iczRfKZw==, + } + dependencies: + '@asyncapi/parser': 3.0.2 + '@openapi-contrib/openapi-schema-to-json-schema': 3.2.0 + ajv: 8.12.0 + ajv-errors: 3.0.0(ajv@8.12.0) + ajv-formats: 2.1.1(ajv@8.12.0) + transitivePeerDependencies: + - encoding + dev: false + /@asyncapi/parser@3.0.2: resolution: { diff --git a/src/index.ts b/src/index.ts index 4745723..edea229 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,12 @@ import { type Input, fromFile, fromURL, Parser } from '@asyncapi/parser'; import AsyncAPIParsingError from './AsyncAPIParsingError'; import validate, { type ValidationFunction } from './validate'; +import openAPISchemaParser from '@asyncapi/openapi-schema-parser'; -const parser = new Parser({ ruleset: { core: true, recommended: false } }); +const parser = new Parser({ + ruleset: { core: true, recommended: false }, + schemaParsers: [openAPISchemaParser()], +}); export default { /** diff --git a/tests/fixtures/valid-schema-openapi-2.4.0.yaml b/tests/fixtures/valid-schema-openapi-2.4.0.yaml new file mode 100644 index 0000000..b4a50f6 --- /dev/null +++ b/tests/fixtures/valid-schema-openapi-2.4.0.yaml @@ -0,0 +1,44 @@ +asyncapi: 2.4.0 +info: + title: My API + version: '1.0.0' + +channels: + myChannel: + publish: + message: + $ref: '#/components/messages/testMessage' + +components: + messages: + testMessage: + schemaFormat: application/vnd.oai.openapi;version=3.0.0 + payload: + type: object + nullable: true + example: + name: Fran + properties: + name: + type: string + discriminatorTest: + discriminator: + propertyName: objectType + oneOf: + - type: object + properties: + objectType: + type: string + prop1: + type: string + - type: object + properties: + objectType: + type: string + prop2: + type: string + test: + type: object + properties: + testing: + type: string diff --git a/tests/fixtures/valid-schema-openapi-3.0.0.yaml b/tests/fixtures/valid-schema-openapi-3.0.0.yaml new file mode 100644 index 0000000..5eeaf90 --- /dev/null +++ b/tests/fixtures/valid-schema-openapi-3.0.0.yaml @@ -0,0 +1,51 @@ +asyncapi: 3.0.0 +info: + title: My API + version: 1.0.0 +channels: + myChannel: + address: myChannel + messages: + publish.message: + $ref: '#/components/messages/testMessage' +operations: + myChannel.publish: + action: receive + channel: + $ref: '#/channels/myChannel' + messages: + - $ref: '#/channels/myChannel/messages/publish.message' +components: + messages: + testMessage: + payload: + schemaFormat: application/vnd.oai.openapi;version=3.0.0 + schema: + type: object + nullable: true + example: + name: Fran + properties: + name: + type: string + discriminatorTest: + discriminator: + propertyName: objectType + oneOf: + - type: object + properties: + objectType: + type: string + prop1: + type: string + - type: object + properties: + objectType: + type: string + prop2: + type: string + test: + type: object + properties: + testing: + type: string diff --git a/tests/from-file.test.ts b/tests/from-file.test.ts index c50f4fc..5a0c028 100644 --- a/tests/from-file.test.ts +++ b/tests/from-file.test.ts @@ -204,4 +204,28 @@ describe('parsing `fromFile`', () => { ); } }); + + it('validate an openapi schema inside a valid Async API 3.0.0 schema', async () => { + const validator = await asyncApiValidation.fromFile( + path.join(__dirname, 'fixtures', 'valid-schema-openapi-3.0.0.yaml') + ); + + const payload = { + name: 'Fran', + }; + + expect(validator('testMessage', payload)).toBe(true); + }); + + it('validate an openapi schema inside a valid Async API 2.4.0 schema', async () => { + const validator = await asyncApiValidation.fromFile( + path.join(__dirname, 'fixtures', 'valid-schema-openapi-2.4.0.yaml') + ); + + const payload = { + name: 'Fran', + }; + + expect(validator('testMessage', payload)).toBe(true); + }); }); diff --git a/tests/from-schema.test.ts b/tests/from-schema.test.ts index 537cc69..a702a10 100644 --- a/tests/from-schema.test.ts +++ b/tests/from-schema.test.ts @@ -218,4 +218,32 @@ describe('parsing `fromSchema`', () => { ); } }); + + it('validate an openapi schema inside a valid Async API 3.0.0 schema', async () => { + const schema = await readFile( + path.join(__dirname, 'fixtures', 'valid-schema-openapi-3.0.0.yaml'), + 'utf-8' + ); + const validator = await asyncApiValidation.fromSchema(schema); + + const payload = { + name: 'Fran', + }; + + expect(validator('testMessage', payload)).toBe(true); + }); + + it('validate an openapi schema inside a valid Async API 2.4.0 schema', async () => { + const schema = await readFile( + path.join(__dirname, 'fixtures', 'valid-schema-openapi-2.4.0.yaml'), + 'utf-8' + ); + const validator = await asyncApiValidation.fromSchema(schema); + + const payload = { + name: 'Fran', + }; + + expect(validator('testMessage', payload)).toBe(true); + }); });