From bb361095538b79252e3415cf5fd471ef3cf1c167 Mon Sep 17 00:00:00 2001 From: Matatjahu Date: Fri, 23 Sep 2022 15:23:05 +0200 Subject: [PATCH] feat(rulesets): add rule to check if the AsyncAPI document is using the latest version --- docs/reference/asyncapi-rules.md | 6 +++++ .../__tests__/asyncapi-latest-version.test.ts | 27 +++++++++++++++++++ .../functions/asyncApi2DocumentSchema.ts | 3 +++ packages/rulesets/src/asyncapi/index.ts | 18 ++++++++++++- .../scenarios/asyncapi2-streetlights.scenario | 15 ++++++----- 5 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 packages/rulesets/src/asyncapi/__tests__/asyncapi-latest-version.test.ts diff --git a/docs/reference/asyncapi-rules.md b/docs/reference/asyncapi-rules.md index 9e547a7f7..091f319a2 100644 --- a/docs/reference/asyncapi-rules.md +++ b/docs/reference/asyncapi-rules.md @@ -174,6 +174,12 @@ info: name: MIT ``` +### asyncapi-latest-version + +Checking if the AsyncAPI document is using the latest version. + +**Recommended:** Yes + ### asyncapi-message-examples All `examples` in message object should follow `payload` and `headers` schemas. diff --git a/packages/rulesets/src/asyncapi/__tests__/asyncapi-latest-version.test.ts b/packages/rulesets/src/asyncapi/__tests__/asyncapi-latest-version.test.ts new file mode 100644 index 000000000..8d4815204 --- /dev/null +++ b/packages/rulesets/src/asyncapi/__tests__/asyncapi-latest-version.test.ts @@ -0,0 +1,27 @@ +import { DiagnosticSeverity } from '@stoplight/types'; +import { latestAsyncApiVersion } from '../functions/asyncApi2DocumentSchema'; +import testRule from './__helpers__/tester'; + +testRule('asyncapi-latest-version', [ + { + name: 'valid case', + document: { + asyncapi: latestAsyncApiVersion, + }, + errors: [], + }, + + { + name: 'invalid case', + document: { + asyncapi: '2.0.0', + }, + errors: [ + { + message: `The latest version is not used. You should update to the "${latestAsyncApiVersion}" version.`, + path: ['asyncapi'], + severity: DiagnosticSeverity.Information, + }, + ], + }, +]); diff --git a/packages/rulesets/src/asyncapi/functions/asyncApi2DocumentSchema.ts b/packages/rulesets/src/asyncapi/functions/asyncApi2DocumentSchema.ts index 4ac8381d0..fe2085612 100644 --- a/packages/rulesets/src/asyncapi/functions/asyncApi2DocumentSchema.ts +++ b/packages/rulesets/src/asyncapi/functions/asyncApi2DocumentSchema.ts @@ -12,6 +12,9 @@ import * as asyncAPI2_2_0Schema from '@asyncapi/specs/schemas/2.2.0.json'; import * as asyncAPI2_3_0Schema from '@asyncapi/specs/schemas/2.3.0.json'; import * as asyncAPI2_4_0Schema from '@asyncapi/specs/schemas/2.4.0.json'; +export const asyncApiSpecVersions = ['2.0.0', '2.1.0', '2.2.0', '2.3.0', '2.4.0']; +export const latestAsyncApiVersion = asyncApiSpecVersions[asyncApiSpecVersions.length - 1]; + function shouldIgnoreError(error: ErrorObject): boolean { return ( // oneOf is a fairly error as we have 2 options to choose from for most of the time. diff --git a/packages/rulesets/src/asyncapi/index.ts b/packages/rulesets/src/asyncapi/index.ts index e7d387bc4..d336ca297 100644 --- a/packages/rulesets/src/asyncapi/index.ts +++ b/packages/rulesets/src/asyncapi/index.ts @@ -10,7 +10,7 @@ import { import asyncApi2ChannelParameters from './functions/asyncApi2ChannelParameters'; import asyncApi2ChannelServers from './functions/asyncApi2ChannelServers'; -import asyncApi2DocumentSchema from './functions/asyncApi2DocumentSchema'; +import asyncApi2DocumentSchema, { latestAsyncApiVersion } from './functions/asyncApi2DocumentSchema'; import asyncApi2MessageExamplesValidation from './functions/asyncApi2MessageExamplesValidation'; import asyncApi2MessageIdUniqueness from './functions/asyncApi2MessageIdUniqueness'; import asyncApi2OperationIdUniqueness from './functions/asyncApi2OperationIdUniqueness'; @@ -172,6 +172,22 @@ export default { function: truthy, }, }, + 'asyncapi-latest-version': { + description: 'Checking if the AsyncAPI document is using the latest version.', + message: `The latest version is not used. You should update to the "${latestAsyncApiVersion}" version.`, + recommended: true, + type: 'style', + severity: 'info', + given: '$.asyncapi', + then: { + function: schema, + functionOptions: { + schema: { + const: latestAsyncApiVersion, + }, + }, + }, + }, 'asyncapi-message-examples': { description: 'Examples of message object should follow by "payload" and "headers" schemas.', message: '{{error}}', diff --git a/test-harness/scenarios/asyncapi2-streetlights.scenario b/test-harness/scenarios/asyncapi2-streetlights.scenario index 32d2f7957..460c6d1a2 100644 --- a/test-harness/scenarios/asyncapi2-streetlights.scenario +++ b/test-harness/scenarios/asyncapi2-streetlights.scenario @@ -217,11 +217,12 @@ module.exports = asyncapi; {bin} lint {document} --ruleset "{asset:ruleset}" ====stdout==== {document} - 1:1 warning asyncapi-tags AsyncAPI object must have non-empty "tags" array. - 2:6 warning asyncapi-info-contact Info object must have "contact" object. info - 45:13 warning asyncapi-operation-description Operation "description" must be present and non-empty string. channels.smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured.publish - 57:15 warning asyncapi-operation-description Operation "description" must be present and non-empty string. channels.smartylighting/streetlights/1/0/action/{streetlightId}/turn/on.subscribe - 68:15 warning asyncapi-operation-description Operation "description" must be present and non-empty string. channels.smartylighting/streetlights/1/0/action/{streetlightId}/turn/off.subscribe - 79:15 warning asyncapi-operation-description Operation "description" must be present and non-empty string. channels.smartylighting/streetlights/1/0/action/{streetlightId}/dim.subscribe + 1:1 warning asyncapi-tags AsyncAPI object must have non-empty "tags" array. + 1:11 information asyncapi-latest-version The latest version is not used. You should update to the "2.4.0" version. asyncapi + 2:6 warning asyncapi-info-contact Info object must have "contact" object. info + 45:13 warning asyncapi-operation-description Operation "description" must be present and non-empty string. channels.smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured.publish + 57:15 warning asyncapi-operation-description Operation "description" must be present and non-empty string. channels.smartylighting/streetlights/1/0/action/{streetlightId}/turn/on.subscribe + 68:15 warning asyncapi-operation-description Operation "description" must be present and non-empty string. channels.smartylighting/streetlights/1/0/action/{streetlightId}/turn/off.subscribe + 79:15 warning asyncapi-operation-description Operation "description" must be present and non-empty string. channels.smartylighting/streetlights/1/0/action/{streetlightId}/dim.subscribe -✖ 6 problems (0 errors, 6 warnings, 0 infos, 0 hints) +✖ 7 problems (0 errors, 6 warnings, 1 info, 0 hints)