diff --git a/.changeset/ten-rooms-fly.md b/.changeset/ten-rooms-fly.md new file mode 100644 index 000000000..bc03e6279 --- /dev/null +++ b/.changeset/ten-rooms-fly.md @@ -0,0 +1,5 @@ +--- +"@asyncapi/parser": minor +--- + +feat: create the rule `asyncapi3-server-variables' for v3 core ruleset diff --git a/packages/parser/src/ruleset/v2/functions/serverVariables.ts b/packages/parser/src/ruleset/functions/serverVariables.ts similarity index 98% rename from packages/parser/src/ruleset/v2/functions/serverVariables.ts rename to packages/parser/src/ruleset/functions/serverVariables.ts index 921c0ed1d..8380e4757 100644 --- a/packages/parser/src/ruleset/v2/functions/serverVariables.ts +++ b/packages/parser/src/ruleset/functions/serverVariables.ts @@ -1,6 +1,6 @@ import { createRulesetFunction } from '@stoplight/spectral-core'; -import { getMissingProps, getRedundantProps, parseUrlVariables } from '../../utils'; +import { getMissingProps, getRedundantProps, parseUrlVariables } from '../utils'; import type { IFunctionResult } from '@stoplight/spectral-core'; diff --git a/packages/parser/src/ruleset/v2/ruleset.ts b/packages/parser/src/ruleset/v2/ruleset.ts index b03a7549f..fec6a882f 100644 --- a/packages/parser/src/ruleset/v2/ruleset.ts +++ b/packages/parser/src/ruleset/v2/ruleset.ts @@ -12,7 +12,7 @@ import { messageIdUniqueness } from './functions/messageIdUniqueness'; import { operationIdUniqueness } from './functions/operationIdUniqueness'; import { schemaValidation } from './functions/schemaValidation'; import { security } from './functions/security'; -import { serverVariables } from './functions/serverVariables'; +import { serverVariables } from '../functions/serverVariables'; import { unusedSecuritySchemes } from './functions/unusedSecuritySchemes'; import { uniquenessTags } from '../functions/uniquenessTags'; import { asyncApi2SchemaParserRule } from '../../schema-parser/spectral-rule-v2'; diff --git a/packages/parser/src/ruleset/v3/ruleset.ts b/packages/parser/src/ruleset/v3/ruleset.ts index efc719483..fca88c709 100644 --- a/packages/parser/src/ruleset/v3/ruleset.ts +++ b/packages/parser/src/ruleset/v3/ruleset.ts @@ -5,11 +5,26 @@ import { AsyncAPIFormats } from '../formats'; import { operationMessagesUnambiguity } from './functions/operationMessagesUnambiguity'; import { pattern } from '@stoplight/spectral-functions'; import { channelServers } from '../functions/channelServers'; +import { serverVariables } from '../functions/serverVariables'; export const v3CoreRuleset = { description: 'Core AsyncAPI 3.x.x ruleset.', formats: AsyncAPIFormats.filterByMajorVersions(['3']).formats(), rules: { + /** + * Server Object rules + */ + 'asyncapi3-server-variables': { + description: 'Server variables must be defined and there must be no redundant variables.', + message: '{{error}}', + severity: 'error', + recommended: true, + given: ['$.servers.*', '$.components.servers.*'], + then: { //NOSONAR + function: serverVariables, + }, + }, + /** * Operation Object rules */ diff --git a/packages/parser/test/ruleset/rules/v3/asyncapi3-server-variables.spec.ts b/packages/parser/test/ruleset/rules/v3/asyncapi3-server-variables.spec.ts new file mode 100644 index 000000000..61d45d2b7 --- /dev/null +++ b/packages/parser/test/ruleset/rules/v3/asyncapi3-server-variables.spec.ts @@ -0,0 +1,154 @@ +import { testRule, DiagnosticSeverity } from '../../tester'; + +testRule('asyncapi3-server-variables', [ + { + name: 'valid case', + document: { + asyncapi: '3.0.0', + servers: { + production: { + url: '{sub}.stoplight.io', + protocol: 'https', + variables: { + sub: {}, + }, + }, + }, + }, + errors: [], + }, + + { + name: 'server has not defined definition for one of the url variables', + document: { + asyncapi: '3.0.0', + servers: { + production: { + url: '{sub}.{anotherParam}.stoplight.io', + protocol: 'https', + variables: { + sub: {}, + }, + }, + }, + }, + errors: [ + { + message: 'Not all server\'s variables are described with "variables" object. Missed: anotherParam.', + path: ['servers', 'production', 'variables'], + severity: DiagnosticSeverity.Error, + }, + ], + }, + + { + name: 'server has not defined definition for two of the url variables', + document: { + asyncapi: '3.0.0', + servers: { + production: { + url: '{sub}.{anotherParam1}.{anotherParam2}.stoplight.io', + protocol: 'https', + variables: { + sub: {}, + }, + }, + }, + }, + errors: [ + { + message: + 'Not all server\'s variables are described with "variables" object. Missed: anotherParam1, anotherParam2.', + path: ['servers', 'production', 'variables'], + severity: DiagnosticSeverity.Error, + }, + ], + }, + + { + name: 'server has not defined definition for one of the url variables (in the components.servers)', + document: { + asyncapi: '3.0.0', + components: { + servers: { + production: { + url: '{sub}.{anotherParam}.stoplight.io', + protocol: 'https', + variables: { + sub: {}, + }, + }, + }, + }, + }, + errors: [ + { + message: 'Not all server\'s variables are described with "variables" object. Missed: anotherParam.', + path: ['components', 'servers', 'production', 'variables'], + severity: DiagnosticSeverity.Error, + }, + ], + }, + + { + name: 'server has redundant url variables', + document: { + asyncapi: '3.0.0', + servers: { + production: { + url: '{sub}.stoplight.io', + protocol: 'https', + variables: { + sub: {}, + anotherParam1: {}, + anotherParam2: {}, + }, + }, + }, + }, + errors: [ + { + message: 'Server\'s "variables" object has redundant defined "anotherParam1" url variable.', + path: ['servers', 'production', 'variables', 'anotherParam1'], + severity: DiagnosticSeverity.Error, + }, + { + message: 'Server\'s "variables" object has redundant defined "anotherParam2" url variable.', + path: ['servers', 'production', 'variables', 'anotherParam2'], + severity: DiagnosticSeverity.Error, + }, + ], + }, + + { + name: 'server has redundant url variables (in the components.servers)', + document: { + asyncapi: '3.0.0', + components: { + servers: { + production: { + url: '{sub}.stoplight.io', + protocol: 'https', + variables: { + sub: {}, + anotherParam1: {}, + anotherParam2: {}, + }, + }, + }, + }, + }, + errors: [ + { + message: 'Server\'s "variables" object has redundant defined "anotherParam1" url variable.', + path: ['components', 'servers', 'production', 'variables', 'anotherParam1'], + severity: DiagnosticSeverity.Error, + }, + { + message: 'Server\'s "variables" object has redundant defined "anotherParam2" url variable.', + path: ['components', 'servers', 'production', 'variables', 'anotherParam2'], + severity: DiagnosticSeverity.Error, + }, + ], + }, +]);