everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
1 lines • 4.01 kB
Source Map (JSON)
{"version":3,"file":"config-slots.mjs","names":[],"sources":["../../src/services/config-slots.ts"],"sourcesContent":["import { isPlainObject } from \"./resolution/merge\";\n\n/**\n * The one app/plugins config-slot walker — every consumer that names config\n * slots (pin verification, release-slot records, deploy-state keys, slot\n * stamps, authorship checks, pointer fingerprints) derives its traversal from\n * here so the dotted-slot-path domain cannot fork per module into silently\n * divergent copies (coding-standards: a hand-maintained constant paralleling\n * what the config schema knows is a driftable copy).\n *\n * Canonical dotted paths: `app.<key>`, `app.<key>.ui`, `plugins.<id>`,\n * `plugins.<id>.ui`. A `ui: false` opt-out is visited (the entry owns the\n * no-surface decision); a bare-string plugin ref is visited with\n * `isPluginRef` true (it owns the plugin and its whole ui surface).\n */\n\nexport interface ConfigSlot {\n slot: string;\n entry: Record<string, unknown> | string | false;\n readonly isPluginRef: boolean;\n}\n\nexport function walkConfigSlots(\n config: Record<string, unknown>,\n visit: (slot: ConfigSlot) => void,\n): void {\n const app = config.app;\n if (isPlainObject(app)) {\n for (const [key, entry] of Object.entries(app)) {\n if (!isPlainObject(entry)) continue;\n visit({ slot: `app.${key}`, entry, isPluginRef: false });\n if (\"ui\" in entry) {\n const ui = (entry as Record<string, unknown>).ui;\n if (isPlainObject(ui) || ui === false) {\n visit({ slot: `app.${key}.ui`, entry: ui, isPluginRef: false });\n }\n }\n }\n }\n const plugins = config.plugins;\n if (isPlainObject(plugins)) {\n for (const [id, entry] of Object.entries(plugins)) {\n if (typeof entry === \"string\") {\n if (entry.length > 0) {\n visit({ slot: `plugins.${id}`, entry, isPluginRef: true });\n }\n continue;\n }\n if (!isPlainObject(entry)) continue;\n visit({ slot: `plugins.${id}`, entry, isPluginRef: false });\n if (\"ui\" in entry) {\n const ui = entry.ui;\n if (isPlainObject(ui) || ui === false) {\n visit({ slot: `plugins.${id}.ui`, entry: ui, isPluginRef: false });\n }\n }\n }\n }\n}\n\n/**\n * Ensure every container of a dotted path exists (creating plain objects along\n * the way) and return the container that holds the final segment. Consumers\n * keep the final-set semantics (replace vs merge-into) local.\n */\nexport function ensureObjectContainers(\n target: Record<string, unknown>,\n segments: readonly string[],\n): Record<string, unknown> {\n let container = target;\n for (const segment of segments) {\n const next = container[segment];\n if (!isPlainObject(next)) {\n const created: Record<string, unknown> = {};\n container[segment] = created;\n container = created;\n } else {\n container = next;\n }\n }\n return container;\n}\n"],"mappings":";;;AAsBA,SAAgB,gBACd,QACA,OACM;CACN,MAAM,MAAM,OAAO;CACnB,IAAI,cAAc,GAAG,GACnB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GAAG,GAAG;EAC9C,IAAI,CAAC,cAAc,KAAK,GAAG;EAC3B,MAAM;GAAE,MAAM,OAAO;GAAO;GAAO,aAAa;EAAM,CAAC;EACvD,IAAI,QAAQ,OAAO;GACjB,MAAM,KAAM,MAAkC;GAC9C,IAAI,cAAc,EAAE,KAAK,OAAO,OAC9B,MAAM;IAAE,MAAM,OAAO,IAAI;IAAM,OAAO;IAAI,aAAa;GAAM,CAAC;EAElE;CACF;CAEF,MAAM,UAAU,OAAO;CACvB,IAAI,cAAc,OAAO,GACvB,KAAK,MAAM,CAAC,IAAI,UAAU,OAAO,QAAQ,OAAO,GAAG;EACjD,IAAI,OAAO,UAAU,UAAU;GAC7B,IAAI,MAAM,SAAS,GACjB,MAAM;IAAE,MAAM,WAAW;IAAM;IAAO,aAAa;GAAK,CAAC;GAE3D;EACF;EACA,IAAI,CAAC,cAAc,KAAK,GAAG;EAC3B,MAAM;GAAE,MAAM,WAAW;GAAM;GAAO,aAAa;EAAM,CAAC;EAC1D,IAAI,QAAQ,OAAO;GACjB,MAAM,KAAK,MAAM;GACjB,IAAI,cAAc,EAAE,KAAK,OAAO,OAC9B,MAAM;IAAE,MAAM,WAAW,GAAG;IAAM,OAAO;IAAI,aAAa;GAAM,CAAC;EAErE;CACF;AAEJ;;;;;;AAOA,SAAgB,uBACd,QACA,UACyB;CACzB,IAAI,YAAY;CAChB,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,OAAO,UAAU;EACvB,IAAI,CAAC,cAAc,IAAI,GAAG;GACxB,MAAM,UAAmC,CAAC;GAC1C,UAAU,WAAW;GACrB,YAAY;EACd,OACE,YAAY;CAEhB;CACA,OAAO;AACT"}