@asyncapi/parser
Advanced tools
Comparing version 2.1.0-next-major-spec.3 to 2.1.0-next-major-spec.4
import type { Format } from '@stoplight/spectral-core'; | ||
export declare const aas2: Format; | ||
export declare const aas2_0: Format; | ||
export declare const aas2_1: Format; | ||
export declare const aas2_2: Format; | ||
export declare const aas2_3: Format; | ||
export declare const aas2_4: Format; | ||
export declare const aas2_5: Format; | ||
export declare const aas2_6: Format; | ||
export declare const aas2All: Format<void>[]; | ||
export declare class Formats extends Map<string, Format> { | ||
filterByMajorVersions(majorsToInclude: string[]): Formats; | ||
excludeByVersions(versionsToExclude: string[]): Formats; | ||
find(version: string): Format | undefined; | ||
formats(): Format[]; | ||
} | ||
export declare const AsyncAPIFormats: Formats; |
"use strict"; | ||
/* eslint-disable security/detect-unsafe-regex */ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.aas2All = exports.aas2_6 = exports.aas2_5 = exports.aas2_4 = exports.aas2_3 = exports.aas2_2 = exports.aas2_1 = exports.aas2_0 = exports.aas2 = void 0; | ||
exports.AsyncAPIFormats = exports.Formats = void 0; | ||
const utils_1 = require("../utils"); | ||
const aas2Regex = /^2\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/; | ||
const aas2_0Regex = /^2\.0(?:\.[0-9]*)?$/; | ||
const aas2_1Regex = /^2\.1(?:\.[0-9]*)?$/; | ||
const aas2_2Regex = /^2\.2(?:\.[0-9]*)?$/; | ||
const aas2_3Regex = /^2\.3(?:\.[0-9]*)?$/; | ||
const aas2_4Regex = /^2\.4(?:\.[0-9]*)?$/; | ||
const aas2_5Regex = /^2\.5(?:\.[0-9]*)?$/; | ||
const aas2_6Regex = /^2\.6(?:\.[0-9]*)?$/; | ||
const isAas2 = (document) => (0, utils_1.isObject)(document) && 'asyncapi' in document && aas2Regex.test(String(document.asyncapi)); | ||
exports.aas2 = isAas2; | ||
exports.aas2.displayName = 'AsyncAPI 2.x'; | ||
const aas2_0 = (document) => isAas2(document) && aas2_0Regex.test(String(document.asyncapi)); | ||
exports.aas2_0 = aas2_0; | ||
exports.aas2_0.displayName = 'AsyncAPI 2.0.x'; | ||
const aas2_1 = (document) => isAas2(document) && aas2_1Regex.test(String(document.asyncapi)); | ||
exports.aas2_1 = aas2_1; | ||
exports.aas2_1.displayName = 'AsyncAPI 2.1.x'; | ||
const aas2_2 = (document) => isAas2(document) && aas2_2Regex.test(String(document.asyncapi)); | ||
exports.aas2_2 = aas2_2; | ||
exports.aas2_2.displayName = 'AsyncAPI 2.2.x'; | ||
const aas2_3 = (document) => isAas2(document) && aas2_3Regex.test(String(document.asyncapi)); | ||
exports.aas2_3 = aas2_3; | ||
exports.aas2_3.displayName = 'AsyncAPI 2.3.x'; | ||
const aas2_4 = (document) => isAas2(document) && aas2_4Regex.test(String(document.asyncapi)); | ||
exports.aas2_4 = aas2_4; | ||
exports.aas2_4.displayName = 'AsyncAPI 2.4.x'; | ||
const aas2_5 = (document) => isAas2(document) && aas2_5Regex.test(String(document.asyncapi)); | ||
exports.aas2_5 = aas2_5; | ||
exports.aas2_5.displayName = 'AsyncAPI 2.5.x'; | ||
const aas2_6 = (document) => isAas2(document) && aas2_6Regex.test(String(document.asyncapi)); | ||
exports.aas2_6 = aas2_6; | ||
exports.aas2_6.displayName = 'AsyncAPI 2.6.x'; | ||
exports.aas2All = [exports.aas2_0, exports.aas2_1, exports.aas2_2, exports.aas2_3, exports.aas2_4, exports.aas2_5, exports.aas2_6]; | ||
const specs_1 = require("@asyncapi/specs"); | ||
class Formats extends Map { | ||
filterByMajorVersions(majorsToInclude) { | ||
return new Formats([...this.entries()].filter(element => { return majorsToInclude.includes(element[0].split('.')[0]); })); | ||
} | ||
excludeByVersions(versionsToExclude) { | ||
return new Formats([...this.entries()].filter(element => { return !versionsToExclude.includes(element[0]); })); | ||
} | ||
find(version) { | ||
return this.get(formatVersion(version)); | ||
} | ||
formats() { | ||
return [...this.values()]; | ||
} | ||
} | ||
exports.Formats = Formats; | ||
exports.AsyncAPIFormats = new Formats(Object.entries(specs_1.schemas).reverse().map(([version]) => [version, createFormat(version)])); // reverse is used for giving newer versions a higher priority when matching | ||
function isAsyncAPIVersion(versionToMatch, document) { | ||
const asyncAPIDoc = document; | ||
if (!asyncAPIDoc) | ||
return false; | ||
const documentVersion = String(asyncAPIDoc.asyncapi); | ||
return (0, utils_1.isObject)(document) && 'asyncapi' in document | ||
&& assertValidAsyncAPIVersion(documentVersion) | ||
&& versionToMatch === formatVersion(documentVersion); | ||
} | ||
function assertValidAsyncAPIVersion(documentVersion) { | ||
const semver = (0, utils_1.getSemver)(documentVersion); | ||
const regexp = new RegExp(`^(${semver.major})\\.(${semver.minor})\\.(0|[1-9][0-9]*)$`); // eslint-disable-line security/detect-non-literal-regexp | ||
return regexp.test(documentVersion); | ||
} | ||
function createFormat(version) { | ||
const format = (document) => isAsyncAPIVersion(version, document); | ||
const semver = (0, utils_1.getSemver)(version); | ||
format.displayName = `AsyncAPI ${semver.major}.${semver.minor}.x`; | ||
return format; | ||
} | ||
const formatVersion = function (version) { | ||
const versionSemver = (0, utils_1.getSemver)(version); | ||
return `${versionSemver.major}.${versionSemver.minor}.0`; | ||
}; |
@@ -0,3 +1,5 @@ | ||
import type { Format } from '@stoplight/spectral-core'; | ||
export declare function getSchema(docFormats: Set<Format>, resolved: boolean): Record<string, any> | void; | ||
export declare const documentStructure: import("@stoplight/spectral-core").RulesetFunctionWithValidator<unknown, { | ||
resolved: boolean; | ||
}>; |
"use strict"; | ||
/* eslint-disable sonarjs/no-duplicate-string */ | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -6,3 +7,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.documentStructure = void 0; | ||
exports.documentStructure = exports.getSchema = void 0; | ||
const specs_1 = __importDefault(require("@asyncapi/specs")); | ||
@@ -12,2 +13,3 @@ const spectral_core_1 = require("@stoplight/spectral-core"); | ||
const formats_1 = require("../formats"); | ||
const utils_1 = require("../../utils"); | ||
function shouldIgnoreError(error) { | ||
@@ -46,2 +48,18 @@ return ( | ||
} | ||
// this is needed because some v3 object fields are expected to be only `$ref` to other objects. | ||
// In order to validate resolved references, we modify those schemas and instead allow the definition of the object | ||
function prepareV3ResolvedSchema(copied) { | ||
// channel object | ||
const channelObject = copied.definitions['http://asyncapi.com/definitions/3.0.0/channel.json']; | ||
channelObject.properties.servers.items.$ref = 'http://asyncapi.com/definitions/3.0.0/server.json'; | ||
// operation object | ||
const operationSchema = copied.definitions['http://asyncapi.com/definitions/3.0.0/operation.json']; | ||
operationSchema.properties.channel.$ref = 'http://asyncapi.com/definitions/3.0.0/channel.json'; | ||
operationSchema.properties.messages.items.$ref = 'http://asyncapi.com/definitions/3.0.0/messageObject.json'; | ||
// operation reply object | ||
const operationReplySchema = copied.definitions['http://asyncapi.com/definitions/3.0.0/operationReply.json']; | ||
operationReplySchema.properties.channel.$ref = 'http://asyncapi.com/definitions/3.0.0/channel.json'; | ||
operationReplySchema.properties.messages.items.$ref = 'http://asyncapi.com/definitions/3.0.0/messageObject.json'; | ||
return copied; | ||
} | ||
function getCopyOfSchema(version) { | ||
@@ -51,4 +69,5 @@ return JSON.parse(JSON.stringify(specs_1.default.schemas[version])); | ||
const serializedSchemas = new Map(); | ||
function getSerializedSchema(version) { | ||
const schema = serializedSchemas.get(version); | ||
function getSerializedSchema(version, resolved) { | ||
const serializedSchemaKey = resolved ? `${version}-resolved` : `${version}-unresolved`; | ||
const schema = serializedSchemas.get(serializedSchemaKey); | ||
if (schema) { | ||
@@ -58,7 +77,13 @@ return schema; | ||
// Copy to not operate on the original json schema - between imports (in different modules) we operate on this same schema. | ||
const copied = getCopyOfSchema(version); | ||
let copied = getCopyOfSchema(version); | ||
// Remove the meta schemas because they are already present within Ajv, and it's not possible to add duplicated schemas. | ||
delete copied.definitions['http://json-schema.org/draft-07/schema']; | ||
delete copied.definitions['http://json-schema.org/draft-04/schema']; | ||
serializedSchemas.set(version, copied); | ||
// Spectral caches the schemas using '$id' property | ||
copied['$id'] = copied['$id'].replace('asyncapi.json', `asyncapi-${resolved ? 'resolved' : 'unresolved'}.json`); | ||
const { major } = (0, utils_1.getSemver)(version); | ||
if (resolved && major === 3) { | ||
copied = prepareV3ResolvedSchema(copied); | ||
} | ||
serializedSchemas.set(serializedSchemaKey, copied); | ||
return copied; | ||
@@ -78,22 +103,10 @@ } | ||
} | ||
function getSchema(formats) { | ||
switch (true) { | ||
case formats.has(formats_1.aas2_6): | ||
return getSerializedSchema('2.6.0'); | ||
case formats.has(formats_1.aas2_5): | ||
return getSerializedSchema('2.5.0'); | ||
case formats.has(formats_1.aas2_4): | ||
return getSerializedSchema('2.4.0'); | ||
case formats.has(formats_1.aas2_3): | ||
return getSerializedSchema('2.3.0'); | ||
case formats.has(formats_1.aas2_2): | ||
return getSerializedSchema('2.2.0'); | ||
case formats.has(formats_1.aas2_1): | ||
return getSerializedSchema('2.1.0'); | ||
case formats.has(formats_1.aas2_0): | ||
return getSerializedSchema('2.0.0'); | ||
default: | ||
return; | ||
function getSchema(docFormats, resolved) { | ||
for (const [version, format] of formats_1.AsyncAPIFormats) { | ||
if (docFormats.has(format)) { | ||
return getSerializedSchema(version, resolved); | ||
} | ||
} | ||
} | ||
exports.getSchema = getSchema; | ||
exports.documentStructure = (0, spectral_core_1.createRulesetFunction)({ | ||
@@ -116,11 +129,12 @@ input: null, | ||
} | ||
const schema = getSchema(formats); | ||
const resolved = options.resolved; | ||
const schema = getSchema(formats, resolved); | ||
if (!schema) { | ||
return; | ||
} | ||
const errors = (0, spectral_functions_1.schema)(targetVal, { allErrors: true, schema, prepareResults: options.resolved ? prepareResults : undefined }, context); | ||
const errors = (0, spectral_functions_1.schema)(targetVal, { allErrors: true, schema, prepareResults: resolved ? prepareResults : undefined }, context); | ||
if (!Array.isArray(errors)) { | ||
return; | ||
} | ||
return filterRefErrors(errors, options.resolved); | ||
return filterRefErrors(errors, resolved); | ||
}); |
@@ -6,3 +6,2 @@ "use strict"; | ||
const spectral_core_1 = require("@stoplight/spectral-core"); | ||
const formats_1 = require("../formats"); | ||
const utils_1 = require("../../utils"); | ||
@@ -24,5 +23,5 @@ exports.unusedComponent = (0, spectral_core_1.createRulesetFunction)({ | ||
Object.keys(components).forEach(componentType => { | ||
// if component type is `securitySchemes` and we operate on AsyncAPI 2.x.x skip validation | ||
// security schemes in 2.x.x are referenced by keys, not by object ref - for this case we have a separate `asyncapi2-unused-securityScheme` rule | ||
if (componentType === 'securitySchemes' && (0, formats_1.aas2)(targetVal, null)) { | ||
// if component type is `securitySchemes` we skip the validation | ||
// security schemes in >=2.x.x are referenced by keys, not by object ref - for this case we have a separate `asyncapi2-unused-securityScheme` rule | ||
if (componentType === 'securitySchemes') { | ||
return; | ||
@@ -29,0 +28,0 @@ } |
@@ -172,2 +172,3 @@ export declare const coreRuleset: { | ||
description: string; | ||
formats: import("@stoplight/spectral-core").Format<void>[]; | ||
recommended: boolean; | ||
@@ -174,0 +175,0 @@ resolved: boolean; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.recommendedRuleset = exports.coreRuleset = void 0; | ||
const formats_1 = require("./formats"); | ||
const constants_1 = require("../constants"); | ||
const spectral_functions_1 = require("@stoplight/spectral-functions"); | ||
@@ -11,5 +9,7 @@ const documentStructure_1 = require("./functions/documentStructure"); | ||
const unusedComponent_1 = require("./functions/unusedComponent"); | ||
const formats_1 = require("./formats"); | ||
const constants_1 = require("../constants"); | ||
exports.coreRuleset = { | ||
description: 'Core AsyncAPI x.x.x ruleset.', | ||
formats: [...formats_1.aas2All], | ||
formats: formats_1.AsyncAPIFormats.formats(), | ||
rules: { | ||
@@ -84,3 +84,3 @@ /** | ||
description: 'Recommended AsyncAPI x.x.x ruleset.', | ||
formats: [...formats_1.aas2All], | ||
formats: formats_1.AsyncAPIFormats.filterByMajorVersions(['2']).formats(), | ||
rules: { | ||
@@ -190,2 +190,3 @@ /** | ||
description: 'Potentially unused component has been detected in AsyncAPI document.', | ||
formats: formats_1.AsyncAPIFormats.filterByMajorVersions(['2']).formats(), | ||
recommended: true, | ||
@@ -192,0 +193,0 @@ resolved: false, |
@@ -148,3 +148,2 @@ import type { Parser } from '../../parser'; | ||
description: string; | ||
formats: import("@stoplight/spectral-core").Format<void>[]; | ||
rules: { | ||
@@ -151,0 +150,0 @@ 'asyncapi2-schemas': import("@stoplight/spectral-core").RuleDefinition; |
@@ -21,3 +21,3 @@ "use strict"; | ||
description: 'Core AsyncAPI 2.x.x ruleset.', | ||
formats: [...formats_1.aas2All], | ||
formats: formats_1.AsyncAPIFormats.filterByMajorVersions(['2']).formats(), | ||
rules: { | ||
@@ -188,3 +188,2 @@ /** | ||
description: 'Schemas AsyncAPI 2.x.x ruleset.', | ||
formats: [...formats_1.aas2All], | ||
rules: { | ||
@@ -242,3 +241,3 @@ 'asyncapi2-schemas': (0, spectral_rule_v2_1.asyncApi2SchemaParserRule)(parser), | ||
description: 'Recommended AsyncAPI 2.x.x ruleset.', | ||
formats: [...formats_1.aas2All], | ||
formats: formats_1.AsyncAPIFormats.filterByMajorVersions(['2']).formats(), | ||
rules: { | ||
@@ -329,3 +328,3 @@ /** | ||
recommended: true, | ||
formats: formats_1.aas2All.slice(4), | ||
formats: formats_1.AsyncAPIFormats.filterByMajorVersions(['2']).excludeByVersions(['2.0.0', '2.1.0', '2.2.0', '2.3.0']).formats(), | ||
given: [ | ||
@@ -332,0 +331,0 @@ '$.channels.*.[publish,subscribe][?(@property === "message" && @.oneOf == void 0)]', |
import type { Format } from '@stoplight/spectral-core'; | ||
export declare const aas2: Format; | ||
export declare const aas2_0: Format; | ||
export declare const aas2_1: Format; | ||
export declare const aas2_2: Format; | ||
export declare const aas2_3: Format; | ||
export declare const aas2_4: Format; | ||
export declare const aas2_5: Format; | ||
export declare const aas2_6: Format; | ||
export declare const aas2All: Format<void>[]; | ||
export declare class Formats extends Map<string, Format> { | ||
filterByMajorVersions(majorsToInclude: string[]): Formats; | ||
excludeByVersions(versionsToExclude: string[]): Formats; | ||
find(version: string): Format | undefined; | ||
formats(): Format[]; | ||
} | ||
export declare const AsyncAPIFormats: Formats; |
@@ -1,28 +0,41 @@ | ||
/* eslint-disable security/detect-unsafe-regex */ | ||
import { isObject } from '../utils'; | ||
const aas2Regex = /^2\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/; | ||
const aas2_0Regex = /^2\.0(?:\.[0-9]*)?$/; | ||
const aas2_1Regex = /^2\.1(?:\.[0-9]*)?$/; | ||
const aas2_2Regex = /^2\.2(?:\.[0-9]*)?$/; | ||
const aas2_3Regex = /^2\.3(?:\.[0-9]*)?$/; | ||
const aas2_4Regex = /^2\.4(?:\.[0-9]*)?$/; | ||
const aas2_5Regex = /^2\.5(?:\.[0-9]*)?$/; | ||
const aas2_6Regex = /^2\.6(?:\.[0-9]*)?$/; | ||
const isAas2 = (document) => isObject(document) && 'asyncapi' in document && aas2Regex.test(String(document.asyncapi)); | ||
export const aas2 = isAas2; | ||
aas2.displayName = 'AsyncAPI 2.x'; | ||
export const aas2_0 = (document) => isAas2(document) && aas2_0Regex.test(String(document.asyncapi)); | ||
aas2_0.displayName = 'AsyncAPI 2.0.x'; | ||
export const aas2_1 = (document) => isAas2(document) && aas2_1Regex.test(String(document.asyncapi)); | ||
aas2_1.displayName = 'AsyncAPI 2.1.x'; | ||
export const aas2_2 = (document) => isAas2(document) && aas2_2Regex.test(String(document.asyncapi)); | ||
aas2_2.displayName = 'AsyncAPI 2.2.x'; | ||
export const aas2_3 = (document) => isAas2(document) && aas2_3Regex.test(String(document.asyncapi)); | ||
aas2_3.displayName = 'AsyncAPI 2.3.x'; | ||
export const aas2_4 = (document) => isAas2(document) && aas2_4Regex.test(String(document.asyncapi)); | ||
aas2_4.displayName = 'AsyncAPI 2.4.x'; | ||
export const aas2_5 = (document) => isAas2(document) && aas2_5Regex.test(String(document.asyncapi)); | ||
aas2_5.displayName = 'AsyncAPI 2.5.x'; | ||
export const aas2_6 = (document) => isAas2(document) && aas2_6Regex.test(String(document.asyncapi)); | ||
aas2_6.displayName = 'AsyncAPI 2.6.x'; | ||
export const aas2All = [aas2_0, aas2_1, aas2_2, aas2_3, aas2_4, aas2_5, aas2_6]; | ||
import { getSemver, isObject } from '../utils'; | ||
import { schemas } from '@asyncapi/specs'; | ||
export class Formats extends Map { | ||
filterByMajorVersions(majorsToInclude) { | ||
return new Formats([...this.entries()].filter(element => { return majorsToInclude.includes(element[0].split('.')[0]); })); | ||
} | ||
excludeByVersions(versionsToExclude) { | ||
return new Formats([...this.entries()].filter(element => { return !versionsToExclude.includes(element[0]); })); | ||
} | ||
find(version) { | ||
return this.get(formatVersion(version)); | ||
} | ||
formats() { | ||
return [...this.values()]; | ||
} | ||
} | ||
export const AsyncAPIFormats = new Formats(Object.entries(schemas).reverse().map(([version]) => [version, createFormat(version)])); // reverse is used for giving newer versions a higher priority when matching | ||
function isAsyncAPIVersion(versionToMatch, document) { | ||
const asyncAPIDoc = document; | ||
if (!asyncAPIDoc) | ||
return false; | ||
const documentVersion = String(asyncAPIDoc.asyncapi); | ||
return isObject(document) && 'asyncapi' in document | ||
&& assertValidAsyncAPIVersion(documentVersion) | ||
&& versionToMatch === formatVersion(documentVersion); | ||
} | ||
function assertValidAsyncAPIVersion(documentVersion) { | ||
const semver = getSemver(documentVersion); | ||
const regexp = new RegExp(`^(${semver.major})\\.(${semver.minor})\\.(0|[1-9][0-9]*)$`); // eslint-disable-line security/detect-non-literal-regexp | ||
return regexp.test(documentVersion); | ||
} | ||
function createFormat(version) { | ||
const format = (document) => isAsyncAPIVersion(version, document); | ||
const semver = getSemver(version); | ||
format.displayName = `AsyncAPI ${semver.major}.${semver.minor}.x`; | ||
return format; | ||
} | ||
const formatVersion = function (version) { | ||
const versionSemver = getSemver(version); | ||
return `${versionSemver.major}.${versionSemver.minor}.0`; | ||
}; |
@@ -0,3 +1,5 @@ | ||
import type { Format } from '@stoplight/spectral-core'; | ||
export declare function getSchema(docFormats: Set<Format>, resolved: boolean): Record<string, any> | void; | ||
export declare const documentStructure: import("@stoplight/spectral-core").RulesetFunctionWithValidator<unknown, { | ||
resolved: boolean; | ||
}>; |
@@ -0,5 +1,7 @@ | ||
/* eslint-disable sonarjs/no-duplicate-string */ | ||
import specs from '@asyncapi/specs'; | ||
import { createRulesetFunction } from '@stoplight/spectral-core'; | ||
import { schema as schemaFn } from '@stoplight/spectral-functions'; | ||
import { aas2_0, aas2_1, aas2_2, aas2_3, aas2_4, aas2_5, aas2_6 } from '../formats'; | ||
import { AsyncAPIFormats } from '../formats'; | ||
import { getSemver } from '../../utils'; | ||
function shouldIgnoreError(error) { | ||
@@ -38,2 +40,18 @@ return ( | ||
} | ||
// this is needed because some v3 object fields are expected to be only `$ref` to other objects. | ||
// In order to validate resolved references, we modify those schemas and instead allow the definition of the object | ||
function prepareV3ResolvedSchema(copied) { | ||
// channel object | ||
const channelObject = copied.definitions['http://asyncapi.com/definitions/3.0.0/channel.json']; | ||
channelObject.properties.servers.items.$ref = 'http://asyncapi.com/definitions/3.0.0/server.json'; | ||
// operation object | ||
const operationSchema = copied.definitions['http://asyncapi.com/definitions/3.0.0/operation.json']; | ||
operationSchema.properties.channel.$ref = 'http://asyncapi.com/definitions/3.0.0/channel.json'; | ||
operationSchema.properties.messages.items.$ref = 'http://asyncapi.com/definitions/3.0.0/messageObject.json'; | ||
// operation reply object | ||
const operationReplySchema = copied.definitions['http://asyncapi.com/definitions/3.0.0/operationReply.json']; | ||
operationReplySchema.properties.channel.$ref = 'http://asyncapi.com/definitions/3.0.0/channel.json'; | ||
operationReplySchema.properties.messages.items.$ref = 'http://asyncapi.com/definitions/3.0.0/messageObject.json'; | ||
return copied; | ||
} | ||
function getCopyOfSchema(version) { | ||
@@ -43,4 +61,5 @@ return JSON.parse(JSON.stringify(specs.schemas[version])); | ||
const serializedSchemas = new Map(); | ||
function getSerializedSchema(version) { | ||
const schema = serializedSchemas.get(version); | ||
function getSerializedSchema(version, resolved) { | ||
const serializedSchemaKey = resolved ? `${version}-resolved` : `${version}-unresolved`; | ||
const schema = serializedSchemas.get(serializedSchemaKey); | ||
if (schema) { | ||
@@ -50,7 +69,13 @@ return schema; | ||
// Copy to not operate on the original json schema - between imports (in different modules) we operate on this same schema. | ||
const copied = getCopyOfSchema(version); | ||
let copied = getCopyOfSchema(version); | ||
// Remove the meta schemas because they are already present within Ajv, and it's not possible to add duplicated schemas. | ||
delete copied.definitions['http://json-schema.org/draft-07/schema']; | ||
delete copied.definitions['http://json-schema.org/draft-04/schema']; | ||
serializedSchemas.set(version, copied); | ||
// Spectral caches the schemas using '$id' property | ||
copied['$id'] = copied['$id'].replace('asyncapi.json', `asyncapi-${resolved ? 'resolved' : 'unresolved'}.json`); | ||
const { major } = getSemver(version); | ||
if (resolved && major === 3) { | ||
copied = prepareV3ResolvedSchema(copied); | ||
} | ||
serializedSchemas.set(serializedSchemaKey, copied); | ||
return copied; | ||
@@ -70,20 +95,7 @@ } | ||
} | ||
function getSchema(formats) { | ||
switch (true) { | ||
case formats.has(aas2_6): | ||
return getSerializedSchema('2.6.0'); | ||
case formats.has(aas2_5): | ||
return getSerializedSchema('2.5.0'); | ||
case formats.has(aas2_4): | ||
return getSerializedSchema('2.4.0'); | ||
case formats.has(aas2_3): | ||
return getSerializedSchema('2.3.0'); | ||
case formats.has(aas2_2): | ||
return getSerializedSchema('2.2.0'); | ||
case formats.has(aas2_1): | ||
return getSerializedSchema('2.1.0'); | ||
case formats.has(aas2_0): | ||
return getSerializedSchema('2.0.0'); | ||
default: | ||
return; | ||
export function getSchema(docFormats, resolved) { | ||
for (const [version, format] of AsyncAPIFormats) { | ||
if (docFormats.has(format)) { | ||
return getSerializedSchema(version, resolved); | ||
} | ||
} | ||
@@ -108,11 +120,12 @@ } | ||
} | ||
const schema = getSchema(formats); | ||
const resolved = options.resolved; | ||
const schema = getSchema(formats, resolved); | ||
if (!schema) { | ||
return; | ||
} | ||
const errors = schemaFn(targetVal, { allErrors: true, schema, prepareResults: options.resolved ? prepareResults : undefined }, context); | ||
const errors = schemaFn(targetVal, { allErrors: true, schema, prepareResults: resolved ? prepareResults : undefined }, context); | ||
if (!Array.isArray(errors)) { | ||
return; | ||
} | ||
return filterRefErrors(errors, options.resolved); | ||
return filterRefErrors(errors, resolved); | ||
}); |
import { unreferencedReusableObject } from '@stoplight/spectral-functions'; | ||
import { createRulesetFunction } from '@stoplight/spectral-core'; | ||
import { aas2 } from '../formats'; | ||
import { isObject } from '../../utils'; | ||
@@ -20,5 +19,5 @@ export const unusedComponent = createRulesetFunction({ | ||
Object.keys(components).forEach(componentType => { | ||
// if component type is `securitySchemes` and we operate on AsyncAPI 2.x.x skip validation | ||
// security schemes in 2.x.x are referenced by keys, not by object ref - for this case we have a separate `asyncapi2-unused-securityScheme` rule | ||
if (componentType === 'securitySchemes' && aas2(targetVal, null)) { | ||
// if component type is `securitySchemes` we skip the validation | ||
// security schemes in >=2.x.x are referenced by keys, not by object ref - for this case we have a separate `asyncapi2-unused-securityScheme` rule | ||
if (componentType === 'securitySchemes') { | ||
return; | ||
@@ -25,0 +24,0 @@ } |
@@ -172,2 +172,3 @@ export declare const coreRuleset: { | ||
description: string; | ||
formats: import("@stoplight/spectral-core").Format<void>[]; | ||
recommended: boolean; | ||
@@ -174,0 +175,0 @@ resolved: boolean; |
@@ -1,3 +0,1 @@ | ||
import { aas2All as aas2AllFormats } from './formats'; | ||
import { lastVersion } from '../constants'; | ||
import { truthy, schema } from '@stoplight/spectral-functions'; | ||
@@ -8,5 +6,7 @@ import { documentStructure } from './functions/documentStructure'; | ||
import { unusedComponent } from './functions/unusedComponent'; | ||
import { AsyncAPIFormats } from './formats'; | ||
import { lastVersion } from '../constants'; | ||
export const coreRuleset = { | ||
description: 'Core AsyncAPI x.x.x ruleset.', | ||
formats: [...aas2AllFormats], | ||
formats: AsyncAPIFormats.formats(), | ||
rules: { | ||
@@ -81,3 +81,3 @@ /** | ||
description: 'Recommended AsyncAPI x.x.x ruleset.', | ||
formats: [...aas2AllFormats], | ||
formats: AsyncAPIFormats.filterByMajorVersions(['2']).formats(), | ||
rules: { | ||
@@ -187,2 +187,3 @@ /** | ||
description: 'Potentially unused component has been detected in AsyncAPI document.', | ||
formats: AsyncAPIFormats.filterByMajorVersions(['2']).formats(), | ||
recommended: true, | ||
@@ -189,0 +190,0 @@ resolved: false, |
@@ -148,3 +148,2 @@ import type { Parser } from '../../parser'; | ||
description: string; | ||
formats: import("@stoplight/spectral-core").Format<void>[]; | ||
rules: { | ||
@@ -151,0 +150,0 @@ 'asyncapi2-schemas': import("@stoplight/spectral-core").RuleDefinition; |
/* eslint-disable sonarjs/no-duplicate-string */ | ||
import { aas2All as aas2AllFormats } from '../formats'; | ||
import { AsyncAPIFormats } from '../formats'; | ||
import { truthy, pattern } from '@stoplight/spectral-functions'; | ||
@@ -18,3 +18,3 @@ import { channelParameters } from './functions/channelParameters'; | ||
description: 'Core AsyncAPI 2.x.x ruleset.', | ||
formats: [...aas2AllFormats], | ||
formats: AsyncAPIFormats.filterByMajorVersions(['2']).formats(), | ||
rules: { | ||
@@ -185,3 +185,2 @@ /** | ||
description: 'Schemas AsyncAPI 2.x.x ruleset.', | ||
formats: [...aas2AllFormats], | ||
rules: { | ||
@@ -238,3 +237,3 @@ 'asyncapi2-schemas': asyncApi2SchemaParserRule(parser), | ||
description: 'Recommended AsyncAPI 2.x.x ruleset.', | ||
formats: [...aas2AllFormats], | ||
formats: AsyncAPIFormats.filterByMajorVersions(['2']).formats(), | ||
rules: { | ||
@@ -325,3 +324,3 @@ /** | ||
recommended: true, | ||
formats: aas2AllFormats.slice(4), | ||
formats: AsyncAPIFormats.filterByMajorVersions(['2']).excludeByVersions(['2.0.0', '2.1.0', '2.2.0', '2.3.0']).formats(), | ||
given: [ | ||
@@ -328,0 +327,0 @@ '$.channels.*.[publish,subscribe][?(@property === "message" && @.oneOf == void 0)]', |
{ | ||
"name": "@asyncapi/parser", | ||
"version": "2.1.0-next-major-spec.3", | ||
"version": "2.1.0-next-major-spec.4", | ||
"description": "JavaScript AsyncAPI parser.", | ||
@@ -5,0 +5,0 @@ "bugs": { |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2607410
26021