diff --git a/projects/standard-rulesets/src/spectral/index.ts b/projects/standard-rulesets/src/spectral/index.ts index 37895f9660..f069a4e1d9 100644 --- a/projects/standard-rulesets/src/spectral/index.ts +++ b/projects/standard-rulesets/src/spectral/index.ts @@ -32,19 +32,47 @@ const configSchema = { description: 'URI of spectral ruleset file (file or URL)', }, }, + changed: { + type: 'array', + items: { + type: 'string', + description: 'URI of spectral ruleset file (file or URL)', + }, + }, + addedOrChanged: { + type: 'array', + items: { + type: 'string', + description: 'URI of spectral ruleset file (file or URL)', + }, + }, }, }; const validateConfigSchema = ajv.compile(configSchema); export class SpectralRulesets extends ExternalRuleBase { - constructor( - private options: { - always: string[]; - added: string[]; - matches?: (context: RuleContext) => boolean; - } - ) { + private options: { + always: string[]; + added: string[]; + changed: string[]; + addedOrChanged: string[]; + matches?: (context: RuleContext) => boolean; + }; + constructor(options: { + always?: string[]; + added?: string[]; + changed?: string[]; + addedOrChanged?: string[]; + matches?: (context: RuleContext) => boolean; + }) { super(); + this.options = { + always: options.always ?? [], + added: options.added ?? [], + changed: options.changed ?? [], + addedOrChanged: options.addedOrChanged ?? [], + matches: options.matches, + }; } async runRules(inputs: { @@ -78,6 +106,39 @@ export class SpectralRulesets extends ExternalRuleBase { matches: this.options.matches, }); }); + const changed = this.options.changed.map((ruleInput) => { + return new SpectralRule({ + name: + 'Spectral Rules applied to changes to the specification: ' + + ruleInput, + flatSpecFile: absolutePathTmpSpec, + applies: 'changed', + rulesetPointer: ruleInput, + matches: this.options.matches, + }); + }); + const addedOrChanged = this.options.addedOrChanged.flatMap((ruleInput) => { + return [ + new SpectralRule({ + name: + 'Spectral Rules applied to additions to the specification: ' + + ruleInput, + flatSpecFile: absolutePathTmpSpec, + applies: 'added', + rulesetPointer: ruleInput, + matches: this.options.matches, + }), + new SpectralRule({ + name: + 'Spectral Rules applied to changes to the specification: ' + + ruleInput, + flatSpecFile: absolutePathTmpSpec, + applies: 'changed', + rulesetPointer: ruleInput, + matches: this.options.matches, + }), + ]; + }); const always = this.options.always.map((ruleInput) => { return new SpectralRule({ name: 'Spectral Rules applied to entire specification: ' + ruleInput, @@ -88,7 +149,7 @@ export class SpectralRulesets extends ExternalRuleBase { }); }); - const allRulesets = [...always, ...added]; + const allRulesets = [...always, ...added, ...changed, ...addedOrChanged]; const allResults = await Promise.all( allRulesets.map((ruleset) => ruleset.runRules(inputs)) @@ -160,11 +221,18 @@ export class SpectralRulesets extends ExternalRuleBase { }) .join('\n- '); } - const configValidated = config as { added?: string[]; always?: string[] }; + const configValidated = config as { + added?: string[]; + always?: string[]; + changed?: string[]; + addedOrChanged?: string[]; + }; return new SpectralRulesets({ added: configValidated.added ?? [], always: configValidated.always ?? [], + changed: configValidated.changed ?? [], + addedOrChanged: configValidated.addedOrChanged ?? [], }); } }