diff --git a/packages/core/src/ruleset/rule.ts b/packages/core/src/ruleset/rule.ts index 3cc581337..c0e2b6f83 100644 --- a/packages/core/src/ruleset/rule.ts +++ b/packages/core/src/ruleset/rule.ts @@ -11,6 +11,7 @@ import type { HumanReadableDiagnosticSeverity, IRuleThen, RuleDefinition, String import { minimatch } from './utils/minimatch'; import { Formats } from './formats'; import { resolveAlias } from './alias'; +import type { Stringified } from './types'; export interface IRule { description: string | null; @@ -25,13 +26,14 @@ export interface IRule { given: string[]; } -export type StringifiedRule = Omit & { +type RuleJson = Omit & { name: string; - formats: string[] | null; then: (Pick & { function: string; functionOptions?: string })[]; owner: number; }; +export type StringifiedRule = Stringified; + export class Rule implements IRule { public description: string | null; public message: string | null; @@ -164,7 +166,7 @@ export class Rule implements IRule { return new Rule(this.name, this.definition, this.owner); } - public toJSON(): Stringifable { + public toJSON(): Stringifable { return { name: this.name, recommended: this.recommended, diff --git a/packages/core/src/ruleset/ruleset.ts b/packages/core/src/ruleset/ruleset.ts index 87f11718a..4020b37e0 100644 --- a/packages/core/src/ruleset/ruleset.ts +++ b/packages/core/src/ruleset/ruleset.ts @@ -17,6 +17,7 @@ import { DEFAULT_PARSER_OPTIONS, getDiagnosticSeverity } from '..'; import { mergeRulesets } from './mergers/rulesets'; import { Formats } from './formats'; import { isSimpleAliasDefinition } from './utils/guards'; +import type { Stringified } from './types'; const STACK_SYMBOL = Symbol('@stoplight/spectral/ruleset/#stack'); const DEFAULT_RULESET_FILE = /^\.?spectral\.(ya?ml|json|m?js)$/; @@ -29,9 +30,9 @@ type RulesetContext = { let SEED = 1; -export type StringifiedRuleset = { +type RulesetJson = { id: number; - extends: StringifiedRuleset[] | null; + extends: RulesetJson[] | null; source: string | null; aliases: RulesetAliasesDefinition | null; formats: Formats | null; @@ -40,6 +41,8 @@ export type StringifiedRuleset = { parserOptions: ParserOptions; }; +export type StringifiedRuleset = Stringified; + export class Ruleset { public readonly id = SEED++; @@ -309,7 +312,7 @@ export class Ruleset { return DEFAULT_RULESET_FILE.test(uri); } - public toJSON(): Stringifable { + public toJSON(): Stringifable { return { id: this.id, extends: this.extends, diff --git a/packages/core/src/ruleset/types.ts b/packages/core/src/ruleset/types.ts index 381a18d10..e18e84b64 100644 --- a/packages/core/src/ruleset/types.ts +++ b/packages/core/src/ruleset/types.ts @@ -113,9 +113,14 @@ export type RulesetDefinition = Readonly< > >; -// eslint-disable-next-line @typescript-eslint/ban-types export type Stringifable = T extends object ? { [P in keyof T]: Stringifable | { toJSON?(): Stringifable }; } : T; + +export type Stringified = T extends object + ? { + [P in keyof T]: NonNullable extends { toJSON(): infer R } ? R : Stringified; + } + : T;