import type { JsonObject, Scope } from "../contract"; import type { EditableField } from "./schema"; export interface SettingsModule { id: string; fields: readonly EditableField[]; parsed: JsonObject; globalData: JsonObject; projectData: JsonObject; } export type SettingChoice = | { kind: "value"; value: string } | { kind: "use-default" } | { kind: "use-global" }; export interface ChiSettingItem { id: string; label: string; type: "enum" | "string"; currentChoice: SettingChoice; choices: readonly SettingChoice[]; fallbackValue: string; moduleId: string; scope: Scope; key: string; } function hasValue(data: JsonObject, key: string): boolean { return Object.prototype.hasOwnProperty.call(data, key); } function row( module: SettingsModule, field: EditableField, scope: Scope, ): ChiSettingItem { const data = scope === "global" ? module.globalData : module.projectData; const fallbackChoice: SettingChoice = scope === "global" ? { kind: "use-default" } : { kind: "use-global" }; const choices: SettingChoice[] = field.type === "enum" ? [...field.values.map((value): SettingChoice => ({ kind: "value", value })), fallbackChoice] : []; const fallbackValue = scope === "global" ? field.defaultValue : hasValue(module.globalData, field.key) ? String(module.globalData[field.key]) : field.defaultValue; return { id: module.id + ":" + scope + ":" + field.key, label: field.key, type: field.type, currentChoice: hasValue(data, field.key) ? { kind: "value", value: String(data[field.key]) } : fallbackChoice, choices, fallbackValue, moduleId: module.id, scope, key: field.key, }; } export function buildModuleSettingsItems( module: SettingsModule, scope: Scope, ): readonly ChiSettingItem[] { return module.fields.map((field) => row(module, field, scope)); } export function moduleDisplayName(id: string): string { return id.startsWith("chi-") ? id.slice(4) : id; } export function buildSettingsItems( modules: readonly SettingsModule[], projectTrusted: boolean, ): readonly ChiSettingItem[] { const items = modules.flatMap((module) => buildModuleSettingsItems(module, "global")); if (!projectTrusted) return items; return [ ...items, ...modules.flatMap((module) => buildModuleSettingsItems(module, "project")), ]; } export function settingChoiceToStoredValue(choice: SettingChoice): string | undefined { return choice.kind === "value" ? choice.value : undefined; }