UNPKG

ut-tools

Version:

Build and Release management automation package.

240 lines 11.1 kB
"use strict"; var _Ruleset_instances, _Ruleset_context, _Ruleset_getRules; Object.defineProperty(exports, "__esModule", { value: true }); exports.Ruleset = void 0; const tslib_1 = require("tslib"); const path_1 = require("@stoplight/path"); const json_1 = require("@stoplight/json"); const minimatch_1 = require("./utils/minimatch"); const rule_1 = require("./rule"); const index_1 = require("./validation/index"); const rules_1 = require("./mergers/rules"); const __1 = require(".."); const rulesets_1 = require("./mergers/rulesets"); const formats_1 = require("./formats"); const guards_1 = require("./utils/guards"); const STACK_SYMBOL = Symbol('@stoplight/spectral/ruleset/#stack'); const EXPLICIT_SEVERITY = Symbol('@stoplight/spectral/ruleset/#explicit-severity'); const DEFAULT_RULESET_FILE = /^\.?spectral\.(ya?ml|json|m?js)$/; let SEED = 1; class Ruleset { constructor(maybeDefinition, context) { var _a; this.maybeDefinition = maybeDefinition; _Ruleset_instances.add(this); this.id = SEED++; this.formats = new formats_1.Formats(); _Ruleset_context.set(this, void 0); let definition; if ((0, json_1.isPlainObject)(maybeDefinition) && 'extends' in maybeDefinition) { const { extends: _, ...def } = maybeDefinition; (0, index_1.assertValidRuleset)({ extends: [], ...def }, 'js'); definition = maybeDefinition; } else { (0, index_1.assertValidRuleset)(maybeDefinition, 'js'); definition = maybeDefinition; } this.definition = definition; (0, tslib_1.__classPrivateFieldSet)(this, _Ruleset_context, { severity: 'recommended', ...context, }, "f"); let hasComplexAliases = false; this.aliases = definition.aliases === void 0 ? null : Object.fromEntries(Object.entries(definition.aliases).map(alias => { const [name, value] = alias; if ((0, guards_1.isSimpleAliasDefinition)(value)) { return alias; } hasComplexAliases = true; const targets = value.targets.map(target => ({ formats: new formats_1.Formats(target.formats), given: target.given, })); return [name, { ...value, targets }]; })); this.hasComplexAliases = hasComplexAliases; const stack = (_a = context === null || context === void 0 ? void 0 : context[STACK_SYMBOL]) !== null && _a !== void 0 ? _a : new Map(); stack.set(this.definition, this); this.extends = 'extends' in definition ? (Array.isArray(definition.extends) ? definition.extends : [definition.extends]).reduce((extensions, extension) => { let actualExtension; let severity = 'recommended'; const explicitSeverity = Array.isArray(extension); if (explicitSeverity) { [actualExtension, severity] = extension; } else { actualExtension = extension; } const existingInstance = stack.get(actualExtension); if (existingInstance !== void 0) { return extensions; } extensions.push(new Ruleset(actualExtension, { severity, [STACK_SYMBOL]: stack, [EXPLICIT_SEVERITY]: explicitSeverity, })); return extensions; }, []) : null; if (stack.size === 1 && definition.overrides) { this.overrides = definition.overrides; } else { this.overrides = null; } stack.delete(this.definition); if (Array.isArray(this.definition.formats)) { for (const format of this.definition.formats) { this.formats.add(format); } } if (Array.isArray(this.extends)) { for (const { formats } of this.extends) { for (const format of formats) { this.formats.add(format); } } } this.rules = (0, tslib_1.__classPrivateFieldGet)(this, _Ruleset_instances, "m", _Ruleset_getRules).call(this); } get source() { var _a; return (_a = (0, tslib_1.__classPrivateFieldGet)(this, _Ruleset_context, "f").source) !== null && _a !== void 0 ? _a : null; } fromSource(source) { if (this.overrides === null) { return this; } const { source: rulesetSource } = this; if (source === null) { throw new Error('Document must have some source assigned. If you use Spectral programmatically make sure to pass the source to Document'); } if (rulesetSource === null) { throw new Error('Ruleset must have some source assigned. If you use Spectral programmatically make sure to pass the source to Ruleset'); } const relativeSource = (0, path_1.relative)((0, path_1.dirname)(rulesetSource), source); const pointerOverrides = {}; const overrides = this.overrides.flatMap(({ files, ...ruleset }) => { var _a, _b; const filteredFiles = []; for (const pattern of files) { const actualPattern = (_a = (0, json_1.extractSourceFromRef)(pattern)) !== null && _a !== void 0 ? _a : pattern; if (!(0, minimatch_1.minimatch)(relativeSource, actualPattern)) continue; const pointer = (0, json_1.extractPointerFromRef)(pattern); if (actualPattern === pattern) { filteredFiles.push(pattern); } else if (!('rules' in ruleset) || pointer === null) { throw new Error('Unknown error. The ruleset is presumably invalid.'); } else { for (const [ruleName, rule] of Object.entries(ruleset.rules)) { if (typeof rule === 'object' || typeof rule === 'boolean') { throw new Error('Unknown error. The ruleset is presumably invalid.'); } const { definition: rulePointerOverrides } = ((_b = pointerOverrides[ruleName]) !== null && _b !== void 0 ? _b : (pointerOverrides[ruleName] = { rulesetSource, definition: new Map(), })); const severity = (0, __1.getDiagnosticSeverity)(rule); let sourceRulePointerOverrides = rulePointerOverrides.get(actualPattern); if (sourceRulePointerOverrides === void 0) { sourceRulePointerOverrides = new Map(); rulePointerOverrides.set(actualPattern, sourceRulePointerOverrides); } sourceRulePointerOverrides.set(pointer, severity); } } } return filteredFiles.length === 0 ? [] : ruleset; }); const { overrides: _, ...definition } = this.definition; if (overrides.length === 0 && Object.keys(pointerOverrides).length === 0) { return this; } const mergedOverrides = overrides.length === 0 ? null : overrides.length > 1 ? overrides .slice(1) .reduce((left, right) => (0, rulesets_1.mergeRulesets)(left, right, true), overrides[0]) : overrides[0]; const ruleset = new Ruleset(mergedOverrides === null ? definition : (0, rulesets_1.mergeRulesets)(definition, mergedOverrides, false), { severity: 'recommended', source: rulesetSource, }); for (const [ruleName, rulePointerOverrides] of Object.entries(pointerOverrides)) { if (ruleName in ruleset.rules) { ruleset.rules[ruleName].overrides = rulePointerOverrides; } } return ruleset; } get parserOptions() { return { ...__1.DEFAULT_PARSER_OPTIONS, ...this.definition.parserOptions }; } static isDefaultRulesetFile(uri) { return DEFAULT_RULESET_FILE.test(uri); } toJSON() { return { id: this.id, extends: this.extends, source: this.source, aliases: this.aliases, formats: this.formats.size === 0 ? null : this.formats, rules: this.rules, overrides: this.overrides, parserOptions: this.parserOptions, }; } } exports.Ruleset = Ruleset; _Ruleset_context = new WeakMap(), _Ruleset_instances = new WeakSet(), _Ruleset_getRules = function _Ruleset_getRules() { const rules = {}; if (this.extends !== null && this.extends.length > 0) { for (const extendedRuleset of this.extends) { if (extendedRuleset === this) continue; for (const rule of Object.values(extendedRuleset.rules)) { rules[rule.name] = rule; if ((0, tslib_1.__classPrivateFieldGet)(this, _Ruleset_context, "f")[STACK_SYMBOL] !== void 0 && (0, tslib_1.__classPrivateFieldGet)(this, _Ruleset_context, "f")[EXPLICIT_SEVERITY] === true) { rule.enabled = rule_1.Rule.isEnabled(rule, (0, tslib_1.__classPrivateFieldGet)(this, _Ruleset_context, "f").severity); } } } } if ('rules' in this.definition) { for (const [name, definition] of Object.entries(this.definition.rules)) { const rule = (0, rules_1.mergeRule)(rules[name], name, definition, this); rules[name] = rule; if (rule.owner === this) { rule.enabled = rule_1.Rule.isEnabled(rule, (0, tslib_1.__classPrivateFieldGet)(this, _Ruleset_context, "f").severity); } if (rule.formats !== null) { for (const format of rule.formats) { this.formats.add(format); } } else if (rule.owner !== this) { rule.formats = rule.owner.definition.formats === void 0 ? null : new formats_1.Formats(rule.owner.definition.formats); } else if (this.definition.formats !== void 0) { rule.formats = new formats_1.Formats(this.definition.formats); } if (this.definition.documentationUrl !== void 0 && rule.documentationUrl === null) { rule.documentationUrl = `${this.definition.documentationUrl}#${name}`; } } } return rules; }; //# sourceMappingURL=ruleset.js.map