@stoplight/spectral
Advanced tools
Comparing version 5.8.1 to 5.9.0
@@ -10,2 +10,23 @@ <!-- markdown-link-check-disable --> | ||
## [5.9.0] - 2021-03-08 | ||
### Added | ||
- Add `duplicated-entry-in-enum` rule to detect duplicated entry in enum [#1478](https://github.com/stoplightio/spectral/issues/1478) | ||
- Improve `additionalProperties` JSON Schema validation [#1433](https://github.com/stoplightio/spectral/pull/1433) | ||
### Changed | ||
- $refs in rulesets linking to json-schema.org are kept unresolved [#1519](https://github.com/stoplightio/spectral/pull/1519) | ||
### Fixed | ||
- Empty $refs should not be ignored [#1540](https://github.com/stoplightio/spectral/pull/1540) | ||
- Proper source detection of an error caused by an empty $ref [#1515](https://github.com/stoplightio/spectral/issues/1515) | ||
- Improve file $ref resolving on Windows [#1514](https://github.com/stoplightio/spectral/pull/1514) | ||
- Proxy settings not applied to all outgoing requests [#1324](https://github.com/stoplightio/spectral/issues/1324) | ||
- Pascal/Camel `casing` do not support single uppercase letters at the end [#1500](https://github.com/stoplightio/spectral/issues/1500) | ||
- Nested extends broken in rulesets Error disabling an extended ruleset in an extended ruleset [#1352](https://github.com/stoplightio/spectral/issues/1352), [#1380](https://github.com/stoplightio/spectral/issues/1380) | ||
- Missing validation of child parameter child properties [#1400](https://github.com/stoplightio/spectral/issues/1400) | ||
## [5.8.1] - 2021-02-11 | ||
@@ -12,0 +33,0 @@ |
@@ -11,7 +11,11 @@ "use strict"; | ||
const getResolver_1 = require("./utils/getResolver"); | ||
const request_1 = require("../../../request"); | ||
async function lint(documents, flags) { | ||
const spectral = new spectral_1.Spectral({ | ||
resolver: getResolver_1.getResolver(flags.resolver), | ||
proxyUri: process.env.PROXY, | ||
}); | ||
const ruleset = await utils_1.getRuleset(flags.ruleset); | ||
const ruleset = await utils_1.getRuleset(flags.ruleset, { | ||
agent: request_1.DEFAULT_REQUEST_OPTIONS.agent, | ||
}); | ||
spectral.setRuleset(ruleset); | ||
@@ -18,0 +22,0 @@ for (const [format, lookup, prettyName] of formats_1.KNOWN_FORMATS) { |
import { Optional } from '@stoplight/types'; | ||
import { IRulesetReadOptions } from '../../../../rulesets'; | ||
import { IRuleset } from '../../../../types/ruleset'; | ||
export declare function getRuleset(rulesetFile: Optional<string[]>): Promise<IRuleset>; | ||
export declare function getRuleset(rulesetFile: Optional<string[]>, opts: IRulesetReadOptions): Promise<IRuleset>; |
@@ -8,3 +8,3 @@ "use strict"; | ||
const formats_1 = require("../../../../formats"); | ||
async function loadRulesets(cwd, rulesetFiles) { | ||
async function loadRulesets(cwd, rulesetFiles, opts) { | ||
if (rulesetFiles.length === 0) { | ||
@@ -17,11 +17,11 @@ return { | ||
} | ||
return rulesets_1.readRuleset(rulesetFiles.map(file => (path_1.isAbsolute(file) ? file : path_1.resolve(cwd, file)))); | ||
return rulesets_1.readRuleset(rulesetFiles.map(file => (path_1.isAbsolute(file) ? file : path_1.resolve(cwd, file))), opts); | ||
} | ||
async function getRuleset(rulesetFile) { | ||
async function getRuleset(rulesetFile, opts) { | ||
const rulesetFiles = rulesetFile !== null && rulesetFile !== void 0 ? rulesetFile : (await loader_1.getDefaultRulesetFile(process.cwd())); | ||
return await (rulesetFiles !== null | ||
? loadRulesets(process.cwd(), Array.isArray(rulesetFiles) ? rulesetFiles : [rulesetFiles]) | ||
: rulesets_1.readRuleset(formats_1.KNOWN_RULESETS)); | ||
? loadRulesets(process.cwd(), Array.isArray(rulesetFiles) ? rulesetFiles : [rulesetFiles], opts) | ||
: rulesets_1.readRuleset(formats_1.KNOWN_RULESETS, opts)); | ||
} | ||
exports.getRuleset = getRuleset; | ||
//# sourceMappingURL=getRuleset.js.map |
import { IParserOptions } from './types/ruleset'; | ||
export declare const NPM_PKG_ROOT = "https://unpkg.com/"; | ||
export declare const SPECTRAL_PKG_NAME = "@stoplight/spectral"; | ||
export declare const SPECTRAL_PKG_VERSION = "5.8.1"; | ||
export declare const SPECTRAL_PKG_VERSION = "5.9.0"; | ||
export declare const DEFAULT_PARSER_OPTIONS: Readonly<Required<IParserOptions>>; |
@@ -7,3 +7,3 @@ "use strict"; | ||
exports.SPECTRAL_PKG_NAME = '@stoplight/spectral'; | ||
exports.SPECTRAL_PKG_VERSION = '5.8.1'; | ||
exports.SPECTRAL_PKG_VERSION = '5.9.0'; | ||
exports.DEFAULT_PARSER_OPTIONS = Object.freeze({ | ||
@@ -10,0 +10,0 @@ incompatibleValues: types_1.DiagnosticSeverity.Error, |
@@ -91,3 +91,3 @@ "use strict"; | ||
const scopedPath = [...utils_1.safePointerToPath($ref), ...newPath]; | ||
let resolvedDoc; | ||
let resolvedDoc = this.document; | ||
if (json_1.isLocalRef($ref)) { | ||
@@ -98,2 +98,9 @@ resolvedDoc = source === this.document.source ? this.document : this.referencedDocuments[source]; | ||
const extractedSource = json_1.extractSourceFromRef($ref); | ||
if (extractedSource === null) { | ||
return { | ||
document: resolvedDoc, | ||
path: utils_1.getClosestJsonPath(resolvedDoc.data, path), | ||
missingPropertyPath: path, | ||
}; | ||
} | ||
source = utils_1.isAbsoluteRef(extractedSource) ? extractedSource : path_1.resolve(source, '..', extractedSource); | ||
@@ -100,0 +107,0 @@ resolvedDoc = source === this.document.source ? this.document : this.referencedDocuments[source]; |
@@ -17,4 +17,4 @@ "use strict"; | ||
[CasingType.flat]: '[a-z][a-z{__DIGITS__}]*', | ||
[CasingType.camel]: '[a-z][a-z{__DIGITS__}]*(?:[A-Z{__DIGITS__}][a-z{__DIGITS__}]+)*', | ||
[CasingType.pascal]: '[A-Z][a-z{__DIGITS__}]*(?:[A-Z{__DIGITS__}][a-z{__DIGITS__}]+)*', | ||
[CasingType.camel]: '[a-z][a-z{__DIGITS__}]*(?:[A-Z{__DIGITS__}](?:[a-z{__DIGITS__}]+|$))*', | ||
[CasingType.pascal]: '[A-Z][a-z{__DIGITS__}]*(?:[A-Z{__DIGITS__}](?:[a-z{__DIGITS__}]+|$))*', | ||
[CasingType.kebab]: '[a-z][a-z{__DIGITS__}]*(?:-[a-z{__DIGITS__}]+)*', | ||
@@ -21,0 +21,0 @@ [CasingType.cobol]: '[A-Z][A-Z{__DIGITS__}]*(?:-[A-Z{__DIGITS__}]+)*', |
@@ -24,3 +24,4 @@ "use strict"; | ||
function getAjv(oasVersion, allErrors) { | ||
const type = oasVersion !== void 0 && oasVersion >= 2 ? 'oas' + oasVersion : 'jsonschema'; | ||
const qual = allErrors === true ? '-all' : ''; | ||
const type = (oasVersion !== void 0 && oasVersion >= 2 ? 'oas' + oasVersion : 'jsonschema') + qual; | ||
if (typeof ajvInstances[type] !== 'undefined') { | ||
@@ -27,0 +28,0 @@ return ajvInstances[type]; |
import { Optional } from '@stoplight/types'; | ||
import { JSONPathExpression } from 'nimma'; | ||
import { IDocument } from './document'; | ||
import { IGivenNode, IRule, IThen, SpectralDiagnosticSeverity } from './types'; | ||
import { IGivenNode, IProcessedRule, IThen } from './types'; | ||
import { DiagnosticSeverity } from '@stoplight/types'; | ||
export declare class Rule { | ||
@@ -9,3 +10,3 @@ readonly name: string; | ||
readonly message: string | null; | ||
readonly severity: SpectralDiagnosticSeverity; | ||
readonly severity: DiagnosticSeverity; | ||
readonly resolved: boolean; | ||
@@ -15,4 +16,4 @@ readonly formats: Optional<string[]>; | ||
readonly given: string[]; | ||
get enabled(): boolean; | ||
constructor(name: string, rule: IRule); | ||
readonly enabled: boolean; | ||
constructor(name: string, rule: IProcessedRule); | ||
matchesFormat(formats: IDocument['formats']): boolean; | ||
@@ -22,4 +23,4 @@ } | ||
readonly expressions: JSONPathExpression[]; | ||
constructor(name: string, rule: IRule); | ||
constructor(name: string, rule: IProcessedRule); | ||
hookup(cb: (rule: OptimizedRule, node: IGivenNode) => void): void; | ||
} |
@@ -9,6 +9,7 @@ "use strict"; | ||
constructor(name, rule) { | ||
var _a, _b; | ||
var _a, _b, _c; | ||
this.name = name; | ||
this.description = (_a = rule.description) !== null && _a !== void 0 ? _a : null; | ||
this.message = (_b = rule.message) !== null && _b !== void 0 ? _b : null; | ||
this.enabled = (_a = rule.enabled) !== null && _a !== void 0 ? _a : true; | ||
this.description = (_b = rule.description) !== null && _b !== void 0 ? _b : null; | ||
this.message = (_c = rule.message) !== null && _c !== void 0 ? _c : null; | ||
this.severity = rule.severity === void 0 ? severity_1.DEFAULT_SEVERITY_LEVEL : severity_1.getDiagnosticSeverity(rule.severity); | ||
@@ -20,5 +21,2 @@ this.resolved = rule.resolved !== false; | ||
} | ||
get enabled() { | ||
return this.severity !== -1; | ||
} | ||
matchesFormat(formats) { | ||
@@ -25,0 +23,0 @@ if (this.formats === void 0) { |
export * from './mergers'; | ||
export { readRuleset } from './reader'; | ||
export { readRuleset, IRulesetReadOptions } from './reader'; | ||
export { assertValidRuleset } from './validation'; |
import { FileRuleCollection, FileRulesetSeverity } from '../../types/ruleset'; | ||
export declare function mergeRules(target: FileRuleCollection, source: FileRuleCollection, rulesetSeverity?: FileRulesetSeverity): FileRuleCollection; | ||
import { Dictionary } from '@stoplight/types'; | ||
import { IProcessedRule } from '../../types'; | ||
export declare function mergeRules(target: Dictionary<IProcessedRule>, source: FileRuleCollection, rulesetSeverity?: FileRulesetSeverity): Dictionary<IProcessedRule>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.mergeRules = void 0; | ||
const types_1 = require("@stoplight/types"); | ||
const lodash_1 = require("lodash"); | ||
const severity_1 = require("../severity"); | ||
@@ -10,12 +8,17 @@ const validation_1 = require("../validation"); | ||
for (const [name, rule] of Object.entries(source)) { | ||
if (rulesetSeverity !== undefined) { | ||
const severity = severity_1.getSeverityLevel(source, name, rulesetSeverity); | ||
if (validation_1.isValidRule(rule)) { | ||
markRule(rule); | ||
rule.severity = severity; | ||
processRule(target, name, rule); | ||
if (rulesetSeverity !== void 0) { | ||
if (validation_1.isValidRule(rule) && !('enabled' in rule)) { | ||
let enabled; | ||
if (rulesetSeverity === 'all') { | ||
enabled = true; | ||
} | ||
else if (rulesetSeverity === 'off') { | ||
enabled = false; | ||
} | ||
else { | ||
enabled = rule.recommended !== false; | ||
} | ||
rule.enabled = enabled; | ||
} | ||
else { | ||
processRule(target, name, typeof rule === 'boolean' ? rule : severity); | ||
} | ||
processRule(target, name, rule); | ||
} | ||
@@ -29,28 +32,2 @@ else { | ||
exports.mergeRules = mergeRules; | ||
const ROOT_DESCRIPTOR = Symbol('root-descriptor'); | ||
function markRule(rule) { | ||
if (!(ROOT_DESCRIPTOR in rule)) { | ||
Object.defineProperty(rule, ROOT_DESCRIPTOR, { | ||
configurable: false, | ||
enumerable: false, | ||
writable: false, | ||
value: copyRule(rule), | ||
}); | ||
} | ||
} | ||
function updateRootRule(root, newRule) { | ||
markRule(root); | ||
Object.assign(root[ROOT_DESCRIPTOR], copyRule(newRule === null ? root : Object.assign(root, newRule))); | ||
} | ||
function getRootRule(rule) { | ||
return rule[ROOT_DESCRIPTOR] !== undefined ? rule[ROOT_DESCRIPTOR] : null; | ||
} | ||
function copyRuleThen(then) { | ||
return Object.assign(Object.assign({}, then), ('functionOptions' in then && lodash_1.isObject(then.functionOptions) ? Object.assign({}, then.functionOptions) : null)); | ||
} | ||
function copyRule(rule) { | ||
return Object.assign(Object.assign({}, rule), ('then' in rule | ||
? { then: Array.isArray(rule.then) ? rule.then.map(copyRuleThen) : copyRuleThen(rule.then) } | ||
: null)); | ||
} | ||
function processRule(rules, name, rule) { | ||
@@ -61,17 +38,3 @@ const existingRule = rules[name]; | ||
if (validation_1.isValidRule(existingRule)) { | ||
const rootRule = getRootRule(existingRule); | ||
if (!rule) { | ||
existingRule.severity = -1; | ||
} | ||
else if (rootRule === null) { | ||
existingRule.severity = severity_1.getSeverityLevel(rules, name, rule); | ||
updateRootRule(existingRule, existingRule); | ||
} | ||
else if ('severity' in rootRule) { | ||
existingRule.severity = rootRule.severity; | ||
updateRootRule(existingRule, existingRule); | ||
} | ||
else { | ||
existingRule.severity = types_1.DiagnosticSeverity.Warning; | ||
} | ||
existingRule.enabled = rule; | ||
} | ||
@@ -82,3 +45,9 @@ break; | ||
if (validation_1.isValidRule(existingRule)) { | ||
existingRule.severity = severity_1.getSeverityLevel(rules, name, rule); | ||
if (rule === 'off') { | ||
existingRule.enabled = false; | ||
} | ||
else { | ||
existingRule.severity = severity_1.getDiagnosticSeverity(rule); | ||
existingRule.enabled = true; | ||
} | ||
} | ||
@@ -89,17 +58,13 @@ break; | ||
processRule(rules, name, rule[0]); | ||
if (validation_1.isValidRule(existingRule) && rule.length === 2 && rule[1] !== undefined) { | ||
if (validation_1.isValidRule(existingRule) && rule.length === 2 && rule[1] !== void 0) { | ||
if ('functionOptions' in existingRule.then) { | ||
existingRule.then.functionOptions = rule[1]; | ||
} | ||
updateRootRule(existingRule, null); | ||
} | ||
} | ||
else if (validation_1.isValidRule(existingRule)) { | ||
normalizeRule(rule, existingRule.severity); | ||
updateRootRule(existingRule, rule); | ||
Object.assign(existingRule, normalizeRule(rule)); | ||
} | ||
else { | ||
normalizeRule(rule, severity_1.getSeverityLevel(rules, name, rule)); | ||
markRule(rule); | ||
rules[name] = rule; | ||
rules[name] = normalizeRule(rule); | ||
} | ||
@@ -111,13 +76,8 @@ break; | ||
} | ||
function normalizeRule(rule, severity) { | ||
if (rule.recommended === void 0) { | ||
rule.recommended = true; | ||
} | ||
if (rule.severity === void 0) { | ||
rule.severity = severity === void 0 ? (rule.recommended !== false ? severity_1.DEFAULT_SEVERITY_LEVEL : -1) : severity; | ||
} | ||
else { | ||
rule.severity = severity_1.getDiagnosticSeverity(rule.severity); | ||
} | ||
function normalizeRule(rule) { | ||
return Object.assign(Object.defineProperties({}, Object.getOwnPropertyDescriptors(rule)), { | ||
recommended: rule.recommended !== false, | ||
severity: rule.severity === void 0 ? severity_1.DEFAULT_SEVERITY_LEVEL : severity_1.getDiagnosticSeverity(rule.severity), | ||
}); | ||
} | ||
//# sourceMappingURL=rules.js.map |
@@ -1,1 +0,1 @@ | ||
"use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t,r,s=e((function(e,t){function r(e){return"oneOf"===e.keyword||"required"===e.keyword&&"$ref"===e.params.missingProperty}Object.defineProperty(t,"__esModule",{value:!0}),t.oasDocumentSchema=t.prepareResults=void 0;const s=[{path:/^components\/securitySchemes\/[^/]+$/,message:"Invalid security scheme"},{path:/^securityDefinitions\/[^/]+$/,message:"Invalid security definition"}];function n(e){for(let t=0;t<e.length;t++){const s=e[t];t+1<e.length&&e[t+1].dataPath===s.dataPath?(e.splice(t+1,1),t--):t>0&&r(s)&&e[t-1].dataPath.startsWith(s.dataPath)&&(e.splice(t,1),t--)}}t.prepareResults=n,t.oasDocumentSchema=function(e,t,...r){const o=this.functions.schema.call(this,e,Object.assign(Object.assign({},t),{prepareResults:n}),...r);return Array.isArray(o)&&function(e){for(const t of e){if(void 0===t.path)continue;const e=t.path.join("/");for(const r of s)if(r.path.test(e)){t.message=r.message;break}}}(o),o},t.default=t.oasDocumentSchema}(r={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&r.path)}},r.exports),r.exports));exports.default=s; | ||
"use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t,r,a=e((function(e,t){function r(e){return"oneOf"===e.keyword||"required"===e.keyword&&"$ref"===e.params.missingProperty}Object.defineProperty(t,"__esModule",{value:!0}),t.oasDocumentSchema=t.prepareResults=void 0;const a=[{path:/^components\/securitySchemes\/[^/]+$/,message:"Invalid security scheme"},{path:/^securityDefinitions\/[^/]+$/,message:"Invalid security definition"}];function o(e){for(const t of e)"additionalProperties"===t.keyword&&(t.dataPath=`${t.dataPath}/${t.params.additionalProperty}`);for(let t=0;t<e.length;t++){const a=e[t];t+1<e.length&&e[t+1].dataPath===a.dataPath?(e.splice(t+1,1),t--):t>0&&r(a)&&e[t-1].dataPath.startsWith(a.dataPath)&&(e.splice(t,1),t--)}}t.prepareResults=o,t.oasDocumentSchema=function(e,t,...r){const s=this.functions.schema.call(this,e,Object.assign(Object.assign({},t),{prepareResults:o}),...r);return Array.isArray(s)&&function(e){for(const t of e){if(void 0===t.path)continue;const e=t.path.join("/");for(const r of a)if(r.path.test(e)){t.message=r.message;break}}}(s),s},t.default=t.oasDocumentSchema}(r={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&r.path)}},r.exports),r.exports));exports.default=a; |
@@ -98,2 +98,19 @@ { | ||
}, | ||
"duplicated-entry-in-enum": { | ||
"description": "Enum values should not have duplicate entry.", | ||
"type": "validation", | ||
"severity": 1, | ||
"recommended": true, | ||
"message": "A duplicated entry in the enum was found. Error: {{error}}", | ||
"given": "$..enum", | ||
"then": { | ||
"function": "schema", | ||
"functionOptions": { | ||
"schema": { | ||
"type": "array", | ||
"uniqueItems": true | ||
} | ||
} | ||
} | ||
}, | ||
"info-contact": { | ||
@@ -100,0 +117,0 @@ "description": "Info object should contain `contact` object.", |
@@ -43,3 +43,3 @@ "use strict"; | ||
const createRulesetProcessor = (processedRulesets, uriCache, readOpts) => { | ||
return async function processRuleset(baseUri, uri, severity) { | ||
return async function processRuleset(baseUri, uri, severity = 'recommended') { | ||
const rulesetUri = await finder_1.findFile(path_1.join(baseUri, '..'), uri); | ||
@@ -62,4 +62,12 @@ if (processedRulesets.has(rulesetUri)) { | ||
uriCache, | ||
transformRef(opts) { | ||
var _a; | ||
const host = (_a = opts.ref) === null || _a === void 0 ? void 0 : _a.host(); | ||
if (host === 'json-schema.org') { | ||
return; | ||
} | ||
return opts.ref; | ||
}, | ||
async parseResolveResult(opts) { | ||
opts.result = parseContent(opts.result, opts.targetAuthority.pathname()); | ||
opts.result = parseContent(opts.result, opts.targetAuthority.href()); | ||
return opts; | ||
@@ -80,9 +88,8 @@ }, | ||
let extendedRuleset; | ||
let parentSeverity; | ||
let parentSeverity = severity; | ||
if (Array.isArray(extended)) { | ||
parentSeverity = severity === void 0 ? extended[1] : severity; | ||
extendedRuleset = await processRuleset(rulesetUri, extended[0], parentSeverity); | ||
parentSeverity = extended[1]; | ||
extendedRuleset = await processRuleset(rulesetUri, extended[0], extended[1]); | ||
} | ||
else { | ||
parentSeverity = severity === void 0 ? 'recommended' : severity; | ||
extendedRuleset = await processRuleset(rulesetUri, extended, parentSeverity); | ||
@@ -98,7 +105,7 @@ } | ||
if (ruleset.rules !== void 0) { | ||
mergers_1.mergeRules(rules, ruleset.rules, severity === void 0 ? 'recommended' : severity); | ||
mergers_1.mergeRules(rules, ruleset.rules, severity); | ||
if (ruleset.documentationUrl !== void 0) { | ||
for (const [name, rule] of Object.entries(ruleset.rules)) { | ||
if (validation_1.isValidRule(rule) && rule.documentationUrl === void 0) { | ||
rule.documentationUrl = `${ruleset.documentationUrl}#${name}`; | ||
newRuleset.rules[name].documentationUrl = `${ruleset.documentationUrl}#${name}`; | ||
} | ||
@@ -105,0 +112,0 @@ } |
import { DiagnosticSeverity } from '@stoplight/types'; | ||
import { HumanReadableDiagnosticSeverity, SpectralDiagnosticSeverity } from '../types'; | ||
import { FileRule, FileRuleCollection, FileRulesetSeverity } from '../types/ruleset'; | ||
export declare const DEFAULT_SEVERITY_LEVEL = DiagnosticSeverity.Warning; | ||
export declare function getSeverityLevel(rules: FileRuleCollection, name: string, newRule: FileRule | FileRulesetSeverity): SpectralDiagnosticSeverity; | ||
export declare function getDiagnosticSeverity(severity: DiagnosticSeverity | HumanReadableDiagnosticSeverity): SpectralDiagnosticSeverity; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getDiagnosticSeverity = exports.getSeverityLevel = exports.DEFAULT_SEVERITY_LEVEL = void 0; | ||
exports.getDiagnosticSeverity = exports.DEFAULT_SEVERITY_LEVEL = void 0; | ||
const types_1 = require("@stoplight/types"); | ||
const validation_1 = require("./validation"); | ||
exports.DEFAULT_SEVERITY_LEVEL = types_1.DiagnosticSeverity.Warning; | ||
function getSeverityForRule(rule, defaultSeverity) { | ||
switch (typeof rule) { | ||
case 'number': | ||
case 'string': | ||
return getDiagnosticSeverity(rule); | ||
case 'boolean': | ||
return rule ? getDiagnosticSeverity(defaultSeverity) : -1; | ||
default: | ||
return defaultSeverity; | ||
} | ||
} | ||
function getSeverityForInvalidRule(existingRule, newRule) { | ||
if (newRule === 'off') | ||
return -1; | ||
if (newRule === 'recommended' || newRule === 'all') { | ||
if (existingRule === false || existingRule === -1 || existingRule === 'off') { | ||
return -1; | ||
} | ||
return getSeverityForRule(existingRule, exports.DEFAULT_SEVERITY_LEVEL); | ||
} | ||
return getSeverityForRule(newRule, exports.DEFAULT_SEVERITY_LEVEL); | ||
} | ||
function getSeverityLevel(rules, name, newRule) { | ||
const existingRule = rules[name]; | ||
if (!validation_1.isValidRule(existingRule)) { | ||
return getSeverityForInvalidRule(existingRule, newRule); | ||
} | ||
const existingSeverity = existingRule.severity !== undefined ? getDiagnosticSeverity(existingRule.severity) : exports.DEFAULT_SEVERITY_LEVEL; | ||
if (newRule === 'recommended') { | ||
return existingRule.recommended !== false ? existingSeverity : -1; | ||
} | ||
if (newRule === 'all') { | ||
return existingSeverity; | ||
} | ||
return getSeverityForRule(newRule, existingSeverity); | ||
} | ||
exports.getSeverityLevel = getSeverityLevel; | ||
const SEVERITY_MAP = { | ||
@@ -45,0 +7,0 @@ error: types_1.DiagnosticSeverity.Error, |
@@ -15,2 +15,5 @@ import { DiagnosticSeverity } from '@stoplight/types'; | ||
} | ||
export interface IProcessedRule extends IRule { | ||
enabled?: boolean; | ||
} | ||
export interface IThen<T = string, O = unknown> { | ||
@@ -17,0 +20,0 @@ field?: string; |
import { IResolveOpts, IResolveResult } from '@stoplight/json-ref-resolver/types'; | ||
import { DiagnosticSeverity, Dictionary, IDiagnostic, JsonPath } from '@stoplight/types'; | ||
import { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema'; | ||
import { IFunction, IRule } from '.'; | ||
import { IFunction, IProcessedRule, IRule } from '.'; | ||
import { Rule } from '../rule'; | ||
import { ComputeFingerprintFunc } from '../utils'; | ||
export declare type FunctionCollection = Dictionary<IFunction<any>, string>; | ||
export declare type RuleCollection = Dictionary<IRule, string>; | ||
export declare type RuleCollection = Dictionary<IProcessedRule, string>; | ||
export declare type PartialRuleCollection = Dictionary<Partial<IRule>, string>; | ||
@@ -10,0 +10,0 @@ export declare type RunRuleCollection = Dictionary<Rule, string>; |
{ | ||
"name": "@stoplight/spectral", | ||
"version": "5.8.1", | ||
"version": "5.9.0", | ||
"description": "A flexible object linter with out of the box support for OpenAPI v2 and v3.", | ||
@@ -65,5 +65,5 @@ "keywords": [ | ||
"dependencies": { | ||
"@stoplight/better-ajv-errors": "0.0.3", | ||
"@stoplight/better-ajv-errors": "0.0.4", | ||
"@stoplight/json": "3.10.2", | ||
"@stoplight/json-ref-readers": "1.2.1", | ||
"@stoplight/json-ref-readers": "1.2.2", | ||
"@stoplight/json-ref-resolver": "3.1.1", | ||
@@ -70,0 +70,0 @@ "@stoplight/lifecycle": "2.3.2", |
@@ -1,1 +0,1 @@ | ||
"use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t,r,s=e((function(e,t){function r(e){return"oneOf"===e.keyword||"required"===e.keyword&&"$ref"===e.params.missingProperty}Object.defineProperty(t,"__esModule",{value:!0}),t.oasDocumentSchema=t.prepareResults=void 0;const s=[{path:/^components\/securitySchemes\/[^/]+$/,message:"Invalid security scheme"},{path:/^securityDefinitions\/[^/]+$/,message:"Invalid security definition"}];function n(e){for(let t=0;t<e.length;t++){const s=e[t];t+1<e.length&&e[t+1].dataPath===s.dataPath?(e.splice(t+1,1),t--):t>0&&r(s)&&e[t-1].dataPath.startsWith(s.dataPath)&&(e.splice(t,1),t--)}}t.prepareResults=n,t.oasDocumentSchema=function(e,t,...r){const o=this.functions.schema.call(this,e,Object.assign(Object.assign({},t),{prepareResults:n}),...r);return Array.isArray(o)&&function(e){for(const t of e){if(void 0===t.path)continue;const e=t.path.join("/");for(const r of s)if(r.path.test(e)){t.message=r.message;break}}}(o),o},t.default=t.oasDocumentSchema}(r={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&r.path)}},r.exports),r.exports));exports.default=s; | ||
"use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t,r,a=e((function(e,t){function r(e){return"oneOf"===e.keyword||"required"===e.keyword&&"$ref"===e.params.missingProperty}Object.defineProperty(t,"__esModule",{value:!0}),t.oasDocumentSchema=t.prepareResults=void 0;const a=[{path:/^components\/securitySchemes\/[^/]+$/,message:"Invalid security scheme"},{path:/^securityDefinitions\/[^/]+$/,message:"Invalid security definition"}];function o(e){for(const t of e)"additionalProperties"===t.keyword&&(t.dataPath=`${t.dataPath}/${t.params.additionalProperty}`);for(let t=0;t<e.length;t++){const a=e[t];t+1<e.length&&e[t+1].dataPath===a.dataPath?(e.splice(t+1,1),t--):t>0&&r(a)&&e[t-1].dataPath.startsWith(a.dataPath)&&(e.splice(t,1),t--)}}t.prepareResults=o,t.oasDocumentSchema=function(e,t,...r){const s=this.functions.schema.call(this,e,Object.assign(Object.assign({},t),{prepareResults:o}),...r);return Array.isArray(s)&&function(e){for(const t of e){if(void 0===t.path)continue;const e=t.path.join("/");for(const r of a)if(r.path.test(e)){t.message=r.message;break}}}(s),s},t.default=t.oasDocumentSchema}(r={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&r.path)}},r.exports),r.exports));exports.default=a; |
@@ -98,2 +98,19 @@ { | ||
}, | ||
"duplicated-entry-in-enum": { | ||
"description": "Enum values should not have duplicate entry.", | ||
"type": "validation", | ||
"severity": 1, | ||
"recommended": true, | ||
"message": "A duplicated entry in the enum was found. Error: {{error}}", | ||
"given": "$..enum", | ||
"then": { | ||
"function": "schema", | ||
"functionOptions": { | ||
"schema": { | ||
"type": "array", | ||
"uniqueItems": true | ||
} | ||
} | ||
} | ||
}, | ||
"info-contact": { | ||
@@ -100,0 +117,0 @@ "description": "Info object should contain `contact` object.", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
2
1035247
17341
14
+ Added@stoplight/better-ajv-errors@0.0.4(transitive)
+ Added@stoplight/json-ref-readers@1.2.2(transitive)
+ Addedtslib@1.14.1(transitive)
- Removed@stoplight/better-ajv-errors@0.0.3(transitive)
- Removed@stoplight/json-ref-readers@1.2.1(transitive)