core/resolvers/plan.resolver.ts
core/resolvers/plan.resolver.ts is a file in GovLab Quality. 121 lines of code and 22 definitions.
import type {
CanonicalConfig,
CanonicalData,
CanonicalSettingRecord,
MappingRow,
OwnershipSurface,
} from "#types/canon.types";
import type { Conflict, ConflictReport, PerTool, ResolvedPlan } from "#types/plan.types";
import {
applyRuleIntent,
applyValueSetting,
detectKnownBadPairs,
indexOwnership,
indexRows,
matchesLang,
} from "#core/resolvers/surface.resolver";
import { channelMismatch, unknownSetting } from "#configuration/strings/quality.strings";
interface Binding {
setting: CanonicalSettingRecord;
value: unknown;
lang: string;
langRows: MappingRow[];
}
interface BindCtx {
entries: [string, unknown][];
expectKind: "rule-intent" | "value";
languages: string[];
rowsById: Map<string, MappingRow[]>;
settingById: Map<string, CanonicalSettingRecord>;
}
interface BindResult {
bindings: Binding[];
conflicts: Conflict[];
}
const bindingsForSetting = function bindingsForSetting(
setting: CanonicalSettingRecord,
value: unknown,
ctx: BindCtx,
): Binding[] {
const rows = ctx.rowsById.get(setting.id) ?? [];
return ctx.languages.flatMap((lang) => {
const langRows = rows.filter((row) => matchesLang(row, lang));
return langRows.length > 0 ? [{ lang, langRows, setting, value }] : [];
});
};
const channelOf = function channelOf(kind: BindCtx["expectKind"]): string {
return kind === "value" ? "values" : "enabled";
};
const bindings = function bindings(ctx: BindCtx): BindResult {
const out: Binding[] = [];
const conflicts: Conflict[] = [];
for (const [canonicalId, value] of ctx.entries) {
const setting = ctx.settingById.get(canonicalId);
if (!setting) {
conflicts.push({ canonicalId, detail: unknownSetting(canonicalId), kind: "unknown-setting" });
} else if (setting.kind === ctx.expectKind) {
out.push(...bindingsForSetting(setting, value, ctx));
} else {
conflicts.push({
canonicalId,
detail: channelMismatch(canonicalId, setting.kind, channelOf(ctx.expectKind)),
kind: "channel-mismatch",
});
}
}
return { bindings: out, conflicts };
};
interface CollectCtx {
data: CanonicalData;
enabledBinds: BindResult;
ownership: Map<string, OwnershipSurface>;
perTool: PerTool;
valueBinds: BindResult;
}
const collectConflicts = function collectConflicts(ctx: CollectCtx): Conflict[] {
const valueConflicts = ctx.valueBinds.bindings.flatMap((bind) =>
applyValueSetting({
lang: bind.lang,
langRows: bind.langRows,
ownership: ctx.ownership,
perTool: ctx.perTool,
setting: bind.setting,
value: bind.value,
}),
);
for (const bind of ctx.enabledBinds.bindings) {
applyRuleIntent({
lang: bind.lang,
langRows: bind.langRows,
ownership: ctx.ownership,
perTool: ctx.perTool,
setting: bind.setting,
});
}
return [
...ctx.valueBinds.conflicts,
...ctx.enabledBinds.conflicts,
...valueConflicts,
...detectKnownBadPairs(ctx.data, ctx.perTool),
];
};
export const resolveConfig = function resolveConfig(
config: CanonicalConfig,
data: CanonicalData,
): ConflictReport | ResolvedPlan {
const perTool: PerTool = {};
const settingById = new Map(
data.settings.map((setting): [string, CanonicalSettingRecord] => [setting.id, setting]),
);
const shared = { languages: config.languages, rowsById: indexRows(data.rows), settingById };
const ownership = indexOwnership(data.ownership);
const valueBinds = bindings({ ...shared, entries: Object.entries(config.values ?? {}), expectKind: "value" });
const enabledBinds = bindings({
...shared,
entries: Object.entries(config.enabled ?? {}).filter(([, on]) => on),
expectKind: "rule-intent",
});
const conflicts = collectConflicts({ data, enabledBinds, ownership, perTool, valueBinds });
const blocking = conflicts.filter((conflict) => conflict.kind !== "unsatisfiable-on-fixed");
return blocking.length > 0 ? { conflicts: blocking } : { perToolConfig: perTool };
};