diff --git a/lib/config/presets/internal/replacements.ts b/lib/config/presets/internal/replacements.ts index 80b6d569c564c2..b2b91debd98331 100644 --- a/lib/config/presets/internal/replacements.ts +++ b/lib/config/presets/internal/replacements.ts @@ -1,10 +1,12 @@ -import replacementGroups from '../../../data/replacements.json'; +import replacementGroupsJson from '../../../data/replacements.json'; import type { Preset } from '../types'; import type { PresetTemplate, Replacement } from './auto-generate-replacements'; import { addPresets } from './auto-generate-replacements'; +const { $schema, ...replacementPresets } = replacementGroupsJson; + /* eslint sort-keys: ["error", "asc", {"caseSensitive": false, "natural": true}] */ -export const presets: Record = replacementGroups; +export const presets: Record = replacementPresets; const muiReplacement: Replacement[] = [ [['@material-ui/codemod'], '@mui/codemod'], diff --git a/lib/data/replacements.json b/lib/data/replacements.json index 9f650fa4773c44..e2f3336b10b2d1 100644 --- a/lib/data/replacements.json +++ b/lib/data/replacements.json @@ -1,4 +1,5 @@ { + "$schema": "../../tools/schemas/replacements-schema.json", "all": { "description": "Apply crowd-sourced package replacement rules.", "extends": [ diff --git a/tools/schemas/monorepo-schema.json b/tools/schemas/monorepo-schema.json index 6bc1d6e7a9fabd..7effc4dce2c72f 100644 --- a/tools/schemas/monorepo-schema.json +++ b/tools/schemas/monorepo-schema.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "https://json-schema.org/draft-04/schema#", "type": "object", "properties": { "repoGroups": { diff --git a/tools/schemas/replacements-schema.json b/tools/schemas/replacements-schema.json new file mode 100644 index 00000000000000..7634f93c9e03ba --- /dev/null +++ b/tools/schemas/replacements-schema.json @@ -0,0 +1,61 @@ +{ + "$schema": "https://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "all": { + "type": "object", + "properties": { + "description": { "type": "string" }, + "extends": { + "type": "array", + "items": { "type": "string" } + }, + "ignoreDeps": { + "type": "array", + "items": { "type": "string" } + } + }, + "required": ["description", "extends"] + } + }, + "patternProperties": { + "^[a-zA-Z0-9-]+$": { + "type": "object", + "properties": { + "description": { "type": "string" }, + "packageRules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "matchCurrentVersion": { "type": "string" }, + "matchDatasources": { + "type": "array", + "items": { "type": "string" } + }, + "matchPackageNames": { + "type": "array", + "items": { "type": "string" } + }, + "replacementName": { "type": "string" }, + "replacementVersion": { "type": "string" }, + "description": { "type": "string" }, + "replacementNameTemplate": { "type": "string" } + }, + "required": ["matchDatasources", "matchPackageNames"] + }, + "contains": { + "type": "object", + "oneOf": [ + { "required": ["replacementName"] }, + { "required": ["replacementNameTemplate"] } + ] + }, + "minItems": 1 + } + }, + "required": ["description", "packageRules"] + } + }, + "additionalProperties": false +} diff --git a/tools/schemas/schema.ts b/tools/schemas/schema.ts index b5361a2472824a..8609e3582e81dc 100644 --- a/tools/schemas/schema.ts +++ b/tools/schemas/schema.ts @@ -5,10 +5,50 @@ const UrlSchema = z.record( z.union([z.string(), z.array(z.string())]), ); -const MonorepoSchema = z.object({ +export const MonorepoSchema = z.object({ repoGroups: UrlSchema, orgGroups: UrlSchema, patternGroups: UrlSchema, }); -export { MonorepoSchema }; +const PackageRuleSchema = z.object({ + matchCurrentVersion: z.string().optional(), + matchDatasources: z.array(z.string()), + matchPackageNames: z.array(z.string()), + replacementName: z.string().optional(), + replacementVersion: z.string().optional(), + description: z.string().optional(), + replacementNameTemplate: z.string().optional(), +}); + +const RuleSetSchema = z.object({ + description: z.string(), + packageRules: z + .array(PackageRuleSchema) + .min(1) + .refine( + (rules) => + rules.some( + (rule) => + rule.replacementName !== undefined || + rule.replacementNameTemplate !== undefined, + ), + { + message: + 'At least one package rule must use either the replacementName config option, or the replacementNameTemplate config option', + }, + ), +}); + +const AllSchema = z.object({ + description: z.string(), + extends: z.array(z.string()), + ignoreDeps: z.array(z.string()).optional(), +}); + +export const ReplacementsSchema = z + .object({ + $schema: z.string(), + all: AllSchema, + }) + .catchall(RuleSetSchema);