import { THEME_OVERRIDE_EXTENSION_ID } from '../constants'; import { overrideRuntimeData } from './artifacts'; import type { CandidateEvaluationRequest, CandidateEvaluationResult, ParsedThemeOverride, RuleDefinition, RuleEvaluator, ThemeOverride, } from './contracts'; import { expandThemeOverrideWithData } from './expand'; import { parseThemeOverrideWithData } from './parser'; import { evaluateIntentRules, evaluateResolvedRules } from './ruleEvaluation'; function candidatePayload( parsed: ParsedThemeOverride, request: CandidateEvaluationRequest, ): ThemeOverride { return { ...parsed.preservedUnknown.topLevel, $extensions: { ...parsed.preservedUnknown.extensions, [THEME_OVERRIDE_EXTENSION_ID]: parsed.metadata, }, inputs: { ...parsed.preservedUnknown.inputs, ...parsed.inputs.known, }, selections: { ...parsed.preservedUnknown.selections, ...parsed.selections.known, [request.selectionId]: request.candidate, }, overrides: { ...parsed.preservedUnknown.overrides, ...parsed.overrides.known, }, } as unknown as ThemeOverride; } function evaluateCandidate( request: CandidateEvaluationRequest, rules: readonly RuleDefinition[], ): CandidateEvaluationResult { const data = { ...overrideRuntimeData, rules }; const parsed = parseThemeOverrideWithData(candidatePayload(request.parsed, request), data); if (!parsed.valid) { return { accepted: false, diagnostics: parsed.diagnostics }; } const expanded = expandThemeOverrideWithData({ parsed: parsed.parsed, platform: request.platform, data, }); if (!expanded.valid) { return { accepted: false, diagnostics: expanded.diagnostics }; } return { accepted: true, diagnostics: [...parsed.diagnostics, ...expanded.expanded.diagnostics], expanded: expanded.expanded, }; } export const overrideRuleEvaluator: RuleEvaluator = { evaluateIntent: (rules, parsed) => evaluateIntentRules(rules, parsed, overrideRuntimeData.catalogs.getSourceSet), evaluateResolved: (rules, context) => evaluateResolvedRules(rules, context.expanded), evaluateCandidate: (rules, request) => evaluateCandidate(request, rules), };