@open-mercato/shared 0.6.8-develop.6915.1.ac6031c503 → 0.6.8-develop.6916.1.f04fff3436

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- [build:shared] found 258 entry points
1
+ [build:shared] found 259 entry points
2
2
  [build:shared] built successfully
package/AGENTS.md CHANGED
@@ -69,8 +69,11 @@ When you need shared type definitions, import from these:
69
69
  | Search config types (`SearchModuleConfig`) | `@open-mercato/shared/modules/search` |
70
70
  | Module setup types (`ModuleSetupConfig`) | `@open-mercato/shared/modules/setup` |
71
71
  | Module registry types (`Module`) | `@open-mercato/shared/modules/registry` |
72
+ | Resolving authored `PageMetadata` into a route manifest's flat shape (`resolvePageRouteMetadata`, and `resolveDeclaredPageRouteMetadata` for partial merges such as page overrides) | `@open-mercato/shared/modules/registry` |
72
73
  | Module-level overrides (`ModuleOverrides`, dispatcher, per-domain compose helpers) | `@open-mercato/shared/modules/overrides` |
73
74
 
75
+ `registry.ts` re-exports `resolvePageRouteMetadata` from `@open-mercato/shared/modules/pageRouteMetadata`, where it lives so `overrides.ts` can reuse it without an import cycle. Import it from `registry` — the split is an implementation detail.
76
+
74
77
  ## Key Patterns
75
78
 
76
79
  ### Database Connection Pool — MUST keep total demand under `max_connections`
@@ -1,4 +1,4 @@
1
- const APP_VERSION = "0.6.8-develop.6915.1.ac6031c503";
1
+ const APP_VERSION = "0.6.8-develop.6916.1.f04fff3436";
2
2
  const appVersion = APP_VERSION;
3
3
  export {
4
4
  APP_VERSION,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/version.ts"],
4
- "sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.6.8-develop.6915.1.ac6031c503';\nexport const appVersion = APP_VERSION;\n"],
4
+ "sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.6.8-develop.6916.1.f04fff3436';\nexport const appVersion = APP_VERSION;\n"],
5
5
  "mappings": "AACO,MAAM,cAAc;AACpB,MAAM,aAAa;",
6
6
  "names": []
7
7
  }
@@ -57,6 +57,7 @@ function applyModuleOverridesFromEnabledModules(modules) {
57
57
  }
58
58
  }
59
59
  import { createLogger } from "../lib/logger/index.js";
60
+ import { resolveDeclaredPageRouteMetadata } from "./pageRouteMetadata.js";
60
61
  const logger = createLogger("shared").child({ component: "module-overrides" });
61
62
  const pageRouteOverrideStore = { modules: {}, programmatic: {} };
62
63
  const subscriberOverrideStore = { modules: {}, programmatic: {} };
@@ -500,7 +501,7 @@ function applyPageOverridesToManifests(routes, overrides, kind) {
500
501
  }
501
502
  const metadata = override.metadata && typeof override.metadata === "object" ? override.metadata : {};
502
503
  const load = hasLoad ? override.load : hasComponent ? async () => override.Component : entry.load;
503
- result.push({ ...entry, ...metadata, load });
504
+ result.push({ ...entry, ...metadata, ...resolveDeclaredPageRouteMetadata(metadata), load });
504
505
  }
505
506
  warnStaleOverrides("routes.pages", Object.fromEntries(
506
507
  overrideKeys.map((key) => [key, normalizedOverrides[key]])
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/modules/overrides.ts"],
4
- "sourcesContent": ["/**\n * Unified `modules.ts` override surface \u2014 one place for downstream apps to\n * replace or disable any contract a module presents.\n *\n * Spec: `.ai/specs/implemented/2026-05-04-modules-ts-unified-overrides.md`\n *\n * Each `ModuleEntry` in `apps/<app>/src/modules.ts` may carry an\n * `overrides` field whose sub-keys address one domain at a time:\n *\n * {\n * id: 'example',\n * from: '@app',\n * overrides: {\n * ai: { agents: {...}, tools: {...} }, // Phase 1 \u2014 wired\n * routes: { api: {...}, pages: {...} }, // Phase 2/3 \u2014 wired\n * events: { subscribers: {...} }, // Phase 4 \u2014 wired\n * workers: {...}, // Phase 5 \u2014 wired\n * ...\n * },\n * }\n *\n * The umbrella shape is the union of every per-domain sub-shape. Per-\n * domain runtime hooks own their composers and apply the override map\n * against their registry. During the rollout the dispatcher emitted a\n * one-shot warning for unwired domains; all domains in this umbrella are\n * now wired, so warnings only indicate a missing custom applier in tests\n * or future domain additions.\n *\n * Resolution order across all domains (highest precedence first):\n *\n * 1. Programmatic \u2014 direct calls into the per-domain `apply*Overrides()` API.\n * 2. `modules.ts` inline \u2014 `entry.overrides.<domain>` here.\n * 3. File-based \u2014 overrides exported from a contributing module's own files.\n * 4. Base \u2014 the module's own registrations.\n *\n * `null` always means \"disable\"; a definition replaces.\n */\n\n// ---------------------------------------------------------------------------\n// Domain sub-shapes\n// ---------------------------------------------------------------------------\n\n/**\n * AI domain \u2014 agents and tools. Re-exports the canonical maps from\n * `@open-mercato/ai-assistant` so consumers do not need to import that\n * package directly when they only want to declare overrides.\n *\n * Imported lazily as `unknown` here because `@open-mercato/shared` must\n * NOT take a runtime dependency on `@open-mercato/ai-assistant` (the\n * dependency direction is the other way around). Apps that author\n * `entry.overrides.ai` should import the strongly-typed\n * `AiAgentOverridesMap` / `AiToolOverridesMap` from `@open-mercato/ai-assistant`\n * directly \u2014 TypeScript structurally compatible types make the loose\n * shape here a no-op annotation cost.\n */\nexport interface AiOverridesShape {\n agents?: Record<string, unknown>\n tools?: Record<string, unknown>\n extensions?: unknown[]\n}\n\n\ntype LooseOverrideMap = Record<string, unknown>\n\n/**\n * Phase 2 (api) / Phase 3 (pages).\n *\n * The `api` sub-shape is keyed by `'METHOD /api/path'` and accepts either\n * a replacement definition (`{ handler, metadata? }`) or `null` to disable.\n * See {@link ApiRouteOverridesMap} for the strongly-typed alias and\n * {@link applyApiOverridesToManifests} for the runtime apply step.\n *\n * The `pages` sub-shape is keyed by `'/backend/path'` or\n * `'/frontend/path'`; `null` disables the page and a definition replaces\n * its loader and/or metadata.\n */\nexport interface RoutesOverridesShape {\n api?: ApiRouteOverridesMap | LooseOverrideMap\n pages?: PageRouteOverridesMap | LooseOverrideMap\n}\n\n/** Phase 4 \u2014 event subscribers. */\nexport interface EventsOverridesShape {\n subscribers?: SubscriberOverridesMap | LooseOverrideMap\n}\n\n/** Phase 6/7/8 \u2014 widget injection, component handles, dashboard widgets. */\nexport interface WidgetsOverridesShape {\n injection?: InjectionWidgetOverridesMap | LooseOverrideMap\n components?: ComponentOverridesMap | LooseOverrideMap\n dashboard?: DashboardWidgetOverridesMap | LooseOverrideMap\n}\n\n/** Phase 9 \u2014 notification types + handlers. */\nexport interface NotificationsOverridesShape {\n types?: NotificationTypeOverridesMap | LooseOverrideMap\n handlers?: NotificationHandlerOverridesMap | LooseOverrideMap\n}\n\n/** Phase 15 \u2014 setup lifecycle hooks. */\nexport interface SetupOverridesShape {\n defaultRoleFeatures?: Record<string, readonly string[]>\n defaultCustomerRoleFeatures?: Record<string, readonly string[]>\n seedDefaults?: false\n seedExamples?: false\n onTenantCreated?: false\n}\n\n/** Phase 16 \u2014 ACL features (per-feature override). */\nexport interface AclOverridesShape {\n features?: AclFeatureOverridesMap | LooseOverrideMap\n}\n\n/** Phase 18 \u2014 encryption maps per entity id. */\nexport interface EncryptionOverridesShape {\n maps?: EncryptionMapOverridesMap | LooseOverrideMap\n}\n\n/**\n * Backend navigation ordering.\n *\n * `groupOrder` **prepends** sidebar nav group ids: the ids listed here rank ahead of every other\n * group, in the order given, and any group not named keeps the ordering it has today. Prepending\n * rather than replacing means an app that only cares about its own group lists that one id, instead of\n * having to enumerate every shipped group and accidentally demoting the ones it forgot.\n *\n * This is a *default*, applied beneath both role and user sidebar preferences \u2014 an operator's own\n * arrangement still wins.\n */\nexport interface NavOverridesShape {\n groupOrder?: string[]\n}\n\n/**\n * Umbrella shape for `entry.overrides`. Every key is optional; a\n * downstream app sets only the domains it cares about.\n */\nexport interface ModuleOverrides {\n ai?: AiOverridesShape\n routes?: RoutesOverridesShape\n events?: EventsOverridesShape\n workers?: WorkerOverridesMap | LooseOverrideMap\n widgets?: WidgetsOverridesShape\n notifications?: NotificationsOverridesShape\n interceptors?: ApiInterceptorOverridesMap | LooseOverrideMap\n commandInterceptors?: CommandInterceptorOverridesMap | LooseOverrideMap\n enrichers?: ResponseEnricherOverridesMap | LooseOverrideMap\n guards?: PageGuardOverridesMap | LooseOverrideMap\n cli?: CliOverridesMap | LooseOverrideMap\n setup?: SetupOverridesShape\n acl?: AclOverridesShape\n di?: DiOverridesMap | LooseOverrideMap\n encryption?: EncryptionOverridesShape\n nav?: NavOverridesShape\n}\n\n/**\n * Public shape consumed by the dispatcher. Mirrors the `ModuleEntry`\n * defined in each app's `modules.ts` \u2014 the dispatcher only needs `id`\n * and `overrides`.\n */\nexport interface ModuleEntryWithOverrides {\n id: string\n from?: string\n overrides?: ModuleOverrides\n}\n\n// ---------------------------------------------------------------------------\n// Per-domain runtime hook registry\n// ---------------------------------------------------------------------------\n\n/**\n * Each wired domain registers an applier that receives the list of\n * `(moduleId, overrides)` pairs in module-load order and forwards them\n * to its own runtime hook. Unwired domains do not register an applier\n * and instead trigger the dispatcher's one-shot warning.\n */\nexport type ModuleOverrideDomain =\n | 'ai'\n | 'routes'\n | 'events'\n | 'workers'\n | 'widgets'\n | 'notifications'\n | 'interceptors'\n | 'commandInterceptors'\n | 'enrichers'\n | 'guards'\n | 'cli'\n | 'setup'\n | 'acl'\n | 'di'\n | 'encryption'\n | 'nav'\n\nexport interface ModuleOverrideEntry<TShape> {\n moduleId: string\n overrides: TShape\n}\n\nexport type ModuleOverrideApplier<TShape> = (\n entries: ReadonlyArray<ModuleOverrideEntry<TShape>>,\n) => void\n\nconst appliers = new Map<ModuleOverrideDomain, ModuleOverrideApplier<unknown>>()\nconst warnedUnwiredDomains = new Set<ModuleOverrideDomain>()\n\n/**\n * Register a per-domain runtime hook. Called once at module-load time\n * by each wired domain (e.g. the AI subsystem registers `'ai'` from\n * `@open-mercato/ai-assistant`).\n */\nexport function registerModuleOverrideApplier<TShape>(\n domain: ModuleOverrideDomain,\n applier: ModuleOverrideApplier<TShape>,\n): void {\n appliers.set(domain, applier as ModuleOverrideApplier<unknown>)\n}\n\n/** @__internal Test-only hook \u2014 clear all registered appliers + warnings. */\nexport function resetModuleOverrideAppliersForTests(): void {\n appliers.clear()\n warnedUnwiredDomains.clear()\n registerBuiltInModuleOverrideAppliers()\n}\n\n// ---------------------------------------------------------------------------\n// Dispatcher\n// ---------------------------------------------------------------------------\n\nconst DOMAIN_KEYS: ModuleOverrideDomain[] = [\n 'ai',\n 'routes',\n 'events',\n 'workers',\n 'widgets',\n 'notifications',\n 'interceptors',\n 'commandInterceptors',\n 'enrichers',\n 'guards',\n 'cli',\n 'setup',\n 'acl',\n 'di',\n 'encryption',\n 'nav',\n]\n\nconst TRACKING_ISSUE_HINT =\n 'See `.ai/specs/implemented/2026-05-04-modules-ts-unified-overrides.md` and tracking issue https://github.com/open-mercato/open-mercato/issues/1787.'\n\n/**\n * Walk every `ModuleEntry` and dispatch its `overrides.<domain>` shape\n * to the matching wired applier. Unwired domains emit a one-shot\n * structured warning.\n *\n * Call this exactly once from `apps/<app>/src/bootstrap.ts` BEFORE any\n * registry first-loads. Calling it more than once is safe but\n * accumulates per-domain entries each time.\n */\nexport function applyModuleOverridesFromEnabledModules(\n modules: ReadonlyArray<ModuleEntryWithOverrides>,\n): void {\n if (!Array.isArray(modules) || modules.length === 0) return\n\n // Bucket entries by domain in module-load order.\n const buckets = new Map<ModuleOverrideDomain, Array<ModuleOverrideEntry<unknown>>>()\n\n for (const entry of modules) {\n if (!entry || typeof entry.id !== 'string' || !entry.id) continue\n const overrides = entry.overrides\n if (!overrides || typeof overrides !== 'object') continue\n\n for (const domain of DOMAIN_KEYS) {\n const value = (overrides as Record<string, unknown>)[domain]\n if (value === undefined || value === null) continue\n if (typeof value !== 'object') continue\n const list = buckets.get(domain) ?? []\n list.push({ moduleId: entry.id, overrides: value })\n buckets.set(domain, list)\n }\n }\n\n // Dispatch each domain to its wired applier; warn on unwired domains.\n for (const [domain, entries] of buckets) {\n const applier = appliers.get(domain)\n if (!applier) {\n if (!warnedUnwiredDomains.has(domain)) {\n warnedUnwiredDomains.add(domain)\n const moduleIds = Array.from(new Set(entries.map((e) => e.moduleId))).join(', ')\n logger.warn('Override domain not yet wired \u2014 entry ignored', { domain, moduleIds, hint: TRACKING_ISSUE_HINT })\n }\n continue\n }\n applier(entries)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Phase 2/3 \u2014 Routes (API + pages) applier\n// ---------------------------------------------------------------------------\n//\n// Wires `entry.overrides.routes.api` so a downstream module can disable or\n// replace any API route declared by another module. The override map is\n// keyed by `'METHOD /api/path'` (case-insensitive method, leading slash on\n// the path), and each value is either:\n//\n// - `null` \u2014 disable the matching method on the route.\n// - `{ handler, metadata? }` \u2014 replace the matching method's handler\n// (and optionally merge override metadata into the route's metadata).\n//\n// Resolution order (lowest precedence first):\n//\n// 1. `modules.ts` inline \u2014 every `entry.overrides.routes.api` on a\n// `ModuleEntry` (last entry per key wins).\n// 2. Programmatic \u2014 `applyApiRouteOverrides({...})` from anywhere at\n// boot or test scaffolds (last call per key wins).\n//\n// A file-based tier (per-module `apiRouteOverrides` exports) is **not**\n// part of Phase 2 \u2014 modules that ship a route override do so via\n// `modules.ts` or programmatically. The umbrella spec keeps the file-based\n// tier \"where applicable\".\n//\n// The applied overrides are consumed by `registerApiRouteManifests` (see\n// `./registry.ts`) which rewrites the manifest array once before storing\n// it. Calls to `applyApiRouteOverrides` made AFTER manifests are already\n// registered do not retro-actively update the stored manifest \u2014 for\n// runtime override scenarios call the dispatcher / programmatic API\n// before `bootstrap.ts` triggers manifest registration.\n//\n// Spec: `.ai/specs/implemented/2026-05-04-modules-ts-unified-overrides.md` (Phases 2/3).\n\n// ApiRouteManifestEntry / ApiHandler / HttpMethod live in ./registry. The\n// type-only import is erased at runtime, so there is no cycle even though\n// ./registry imports the runtime helpers below.\nimport type {\n ApiHandler,\n ApiRouteManifestEntry,\n BackendRouteManifestEntry,\n FrontendRouteManifestEntry,\n HttpMethod,\n Module,\n ModuleCli,\n ModuleDashboardWidgetEntry,\n ModuleInjectionWidgetEntry,\n ModuleSubscriber,\n ModuleWorker,\n} from './registry'\nimport { createLogger } from '../lib/logger'\nimport type { ModuleInjectionTable } from './widgets/injection'\nimport type { ComponentOverride } from './widgets/component-registry'\nimport type { NotificationHandler } from './notifications/handler'\nimport type { NotificationTypeDefinition } from './notifications/types'\nimport type { ModuleEncryptionMap } from './encryption'\nimport type { ModuleSetupConfig } from './setup'\nimport type { ApiInterceptor } from '../lib/crud/api-interceptor'\nimport type { ResponseEnricher } from '../lib/crud/response-enricher'\nimport type { CommandInterceptor } from '../lib/commands/command-interceptor'\nimport type { PageMiddlewareRegistryEntry, PageRouteMiddleware } from './middleware/page'\n\nconst logger = createLogger('shared').child({ component: 'module-overrides' })\n\n/** Override for a single API route entry: replace handler/metadata, or `null` to disable. */\nexport interface ApiRouteOverrideDefinition {\n /** Replacement handler. Same signature as the original API route handler. */\n handler: ApiHandler\n /** Optional metadata override \u2014 replaces the per-method metadata on the route. */\n metadata?: unknown\n}\n\n/** Override value per `'METHOD /api/path'` key \u2014 definition or `null` to disable. */\nexport type ApiRouteOverride = ApiRouteOverrideDefinition | null\n\n/** Map of `'METHOD /api/path'` \u2192 override. */\nexport type ApiRouteOverridesMap = Record<string, ApiRouteOverride>\n\ntype OverrideStore<T> = {\n modules: Record<string, T | null>\n programmatic: Record<string, T | null>\n}\n\ntype OverrideValue<T> = T | null\ntype OverrideMap<T> = Record<string, OverrideValue<T>>\n\n/** Override for a backend/frontend page route: replace loader/metadata, or `null` to disable. */\nexport interface PageRouteOverrideDefinition {\n load?: BackendRouteManifestEntry['load']\n Component?: Awaited<ReturnType<BackendRouteManifestEntry['load']>>\n metadata?: Partial<Omit<BackendRouteManifestEntry | FrontendRouteManifestEntry, 'moduleId' | 'load'>>\n}\n\nexport type PageRouteOverride = PageRouteOverrideDefinition | null\nexport type PageRouteOverridesMap = Record<string, PageRouteOverride>\n\nexport type SubscriberOverride = ModuleSubscriber | null\nexport type SubscriberOverridesMap = Record<string, SubscriberOverride>\n\nexport type WorkerOverride = ModuleWorker | null\nexport type WorkerOverridesMap = Record<string, WorkerOverride>\n\nexport type CliOverride = ModuleCli | null\nexport type CliOverridesMap = Record<string, CliOverride>\n\nexport type InjectionWidgetOverride = ModuleInjectionWidgetEntry | null\nexport type InjectionWidgetOverridesMap = Record<string, InjectionWidgetOverride>\n\nexport type DashboardWidgetOverride = ModuleDashboardWidgetEntry | null\nexport type DashboardWidgetOverridesMap = Record<string, DashboardWidgetOverride>\n\nexport type ComponentOverrideValue = ComponentOverride | ComponentOverride[] | null\nexport type ComponentOverridesMap = Record<string, ComponentOverrideValue>\n\nexport type NotificationTypeOverride = NotificationTypeDefinition | null\nexport type NotificationTypeOverridesMap = Record<string, NotificationTypeOverride>\n\nexport type NotificationHandlerOverride = NotificationHandler | null\nexport type NotificationHandlerOverridesMap = Record<string, NotificationHandlerOverride>\n\nexport type ApiInterceptorOverride = ApiInterceptor | null\nexport type ApiInterceptorOverridesMap = Record<string, ApiInterceptorOverride>\n\nexport type CommandInterceptorOverride = CommandInterceptor | null\nexport type CommandInterceptorOverridesMap = Record<string, CommandInterceptorOverride>\n\nexport type ResponseEnricherOverride = ResponseEnricher | null\nexport type ResponseEnricherOverridesMap = Record<string, ResponseEnricherOverride>\n\nexport type PageGuardOverride = PageRouteMiddleware | null\nexport type PageGuardOverridesMap = Record<string, PageGuardOverride>\n\nexport type AclFeatureOverride = string | { id: string; [key: string]: unknown } | null\nexport type AclFeatureOverridesMap = Record<string, AclFeatureOverride>\n\nexport type EncryptionMapOverride = ModuleEncryptionMap | null\nexport type EncryptionMapOverridesMap = Record<string, EncryptionMapOverride>\n\nexport type DiBindingOverrideDefinition = {\n register: (container: { register: (registrations: Record<string, unknown>) => unknown }, key: string) => void\n}\nexport type DiBindingOverride = DiBindingOverrideDefinition | unknown | null\nexport type DiOverridesMap = Record<string, DiBindingOverride>\n\nconst pageRouteOverrideStore: OverrideStore<PageRouteOverrideDefinition> = { modules: {}, programmatic: {} }\nconst subscriberOverrideStore: OverrideStore<ModuleSubscriber> = { modules: {}, programmatic: {} }\nconst workerOverrideStore: OverrideStore<ModuleWorker> = { modules: {}, programmatic: {} }\nconst cliOverrideStore: OverrideStore<ModuleCli> = { modules: {}, programmatic: {} }\nconst injectionWidgetOverrideStore: OverrideStore<ModuleInjectionWidgetEntry> = { modules: {}, programmatic: {} }\nconst dashboardWidgetOverrideStore: OverrideStore<ModuleDashboardWidgetEntry> = { modules: {}, programmatic: {} }\nconst componentOverrideStore: OverrideStore<ComponentOverride | ComponentOverride[]> = { modules: {}, programmatic: {} }\nconst notificationTypeOverrideStore: OverrideStore<NotificationTypeDefinition> = { modules: {}, programmatic: {} }\nconst notificationHandlerOverrideStore: OverrideStore<NotificationHandler> = { modules: {}, programmatic: {} }\nconst apiInterceptorOverrideStore: OverrideStore<ApiInterceptor> = { modules: {}, programmatic: {} }\nconst commandInterceptorOverrideStore: OverrideStore<CommandInterceptor> = { modules: {}, programmatic: {} }\nconst responseEnricherOverrideStore: OverrideStore<ResponseEnricher> = { modules: {}, programmatic: {} }\nconst pageGuardOverrideStore: OverrideStore<PageRouteMiddleware> = { modules: {}, programmatic: {} }\nconst aclFeatureOverrideStore: OverrideStore<Exclude<AclFeatureOverride, null>> = { modules: {}, programmatic: {} }\nconst encryptionMapOverrideStore: OverrideStore<ModuleEncryptionMap> = { modules: {}, programmatic: {} }\nconst diOverrideStore: OverrideStore<Exclude<DiBindingOverride, null>> = { modules: {}, programmatic: {} }\nconst setupOverridesByModule: Record<string, SetupOverridesShape> = {}\n\n/**\n * Sidebar nav ordering state.\n *\n * Persisted on `globalThis` rather than in a module-local variable. This is the one override domain\n * whose consumer lives in a *different package* (`@open-mercato/core`'s backend chrome reads what the\n * app's bootstrap wrote), and standalone builds can evaluate `@open-mercato/shared` through more than\n * one server chunk \u2014 bootstrap would store the value in one instance while the reader saw `null` from\n * another. See `.ai/lessons.md`, \"Global registries in publishable packages must use `globalThis`\".\n *\n * Two tiers, matching every other override domain and the documented resolution order: programmatic\n * calls win over `modules.ts` inline declarations.\n */\nconst GLOBAL_NAV_OVERRIDE_STATE_KEY = '__openMercatoNavOverrideState__'\n\ntype NavOverrideState = {\n /** From `modules.ts` inline `overrides.nav`, with the module entry that supplied it. */\n modules: { moduleId: string; groupOrder: string[] } | null\n /** From `applyNavGroupOrderOverrides`. Takes precedence over `modules`. */\n programmatic: string[] | null\n}\n\nfunction getNavOverrideState(): NavOverrideState {\n const existing = (globalThis as Record<string, unknown>)[GLOBAL_NAV_OVERRIDE_STATE_KEY]\n if (existing && typeof existing === 'object') {\n const typed = existing as NavOverrideState\n if ('modules' in typed && 'programmatic' in typed) return typed\n }\n const initial: NavOverrideState = { modules: null, programmatic: null }\n ;(globalThis as Record<string, unknown>)[GLOBAL_NAV_OVERRIDE_STATE_KEY] = initial\n return initial\n}\n\n/** Drops blank/duplicate ids and returns `null` when nothing usable remains. */\nfunction normalizeNavGroupOrder(value: unknown): string[] | null {\n if (!Array.isArray(value)) return null\n const ids = Array.from(\n new Set(\n value\n .filter((id): id is string => typeof id === 'string' && id.trim().length > 0)\n .map((id) => id.trim()),\n ),\n )\n return ids.length > 0 ? ids : null\n}\n\n/**\n * Programmatic nav ordering, for env-driven boot decisions and tests. Takes precedence over\n * `modules.ts` inline `overrides.nav`, consistent with the other domains' programmatic tier. Pass\n * `null` to clear it and fall back to the inline declaration.\n */\nexport function applyNavGroupOrderOverrides(groupOrder: string[] | null): void {\n getNavOverrideState().programmatic = groupOrder === null ? null : normalizeNavGroupOrder(groupOrder)\n}\n\n/**\n * Nav group ids an app wants ranked ahead of the built-in order, or `null` when none is configured.\n *\n * Consumers MUST treat `null` as \"use the shipped ordering unchanged\" \u2014 this is a default, applied\n * beneath role and user sidebar preferences.\n */\nexport function getNavGroupOrderOverride(): readonly string[] | null {\n const state = getNavOverrideState()\n return state.programmatic ?? state.modules?.groupOrder ?? null\n}\n\nfunction normalizeIdOverrideKey(key: string, label: string): string | null {\n if (typeof key !== 'string') return null\n const trimmed = key.trim()\n if (trimmed) return trimmed\n logger.warn('Skipping malformed override key \u2014 expected a non-empty string', { label, key })\n return null\n}\n\nfunction clearStore<T>(store: OverrideStore<T>): void {\n for (const key of Object.keys(store.modules)) delete store.modules[key]\n for (const key of Object.keys(store.programmatic)) delete store.programmatic[key]\n}\n\n// Shared frozen empty override map. Returned from compose* helpers when both\n// the modules-tier and programmatic-tier stores are empty so per-request hot\n// paths (page guards, etc.) reuse one object instead of allocating fresh `{}`\n// per call. Consumers MUST NOT mutate \u2014 internal applier loops iterate keys\n// only, and the public API hands out shallow copies through composeApiRouteOverrides.\nconst EMPTY_OVERRIDE_MAP: Readonly<Record<string, never>> = Object.freeze({})\n\nfunction applyStoreOverrides<T>(\n store: OverrideStore<T>,\n target: 'modules' | 'programmatic',\n overrides: OverrideMap<T> | undefined,\n options: {\n label: string\n normalizeKey?: (key: string) => string | null\n },\n): void {\n if (!overrides || typeof overrides !== 'object') return\n const normalize = options.normalizeKey ?? ((key: string) => normalizeIdOverrideKey(key, options.label))\n for (const [rawKey, value] of Object.entries(overrides)) {\n const key = normalize(rawKey)\n if (!key) continue\n store[target][key] = value\n }\n}\n\nfunction composeStore<T>(store: OverrideStore<T>): OverrideMap<T> {\n const modulesKeys = Object.keys(store.modules)\n const programmaticKeys = Object.keys(store.programmatic)\n if (modulesKeys.length === 0 && programmaticKeys.length === 0) {\n return EMPTY_OVERRIDE_MAP as OverrideMap<T>\n }\n return { ...store.modules, ...store.programmatic }\n}\n\nfunction applyArrayOverrides<T>(\n items: readonly T[] | undefined,\n overrides: Readonly<OverrideMap<T>>,\n options: {\n label: string\n getId: (value: T) => string | null\n isReplacement?: (value: unknown) => value is T\n },\n): { items: T[] | undefined; consumed: Set<string>; changed: boolean } {\n if (!items || Object.keys(overrides).length === 0) {\n return { items: items ? Array.from(items) : items, consumed: new Set(), changed: false }\n }\n\n const consumed = new Set<string>()\n const result: T[] = []\n let changed = false\n\n for (const item of items) {\n const id = options.getId(item)\n if (!id || !Object.prototype.hasOwnProperty.call(overrides, id)) {\n result.push(item)\n continue\n }\n consumed.add(id)\n changed = true\n const replacement = overrides[id]\n if (replacement === null) continue\n if (options.isReplacement && !options.isReplacement(replacement)) {\n logger.warn('Skipping malformed override \u2014 replacement has the wrong shape', { label: options.label, id })\n result.push(item)\n continue\n }\n const replacementId = options.getId(replacement)\n if (replacementId !== id) {\n logger.warn('Skipping malformed override \u2014 replacement id must match the override key', { label: options.label, id })\n result.push(item)\n continue\n }\n result.push(replacement)\n }\n\n return { items: result, consumed, changed }\n}\n\nfunction warnStaleOverrides(label: string, overrides: Readonly<Record<string, unknown>>, consumed: ReadonlySet<string>): void {\n for (const key of Object.keys(overrides)) {\n if (!consumed.has(key)) {\n logger.warn('Override did not match any registered entry \u2014 override skipped', { label, key })\n }\n }\n}\n\nfunction isObjectWithId(value: unknown): value is { id: string } {\n return !!value && typeof value === 'object' && typeof (value as { id?: unknown }).id === 'string'\n}\n\nfunction isModuleSubscriber(value: unknown): value is ModuleSubscriber {\n return isObjectWithId(value)\n && typeof (value as ModuleSubscriber).event === 'string'\n && typeof (value as ModuleSubscriber).handler === 'function'\n}\n\nfunction isModuleWorker(value: unknown): value is ModuleWorker {\n return isObjectWithId(value)\n && typeof (value as ModuleWorker).queue === 'string'\n && typeof (value as ModuleWorker).handler === 'function'\n}\n\nfunction isModuleCli(value: unknown): value is ModuleCli {\n return !!value\n && typeof value === 'object'\n && typeof (value as ModuleCli).command === 'string'\n && typeof (value as ModuleCli).run === 'function'\n}\n\nfunction isInjectionWidgetEntry(value: unknown): value is ModuleInjectionWidgetEntry {\n return !!value\n && typeof value === 'object'\n && typeof (value as ModuleInjectionWidgetEntry).key === 'string'\n && typeof (value as ModuleInjectionWidgetEntry).loader === 'function'\n}\n\nfunction isDashboardWidgetEntry(value: unknown): value is ModuleDashboardWidgetEntry {\n return !!value\n && typeof value === 'object'\n && typeof (value as ModuleDashboardWidgetEntry).key === 'string'\n && typeof (value as ModuleDashboardWidgetEntry).loader === 'function'\n}\n\nfunction isComponentOverrideValue(value: unknown): value is ComponentOverride | ComponentOverride[] {\n const items = Array.isArray(value) ? value : [value]\n return items.every((item) =>\n !!item\n && typeof item === 'object'\n && !!(item as ComponentOverride).target\n && typeof (item as ComponentOverride).target.componentId === 'string',\n )\n}\n\nfunction isNotificationType(value: unknown): value is NotificationTypeDefinition {\n return !!value && typeof value === 'object' && typeof (value as NotificationTypeDefinition).type === 'string'\n}\n\nfunction isNotificationHandler(value: unknown): value is NotificationHandler {\n return isObjectWithId(value) && typeof (value as NotificationHandler).handle === 'function'\n}\n\nfunction isApiInterceptor(value: unknown): value is ApiInterceptor {\n return isObjectWithId(value) && typeof (value as ApiInterceptor).targetRoute === 'string'\n}\n\nfunction isCommandInterceptor(value: unknown): value is CommandInterceptor {\n return isObjectWithId(value) && typeof (value as CommandInterceptor).targetCommand === 'string'\n}\n\nfunction isResponseEnricher(value: unknown): value is ResponseEnricher {\n return isObjectWithId(value)\n && typeof (value as ResponseEnricher).targetEntity === 'string'\n && typeof (value as ResponseEnricher).enrichOne === 'function'\n}\n\nfunction isPageRouteMiddleware(value: unknown): value is PageRouteMiddleware {\n return isObjectWithId(value) && typeof (value as PageRouteMiddleware).run === 'function'\n}\n\nfunction isEncryptionMap(value: unknown): value is ModuleEncryptionMap {\n return !!value\n && typeof value === 'object'\n && typeof (value as ModuleEncryptionMap).entityId === 'string'\n && Array.isArray((value as ModuleEncryptionMap).fields)\n}\n\nfunction getFeatureId(value: unknown): string | null {\n if (typeof value === 'string' && value.trim()) return value.trim()\n if (value && typeof value === 'object' && typeof (value as { id?: unknown }).id === 'string') {\n return (value as { id: string }).id\n }\n return null\n}\n\nconst VALID_HTTP_METHODS: readonly HttpMethod[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']\n\nconst programmaticApiRouteOverrides: ApiRouteOverridesMap = {}\nconst modulesConfigApiRouteOverrides: ApiRouteOverridesMap = {}\n\n/**\n * Normalize an override key to the canonical `'METHOD /api/path'` form.\n * Returns `null` if the key is malformed (missing method, unknown method,\n * empty path). Trailing slashes on the path are stripped.\n */\nfunction normalizeApiRouteOverrideKey(key: string): string | null {\n if (typeof key !== 'string') return null\n const trimmed = key.trim()\n if (!trimmed) return null\n const parts = trimmed.split(/\\s+/)\n if (parts.length < 2) return null\n const method = parts[0].toUpperCase() as HttpMethod\n if (!VALID_HTTP_METHODS.includes(method)) return null\n const rawPath = parts.slice(1).join(' ').trim()\n if (!rawPath) return null\n const withLead = rawPath.startsWith('/') ? rawPath : `/${rawPath}`\n const normalized = withLead.replace(/\\/+$/, '') || '/'\n return `${method} ${normalized}`\n}\n\nfunction normalizePageRouteOverrideKey(key: string): string | null {\n if (typeof key !== 'string') return null\n const trimmed = key.trim()\n if (!trimmed) return null\n if (trimmed.startsWith('backend:') || trimmed.startsWith('frontend:')) return trimmed\n const withLead = trimmed.startsWith('/') ? trimmed : `/${trimmed}`\n const stripped = withLead.replace(/\\/+$/, '') || '/'\n if (stripped === '/frontend') return 'frontend:/'\n if (stripped.startsWith('/frontend/')) return `frontend:/${stripped.slice('/frontend/'.length)}`\n if (stripped === '/backend' || stripped.startsWith('/backend/')) return `backend:${stripped}`\n return `frontend:${stripped}`\n}\n\n/**\n * Programmatic API: apply API-route overrides. Supersedes any matching\n * `modules.ts` inline overrides for the same key. Call before\n * `registerApiRouteManifests` (i.e. before generated `apiRoutes` lands in\n * the registry); calls after registration do not retro-actively update\n * the stored manifest.\n *\n * @example\n * applyApiRouteOverrides({\n * 'GET /api/example/items': null, // disable\n * 'POST /api/example/items': { handler: customHandler }, // replace\n * })\n */\nexport function applyApiRouteOverrides(overrides: ApiRouteOverridesMap): void {\n if (!overrides) return\n for (const [rawKey, value] of Object.entries(overrides)) {\n const key = normalizeApiRouteOverrideKey(rawKey)\n if (!key) {\n logger.warn('Skipping malformed routes.api key \u2014 expected \"METHOD /api/path\"', { key: rawKey })\n continue\n }\n programmaticApiRouteOverrides[key] = value\n }\n}\n\n/** @__internal Test-only hook \u2014 clear programmatic + modules.ts route override state. */\nexport function resetApiRouteOverridesForTests(): void {\n for (const key of Object.keys(programmaticApiRouteOverrides)) {\n delete programmaticApiRouteOverrides[key]\n }\n for (const key of Object.keys(modulesConfigApiRouteOverrides)) {\n delete modulesConfigApiRouteOverrides[key]\n }\n}\n\n/** @__internal Test-only hook \u2014 clear every per-domain override store. */\nexport function resetModuleContractOverridesForTests(): void {\n resetApiRouteOverridesForTests()\n clearStore(pageRouteOverrideStore)\n clearStore(subscriberOverrideStore)\n clearStore(workerOverrideStore)\n clearStore(cliOverrideStore)\n clearStore(injectionWidgetOverrideStore)\n clearStore(dashboardWidgetOverrideStore)\n clearStore(componentOverrideStore)\n clearStore(notificationTypeOverrideStore)\n clearStore(notificationHandlerOverrideStore)\n clearStore(apiInterceptorOverrideStore)\n clearStore(commandInterceptorOverrideStore)\n clearStore(responseEnricherOverrideStore)\n clearStore(pageGuardOverrideStore)\n clearStore(aclFeatureOverrideStore)\n clearStore(encryptionMapOverrideStore)\n clearStore(diOverrideStore)\n for (const key of Object.keys(setupOverridesByModule)) delete setupOverridesByModule[key]\n const navState = getNavOverrideState()\n navState.modules = null\n navState.programmatic = null\n}\n\n/**\n * Resolve the final API-route override map. Resolution order (lowest \u2192\n * highest precedence):\n *\n * 1. `modules.ts` inline (applied via the dispatcher).\n * 2. Programmatic (`applyApiRouteOverrides`).\n */\nexport function composeApiRouteOverrides(): ApiRouteOverridesMap {\n const modulesKeys = Object.keys(modulesConfigApiRouteOverrides)\n const programmaticKeys = Object.keys(programmaticApiRouteOverrides)\n if (modulesKeys.length === 0 && programmaticKeys.length === 0) {\n return EMPTY_OVERRIDE_MAP as ApiRouteOverridesMap\n }\n const out: ApiRouteOverridesMap = {}\n for (const k of modulesKeys) out[k] = modulesConfigApiRouteOverrides[k]\n for (const k of programmaticKeys) out[k] = programmaticApiRouteOverrides[k]\n return out\n}\n\nexport function applyPageRouteOverrides(overrides: PageRouteOverridesMap): void {\n applyStoreOverrides(pageRouteOverrideStore, 'programmatic', overrides as OverrideMap<PageRouteOverrideDefinition>, {\n label: 'routes.pages',\n normalizeKey: normalizePageRouteOverrideKey,\n })\n}\n\nexport function composePageRouteOverrides(): PageRouteOverridesMap {\n return composeStore(pageRouteOverrideStore) as PageRouteOverridesMap\n}\n\nexport function applySubscriberOverrides(overrides: SubscriberOverridesMap): void {\n applyStoreOverrides(subscriberOverrideStore, 'programmatic', overrides as OverrideMap<ModuleSubscriber>, { label: 'events.subscribers' })\n}\n\nexport function composeSubscriberOverrides(): SubscriberOverridesMap {\n return composeStore(subscriberOverrideStore) as SubscriberOverridesMap\n}\n\nexport function applyWorkerOverrides(overrides: WorkerOverridesMap): void {\n applyStoreOverrides(workerOverrideStore, 'programmatic', overrides as OverrideMap<ModuleWorker>, { label: 'workers' })\n}\n\nexport function composeWorkerOverrides(): WorkerOverridesMap {\n return composeStore(workerOverrideStore) as WorkerOverridesMap\n}\n\nexport function applyCliOverrides(overrides: CliOverridesMap): void {\n applyStoreOverrides(cliOverrideStore, 'programmatic', overrides as OverrideMap<ModuleCli>, { label: 'cli' })\n}\n\nexport function composeCliOverrides(): CliOverridesMap {\n return composeStore(cliOverrideStore) as CliOverridesMap\n}\n\nexport function applyInjectionWidgetOverrides(overrides: InjectionWidgetOverridesMap): void {\n applyStoreOverrides(injectionWidgetOverrideStore, 'programmatic', overrides as OverrideMap<ModuleInjectionWidgetEntry>, { label: 'widgets.injection' })\n}\n\nexport function composeInjectionWidgetOverrides(): InjectionWidgetOverridesMap {\n return composeStore(injectionWidgetOverrideStore) as InjectionWidgetOverridesMap\n}\n\nexport function applyDashboardWidgetOverrides(overrides: DashboardWidgetOverridesMap): void {\n applyStoreOverrides(dashboardWidgetOverrideStore, 'programmatic', overrides as OverrideMap<ModuleDashboardWidgetEntry>, { label: 'widgets.dashboard' })\n}\n\nexport function composeDashboardWidgetOverrides(): DashboardWidgetOverridesMap {\n return composeStore(dashboardWidgetOverrideStore) as DashboardWidgetOverridesMap\n}\n\nexport function applyComponentOverrides(overrides: ComponentOverridesMap): void {\n applyStoreOverrides(componentOverrideStore, 'programmatic', overrides as OverrideMap<ComponentOverride | ComponentOverride[]>, { label: 'widgets.components' })\n}\n\nexport function composeComponentOverrides(): ComponentOverridesMap {\n return composeStore(componentOverrideStore) as ComponentOverridesMap\n}\n\nexport function applyNotificationTypeOverrides(overrides: NotificationTypeOverridesMap): void {\n applyStoreOverrides(notificationTypeOverrideStore, 'programmatic', overrides as OverrideMap<NotificationTypeDefinition>, { label: 'notifications.types' })\n}\n\nexport function composeNotificationTypeOverrides(): NotificationTypeOverridesMap {\n return composeStore(notificationTypeOverrideStore) as NotificationTypeOverridesMap\n}\n\nexport function applyNotificationHandlerOverrides(overrides: NotificationHandlerOverridesMap): void {\n applyStoreOverrides(notificationHandlerOverrideStore, 'programmatic', overrides as OverrideMap<NotificationHandler>, { label: 'notifications.handlers' })\n}\n\nexport function composeNotificationHandlerOverrides(): NotificationHandlerOverridesMap {\n return composeStore(notificationHandlerOverrideStore) as NotificationHandlerOverridesMap\n}\n\nexport function applyApiInterceptorOverrides(overrides: ApiInterceptorOverridesMap): void {\n applyStoreOverrides(apiInterceptorOverrideStore, 'programmatic', overrides as OverrideMap<ApiInterceptor>, { label: 'interceptors' })\n}\n\nexport function composeApiInterceptorOverrides(): ApiInterceptorOverridesMap {\n return composeStore(apiInterceptorOverrideStore) as ApiInterceptorOverridesMap\n}\n\nexport function applyCommandInterceptorOverrides(overrides: CommandInterceptorOverridesMap): void {\n applyStoreOverrides(commandInterceptorOverrideStore, 'programmatic', overrides as OverrideMap<CommandInterceptor>, { label: 'commandInterceptors' })\n}\n\nexport function composeCommandInterceptorOverrides(): CommandInterceptorOverridesMap {\n return composeStore(commandInterceptorOverrideStore) as CommandInterceptorOverridesMap\n}\n\nexport function applyResponseEnricherOverrides(overrides: ResponseEnricherOverridesMap): void {\n applyStoreOverrides(responseEnricherOverrideStore, 'programmatic', overrides as OverrideMap<ResponseEnricher>, { label: 'enrichers' })\n}\n\nexport function composeResponseEnricherOverrides(): ResponseEnricherOverridesMap {\n return composeStore(responseEnricherOverrideStore) as ResponseEnricherOverridesMap\n}\n\nexport function applyPageGuardOverrides(overrides: PageGuardOverridesMap): void {\n applyStoreOverrides(pageGuardOverrideStore, 'programmatic', overrides as OverrideMap<PageRouteMiddleware>, { label: 'guards' })\n}\n\nexport function composePageGuardOverrides(): PageGuardOverridesMap {\n return composeStore(pageGuardOverrideStore) as PageGuardOverridesMap\n}\n\nexport function applyAclFeatureOverrides(overrides: AclFeatureOverridesMap): void {\n applyStoreOverrides(aclFeatureOverrideStore, 'programmatic', overrides as OverrideMap<Exclude<AclFeatureOverride, null>>, { label: 'acl.features' })\n}\n\nexport function composeAclFeatureOverrides(): AclFeatureOverridesMap {\n return composeStore(aclFeatureOverrideStore) as AclFeatureOverridesMap\n}\n\nexport function applyEncryptionMapOverrides(overrides: EncryptionMapOverridesMap): void {\n applyStoreOverrides(encryptionMapOverrideStore, 'programmatic', overrides as OverrideMap<ModuleEncryptionMap>, { label: 'encryption.maps' })\n}\n\nexport function composeEncryptionMapOverrides(): EncryptionMapOverridesMap {\n return composeStore(encryptionMapOverrideStore) as EncryptionMapOverridesMap\n}\n\nexport function applyDiOverrides(overrides: DiOverridesMap): void {\n applyStoreOverrides(diOverrideStore, 'programmatic', overrides as OverrideMap<Exclude<DiBindingOverride, null>>, { label: 'di' })\n}\n\nexport function composeDiOverrides(): DiOverridesMap {\n return composeStore(diOverrideStore) as DiOverridesMap\n}\n\n/**\n * Apply an API-route override map to a list of registered manifest entries.\n * Returns a NEW array \u2014 never mutates input.\n *\n * Behavior:\n * - For each entry, walk every method in `entry.methods`.\n * - If the override key `'METHOD path'` is `null`, drop that method from\n * the entry's `methods` array.\n * - If the override key is a definition, wrap `entry.load()` to return a\n * module that exposes the override handler at `module[METHOD]` (top-level)\n * and the override metadata at `module.metadata[METHOD]`.\n * - If every method on the entry is disabled, the entry is dropped.\n * - Overrides naming a key that does not match any entry log a single\n * warning so an operator notices a stale override.\n */\nexport function applyApiOverridesToManifests<T extends ApiRouteManifestEntry>(\n routes: readonly T[],\n overrides: Readonly<ApiRouteOverridesMap>,\n): T[] {\n if (!routes || routes.length === 0) return Array.from(routes)\n const overrideKeys = Object.keys(overrides)\n if (overrideKeys.length === 0) return Array.from(routes)\n\n const consumedKeys = new Set<string>()\n const result: T[] = []\n\n for (const entry of routes) {\n const path = entry.path\n const remainingMethods: HttpMethod[] = []\n const methodOverrides = new Map<HttpMethod, ApiRouteOverrideDefinition>()\n\n for (const method of entry.methods) {\n const manifestKey = `${method} ${path}`\n const publicKey = path.startsWith('/api/')\n ? manifestKey\n : `${method} /api${path === '/' ? '' : path}`\n const key = Object.prototype.hasOwnProperty.call(overrides, manifestKey)\n ? manifestKey\n : Object.prototype.hasOwnProperty.call(overrides, publicKey)\n ? publicKey\n : null\n if (!key) {\n remainingMethods.push(method)\n continue\n }\n consumedKeys.add(key)\n const value = overrides[key]\n if (value === null) continue\n if (value && typeof value === 'object' && typeof value.handler === 'function') {\n methodOverrides.set(method, value)\n remainingMethods.push(method)\n } else {\n logger.warn('Skipping malformed routes.api override \u2014 expected { handler, metadata? } or null', { key })\n remainingMethods.push(method)\n }\n }\n\n if (remainingMethods.length === 0) continue\n\n const methodsChanged = remainingMethods.length !== entry.methods.length\n const hasReplacements = methodOverrides.size > 0\n\n if (!methodsChanged && !hasReplacements) {\n result.push(entry)\n continue\n }\n\n const originalLoad = entry.load\n const wrappedLoad: T['load'] = hasReplacements\n ? async () => {\n const original = await originalLoad()\n const out: Record<string, unknown> = { ...original }\n const baseMetadata = original && typeof original === 'object' && original.metadata !== undefined\n ? original.metadata\n : null\n const mergedMetadata: Record<string, unknown> = baseMetadata && typeof baseMetadata === 'object'\n ? { ...(baseMetadata as Record<string, unknown>) }\n : {}\n for (const [method, def] of methodOverrides) {\n out[method] = def.handler\n if (def.metadata !== undefined) mergedMetadata[method] = def.metadata\n }\n if (Object.keys(mergedMetadata).length > 0) out.metadata = mergedMetadata\n return out\n }\n : originalLoad\n\n result.push({ ...entry, methods: remainingMethods, load: wrappedLoad })\n }\n\n for (const key of overrideKeys) {\n if (!consumedKeys.has(key)) {\n logger.warn('routes.api override did not match any registered API route \u2014 override skipped', { key })\n }\n }\n\n return result\n}\n\nexport function applyPageOverridesToManifests<T extends BackendRouteManifestEntry | FrontendRouteManifestEntry>(\n routes: readonly T[],\n overrides: Readonly<PageRouteOverridesMap>,\n kind: 'backend' | 'frontend',\n): T[] {\n if (!routes || routes.length === 0) return Array.from(routes)\n const normalizedOverrides: PageRouteOverridesMap = {}\n for (const [rawKey, value] of Object.entries(overrides)) {\n const key = normalizePageRouteOverrideKey(rawKey)\n if (!key) {\n logger.warn('Skipping malformed routes.pages key \u2014 expected \"/backend/path\" or \"/frontend/path\"', { key: rawKey })\n continue\n }\n normalizedOverrides[key] = value\n }\n const overrideKeys = Object.keys(normalizedOverrides).filter((key) => key.startsWith(`${kind}:`))\n if (overrideKeys.length === 0) return Array.from(routes)\n\n const consumed = new Set<string>()\n const result: T[] = []\n\n for (const entry of routes) {\n const path = entry.pattern ?? entry.path ?? '/'\n const key = `${kind}:${path.replace(/\\/+$/, '') || '/'}`\n if (!Object.prototype.hasOwnProperty.call(normalizedOverrides, key)) {\n result.push(entry)\n continue\n }\n\n consumed.add(key)\n const override = normalizedOverrides[key]\n if (override === null) continue\n if (!override || typeof override !== 'object') {\n logger.warn('Skipping malformed routes.pages override \u2014 expected { load?, Component?, metadata? } or null', { key })\n result.push(entry)\n continue\n }\n\n const hasLoad = typeof override.load === 'function'\n const hasComponent = typeof override.Component === 'function'\n if (!hasLoad && !hasComponent && override.metadata === undefined) {\n logger.warn('Skipping malformed routes.pages override \u2014 expected a loader, component, metadata, or null', { key })\n result.push(entry)\n continue\n }\n\n const metadata = override.metadata && typeof override.metadata === 'object'\n ? override.metadata\n : {}\n const load = hasLoad\n ? override.load!\n : hasComponent\n ? async () => override.Component!\n : entry.load\n\n result.push({ ...entry, ...metadata, load })\n }\n\n warnStaleOverrides('routes.pages', Object.fromEntries(\n overrideKeys.map((key) => [key, normalizedOverrides[key]]),\n ), consumed)\n return result\n}\n\nfunction applyEntryListOverrides<TEntry extends { moduleId: string }, TValue>(\n entries: readonly TEntry[] | undefined,\n overrides: Readonly<OverrideMap<TValue>>,\n options: {\n listKey: keyof TEntry\n label: string\n getId: (value: TValue) => string | null\n isReplacement: (value: unknown) => value is TValue\n },\n): TEntry[] | undefined {\n // Fast path: when no overrides are registered, return the input directly.\n // All known callers iterate the result (.forEach/.flatMap/.map/storage),\n // never mutate it. This avoids a per-request Array.from copy on hot paths\n // like executePageMiddleware \u2192 applyPageGuardOverridesToEntries.\n if (!entries || Object.keys(overrides).length === 0) return entries as TEntry[] | undefined\n const consumed = new Set<string>()\n let changed = false\n const result = entries.map((entry) => {\n const list = entry[options.listKey]\n if (!Array.isArray(list)) return entry\n const applied = applyArrayOverrides(list as TValue[], overrides, {\n label: options.label,\n getId: options.getId,\n isReplacement: options.isReplacement,\n })\n for (const key of applied.consumed) consumed.add(key)\n if (!applied.changed) return entry\n changed = true\n return { ...entry, [options.listKey]: applied.items ?? [] }\n })\n warnStaleOverrides(options.label, overrides, consumed)\n return changed ? result : Array.from(entries)\n}\n\nexport function applyInjectionWidgetOverridesToEntries(\n entries: readonly ModuleInjectionWidgetEntry[],\n overrides: Readonly<InjectionWidgetOverridesMap> = composeInjectionWidgetOverrides(),\n): ModuleInjectionWidgetEntry[] {\n const applied = applyArrayOverrides(entries, overrides as OverrideMap<ModuleInjectionWidgetEntry>, {\n label: 'widgets.injection',\n getId: (entry) => entry.key,\n isReplacement: isInjectionWidgetEntry,\n })\n warnStaleOverrides('widgets.injection', overrides, applied.consumed)\n return applied.items ?? []\n}\n\nexport function applyDashboardWidgetOverridesToEntries(\n entries: readonly ModuleDashboardWidgetEntry[],\n overrides: Readonly<DashboardWidgetOverridesMap> = composeDashboardWidgetOverrides(),\n): ModuleDashboardWidgetEntry[] {\n const applied = applyArrayOverrides(entries, overrides as OverrideMap<ModuleDashboardWidgetEntry>, {\n label: 'widgets.dashboard',\n getId: (entry) => entry.key,\n isReplacement: isDashboardWidgetEntry,\n })\n warnStaleOverrides('widgets.dashboard', overrides, applied.consumed)\n return applied.items ?? []\n}\n\nexport function applyWorkerOverridesToDescriptors<T extends { id: string; queue: string; concurrency: number; handler: unknown }>(\n entries: readonly T[],\n overrides: Readonly<WorkerOverridesMap> = composeWorkerOverrides(),\n): T[] {\n const applied = applyArrayOverrides(entries, overrides as OverrideMap<T>, {\n label: 'workers',\n getId: (entry) => entry.id,\n isReplacement: (value): value is T =>\n !!value\n && typeof value === 'object'\n && typeof (value as { id?: unknown }).id === 'string'\n && typeof (value as { queue?: unknown }).queue === 'string'\n && typeof (value as { concurrency?: unknown }).concurrency === 'number'\n && typeof (value as { handler?: unknown }).handler === 'function',\n })\n warnStaleOverrides('workers', overrides, applied.consumed)\n return applied.items ?? []\n}\n\nexport function applyInjectionWidgetOverridesToTables(\n tables: readonly { moduleId: string; table: ModuleInjectionTable }[],\n overrides: Readonly<InjectionWidgetOverridesMap> = composeInjectionWidgetOverrides(),\n): Array<{ moduleId: string; table: ModuleInjectionTable }> {\n const disabled = new Set(Object.entries(overrides).filter(([, value]) => value === null).map(([key]) => key))\n if (disabled.size === 0) return Array.from(tables)\n\n const filterSlot = (slot: unknown): unknown => {\n if (typeof slot === 'string') return disabled.has(slot) ? null : slot\n if (slot && typeof slot === 'object') {\n const widgetId = (slot as { widgetId?: unknown }).widgetId\n return typeof widgetId === 'string' && disabled.has(widgetId) ? null : slot\n }\n return slot\n }\n\n return tables.map((entry) => {\n const nextTable: ModuleInjectionTable = {}\n for (const [spotId, rawSlot] of Object.entries(entry.table)) {\n const filtered = Array.isArray(rawSlot)\n ? rawSlot.map(filterSlot).filter((slot): slot is NonNullable<typeof slot> => slot !== null)\n : filterSlot(rawSlot)\n if (Array.isArray(filtered)) {\n if (filtered.length > 0) nextTable[spotId] = filtered as ModuleInjectionTable[string]\n } else if (filtered !== null) {\n nextTable[spotId] = filtered as ModuleInjectionTable[string]\n }\n }\n return { ...entry, table: nextTable }\n })\n}\n\nexport function applyComponentOverridesToEntries(\n entries: readonly { moduleId: string; componentOverrides: ComponentOverride[] }[],\n overrides: Readonly<ComponentOverridesMap> = composeComponentOverrides(),\n): Array<{ moduleId: string; componentOverrides: ComponentOverride[] }> {\n const overrideKeys = Object.keys(overrides)\n if (overrideKeys.length === 0) return Array.from(entries)\n const consumed = new Set<string>()\n const additions: ComponentOverride[] = []\n const result = entries.map((entry) => {\n const next = entry.componentOverrides.filter((override) => {\n const id = override.target.componentId\n if (!Object.prototype.hasOwnProperty.call(overrides, id)) return true\n consumed.add(id)\n return false\n })\n return { ...entry, componentOverrides: next }\n })\n for (const key of overrideKeys) {\n const value = overrides[key]\n if (value === null) continue\n if (!isComponentOverrideValue(value)) {\n logger.warn('Skipping malformed widgets.components override \u2014 expected ComponentOverride, ComponentOverride[], or null', { key })\n continue\n }\n const values = Array.isArray(value) ? value : [value]\n for (const override of values) {\n if (override.target.componentId !== key) {\n logger.warn('Skipping malformed widgets.components override \u2014 target.componentId must match the override key', { key })\n continue\n }\n additions.push(override)\n consumed.add(key)\n }\n }\n if (additions.length > 0) {\n result.push({ moduleId: 'overrides', componentOverrides: additions })\n }\n warnStaleOverrides('widgets.components', overrides, consumed)\n return result\n}\n\nexport function applyNotificationTypeOverridesToEntries(\n entries: readonly { moduleId: string; types: NotificationTypeDefinition[] }[],\n overrides: Readonly<NotificationTypeOverridesMap> = composeNotificationTypeOverrides(),\n): Array<{ moduleId: string; types: NotificationTypeDefinition[] }> {\n return applyEntryListOverrides(entries, overrides as OverrideMap<NotificationTypeDefinition>, {\n listKey: 'types',\n label: 'notifications.types',\n getId: (entry) => entry.type,\n isReplacement: isNotificationType,\n }) ?? []\n}\n\nexport function applyNotificationHandlerOverridesToEntries(\n entries: readonly { moduleId: string; handlers: NotificationHandler[] }[],\n overrides: Readonly<NotificationHandlerOverridesMap> = composeNotificationHandlerOverrides(),\n): Array<{ moduleId: string; handlers: NotificationHandler[] }> {\n return applyEntryListOverrides(entries, overrides as OverrideMap<NotificationHandler>, {\n listKey: 'handlers',\n label: 'notifications.handlers',\n getId: (entry) => entry.id,\n isReplacement: isNotificationHandler,\n }) ?? []\n}\n\nexport function applyApiInterceptorOverridesToEntries(\n entries: readonly { moduleId: string; interceptors: ApiInterceptor[] }[],\n overrides: Readonly<ApiInterceptorOverridesMap> = composeApiInterceptorOverrides(),\n): Array<{ moduleId: string; interceptors: ApiInterceptor[] }> {\n return applyEntryListOverrides(entries, overrides as OverrideMap<ApiInterceptor>, {\n listKey: 'interceptors',\n label: 'interceptors',\n getId: (entry) => entry.id,\n isReplacement: isApiInterceptor,\n }) ?? []\n}\n\nexport function applyCommandInterceptorOverridesToEntries(\n entries: readonly { moduleId: string; interceptors: CommandInterceptor[] }[],\n overrides: Readonly<CommandInterceptorOverridesMap> = composeCommandInterceptorOverrides(),\n): Array<{ moduleId: string; interceptors: CommandInterceptor[] }> {\n return applyEntryListOverrides(entries, overrides as OverrideMap<CommandInterceptor>, {\n listKey: 'interceptors',\n label: 'commandInterceptors',\n getId: (entry) => entry.id,\n isReplacement: isCommandInterceptor,\n }) ?? []\n}\n\nexport function applyResponseEnricherOverridesToEntries(\n entries: readonly { moduleId: string; enrichers: ResponseEnricher[] }[],\n overrides: Readonly<ResponseEnricherOverridesMap> = composeResponseEnricherOverrides(),\n): Array<{ moduleId: string; enrichers: ResponseEnricher[] }> {\n return applyEntryListOverrides(entries, overrides as OverrideMap<ResponseEnricher>, {\n listKey: 'enrichers',\n label: 'enrichers',\n getId: (entry) => entry.id,\n isReplacement: isResponseEnricher,\n }) ?? []\n}\n\nexport function applyPageGuardOverridesToEntries(\n entries: readonly PageMiddlewareRegistryEntry[],\n overrides: Readonly<PageGuardOverridesMap> = composePageGuardOverrides(),\n): PageMiddlewareRegistryEntry[] {\n return applyEntryListOverrides(entries, overrides as OverrideMap<PageRouteMiddleware>, {\n listKey: 'middleware',\n label: 'guards',\n getId: (entry) => entry.id,\n isReplacement: isPageRouteMiddleware,\n }) ?? []\n}\n\nfunction applySetupOverride(setup: ModuleSetupConfig | undefined, override: SetupOverridesShape | undefined): ModuleSetupConfig | undefined {\n if (!override) return setup\n const next: ModuleSetupConfig = { ...(setup ?? {}) }\n if (override.defaultRoleFeatures) {\n next.defaultRoleFeatures = Object.fromEntries(\n Object.entries(override.defaultRoleFeatures).map(([role, features]) => [role, Array.from(features)]),\n )\n }\n if (override.defaultCustomerRoleFeatures) {\n next.defaultCustomerRoleFeatures = Object.fromEntries(\n Object.entries(override.defaultCustomerRoleFeatures).map(([role, features]) => [role, Array.from(features)]),\n )\n }\n if (override.seedDefaults === false) delete next.seedDefaults\n if (override.seedExamples === false) delete next.seedExamples\n if (override.onTenantCreated === false) delete next.onTenantCreated\n return next\n}\n\nexport function applyModuleOverridesToModules(modules: readonly Module[]): Module[] {\n const subscriberOverrides = composeSubscriberOverrides()\n const workerOverrides = composeWorkerOverrides()\n const cliOverrides = composeCliOverrides()\n const aclOverrides = composeAclFeatureOverrides()\n const encryptionOverrides = composeEncryptionMapOverrides()\n const hasSetupOverrides = Object.keys(setupOverridesByModule).length > 0\n const hasAny =\n Object.keys(subscriberOverrides).length > 0\n || Object.keys(workerOverrides).length > 0\n || Object.keys(cliOverrides).length > 0\n || Object.keys(aclOverrides).length > 0\n || Object.keys(encryptionOverrides).length > 0\n || hasSetupOverrides\n\n if (!hasAny) return modules as Module[]\n\n const subscriberConsumed = new Set<string>()\n const workerConsumed = new Set<string>()\n const cliConsumed = new Set<string>()\n const aclConsumed = new Set<string>()\n const encryptionConsumed = new Set<string>()\n\n const result = modules.map((module) => {\n let next = module\n\n const subscribers = applyArrayOverrides(module.subscribers, subscriberOverrides as OverrideMap<ModuleSubscriber>, {\n label: 'events.subscribers',\n getId: (entry) => entry.id,\n isReplacement: isModuleSubscriber,\n })\n for (const key of subscribers.consumed) subscriberConsumed.add(key)\n if (subscribers.changed) next = { ...next, subscribers: subscribers.items }\n\n const workers = applyArrayOverrides(module.workers, workerOverrides as OverrideMap<ModuleWorker>, {\n label: 'workers',\n getId: (entry) => entry.id,\n isReplacement: isModuleWorker,\n })\n for (const key of workers.consumed) workerConsumed.add(key)\n if (workers.changed) next = { ...next, workers: workers.items }\n\n const cli = applyArrayOverrides(module.cli, cliOverrides as OverrideMap<ModuleCli>, {\n label: 'cli',\n getId: (entry) => entry.command,\n isReplacement: isModuleCli,\n })\n for (const key of cli.consumed) cliConsumed.add(key)\n if (cli.changed) next = { ...next, cli: cli.items }\n\n const features = applyArrayOverrides(module.features, aclOverrides as OverrideMap<NonNullable<Module['features']>[number]>, {\n label: 'acl.features',\n getId: getFeatureId,\n isReplacement: (value): value is NonNullable<Module['features']>[number] => getFeatureId(value) !== null,\n })\n for (const key of features.consumed) aclConsumed.add(key)\n if (features.changed) next = { ...next, features: features.items }\n\n const maps = applyArrayOverrides(module.defaultEncryptionMaps, encryptionOverrides as OverrideMap<ModuleEncryptionMap>, {\n label: 'encryption.maps',\n getId: (entry) => entry.entityId,\n isReplacement: isEncryptionMap,\n })\n for (const key of maps.consumed) encryptionConsumed.add(key)\n if (maps.changed) next = { ...next, defaultEncryptionMaps: maps.items }\n\n const setupOverride = setupOverridesByModule[module.id]\n if (setupOverride) {\n next = { ...next, setup: applySetupOverride(module.setup, setupOverride) }\n }\n\n return next\n })\n\n warnStaleOverrides('events.subscribers', subscriberOverrides, subscriberConsumed)\n warnStaleOverrides('workers', workerOverrides, workerConsumed)\n warnStaleOverrides('cli', cliOverrides, cliConsumed)\n warnStaleOverrides('acl.features', aclOverrides, aclConsumed)\n warnStaleOverrides('encryption.maps', encryptionOverrides, encryptionConsumed)\n\n return result\n}\n\nexport function applyDiOverridesToContainer(container: {\n register: (registrations: Record<string, unknown>) => unknown\n unregister?: (name: string) => unknown\n registrations?: Record<string, unknown>\n}): void {\n const overrides = composeDiOverrides()\n for (const [key, value] of Object.entries(overrides)) {\n if (value === null) {\n if (typeof container.unregister === 'function') {\n container.unregister(key)\n } else if (container.registrations && key in container.registrations) {\n delete container.registrations[key]\n }\n continue\n }\n if (value && typeof value === 'object' && typeof (value as DiBindingOverrideDefinition).register === 'function') {\n ;(value as DiBindingOverrideDefinition).register(container, key)\n continue\n }\n container.register({ [key]: value })\n }\n}\n\n/**\n * Dispatcher applier for the `'routes'` domain. Buckets every entry's\n * `overrides.routes.api` and `overrides.routes.pages` into the\n * `modules.ts` tier.\n */\nfunction routesOverridesApplier(\n entries: ReadonlyArray<ModuleOverrideEntry<RoutesOverridesShape>>,\n): void {\n for (const entry of entries) {\n const shape = entry.overrides\n if (!shape || typeof shape !== 'object') continue\n const api = shape.api\n if (api && typeof api === 'object') {\n for (const [rawKey, value] of Object.entries(api)) {\n const key = normalizeApiRouteOverrideKey(rawKey)\n if (!key) {\n logger.warn('Skipping malformed routes.api key \u2014 expected \"METHOD /api/path\"', { key: rawKey })\n continue\n }\n modulesConfigApiRouteOverrides[key] = value as ApiRouteOverride\n }\n }\n const pages = shape.pages\n if (pages && typeof pages === 'object' && Object.keys(pages).length > 0) {\n applyStoreOverrides(pageRouteOverrideStore, 'modules', pages as OverrideMap<PageRouteOverrideDefinition>, {\n label: 'routes.pages',\n normalizeKey: normalizePageRouteOverrideKey,\n })\n }\n }\n}\n\nfunction eventsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<EventsOverridesShape>>): void {\n for (const entry of entries) {\n const subscribers = entry.overrides?.subscribers\n applyStoreOverrides(subscriberOverrideStore, 'modules', subscribers as OverrideMap<ModuleSubscriber>, { label: 'events.subscribers' })\n }\n}\n\nfunction workersOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<WorkerOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(workerOverrideStore, 'modules', entry.overrides as OverrideMap<ModuleWorker>, { label: 'workers' })\n }\n}\n\nfunction widgetsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<WidgetsOverridesShape>>): void {\n for (const entry of entries) {\n applyStoreOverrides(injectionWidgetOverrideStore, 'modules', entry.overrides?.injection as OverrideMap<ModuleInjectionWidgetEntry>, { label: 'widgets.injection' })\n applyStoreOverrides(componentOverrideStore, 'modules', entry.overrides?.components as OverrideMap<ComponentOverride | ComponentOverride[]>, { label: 'widgets.components' })\n applyStoreOverrides(dashboardWidgetOverrideStore, 'modules', entry.overrides?.dashboard as OverrideMap<ModuleDashboardWidgetEntry>, { label: 'widgets.dashboard' })\n }\n}\n\nfunction notificationsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<NotificationsOverridesShape>>): void {\n for (const entry of entries) {\n applyStoreOverrides(notificationTypeOverrideStore, 'modules', entry.overrides?.types as OverrideMap<NotificationTypeDefinition>, { label: 'notifications.types' })\n applyStoreOverrides(notificationHandlerOverrideStore, 'modules', entry.overrides?.handlers as OverrideMap<NotificationHandler>, { label: 'notifications.handlers' })\n }\n}\n\nfunction interceptorsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<ApiInterceptorOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(apiInterceptorOverrideStore, 'modules', entry.overrides as OverrideMap<ApiInterceptor>, { label: 'interceptors' })\n }\n}\n\nfunction commandInterceptorsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<CommandInterceptorOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(commandInterceptorOverrideStore, 'modules', entry.overrides as OverrideMap<CommandInterceptor>, { label: 'commandInterceptors' })\n }\n}\n\nfunction enrichersOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<ResponseEnricherOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(responseEnricherOverrideStore, 'modules', entry.overrides as OverrideMap<ResponseEnricher>, { label: 'enrichers' })\n }\n}\n\nfunction guardsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<PageGuardOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(pageGuardOverrideStore, 'modules', entry.overrides as OverrideMap<PageRouteMiddleware>, { label: 'guards' })\n }\n}\n\nfunction cliOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<CliOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(cliOverrideStore, 'modules', entry.overrides as OverrideMap<ModuleCli>, { label: 'cli' })\n }\n}\n\nfunction setupOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<SetupOverridesShape>>): void {\n for (const entry of entries) {\n if (!entry.overrides || typeof entry.overrides !== 'object') continue\n setupOverridesByModule[entry.moduleId] = entry.overrides\n }\n}\n\nfunction aclOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<AclOverridesShape>>): void {\n for (const entry of entries) {\n applyStoreOverrides(aclFeatureOverrideStore, 'modules', entry.overrides?.features as OverrideMap<Exclude<AclFeatureOverride, null>>, { label: 'acl.features' })\n }\n}\n\nfunction diOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<DiOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(diOverrideStore, 'modules', entry.overrides as OverrideMap<Exclude<DiBindingOverride, null>>, { label: 'di' })\n }\n}\n\nfunction encryptionOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<EncryptionOverridesShape>>): void {\n for (const entry of entries) {\n applyStoreOverrides(encryptionMapOverrideStore, 'modules', entry.overrides?.maps as OverrideMap<ModuleEncryptionMap>, { label: 'encryption.maps' })\n }\n}\n\nfunction navOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<NavOverridesShape>>): void {\n const state = getNavOverrideState()\n for (const entry of entries) {\n const groupOrder = normalizeNavGroupOrder(entry.overrides?.groupOrder)\n if (!groupOrder) continue\n if (state.modules && state.modules.moduleId !== entry.moduleId) {\n logger.warn('nav.groupOrder declared by more than one module \u2014 the later one wins', {\n previousModuleId: state.modules.moduleId,\n moduleId: entry.moduleId,\n hint: 'Sidebar group ordering is a single app-wide decision; declare it on one module entry.',\n })\n }\n state.modules = { moduleId: entry.moduleId, groupOrder }\n }\n}\n\nfunction registerBuiltInModuleOverrideAppliers(): void {\n registerModuleOverrideApplier<NavOverridesShape>('nav', navOverridesApplier)\n registerModuleOverrideApplier<RoutesOverridesShape>('routes', routesOverridesApplier)\n registerModuleOverrideApplier<EventsOverridesShape>('events', eventsOverridesApplier)\n registerModuleOverrideApplier<WorkerOverridesMap>('workers', workersOverridesApplier)\n registerModuleOverrideApplier<WidgetsOverridesShape>('widgets', widgetsOverridesApplier)\n registerModuleOverrideApplier<NotificationsOverridesShape>('notifications', notificationsOverridesApplier)\n registerModuleOverrideApplier<ApiInterceptorOverridesMap>('interceptors', interceptorsOverridesApplier)\n registerModuleOverrideApplier<CommandInterceptorOverridesMap>('commandInterceptors', commandInterceptorsOverridesApplier)\n registerModuleOverrideApplier<ResponseEnricherOverridesMap>('enrichers', enrichersOverridesApplier)\n registerModuleOverrideApplier<PageGuardOverridesMap>('guards', guardsOverridesApplier)\n registerModuleOverrideApplier<CliOverridesMap>('cli', cliOverridesApplier)\n registerModuleOverrideApplier<SetupOverridesShape>('setup', setupOverridesApplier)\n registerModuleOverrideApplier<AclOverridesShape>('acl', aclOverridesApplier)\n registerModuleOverrideApplier<DiOverridesMap>('di', diOverridesApplier)\n registerModuleOverrideApplier<EncryptionOverridesShape>('encryption', encryptionOverridesApplier)\n}\n\nregisterBuiltInModuleOverrideAppliers()\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Unified `modules.ts` override surface \u2014 one place for downstream apps to\n * replace or disable any contract a module presents.\n *\n * Spec: `.ai/specs/implemented/2026-05-04-modules-ts-unified-overrides.md`\n *\n * Each `ModuleEntry` in `apps/<app>/src/modules.ts` may carry an\n * `overrides` field whose sub-keys address one domain at a time:\n *\n * {\n * id: 'example',\n * from: '@app',\n * overrides: {\n * ai: { agents: {...}, tools: {...} }, // Phase 1 \u2014 wired\n * routes: { api: {...}, pages: {...} }, // Phase 2/3 \u2014 wired\n * events: { subscribers: {...} }, // Phase 4 \u2014 wired\n * workers: {...}, // Phase 5 \u2014 wired\n * ...\n * },\n * }\n *\n * The umbrella shape is the union of every per-domain sub-shape. Per-\n * domain runtime hooks own their composers and apply the override map\n * against their registry. During the rollout the dispatcher emitted a\n * one-shot warning for unwired domains; all domains in this umbrella are\n * now wired, so warnings only indicate a missing custom applier in tests\n * or future domain additions.\n *\n * Resolution order across all domains (highest precedence first):\n *\n * 1. Programmatic \u2014 direct calls into the per-domain `apply*Overrides()` API.\n * 2. `modules.ts` inline \u2014 `entry.overrides.<domain>` here.\n * 3. File-based \u2014 overrides exported from a contributing module's own files.\n * 4. Base \u2014 the module's own registrations.\n *\n * `null` always means \"disable\"; a definition replaces.\n */\n\n// ---------------------------------------------------------------------------\n// Domain sub-shapes\n// ---------------------------------------------------------------------------\n\n/**\n * AI domain \u2014 agents and tools. Re-exports the canonical maps from\n * `@open-mercato/ai-assistant` so consumers do not need to import that\n * package directly when they only want to declare overrides.\n *\n * Imported lazily as `unknown` here because `@open-mercato/shared` must\n * NOT take a runtime dependency on `@open-mercato/ai-assistant` (the\n * dependency direction is the other way around). Apps that author\n * `entry.overrides.ai` should import the strongly-typed\n * `AiAgentOverridesMap` / `AiToolOverridesMap` from `@open-mercato/ai-assistant`\n * directly \u2014 TypeScript structurally compatible types make the loose\n * shape here a no-op annotation cost.\n */\nexport interface AiOverridesShape {\n agents?: Record<string, unknown>\n tools?: Record<string, unknown>\n extensions?: unknown[]\n}\n\n\ntype LooseOverrideMap = Record<string, unknown>\n\n/**\n * Phase 2 (api) / Phase 3 (pages).\n *\n * The `api` sub-shape is keyed by `'METHOD /api/path'` and accepts either\n * a replacement definition (`{ handler, metadata? }`) or `null` to disable.\n * See {@link ApiRouteOverridesMap} for the strongly-typed alias and\n * {@link applyApiOverridesToManifests} for the runtime apply step.\n *\n * The `pages` sub-shape is keyed by `'/backend/path'` or\n * `'/frontend/path'`; `null` disables the page and a definition replaces\n * its loader and/or metadata.\n */\nexport interface RoutesOverridesShape {\n api?: ApiRouteOverridesMap | LooseOverrideMap\n pages?: PageRouteOverridesMap | LooseOverrideMap\n}\n\n/** Phase 4 \u2014 event subscribers. */\nexport interface EventsOverridesShape {\n subscribers?: SubscriberOverridesMap | LooseOverrideMap\n}\n\n/** Phase 6/7/8 \u2014 widget injection, component handles, dashboard widgets. */\nexport interface WidgetsOverridesShape {\n injection?: InjectionWidgetOverridesMap | LooseOverrideMap\n components?: ComponentOverridesMap | LooseOverrideMap\n dashboard?: DashboardWidgetOverridesMap | LooseOverrideMap\n}\n\n/** Phase 9 \u2014 notification types + handlers. */\nexport interface NotificationsOverridesShape {\n types?: NotificationTypeOverridesMap | LooseOverrideMap\n handlers?: NotificationHandlerOverridesMap | LooseOverrideMap\n}\n\n/** Phase 15 \u2014 setup lifecycle hooks. */\nexport interface SetupOverridesShape {\n defaultRoleFeatures?: Record<string, readonly string[]>\n defaultCustomerRoleFeatures?: Record<string, readonly string[]>\n seedDefaults?: false\n seedExamples?: false\n onTenantCreated?: false\n}\n\n/** Phase 16 \u2014 ACL features (per-feature override). */\nexport interface AclOverridesShape {\n features?: AclFeatureOverridesMap | LooseOverrideMap\n}\n\n/** Phase 18 \u2014 encryption maps per entity id. */\nexport interface EncryptionOverridesShape {\n maps?: EncryptionMapOverridesMap | LooseOverrideMap\n}\n\n/**\n * Backend navigation ordering.\n *\n * `groupOrder` **prepends** sidebar nav group ids: the ids listed here rank ahead of every other\n * group, in the order given, and any group not named keeps the ordering it has today. Prepending\n * rather than replacing means an app that only cares about its own group lists that one id, instead of\n * having to enumerate every shipped group and accidentally demoting the ones it forgot.\n *\n * This is a *default*, applied beneath both role and user sidebar preferences \u2014 an operator's own\n * arrangement still wins.\n */\nexport interface NavOverridesShape {\n groupOrder?: string[]\n}\n\n/**\n * Umbrella shape for `entry.overrides`. Every key is optional; a\n * downstream app sets only the domains it cares about.\n */\nexport interface ModuleOverrides {\n ai?: AiOverridesShape\n routes?: RoutesOverridesShape\n events?: EventsOverridesShape\n workers?: WorkerOverridesMap | LooseOverrideMap\n widgets?: WidgetsOverridesShape\n notifications?: NotificationsOverridesShape\n interceptors?: ApiInterceptorOverridesMap | LooseOverrideMap\n commandInterceptors?: CommandInterceptorOverridesMap | LooseOverrideMap\n enrichers?: ResponseEnricherOverridesMap | LooseOverrideMap\n guards?: PageGuardOverridesMap | LooseOverrideMap\n cli?: CliOverridesMap | LooseOverrideMap\n setup?: SetupOverridesShape\n acl?: AclOverridesShape\n di?: DiOverridesMap | LooseOverrideMap\n encryption?: EncryptionOverridesShape\n nav?: NavOverridesShape\n}\n\n/**\n * Public shape consumed by the dispatcher. Mirrors the `ModuleEntry`\n * defined in each app's `modules.ts` \u2014 the dispatcher only needs `id`\n * and `overrides`.\n */\nexport interface ModuleEntryWithOverrides {\n id: string\n from?: string\n overrides?: ModuleOverrides\n}\n\n// ---------------------------------------------------------------------------\n// Per-domain runtime hook registry\n// ---------------------------------------------------------------------------\n\n/**\n * Each wired domain registers an applier that receives the list of\n * `(moduleId, overrides)` pairs in module-load order and forwards them\n * to its own runtime hook. Unwired domains do not register an applier\n * and instead trigger the dispatcher's one-shot warning.\n */\nexport type ModuleOverrideDomain =\n | 'ai'\n | 'routes'\n | 'events'\n | 'workers'\n | 'widgets'\n | 'notifications'\n | 'interceptors'\n | 'commandInterceptors'\n | 'enrichers'\n | 'guards'\n | 'cli'\n | 'setup'\n | 'acl'\n | 'di'\n | 'encryption'\n | 'nav'\n\nexport interface ModuleOverrideEntry<TShape> {\n moduleId: string\n overrides: TShape\n}\n\nexport type ModuleOverrideApplier<TShape> = (\n entries: ReadonlyArray<ModuleOverrideEntry<TShape>>,\n) => void\n\nconst appliers = new Map<ModuleOverrideDomain, ModuleOverrideApplier<unknown>>()\nconst warnedUnwiredDomains = new Set<ModuleOverrideDomain>()\n\n/**\n * Register a per-domain runtime hook. Called once at module-load time\n * by each wired domain (e.g. the AI subsystem registers `'ai'` from\n * `@open-mercato/ai-assistant`).\n */\nexport function registerModuleOverrideApplier<TShape>(\n domain: ModuleOverrideDomain,\n applier: ModuleOverrideApplier<TShape>,\n): void {\n appliers.set(domain, applier as ModuleOverrideApplier<unknown>)\n}\n\n/** @__internal Test-only hook \u2014 clear all registered appliers + warnings. */\nexport function resetModuleOverrideAppliersForTests(): void {\n appliers.clear()\n warnedUnwiredDomains.clear()\n registerBuiltInModuleOverrideAppliers()\n}\n\n// ---------------------------------------------------------------------------\n// Dispatcher\n// ---------------------------------------------------------------------------\n\nconst DOMAIN_KEYS: ModuleOverrideDomain[] = [\n 'ai',\n 'routes',\n 'events',\n 'workers',\n 'widgets',\n 'notifications',\n 'interceptors',\n 'commandInterceptors',\n 'enrichers',\n 'guards',\n 'cli',\n 'setup',\n 'acl',\n 'di',\n 'encryption',\n 'nav',\n]\n\nconst TRACKING_ISSUE_HINT =\n 'See `.ai/specs/implemented/2026-05-04-modules-ts-unified-overrides.md` and tracking issue https://github.com/open-mercato/open-mercato/issues/1787.'\n\n/**\n * Walk every `ModuleEntry` and dispatch its `overrides.<domain>` shape\n * to the matching wired applier. Unwired domains emit a one-shot\n * structured warning.\n *\n * Call this exactly once from `apps/<app>/src/bootstrap.ts` BEFORE any\n * registry first-loads. Calling it more than once is safe but\n * accumulates per-domain entries each time.\n */\nexport function applyModuleOverridesFromEnabledModules(\n modules: ReadonlyArray<ModuleEntryWithOverrides>,\n): void {\n if (!Array.isArray(modules) || modules.length === 0) return\n\n // Bucket entries by domain in module-load order.\n const buckets = new Map<ModuleOverrideDomain, Array<ModuleOverrideEntry<unknown>>>()\n\n for (const entry of modules) {\n if (!entry || typeof entry.id !== 'string' || !entry.id) continue\n const overrides = entry.overrides\n if (!overrides || typeof overrides !== 'object') continue\n\n for (const domain of DOMAIN_KEYS) {\n const value = (overrides as Record<string, unknown>)[domain]\n if (value === undefined || value === null) continue\n if (typeof value !== 'object') continue\n const list = buckets.get(domain) ?? []\n list.push({ moduleId: entry.id, overrides: value })\n buckets.set(domain, list)\n }\n }\n\n // Dispatch each domain to its wired applier; warn on unwired domains.\n for (const [domain, entries] of buckets) {\n const applier = appliers.get(domain)\n if (!applier) {\n if (!warnedUnwiredDomains.has(domain)) {\n warnedUnwiredDomains.add(domain)\n const moduleIds = Array.from(new Set(entries.map((e) => e.moduleId))).join(', ')\n logger.warn('Override domain not yet wired \u2014 entry ignored', { domain, moduleIds, hint: TRACKING_ISSUE_HINT })\n }\n continue\n }\n applier(entries)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Phase 2/3 \u2014 Routes (API + pages) applier\n// ---------------------------------------------------------------------------\n//\n// Wires `entry.overrides.routes.api` so a downstream module can disable or\n// replace any API route declared by another module. The override map is\n// keyed by `'METHOD /api/path'` (case-insensitive method, leading slash on\n// the path), and each value is either:\n//\n// - `null` \u2014 disable the matching method on the route.\n// - `{ handler, metadata? }` \u2014 replace the matching method's handler\n// (and optionally merge override metadata into the route's metadata).\n//\n// Resolution order (lowest precedence first):\n//\n// 1. `modules.ts` inline \u2014 every `entry.overrides.routes.api` on a\n// `ModuleEntry` (last entry per key wins).\n// 2. Programmatic \u2014 `applyApiRouteOverrides({...})` from anywhere at\n// boot or test scaffolds (last call per key wins).\n//\n// A file-based tier (per-module `apiRouteOverrides` exports) is **not**\n// part of Phase 2 \u2014 modules that ship a route override do so via\n// `modules.ts` or programmatically. The umbrella spec keeps the file-based\n// tier \"where applicable\".\n//\n// The applied overrides are consumed by `registerApiRouteManifests` (see\n// `./registry.ts`) which rewrites the manifest array once before storing\n// it. Calls to `applyApiRouteOverrides` made AFTER manifests are already\n// registered do not retro-actively update the stored manifest \u2014 for\n// runtime override scenarios call the dispatcher / programmatic API\n// before `bootstrap.ts` triggers manifest registration.\n//\n// Spec: `.ai/specs/implemented/2026-05-04-modules-ts-unified-overrides.md` (Phases 2/3).\n\n// ApiRouteManifestEntry / ApiHandler / HttpMethod live in ./registry. The\n// type-only import is erased at runtime, so there is no cycle even though\n// ./registry imports the runtime helpers below.\nimport type {\n ApiHandler,\n ApiRouteManifestEntry,\n BackendRouteManifestEntry,\n FrontendRouteManifestEntry,\n HttpMethod,\n Module,\n ModuleCli,\n ModuleDashboardWidgetEntry,\n ModuleInjectionWidgetEntry,\n ModuleSubscriber,\n ModuleWorker,\n} from './registry'\nimport { createLogger } from '../lib/logger'\nimport { resolveDeclaredPageRouteMetadata } from './pageRouteMetadata'\nimport type { ModuleInjectionTable } from './widgets/injection'\nimport type { ComponentOverride } from './widgets/component-registry'\nimport type { NotificationHandler } from './notifications/handler'\nimport type { NotificationTypeDefinition } from './notifications/types'\nimport type { ModuleEncryptionMap } from './encryption'\nimport type { ModuleSetupConfig } from './setup'\nimport type { ApiInterceptor } from '../lib/crud/api-interceptor'\nimport type { ResponseEnricher } from '../lib/crud/response-enricher'\nimport type { CommandInterceptor } from '../lib/commands/command-interceptor'\nimport type { PageMiddlewareRegistryEntry, PageRouteMiddleware } from './middleware/page'\n\nconst logger = createLogger('shared').child({ component: 'module-overrides' })\n\n/** Override for a single API route entry: replace handler/metadata, or `null` to disable. */\nexport interface ApiRouteOverrideDefinition {\n /** Replacement handler. Same signature as the original API route handler. */\n handler: ApiHandler\n /** Optional metadata override \u2014 replaces the per-method metadata on the route. */\n metadata?: unknown\n}\n\n/** Override value per `'METHOD /api/path'` key \u2014 definition or `null` to disable. */\nexport type ApiRouteOverride = ApiRouteOverrideDefinition | null\n\n/** Map of `'METHOD /api/path'` \u2192 override. */\nexport type ApiRouteOverridesMap = Record<string, ApiRouteOverride>\n\ntype OverrideStore<T> = {\n modules: Record<string, T | null>\n programmatic: Record<string, T | null>\n}\n\ntype OverrideValue<T> = T | null\ntype OverrideMap<T> = Record<string, OverrideValue<T>>\n\n/** Override for a backend/frontend page route: replace loader/metadata, or `null` to disable. */\nexport interface PageRouteOverrideDefinition {\n load?: BackendRouteManifestEntry['load']\n Component?: Awaited<ReturnType<BackendRouteManifestEntry['load']>>\n metadata?: Partial<Omit<BackendRouteManifestEntry | FrontendRouteManifestEntry, 'moduleId' | 'load'>>\n}\n\nexport type PageRouteOverride = PageRouteOverrideDefinition | null\nexport type PageRouteOverridesMap = Record<string, PageRouteOverride>\n\nexport type SubscriberOverride = ModuleSubscriber | null\nexport type SubscriberOverridesMap = Record<string, SubscriberOverride>\n\nexport type WorkerOverride = ModuleWorker | null\nexport type WorkerOverridesMap = Record<string, WorkerOverride>\n\nexport type CliOverride = ModuleCli | null\nexport type CliOverridesMap = Record<string, CliOverride>\n\nexport type InjectionWidgetOverride = ModuleInjectionWidgetEntry | null\nexport type InjectionWidgetOverridesMap = Record<string, InjectionWidgetOverride>\n\nexport type DashboardWidgetOverride = ModuleDashboardWidgetEntry | null\nexport type DashboardWidgetOverridesMap = Record<string, DashboardWidgetOverride>\n\nexport type ComponentOverrideValue = ComponentOverride | ComponentOverride[] | null\nexport type ComponentOverridesMap = Record<string, ComponentOverrideValue>\n\nexport type NotificationTypeOverride = NotificationTypeDefinition | null\nexport type NotificationTypeOverridesMap = Record<string, NotificationTypeOverride>\n\nexport type NotificationHandlerOverride = NotificationHandler | null\nexport type NotificationHandlerOverridesMap = Record<string, NotificationHandlerOverride>\n\nexport type ApiInterceptorOverride = ApiInterceptor | null\nexport type ApiInterceptorOverridesMap = Record<string, ApiInterceptorOverride>\n\nexport type CommandInterceptorOverride = CommandInterceptor | null\nexport type CommandInterceptorOverridesMap = Record<string, CommandInterceptorOverride>\n\nexport type ResponseEnricherOverride = ResponseEnricher | null\nexport type ResponseEnricherOverridesMap = Record<string, ResponseEnricherOverride>\n\nexport type PageGuardOverride = PageRouteMiddleware | null\nexport type PageGuardOverridesMap = Record<string, PageGuardOverride>\n\nexport type AclFeatureOverride = string | { id: string; [key: string]: unknown } | null\nexport type AclFeatureOverridesMap = Record<string, AclFeatureOverride>\n\nexport type EncryptionMapOverride = ModuleEncryptionMap | null\nexport type EncryptionMapOverridesMap = Record<string, EncryptionMapOverride>\n\nexport type DiBindingOverrideDefinition = {\n register: (container: { register: (registrations: Record<string, unknown>) => unknown }, key: string) => void\n}\nexport type DiBindingOverride = DiBindingOverrideDefinition | unknown | null\nexport type DiOverridesMap = Record<string, DiBindingOverride>\n\nconst pageRouteOverrideStore: OverrideStore<PageRouteOverrideDefinition> = { modules: {}, programmatic: {} }\nconst subscriberOverrideStore: OverrideStore<ModuleSubscriber> = { modules: {}, programmatic: {} }\nconst workerOverrideStore: OverrideStore<ModuleWorker> = { modules: {}, programmatic: {} }\nconst cliOverrideStore: OverrideStore<ModuleCli> = { modules: {}, programmatic: {} }\nconst injectionWidgetOverrideStore: OverrideStore<ModuleInjectionWidgetEntry> = { modules: {}, programmatic: {} }\nconst dashboardWidgetOverrideStore: OverrideStore<ModuleDashboardWidgetEntry> = { modules: {}, programmatic: {} }\nconst componentOverrideStore: OverrideStore<ComponentOverride | ComponentOverride[]> = { modules: {}, programmatic: {} }\nconst notificationTypeOverrideStore: OverrideStore<NotificationTypeDefinition> = { modules: {}, programmatic: {} }\nconst notificationHandlerOverrideStore: OverrideStore<NotificationHandler> = { modules: {}, programmatic: {} }\nconst apiInterceptorOverrideStore: OverrideStore<ApiInterceptor> = { modules: {}, programmatic: {} }\nconst commandInterceptorOverrideStore: OverrideStore<CommandInterceptor> = { modules: {}, programmatic: {} }\nconst responseEnricherOverrideStore: OverrideStore<ResponseEnricher> = { modules: {}, programmatic: {} }\nconst pageGuardOverrideStore: OverrideStore<PageRouteMiddleware> = { modules: {}, programmatic: {} }\nconst aclFeatureOverrideStore: OverrideStore<Exclude<AclFeatureOverride, null>> = { modules: {}, programmatic: {} }\nconst encryptionMapOverrideStore: OverrideStore<ModuleEncryptionMap> = { modules: {}, programmatic: {} }\nconst diOverrideStore: OverrideStore<Exclude<DiBindingOverride, null>> = { modules: {}, programmatic: {} }\nconst setupOverridesByModule: Record<string, SetupOverridesShape> = {}\n\n/**\n * Sidebar nav ordering state.\n *\n * Persisted on `globalThis` rather than in a module-local variable. This is the one override domain\n * whose consumer lives in a *different package* (`@open-mercato/core`'s backend chrome reads what the\n * app's bootstrap wrote), and standalone builds can evaluate `@open-mercato/shared` through more than\n * one server chunk \u2014 bootstrap would store the value in one instance while the reader saw `null` from\n * another. See `.ai/lessons.md`, \"Global registries in publishable packages must use `globalThis`\".\n *\n * Two tiers, matching every other override domain and the documented resolution order: programmatic\n * calls win over `modules.ts` inline declarations.\n */\nconst GLOBAL_NAV_OVERRIDE_STATE_KEY = '__openMercatoNavOverrideState__'\n\ntype NavOverrideState = {\n /** From `modules.ts` inline `overrides.nav`, with the module entry that supplied it. */\n modules: { moduleId: string; groupOrder: string[] } | null\n /** From `applyNavGroupOrderOverrides`. Takes precedence over `modules`. */\n programmatic: string[] | null\n}\n\nfunction getNavOverrideState(): NavOverrideState {\n const existing = (globalThis as Record<string, unknown>)[GLOBAL_NAV_OVERRIDE_STATE_KEY]\n if (existing && typeof existing === 'object') {\n const typed = existing as NavOverrideState\n if ('modules' in typed && 'programmatic' in typed) return typed\n }\n const initial: NavOverrideState = { modules: null, programmatic: null }\n ;(globalThis as Record<string, unknown>)[GLOBAL_NAV_OVERRIDE_STATE_KEY] = initial\n return initial\n}\n\n/** Drops blank/duplicate ids and returns `null` when nothing usable remains. */\nfunction normalizeNavGroupOrder(value: unknown): string[] | null {\n if (!Array.isArray(value)) return null\n const ids = Array.from(\n new Set(\n value\n .filter((id): id is string => typeof id === 'string' && id.trim().length > 0)\n .map((id) => id.trim()),\n ),\n )\n return ids.length > 0 ? ids : null\n}\n\n/**\n * Programmatic nav ordering, for env-driven boot decisions and tests. Takes precedence over\n * `modules.ts` inline `overrides.nav`, consistent with the other domains' programmatic tier. Pass\n * `null` to clear it and fall back to the inline declaration.\n */\nexport function applyNavGroupOrderOverrides(groupOrder: string[] | null): void {\n getNavOverrideState().programmatic = groupOrder === null ? null : normalizeNavGroupOrder(groupOrder)\n}\n\n/**\n * Nav group ids an app wants ranked ahead of the built-in order, or `null` when none is configured.\n *\n * Consumers MUST treat `null` as \"use the shipped ordering unchanged\" \u2014 this is a default, applied\n * beneath role and user sidebar preferences.\n */\nexport function getNavGroupOrderOverride(): readonly string[] | null {\n const state = getNavOverrideState()\n return state.programmatic ?? state.modules?.groupOrder ?? null\n}\n\nfunction normalizeIdOverrideKey(key: string, label: string): string | null {\n if (typeof key !== 'string') return null\n const trimmed = key.trim()\n if (trimmed) return trimmed\n logger.warn('Skipping malformed override key \u2014 expected a non-empty string', { label, key })\n return null\n}\n\nfunction clearStore<T>(store: OverrideStore<T>): void {\n for (const key of Object.keys(store.modules)) delete store.modules[key]\n for (const key of Object.keys(store.programmatic)) delete store.programmatic[key]\n}\n\n// Shared frozen empty override map. Returned from compose* helpers when both\n// the modules-tier and programmatic-tier stores are empty so per-request hot\n// paths (page guards, etc.) reuse one object instead of allocating fresh `{}`\n// per call. Consumers MUST NOT mutate \u2014 internal applier loops iterate keys\n// only, and the public API hands out shallow copies through composeApiRouteOverrides.\nconst EMPTY_OVERRIDE_MAP: Readonly<Record<string, never>> = Object.freeze({})\n\nfunction applyStoreOverrides<T>(\n store: OverrideStore<T>,\n target: 'modules' | 'programmatic',\n overrides: OverrideMap<T> | undefined,\n options: {\n label: string\n normalizeKey?: (key: string) => string | null\n },\n): void {\n if (!overrides || typeof overrides !== 'object') return\n const normalize = options.normalizeKey ?? ((key: string) => normalizeIdOverrideKey(key, options.label))\n for (const [rawKey, value] of Object.entries(overrides)) {\n const key = normalize(rawKey)\n if (!key) continue\n store[target][key] = value\n }\n}\n\nfunction composeStore<T>(store: OverrideStore<T>): OverrideMap<T> {\n const modulesKeys = Object.keys(store.modules)\n const programmaticKeys = Object.keys(store.programmatic)\n if (modulesKeys.length === 0 && programmaticKeys.length === 0) {\n return EMPTY_OVERRIDE_MAP as OverrideMap<T>\n }\n return { ...store.modules, ...store.programmatic }\n}\n\nfunction applyArrayOverrides<T>(\n items: readonly T[] | undefined,\n overrides: Readonly<OverrideMap<T>>,\n options: {\n label: string\n getId: (value: T) => string | null\n isReplacement?: (value: unknown) => value is T\n },\n): { items: T[] | undefined; consumed: Set<string>; changed: boolean } {\n if (!items || Object.keys(overrides).length === 0) {\n return { items: items ? Array.from(items) : items, consumed: new Set(), changed: false }\n }\n\n const consumed = new Set<string>()\n const result: T[] = []\n let changed = false\n\n for (const item of items) {\n const id = options.getId(item)\n if (!id || !Object.prototype.hasOwnProperty.call(overrides, id)) {\n result.push(item)\n continue\n }\n consumed.add(id)\n changed = true\n const replacement = overrides[id]\n if (replacement === null) continue\n if (options.isReplacement && !options.isReplacement(replacement)) {\n logger.warn('Skipping malformed override \u2014 replacement has the wrong shape', { label: options.label, id })\n result.push(item)\n continue\n }\n const replacementId = options.getId(replacement)\n if (replacementId !== id) {\n logger.warn('Skipping malformed override \u2014 replacement id must match the override key', { label: options.label, id })\n result.push(item)\n continue\n }\n result.push(replacement)\n }\n\n return { items: result, consumed, changed }\n}\n\nfunction warnStaleOverrides(label: string, overrides: Readonly<Record<string, unknown>>, consumed: ReadonlySet<string>): void {\n for (const key of Object.keys(overrides)) {\n if (!consumed.has(key)) {\n logger.warn('Override did not match any registered entry \u2014 override skipped', { label, key })\n }\n }\n}\n\nfunction isObjectWithId(value: unknown): value is { id: string } {\n return !!value && typeof value === 'object' && typeof (value as { id?: unknown }).id === 'string'\n}\n\nfunction isModuleSubscriber(value: unknown): value is ModuleSubscriber {\n return isObjectWithId(value)\n && typeof (value as ModuleSubscriber).event === 'string'\n && typeof (value as ModuleSubscriber).handler === 'function'\n}\n\nfunction isModuleWorker(value: unknown): value is ModuleWorker {\n return isObjectWithId(value)\n && typeof (value as ModuleWorker).queue === 'string'\n && typeof (value as ModuleWorker).handler === 'function'\n}\n\nfunction isModuleCli(value: unknown): value is ModuleCli {\n return !!value\n && typeof value === 'object'\n && typeof (value as ModuleCli).command === 'string'\n && typeof (value as ModuleCli).run === 'function'\n}\n\nfunction isInjectionWidgetEntry(value: unknown): value is ModuleInjectionWidgetEntry {\n return !!value\n && typeof value === 'object'\n && typeof (value as ModuleInjectionWidgetEntry).key === 'string'\n && typeof (value as ModuleInjectionWidgetEntry).loader === 'function'\n}\n\nfunction isDashboardWidgetEntry(value: unknown): value is ModuleDashboardWidgetEntry {\n return !!value\n && typeof value === 'object'\n && typeof (value as ModuleDashboardWidgetEntry).key === 'string'\n && typeof (value as ModuleDashboardWidgetEntry).loader === 'function'\n}\n\nfunction isComponentOverrideValue(value: unknown): value is ComponentOverride | ComponentOverride[] {\n const items = Array.isArray(value) ? value : [value]\n return items.every((item) =>\n !!item\n && typeof item === 'object'\n && !!(item as ComponentOverride).target\n && typeof (item as ComponentOverride).target.componentId === 'string',\n )\n}\n\nfunction isNotificationType(value: unknown): value is NotificationTypeDefinition {\n return !!value && typeof value === 'object' && typeof (value as NotificationTypeDefinition).type === 'string'\n}\n\nfunction isNotificationHandler(value: unknown): value is NotificationHandler {\n return isObjectWithId(value) && typeof (value as NotificationHandler).handle === 'function'\n}\n\nfunction isApiInterceptor(value: unknown): value is ApiInterceptor {\n return isObjectWithId(value) && typeof (value as ApiInterceptor).targetRoute === 'string'\n}\n\nfunction isCommandInterceptor(value: unknown): value is CommandInterceptor {\n return isObjectWithId(value) && typeof (value as CommandInterceptor).targetCommand === 'string'\n}\n\nfunction isResponseEnricher(value: unknown): value is ResponseEnricher {\n return isObjectWithId(value)\n && typeof (value as ResponseEnricher).targetEntity === 'string'\n && typeof (value as ResponseEnricher).enrichOne === 'function'\n}\n\nfunction isPageRouteMiddleware(value: unknown): value is PageRouteMiddleware {\n return isObjectWithId(value) && typeof (value as PageRouteMiddleware).run === 'function'\n}\n\nfunction isEncryptionMap(value: unknown): value is ModuleEncryptionMap {\n return !!value\n && typeof value === 'object'\n && typeof (value as ModuleEncryptionMap).entityId === 'string'\n && Array.isArray((value as ModuleEncryptionMap).fields)\n}\n\nfunction getFeatureId(value: unknown): string | null {\n if (typeof value === 'string' && value.trim()) return value.trim()\n if (value && typeof value === 'object' && typeof (value as { id?: unknown }).id === 'string') {\n return (value as { id: string }).id\n }\n return null\n}\n\nconst VALID_HTTP_METHODS: readonly HttpMethod[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']\n\nconst programmaticApiRouteOverrides: ApiRouteOverridesMap = {}\nconst modulesConfigApiRouteOverrides: ApiRouteOverridesMap = {}\n\n/**\n * Normalize an override key to the canonical `'METHOD /api/path'` form.\n * Returns `null` if the key is malformed (missing method, unknown method,\n * empty path). Trailing slashes on the path are stripped.\n */\nfunction normalizeApiRouteOverrideKey(key: string): string | null {\n if (typeof key !== 'string') return null\n const trimmed = key.trim()\n if (!trimmed) return null\n const parts = trimmed.split(/\\s+/)\n if (parts.length < 2) return null\n const method = parts[0].toUpperCase() as HttpMethod\n if (!VALID_HTTP_METHODS.includes(method)) return null\n const rawPath = parts.slice(1).join(' ').trim()\n if (!rawPath) return null\n const withLead = rawPath.startsWith('/') ? rawPath : `/${rawPath}`\n const normalized = withLead.replace(/\\/+$/, '') || '/'\n return `${method} ${normalized}`\n}\n\nfunction normalizePageRouteOverrideKey(key: string): string | null {\n if (typeof key !== 'string') return null\n const trimmed = key.trim()\n if (!trimmed) return null\n if (trimmed.startsWith('backend:') || trimmed.startsWith('frontend:')) return trimmed\n const withLead = trimmed.startsWith('/') ? trimmed : `/${trimmed}`\n const stripped = withLead.replace(/\\/+$/, '') || '/'\n if (stripped === '/frontend') return 'frontend:/'\n if (stripped.startsWith('/frontend/')) return `frontend:/${stripped.slice('/frontend/'.length)}`\n if (stripped === '/backend' || stripped.startsWith('/backend/')) return `backend:${stripped}`\n return `frontend:${stripped}`\n}\n\n/**\n * Programmatic API: apply API-route overrides. Supersedes any matching\n * `modules.ts` inline overrides for the same key. Call before\n * `registerApiRouteManifests` (i.e. before generated `apiRoutes` lands in\n * the registry); calls after registration do not retro-actively update\n * the stored manifest.\n *\n * @example\n * applyApiRouteOverrides({\n * 'GET /api/example/items': null, // disable\n * 'POST /api/example/items': { handler: customHandler }, // replace\n * })\n */\nexport function applyApiRouteOverrides(overrides: ApiRouteOverridesMap): void {\n if (!overrides) return\n for (const [rawKey, value] of Object.entries(overrides)) {\n const key = normalizeApiRouteOverrideKey(rawKey)\n if (!key) {\n logger.warn('Skipping malformed routes.api key \u2014 expected \"METHOD /api/path\"', { key: rawKey })\n continue\n }\n programmaticApiRouteOverrides[key] = value\n }\n}\n\n/** @__internal Test-only hook \u2014 clear programmatic + modules.ts route override state. */\nexport function resetApiRouteOverridesForTests(): void {\n for (const key of Object.keys(programmaticApiRouteOverrides)) {\n delete programmaticApiRouteOverrides[key]\n }\n for (const key of Object.keys(modulesConfigApiRouteOverrides)) {\n delete modulesConfigApiRouteOverrides[key]\n }\n}\n\n/** @__internal Test-only hook \u2014 clear every per-domain override store. */\nexport function resetModuleContractOverridesForTests(): void {\n resetApiRouteOverridesForTests()\n clearStore(pageRouteOverrideStore)\n clearStore(subscriberOverrideStore)\n clearStore(workerOverrideStore)\n clearStore(cliOverrideStore)\n clearStore(injectionWidgetOverrideStore)\n clearStore(dashboardWidgetOverrideStore)\n clearStore(componentOverrideStore)\n clearStore(notificationTypeOverrideStore)\n clearStore(notificationHandlerOverrideStore)\n clearStore(apiInterceptorOverrideStore)\n clearStore(commandInterceptorOverrideStore)\n clearStore(responseEnricherOverrideStore)\n clearStore(pageGuardOverrideStore)\n clearStore(aclFeatureOverrideStore)\n clearStore(encryptionMapOverrideStore)\n clearStore(diOverrideStore)\n for (const key of Object.keys(setupOverridesByModule)) delete setupOverridesByModule[key]\n const navState = getNavOverrideState()\n navState.modules = null\n navState.programmatic = null\n}\n\n/**\n * Resolve the final API-route override map. Resolution order (lowest \u2192\n * highest precedence):\n *\n * 1. `modules.ts` inline (applied via the dispatcher).\n * 2. Programmatic (`applyApiRouteOverrides`).\n */\nexport function composeApiRouteOverrides(): ApiRouteOverridesMap {\n const modulesKeys = Object.keys(modulesConfigApiRouteOverrides)\n const programmaticKeys = Object.keys(programmaticApiRouteOverrides)\n if (modulesKeys.length === 0 && programmaticKeys.length === 0) {\n return EMPTY_OVERRIDE_MAP as ApiRouteOverridesMap\n }\n const out: ApiRouteOverridesMap = {}\n for (const k of modulesKeys) out[k] = modulesConfigApiRouteOverrides[k]\n for (const k of programmaticKeys) out[k] = programmaticApiRouteOverrides[k]\n return out\n}\n\nexport function applyPageRouteOverrides(overrides: PageRouteOverridesMap): void {\n applyStoreOverrides(pageRouteOverrideStore, 'programmatic', overrides as OverrideMap<PageRouteOverrideDefinition>, {\n label: 'routes.pages',\n normalizeKey: normalizePageRouteOverrideKey,\n })\n}\n\nexport function composePageRouteOverrides(): PageRouteOverridesMap {\n return composeStore(pageRouteOverrideStore) as PageRouteOverridesMap\n}\n\nexport function applySubscriberOverrides(overrides: SubscriberOverridesMap): void {\n applyStoreOverrides(subscriberOverrideStore, 'programmatic', overrides as OverrideMap<ModuleSubscriber>, { label: 'events.subscribers' })\n}\n\nexport function composeSubscriberOverrides(): SubscriberOverridesMap {\n return composeStore(subscriberOverrideStore) as SubscriberOverridesMap\n}\n\nexport function applyWorkerOverrides(overrides: WorkerOverridesMap): void {\n applyStoreOverrides(workerOverrideStore, 'programmatic', overrides as OverrideMap<ModuleWorker>, { label: 'workers' })\n}\n\nexport function composeWorkerOverrides(): WorkerOverridesMap {\n return composeStore(workerOverrideStore) as WorkerOverridesMap\n}\n\nexport function applyCliOverrides(overrides: CliOverridesMap): void {\n applyStoreOverrides(cliOverrideStore, 'programmatic', overrides as OverrideMap<ModuleCli>, { label: 'cli' })\n}\n\nexport function composeCliOverrides(): CliOverridesMap {\n return composeStore(cliOverrideStore) as CliOverridesMap\n}\n\nexport function applyInjectionWidgetOverrides(overrides: InjectionWidgetOverridesMap): void {\n applyStoreOverrides(injectionWidgetOverrideStore, 'programmatic', overrides as OverrideMap<ModuleInjectionWidgetEntry>, { label: 'widgets.injection' })\n}\n\nexport function composeInjectionWidgetOverrides(): InjectionWidgetOverridesMap {\n return composeStore(injectionWidgetOverrideStore) as InjectionWidgetOverridesMap\n}\n\nexport function applyDashboardWidgetOverrides(overrides: DashboardWidgetOverridesMap): void {\n applyStoreOverrides(dashboardWidgetOverrideStore, 'programmatic', overrides as OverrideMap<ModuleDashboardWidgetEntry>, { label: 'widgets.dashboard' })\n}\n\nexport function composeDashboardWidgetOverrides(): DashboardWidgetOverridesMap {\n return composeStore(dashboardWidgetOverrideStore) as DashboardWidgetOverridesMap\n}\n\nexport function applyComponentOverrides(overrides: ComponentOverridesMap): void {\n applyStoreOverrides(componentOverrideStore, 'programmatic', overrides as OverrideMap<ComponentOverride | ComponentOverride[]>, { label: 'widgets.components' })\n}\n\nexport function composeComponentOverrides(): ComponentOverridesMap {\n return composeStore(componentOverrideStore) as ComponentOverridesMap\n}\n\nexport function applyNotificationTypeOverrides(overrides: NotificationTypeOverridesMap): void {\n applyStoreOverrides(notificationTypeOverrideStore, 'programmatic', overrides as OverrideMap<NotificationTypeDefinition>, { label: 'notifications.types' })\n}\n\nexport function composeNotificationTypeOverrides(): NotificationTypeOverridesMap {\n return composeStore(notificationTypeOverrideStore) as NotificationTypeOverridesMap\n}\n\nexport function applyNotificationHandlerOverrides(overrides: NotificationHandlerOverridesMap): void {\n applyStoreOverrides(notificationHandlerOverrideStore, 'programmatic', overrides as OverrideMap<NotificationHandler>, { label: 'notifications.handlers' })\n}\n\nexport function composeNotificationHandlerOverrides(): NotificationHandlerOverridesMap {\n return composeStore(notificationHandlerOverrideStore) as NotificationHandlerOverridesMap\n}\n\nexport function applyApiInterceptorOverrides(overrides: ApiInterceptorOverridesMap): void {\n applyStoreOverrides(apiInterceptorOverrideStore, 'programmatic', overrides as OverrideMap<ApiInterceptor>, { label: 'interceptors' })\n}\n\nexport function composeApiInterceptorOverrides(): ApiInterceptorOverridesMap {\n return composeStore(apiInterceptorOverrideStore) as ApiInterceptorOverridesMap\n}\n\nexport function applyCommandInterceptorOverrides(overrides: CommandInterceptorOverridesMap): void {\n applyStoreOverrides(commandInterceptorOverrideStore, 'programmatic', overrides as OverrideMap<CommandInterceptor>, { label: 'commandInterceptors' })\n}\n\nexport function composeCommandInterceptorOverrides(): CommandInterceptorOverridesMap {\n return composeStore(commandInterceptorOverrideStore) as CommandInterceptorOverridesMap\n}\n\nexport function applyResponseEnricherOverrides(overrides: ResponseEnricherOverridesMap): void {\n applyStoreOverrides(responseEnricherOverrideStore, 'programmatic', overrides as OverrideMap<ResponseEnricher>, { label: 'enrichers' })\n}\n\nexport function composeResponseEnricherOverrides(): ResponseEnricherOverridesMap {\n return composeStore(responseEnricherOverrideStore) as ResponseEnricherOverridesMap\n}\n\nexport function applyPageGuardOverrides(overrides: PageGuardOverridesMap): void {\n applyStoreOverrides(pageGuardOverrideStore, 'programmatic', overrides as OverrideMap<PageRouteMiddleware>, { label: 'guards' })\n}\n\nexport function composePageGuardOverrides(): PageGuardOverridesMap {\n return composeStore(pageGuardOverrideStore) as PageGuardOverridesMap\n}\n\nexport function applyAclFeatureOverrides(overrides: AclFeatureOverridesMap): void {\n applyStoreOverrides(aclFeatureOverrideStore, 'programmatic', overrides as OverrideMap<Exclude<AclFeatureOverride, null>>, { label: 'acl.features' })\n}\n\nexport function composeAclFeatureOverrides(): AclFeatureOverridesMap {\n return composeStore(aclFeatureOverrideStore) as AclFeatureOverridesMap\n}\n\nexport function applyEncryptionMapOverrides(overrides: EncryptionMapOverridesMap): void {\n applyStoreOverrides(encryptionMapOverrideStore, 'programmatic', overrides as OverrideMap<ModuleEncryptionMap>, { label: 'encryption.maps' })\n}\n\nexport function composeEncryptionMapOverrides(): EncryptionMapOverridesMap {\n return composeStore(encryptionMapOverrideStore) as EncryptionMapOverridesMap\n}\n\nexport function applyDiOverrides(overrides: DiOverridesMap): void {\n applyStoreOverrides(diOverrideStore, 'programmatic', overrides as OverrideMap<Exclude<DiBindingOverride, null>>, { label: 'di' })\n}\n\nexport function composeDiOverrides(): DiOverridesMap {\n return composeStore(diOverrideStore) as DiOverridesMap\n}\n\n/**\n * Apply an API-route override map to a list of registered manifest entries.\n * Returns a NEW array \u2014 never mutates input.\n *\n * Behavior:\n * - For each entry, walk every method in `entry.methods`.\n * - If the override key `'METHOD path'` is `null`, drop that method from\n * the entry's `methods` array.\n * - If the override key is a definition, wrap `entry.load()` to return a\n * module that exposes the override handler at `module[METHOD]` (top-level)\n * and the override metadata at `module.metadata[METHOD]`.\n * - If every method on the entry is disabled, the entry is dropped.\n * - Overrides naming a key that does not match any entry log a single\n * warning so an operator notices a stale override.\n */\nexport function applyApiOverridesToManifests<T extends ApiRouteManifestEntry>(\n routes: readonly T[],\n overrides: Readonly<ApiRouteOverridesMap>,\n): T[] {\n if (!routes || routes.length === 0) return Array.from(routes)\n const overrideKeys = Object.keys(overrides)\n if (overrideKeys.length === 0) return Array.from(routes)\n\n const consumedKeys = new Set<string>()\n const result: T[] = []\n\n for (const entry of routes) {\n const path = entry.path\n const remainingMethods: HttpMethod[] = []\n const methodOverrides = new Map<HttpMethod, ApiRouteOverrideDefinition>()\n\n for (const method of entry.methods) {\n const manifestKey = `${method} ${path}`\n const publicKey = path.startsWith('/api/')\n ? manifestKey\n : `${method} /api${path === '/' ? '' : path}`\n const key = Object.prototype.hasOwnProperty.call(overrides, manifestKey)\n ? manifestKey\n : Object.prototype.hasOwnProperty.call(overrides, publicKey)\n ? publicKey\n : null\n if (!key) {\n remainingMethods.push(method)\n continue\n }\n consumedKeys.add(key)\n const value = overrides[key]\n if (value === null) continue\n if (value && typeof value === 'object' && typeof value.handler === 'function') {\n methodOverrides.set(method, value)\n remainingMethods.push(method)\n } else {\n logger.warn('Skipping malformed routes.api override \u2014 expected { handler, metadata? } or null', { key })\n remainingMethods.push(method)\n }\n }\n\n if (remainingMethods.length === 0) continue\n\n const methodsChanged = remainingMethods.length !== entry.methods.length\n const hasReplacements = methodOverrides.size > 0\n\n if (!methodsChanged && !hasReplacements) {\n result.push(entry)\n continue\n }\n\n const originalLoad = entry.load\n const wrappedLoad: T['load'] = hasReplacements\n ? async () => {\n const original = await originalLoad()\n const out: Record<string, unknown> = { ...original }\n const baseMetadata = original && typeof original === 'object' && original.metadata !== undefined\n ? original.metadata\n : null\n const mergedMetadata: Record<string, unknown> = baseMetadata && typeof baseMetadata === 'object'\n ? { ...(baseMetadata as Record<string, unknown>) }\n : {}\n for (const [method, def] of methodOverrides) {\n out[method] = def.handler\n if (def.metadata !== undefined) mergedMetadata[method] = def.metadata\n }\n if (Object.keys(mergedMetadata).length > 0) out.metadata = mergedMetadata\n return out\n }\n : originalLoad\n\n result.push({ ...entry, methods: remainingMethods, load: wrappedLoad })\n }\n\n for (const key of overrideKeys) {\n if (!consumedKeys.has(key)) {\n logger.warn('routes.api override did not match any registered API route \u2014 override skipped', { key })\n }\n }\n\n return result\n}\n\n/**\n * A manifest entry holds *resolved* metadata (`order`, `title`, `group`), while an override\n * declares *authored* metadata, which may use the `page*` aliases (`pageOrder`, `pageTitle`).\n * Spreading the raw override alone left those aliases on keys nothing reads, so an override\n * could retitle a page through `pageTitleKey` yet never reposition it through `pageOrder`\n * (#4845). The raw metadata is still spread first so unrecognized keys keep reaching the\n * entry, then the resolved-and-declared subset lands on top.\n */\nexport function applyPageOverridesToManifests<T extends BackendRouteManifestEntry | FrontendRouteManifestEntry>(\n routes: readonly T[],\n overrides: Readonly<PageRouteOverridesMap>,\n kind: 'backend' | 'frontend',\n): T[] {\n if (!routes || routes.length === 0) return Array.from(routes)\n const normalizedOverrides: PageRouteOverridesMap = {}\n for (const [rawKey, value] of Object.entries(overrides)) {\n const key = normalizePageRouteOverrideKey(rawKey)\n if (!key) {\n logger.warn('Skipping malformed routes.pages key \u2014 expected \"/backend/path\" or \"/frontend/path\"', { key: rawKey })\n continue\n }\n normalizedOverrides[key] = value\n }\n const overrideKeys = Object.keys(normalizedOverrides).filter((key) => key.startsWith(`${kind}:`))\n if (overrideKeys.length === 0) return Array.from(routes)\n\n const consumed = new Set<string>()\n const result: T[] = []\n\n for (const entry of routes) {\n const path = entry.pattern ?? entry.path ?? '/'\n const key = `${kind}:${path.replace(/\\/+$/, '') || '/'}`\n if (!Object.prototype.hasOwnProperty.call(normalizedOverrides, key)) {\n result.push(entry)\n continue\n }\n\n consumed.add(key)\n const override = normalizedOverrides[key]\n if (override === null) continue\n if (!override || typeof override !== 'object') {\n logger.warn('Skipping malformed routes.pages override \u2014 expected { load?, Component?, metadata? } or null', { key })\n result.push(entry)\n continue\n }\n\n const hasLoad = typeof override.load === 'function'\n const hasComponent = typeof override.Component === 'function'\n if (!hasLoad && !hasComponent && override.metadata === undefined) {\n logger.warn('Skipping malformed routes.pages override \u2014 expected a loader, component, metadata, or null', { key })\n result.push(entry)\n continue\n }\n\n const metadata = override.metadata && typeof override.metadata === 'object'\n ? override.metadata\n : {}\n const load = hasLoad\n ? override.load!\n : hasComponent\n ? async () => override.Component!\n : entry.load\n\n result.push({ ...entry, ...metadata, ...resolveDeclaredPageRouteMetadata(metadata), load })\n }\n\n warnStaleOverrides('routes.pages', Object.fromEntries(\n overrideKeys.map((key) => [key, normalizedOverrides[key]]),\n ), consumed)\n return result\n}\n\nfunction applyEntryListOverrides<TEntry extends { moduleId: string }, TValue>(\n entries: readonly TEntry[] | undefined,\n overrides: Readonly<OverrideMap<TValue>>,\n options: {\n listKey: keyof TEntry\n label: string\n getId: (value: TValue) => string | null\n isReplacement: (value: unknown) => value is TValue\n },\n): TEntry[] | undefined {\n // Fast path: when no overrides are registered, return the input directly.\n // All known callers iterate the result (.forEach/.flatMap/.map/storage),\n // never mutate it. This avoids a per-request Array.from copy on hot paths\n // like executePageMiddleware \u2192 applyPageGuardOverridesToEntries.\n if (!entries || Object.keys(overrides).length === 0) return entries as TEntry[] | undefined\n const consumed = new Set<string>()\n let changed = false\n const result = entries.map((entry) => {\n const list = entry[options.listKey]\n if (!Array.isArray(list)) return entry\n const applied = applyArrayOverrides(list as TValue[], overrides, {\n label: options.label,\n getId: options.getId,\n isReplacement: options.isReplacement,\n })\n for (const key of applied.consumed) consumed.add(key)\n if (!applied.changed) return entry\n changed = true\n return { ...entry, [options.listKey]: applied.items ?? [] }\n })\n warnStaleOverrides(options.label, overrides, consumed)\n return changed ? result : Array.from(entries)\n}\n\nexport function applyInjectionWidgetOverridesToEntries(\n entries: readonly ModuleInjectionWidgetEntry[],\n overrides: Readonly<InjectionWidgetOverridesMap> = composeInjectionWidgetOverrides(),\n): ModuleInjectionWidgetEntry[] {\n const applied = applyArrayOverrides(entries, overrides as OverrideMap<ModuleInjectionWidgetEntry>, {\n label: 'widgets.injection',\n getId: (entry) => entry.key,\n isReplacement: isInjectionWidgetEntry,\n })\n warnStaleOverrides('widgets.injection', overrides, applied.consumed)\n return applied.items ?? []\n}\n\nexport function applyDashboardWidgetOverridesToEntries(\n entries: readonly ModuleDashboardWidgetEntry[],\n overrides: Readonly<DashboardWidgetOverridesMap> = composeDashboardWidgetOverrides(),\n): ModuleDashboardWidgetEntry[] {\n const applied = applyArrayOverrides(entries, overrides as OverrideMap<ModuleDashboardWidgetEntry>, {\n label: 'widgets.dashboard',\n getId: (entry) => entry.key,\n isReplacement: isDashboardWidgetEntry,\n })\n warnStaleOverrides('widgets.dashboard', overrides, applied.consumed)\n return applied.items ?? []\n}\n\nexport function applyWorkerOverridesToDescriptors<T extends { id: string; queue: string; concurrency: number; handler: unknown }>(\n entries: readonly T[],\n overrides: Readonly<WorkerOverridesMap> = composeWorkerOverrides(),\n): T[] {\n const applied = applyArrayOverrides(entries, overrides as OverrideMap<T>, {\n label: 'workers',\n getId: (entry) => entry.id,\n isReplacement: (value): value is T =>\n !!value\n && typeof value === 'object'\n && typeof (value as { id?: unknown }).id === 'string'\n && typeof (value as { queue?: unknown }).queue === 'string'\n && typeof (value as { concurrency?: unknown }).concurrency === 'number'\n && typeof (value as { handler?: unknown }).handler === 'function',\n })\n warnStaleOverrides('workers', overrides, applied.consumed)\n return applied.items ?? []\n}\n\nexport function applyInjectionWidgetOverridesToTables(\n tables: readonly { moduleId: string; table: ModuleInjectionTable }[],\n overrides: Readonly<InjectionWidgetOverridesMap> = composeInjectionWidgetOverrides(),\n): Array<{ moduleId: string; table: ModuleInjectionTable }> {\n const disabled = new Set(Object.entries(overrides).filter(([, value]) => value === null).map(([key]) => key))\n if (disabled.size === 0) return Array.from(tables)\n\n const filterSlot = (slot: unknown): unknown => {\n if (typeof slot === 'string') return disabled.has(slot) ? null : slot\n if (slot && typeof slot === 'object') {\n const widgetId = (slot as { widgetId?: unknown }).widgetId\n return typeof widgetId === 'string' && disabled.has(widgetId) ? null : slot\n }\n return slot\n }\n\n return tables.map((entry) => {\n const nextTable: ModuleInjectionTable = {}\n for (const [spotId, rawSlot] of Object.entries(entry.table)) {\n const filtered = Array.isArray(rawSlot)\n ? rawSlot.map(filterSlot).filter((slot): slot is NonNullable<typeof slot> => slot !== null)\n : filterSlot(rawSlot)\n if (Array.isArray(filtered)) {\n if (filtered.length > 0) nextTable[spotId] = filtered as ModuleInjectionTable[string]\n } else if (filtered !== null) {\n nextTable[spotId] = filtered as ModuleInjectionTable[string]\n }\n }\n return { ...entry, table: nextTable }\n })\n}\n\nexport function applyComponentOverridesToEntries(\n entries: readonly { moduleId: string; componentOverrides: ComponentOverride[] }[],\n overrides: Readonly<ComponentOverridesMap> = composeComponentOverrides(),\n): Array<{ moduleId: string; componentOverrides: ComponentOverride[] }> {\n const overrideKeys = Object.keys(overrides)\n if (overrideKeys.length === 0) return Array.from(entries)\n const consumed = new Set<string>()\n const additions: ComponentOverride[] = []\n const result = entries.map((entry) => {\n const next = entry.componentOverrides.filter((override) => {\n const id = override.target.componentId\n if (!Object.prototype.hasOwnProperty.call(overrides, id)) return true\n consumed.add(id)\n return false\n })\n return { ...entry, componentOverrides: next }\n })\n for (const key of overrideKeys) {\n const value = overrides[key]\n if (value === null) continue\n if (!isComponentOverrideValue(value)) {\n logger.warn('Skipping malformed widgets.components override \u2014 expected ComponentOverride, ComponentOverride[], or null', { key })\n continue\n }\n const values = Array.isArray(value) ? value : [value]\n for (const override of values) {\n if (override.target.componentId !== key) {\n logger.warn('Skipping malformed widgets.components override \u2014 target.componentId must match the override key', { key })\n continue\n }\n additions.push(override)\n consumed.add(key)\n }\n }\n if (additions.length > 0) {\n result.push({ moduleId: 'overrides', componentOverrides: additions })\n }\n warnStaleOverrides('widgets.components', overrides, consumed)\n return result\n}\n\nexport function applyNotificationTypeOverridesToEntries(\n entries: readonly { moduleId: string; types: NotificationTypeDefinition[] }[],\n overrides: Readonly<NotificationTypeOverridesMap> = composeNotificationTypeOverrides(),\n): Array<{ moduleId: string; types: NotificationTypeDefinition[] }> {\n return applyEntryListOverrides(entries, overrides as OverrideMap<NotificationTypeDefinition>, {\n listKey: 'types',\n label: 'notifications.types',\n getId: (entry) => entry.type,\n isReplacement: isNotificationType,\n }) ?? []\n}\n\nexport function applyNotificationHandlerOverridesToEntries(\n entries: readonly { moduleId: string; handlers: NotificationHandler[] }[],\n overrides: Readonly<NotificationHandlerOverridesMap> = composeNotificationHandlerOverrides(),\n): Array<{ moduleId: string; handlers: NotificationHandler[] }> {\n return applyEntryListOverrides(entries, overrides as OverrideMap<NotificationHandler>, {\n listKey: 'handlers',\n label: 'notifications.handlers',\n getId: (entry) => entry.id,\n isReplacement: isNotificationHandler,\n }) ?? []\n}\n\nexport function applyApiInterceptorOverridesToEntries(\n entries: readonly { moduleId: string; interceptors: ApiInterceptor[] }[],\n overrides: Readonly<ApiInterceptorOverridesMap> = composeApiInterceptorOverrides(),\n): Array<{ moduleId: string; interceptors: ApiInterceptor[] }> {\n return applyEntryListOverrides(entries, overrides as OverrideMap<ApiInterceptor>, {\n listKey: 'interceptors',\n label: 'interceptors',\n getId: (entry) => entry.id,\n isReplacement: isApiInterceptor,\n }) ?? []\n}\n\nexport function applyCommandInterceptorOverridesToEntries(\n entries: readonly { moduleId: string; interceptors: CommandInterceptor[] }[],\n overrides: Readonly<CommandInterceptorOverridesMap> = composeCommandInterceptorOverrides(),\n): Array<{ moduleId: string; interceptors: CommandInterceptor[] }> {\n return applyEntryListOverrides(entries, overrides as OverrideMap<CommandInterceptor>, {\n listKey: 'interceptors',\n label: 'commandInterceptors',\n getId: (entry) => entry.id,\n isReplacement: isCommandInterceptor,\n }) ?? []\n}\n\nexport function applyResponseEnricherOverridesToEntries(\n entries: readonly { moduleId: string; enrichers: ResponseEnricher[] }[],\n overrides: Readonly<ResponseEnricherOverridesMap> = composeResponseEnricherOverrides(),\n): Array<{ moduleId: string; enrichers: ResponseEnricher[] }> {\n return applyEntryListOverrides(entries, overrides as OverrideMap<ResponseEnricher>, {\n listKey: 'enrichers',\n label: 'enrichers',\n getId: (entry) => entry.id,\n isReplacement: isResponseEnricher,\n }) ?? []\n}\n\nexport function applyPageGuardOverridesToEntries(\n entries: readonly PageMiddlewareRegistryEntry[],\n overrides: Readonly<PageGuardOverridesMap> = composePageGuardOverrides(),\n): PageMiddlewareRegistryEntry[] {\n return applyEntryListOverrides(entries, overrides as OverrideMap<PageRouteMiddleware>, {\n listKey: 'middleware',\n label: 'guards',\n getId: (entry) => entry.id,\n isReplacement: isPageRouteMiddleware,\n }) ?? []\n}\n\nfunction applySetupOverride(setup: ModuleSetupConfig | undefined, override: SetupOverridesShape | undefined): ModuleSetupConfig | undefined {\n if (!override) return setup\n const next: ModuleSetupConfig = { ...(setup ?? {}) }\n if (override.defaultRoleFeatures) {\n next.defaultRoleFeatures = Object.fromEntries(\n Object.entries(override.defaultRoleFeatures).map(([role, features]) => [role, Array.from(features)]),\n )\n }\n if (override.defaultCustomerRoleFeatures) {\n next.defaultCustomerRoleFeatures = Object.fromEntries(\n Object.entries(override.defaultCustomerRoleFeatures).map(([role, features]) => [role, Array.from(features)]),\n )\n }\n if (override.seedDefaults === false) delete next.seedDefaults\n if (override.seedExamples === false) delete next.seedExamples\n if (override.onTenantCreated === false) delete next.onTenantCreated\n return next\n}\n\nexport function applyModuleOverridesToModules(modules: readonly Module[]): Module[] {\n const subscriberOverrides = composeSubscriberOverrides()\n const workerOverrides = composeWorkerOverrides()\n const cliOverrides = composeCliOverrides()\n const aclOverrides = composeAclFeatureOverrides()\n const encryptionOverrides = composeEncryptionMapOverrides()\n const hasSetupOverrides = Object.keys(setupOverridesByModule).length > 0\n const hasAny =\n Object.keys(subscriberOverrides).length > 0\n || Object.keys(workerOverrides).length > 0\n || Object.keys(cliOverrides).length > 0\n || Object.keys(aclOverrides).length > 0\n || Object.keys(encryptionOverrides).length > 0\n || hasSetupOverrides\n\n if (!hasAny) return modules as Module[]\n\n const subscriberConsumed = new Set<string>()\n const workerConsumed = new Set<string>()\n const cliConsumed = new Set<string>()\n const aclConsumed = new Set<string>()\n const encryptionConsumed = new Set<string>()\n\n const result = modules.map((module) => {\n let next = module\n\n const subscribers = applyArrayOverrides(module.subscribers, subscriberOverrides as OverrideMap<ModuleSubscriber>, {\n label: 'events.subscribers',\n getId: (entry) => entry.id,\n isReplacement: isModuleSubscriber,\n })\n for (const key of subscribers.consumed) subscriberConsumed.add(key)\n if (subscribers.changed) next = { ...next, subscribers: subscribers.items }\n\n const workers = applyArrayOverrides(module.workers, workerOverrides as OverrideMap<ModuleWorker>, {\n label: 'workers',\n getId: (entry) => entry.id,\n isReplacement: isModuleWorker,\n })\n for (const key of workers.consumed) workerConsumed.add(key)\n if (workers.changed) next = { ...next, workers: workers.items }\n\n const cli = applyArrayOverrides(module.cli, cliOverrides as OverrideMap<ModuleCli>, {\n label: 'cli',\n getId: (entry) => entry.command,\n isReplacement: isModuleCli,\n })\n for (const key of cli.consumed) cliConsumed.add(key)\n if (cli.changed) next = { ...next, cli: cli.items }\n\n const features = applyArrayOverrides(module.features, aclOverrides as OverrideMap<NonNullable<Module['features']>[number]>, {\n label: 'acl.features',\n getId: getFeatureId,\n isReplacement: (value): value is NonNullable<Module['features']>[number] => getFeatureId(value) !== null,\n })\n for (const key of features.consumed) aclConsumed.add(key)\n if (features.changed) next = { ...next, features: features.items }\n\n const maps = applyArrayOverrides(module.defaultEncryptionMaps, encryptionOverrides as OverrideMap<ModuleEncryptionMap>, {\n label: 'encryption.maps',\n getId: (entry) => entry.entityId,\n isReplacement: isEncryptionMap,\n })\n for (const key of maps.consumed) encryptionConsumed.add(key)\n if (maps.changed) next = { ...next, defaultEncryptionMaps: maps.items }\n\n const setupOverride = setupOverridesByModule[module.id]\n if (setupOverride) {\n next = { ...next, setup: applySetupOverride(module.setup, setupOverride) }\n }\n\n return next\n })\n\n warnStaleOverrides('events.subscribers', subscriberOverrides, subscriberConsumed)\n warnStaleOverrides('workers', workerOverrides, workerConsumed)\n warnStaleOverrides('cli', cliOverrides, cliConsumed)\n warnStaleOverrides('acl.features', aclOverrides, aclConsumed)\n warnStaleOverrides('encryption.maps', encryptionOverrides, encryptionConsumed)\n\n return result\n}\n\nexport function applyDiOverridesToContainer(container: {\n register: (registrations: Record<string, unknown>) => unknown\n unregister?: (name: string) => unknown\n registrations?: Record<string, unknown>\n}): void {\n const overrides = composeDiOverrides()\n for (const [key, value] of Object.entries(overrides)) {\n if (value === null) {\n if (typeof container.unregister === 'function') {\n container.unregister(key)\n } else if (container.registrations && key in container.registrations) {\n delete container.registrations[key]\n }\n continue\n }\n if (value && typeof value === 'object' && typeof (value as DiBindingOverrideDefinition).register === 'function') {\n ;(value as DiBindingOverrideDefinition).register(container, key)\n continue\n }\n container.register({ [key]: value })\n }\n}\n\n/**\n * Dispatcher applier for the `'routes'` domain. Buckets every entry's\n * `overrides.routes.api` and `overrides.routes.pages` into the\n * `modules.ts` tier.\n */\nfunction routesOverridesApplier(\n entries: ReadonlyArray<ModuleOverrideEntry<RoutesOverridesShape>>,\n): void {\n for (const entry of entries) {\n const shape = entry.overrides\n if (!shape || typeof shape !== 'object') continue\n const api = shape.api\n if (api && typeof api === 'object') {\n for (const [rawKey, value] of Object.entries(api)) {\n const key = normalizeApiRouteOverrideKey(rawKey)\n if (!key) {\n logger.warn('Skipping malformed routes.api key \u2014 expected \"METHOD /api/path\"', { key: rawKey })\n continue\n }\n modulesConfigApiRouteOverrides[key] = value as ApiRouteOverride\n }\n }\n const pages = shape.pages\n if (pages && typeof pages === 'object' && Object.keys(pages).length > 0) {\n applyStoreOverrides(pageRouteOverrideStore, 'modules', pages as OverrideMap<PageRouteOverrideDefinition>, {\n label: 'routes.pages',\n normalizeKey: normalizePageRouteOverrideKey,\n })\n }\n }\n}\n\nfunction eventsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<EventsOverridesShape>>): void {\n for (const entry of entries) {\n const subscribers = entry.overrides?.subscribers\n applyStoreOverrides(subscriberOverrideStore, 'modules', subscribers as OverrideMap<ModuleSubscriber>, { label: 'events.subscribers' })\n }\n}\n\nfunction workersOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<WorkerOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(workerOverrideStore, 'modules', entry.overrides as OverrideMap<ModuleWorker>, { label: 'workers' })\n }\n}\n\nfunction widgetsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<WidgetsOverridesShape>>): void {\n for (const entry of entries) {\n applyStoreOverrides(injectionWidgetOverrideStore, 'modules', entry.overrides?.injection as OverrideMap<ModuleInjectionWidgetEntry>, { label: 'widgets.injection' })\n applyStoreOverrides(componentOverrideStore, 'modules', entry.overrides?.components as OverrideMap<ComponentOverride | ComponentOverride[]>, { label: 'widgets.components' })\n applyStoreOverrides(dashboardWidgetOverrideStore, 'modules', entry.overrides?.dashboard as OverrideMap<ModuleDashboardWidgetEntry>, { label: 'widgets.dashboard' })\n }\n}\n\nfunction notificationsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<NotificationsOverridesShape>>): void {\n for (const entry of entries) {\n applyStoreOverrides(notificationTypeOverrideStore, 'modules', entry.overrides?.types as OverrideMap<NotificationTypeDefinition>, { label: 'notifications.types' })\n applyStoreOverrides(notificationHandlerOverrideStore, 'modules', entry.overrides?.handlers as OverrideMap<NotificationHandler>, { label: 'notifications.handlers' })\n }\n}\n\nfunction interceptorsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<ApiInterceptorOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(apiInterceptorOverrideStore, 'modules', entry.overrides as OverrideMap<ApiInterceptor>, { label: 'interceptors' })\n }\n}\n\nfunction commandInterceptorsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<CommandInterceptorOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(commandInterceptorOverrideStore, 'modules', entry.overrides as OverrideMap<CommandInterceptor>, { label: 'commandInterceptors' })\n }\n}\n\nfunction enrichersOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<ResponseEnricherOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(responseEnricherOverrideStore, 'modules', entry.overrides as OverrideMap<ResponseEnricher>, { label: 'enrichers' })\n }\n}\n\nfunction guardsOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<PageGuardOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(pageGuardOverrideStore, 'modules', entry.overrides as OverrideMap<PageRouteMiddleware>, { label: 'guards' })\n }\n}\n\nfunction cliOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<CliOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(cliOverrideStore, 'modules', entry.overrides as OverrideMap<ModuleCli>, { label: 'cli' })\n }\n}\n\nfunction setupOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<SetupOverridesShape>>): void {\n for (const entry of entries) {\n if (!entry.overrides || typeof entry.overrides !== 'object') continue\n setupOverridesByModule[entry.moduleId] = entry.overrides\n }\n}\n\nfunction aclOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<AclOverridesShape>>): void {\n for (const entry of entries) {\n applyStoreOverrides(aclFeatureOverrideStore, 'modules', entry.overrides?.features as OverrideMap<Exclude<AclFeatureOverride, null>>, { label: 'acl.features' })\n }\n}\n\nfunction diOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<DiOverridesMap>>): void {\n for (const entry of entries) {\n applyStoreOverrides(diOverrideStore, 'modules', entry.overrides as OverrideMap<Exclude<DiBindingOverride, null>>, { label: 'di' })\n }\n}\n\nfunction encryptionOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<EncryptionOverridesShape>>): void {\n for (const entry of entries) {\n applyStoreOverrides(encryptionMapOverrideStore, 'modules', entry.overrides?.maps as OverrideMap<ModuleEncryptionMap>, { label: 'encryption.maps' })\n }\n}\n\nfunction navOverridesApplier(entries: ReadonlyArray<ModuleOverrideEntry<NavOverridesShape>>): void {\n const state = getNavOverrideState()\n for (const entry of entries) {\n const groupOrder = normalizeNavGroupOrder(entry.overrides?.groupOrder)\n if (!groupOrder) continue\n if (state.modules && state.modules.moduleId !== entry.moduleId) {\n logger.warn('nav.groupOrder declared by more than one module \u2014 the later one wins', {\n previousModuleId: state.modules.moduleId,\n moduleId: entry.moduleId,\n hint: 'Sidebar group ordering is a single app-wide decision; declare it on one module entry.',\n })\n }\n state.modules = { moduleId: entry.moduleId, groupOrder }\n }\n}\n\nfunction registerBuiltInModuleOverrideAppliers(): void {\n registerModuleOverrideApplier<NavOverridesShape>('nav', navOverridesApplier)\n registerModuleOverrideApplier<RoutesOverridesShape>('routes', routesOverridesApplier)\n registerModuleOverrideApplier<EventsOverridesShape>('events', eventsOverridesApplier)\n registerModuleOverrideApplier<WorkerOverridesMap>('workers', workersOverridesApplier)\n registerModuleOverrideApplier<WidgetsOverridesShape>('widgets', widgetsOverridesApplier)\n registerModuleOverrideApplier<NotificationsOverridesShape>('notifications', notificationsOverridesApplier)\n registerModuleOverrideApplier<ApiInterceptorOverridesMap>('interceptors', interceptorsOverridesApplier)\n registerModuleOverrideApplier<CommandInterceptorOverridesMap>('commandInterceptors', commandInterceptorsOverridesApplier)\n registerModuleOverrideApplier<ResponseEnricherOverridesMap>('enrichers', enrichersOverridesApplier)\n registerModuleOverrideApplier<PageGuardOverridesMap>('guards', guardsOverridesApplier)\n registerModuleOverrideApplier<CliOverridesMap>('cli', cliOverridesApplier)\n registerModuleOverrideApplier<SetupOverridesShape>('setup', setupOverridesApplier)\n registerModuleOverrideApplier<AclOverridesShape>('acl', aclOverridesApplier)\n registerModuleOverrideApplier<DiOverridesMap>('di', diOverridesApplier)\n registerModuleOverrideApplier<EncryptionOverridesShape>('encryption', encryptionOverridesApplier)\n}\n\nregisterBuiltInModuleOverrideAppliers()\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,37 @@
1
+ function resolvePageRouteMetadata(pattern, metadata) {
2
+ return {
3
+ pattern: pattern || "/",
4
+ requireAuth: metadata?.requireAuth,
5
+ requireRoles: Array.isArray(metadata?.requireRoles) ? [...metadata.requireRoles] : void 0,
6
+ requireFeatures: Array.isArray(metadata?.requireFeatures) ? [...metadata.requireFeatures] : void 0,
7
+ requireCustomerAuth: metadata?.requireCustomerAuth,
8
+ requireCustomerFeatures: Array.isArray(metadata?.requireCustomerFeatures) ? [...metadata.requireCustomerFeatures] : void 0,
9
+ nav: metadata?.nav,
10
+ title: metadata?.pageTitle ?? metadata?.title,
11
+ titleKey: metadata?.pageTitleKey ?? metadata?.titleKey,
12
+ group: metadata?.pageGroup ?? metadata?.group,
13
+ groupKey: metadata?.pageGroupKey ?? metadata?.groupKey,
14
+ icon: metadata?.icon,
15
+ order: metadata?.pageOrder ?? metadata?.order,
16
+ priority: metadata?.pagePriority ?? metadata?.priority,
17
+ navHidden: metadata?.navHidden,
18
+ visible: metadata?.visible,
19
+ enabled: metadata?.enabled,
20
+ breadcrumb: metadata?.breadcrumb,
21
+ pageContext: metadata?.pageContext,
22
+ placement: metadata?.placement
23
+ };
24
+ }
25
+ function resolveDeclaredPageRouteMetadata(metadata) {
26
+ const { pattern: _pattern, ...resolved } = resolvePageRouteMetadata("/", metadata);
27
+ const declared = {};
28
+ for (const [key, value] of Object.entries(resolved)) {
29
+ if (value !== void 0) declared[key] = value;
30
+ }
31
+ return declared;
32
+ }
33
+ export {
34
+ resolveDeclaredPageRouteMetadata,
35
+ resolvePageRouteMetadata
36
+ };
37
+ //# sourceMappingURL=pageRouteMetadata.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/modules/pageRouteMetadata.ts"],
4
+ "sourcesContent": ["/**\n * Resolution of a page's authored `PageMetadata` into the flat `ModuleRouteMetadata`\n * shape that route manifests carry.\n *\n * This lives in its own module rather than in `registry.ts` so `overrides.ts` can reuse\n * it without an import cycle (`registry.ts` imports the override appliers). `registry.ts`\n * re-exports `resolvePageRouteMetadata` so its published import path stays valid.\n *\n * Because `overrides.ts` feeds this module-authored override metadata it deliberately treats\n * as untrusted (it warns and skips on malformed keys and values), the guard arrays are copied\n * behind an `Array.isArray` check: a mistyped `requireRoles` in one app's `modules.ts` must not\n * throw while route manifests are being built, nor be spread into a bogus character array.\n */\nimport type { ModuleRouteMetadata, PageMetadata } from './registry'\n\nexport function resolvePageRouteMetadata(pattern: string, metadata: PageMetadata | null | undefined): ModuleRouteMetadata {\n return {\n pattern: pattern || '/',\n requireAuth: metadata?.requireAuth,\n requireRoles: Array.isArray(metadata?.requireRoles) ? [...metadata.requireRoles] : undefined,\n requireFeatures: Array.isArray(metadata?.requireFeatures) ? [...metadata.requireFeatures] : undefined,\n requireCustomerAuth: metadata?.requireCustomerAuth,\n requireCustomerFeatures: Array.isArray(metadata?.requireCustomerFeatures) ? [...metadata.requireCustomerFeatures] : undefined,\n nav: metadata?.nav,\n title: metadata?.pageTitle ?? metadata?.title,\n titleKey: metadata?.pageTitleKey ?? metadata?.titleKey,\n group: metadata?.pageGroup ?? metadata?.group,\n groupKey: metadata?.pageGroupKey ?? metadata?.groupKey,\n icon: metadata?.icon,\n order: metadata?.pageOrder ?? metadata?.order,\n priority: metadata?.pagePriority ?? metadata?.priority,\n navHidden: metadata?.navHidden,\n visible: metadata?.visible,\n enabled: metadata?.enabled,\n breadcrumb: metadata?.breadcrumb,\n pageContext: metadata?.pageContext,\n placement: metadata?.placement,\n }\n}\n\n/**\n * The subset of `resolvePageRouteMetadata`'s output a caller actually declared.\n *\n * A page override supplies a partial `PageMetadata`, so merging the full resolved shape\n * would overwrite fields the override never mentioned with `undefined`. Dropping the\n * undefined entries keeps an override additive while still normalizing the `page*`\n * aliases (`pageOrder` \u2192 `order`, `pageTitle` \u2192 `title`, \u2026) that the manifest reads (#4845).\n *\n * `pattern` is never part of the result: an override adjusts a route's metadata, never the\n * route key it was matched by.\n */\nexport function resolveDeclaredPageRouteMetadata(\n metadata: PageMetadata | null | undefined,\n): Partial<ModuleRouteMetadata> {\n const { pattern: _pattern, ...resolved } = resolvePageRouteMetadata('/', metadata)\n const declared: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(resolved)) {\n if (value !== undefined) declared[key] = value\n }\n return declared as Partial<ModuleRouteMetadata>\n}\n"],
5
+ "mappings": "AAeO,SAAS,yBAAyB,SAAiB,UAAgE;AACxH,SAAO;AAAA,IACL,SAAS,WAAW;AAAA,IACpB,aAAa,UAAU;AAAA,IACvB,cAAc,MAAM,QAAQ,UAAU,YAAY,IAAI,CAAC,GAAG,SAAS,YAAY,IAAI;AAAA,IACnF,iBAAiB,MAAM,QAAQ,UAAU,eAAe,IAAI,CAAC,GAAG,SAAS,eAAe,IAAI;AAAA,IAC5F,qBAAqB,UAAU;AAAA,IAC/B,yBAAyB,MAAM,QAAQ,UAAU,uBAAuB,IAAI,CAAC,GAAG,SAAS,uBAAuB,IAAI;AAAA,IACpH,KAAK,UAAU;AAAA,IACf,OAAO,UAAU,aAAa,UAAU;AAAA,IACxC,UAAU,UAAU,gBAAgB,UAAU;AAAA,IAC9C,OAAO,UAAU,aAAa,UAAU;AAAA,IACxC,UAAU,UAAU,gBAAgB,UAAU;AAAA,IAC9C,MAAM,UAAU;AAAA,IAChB,OAAO,UAAU,aAAa,UAAU;AAAA,IACxC,UAAU,UAAU,gBAAgB,UAAU;AAAA,IAC9C,WAAW,UAAU;AAAA,IACrB,SAAS,UAAU;AAAA,IACnB,SAAS,UAAU;AAAA,IACnB,YAAY,UAAU;AAAA,IACtB,aAAa,UAAU;AAAA,IACvB,WAAW,UAAU;AAAA,EACvB;AACF;AAaO,SAAS,iCACd,UAC8B;AAC9B,QAAM,EAAE,SAAS,UAAU,GAAG,SAAS,IAAI,yBAAyB,KAAK,QAAQ;AACjF,QAAM,WAAoC,CAAC;AAC3C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,QAAI,UAAU,OAAW,UAAS,GAAG,IAAI;AAAA,EAC3C;AACA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -127,30 +127,7 @@ function findApiRouteManifestMatch(routes, method, pathname) {
127
127
  }
128
128
  }
129
129
  }
130
- function resolvePageRouteMetadata(pattern, metadata) {
131
- return {
132
- pattern: pattern || "/",
133
- requireAuth: metadata?.requireAuth,
134
- requireRoles: metadata?.requireRoles ? [...metadata.requireRoles] : void 0,
135
- requireFeatures: metadata?.requireFeatures ? [...metadata.requireFeatures] : void 0,
136
- requireCustomerAuth: metadata?.requireCustomerAuth,
137
- requireCustomerFeatures: metadata?.requireCustomerFeatures ? [...metadata.requireCustomerFeatures] : void 0,
138
- nav: metadata?.nav,
139
- title: metadata?.pageTitle ?? metadata?.title,
140
- titleKey: metadata?.pageTitleKey ?? metadata?.titleKey,
141
- group: metadata?.pageGroup ?? metadata?.group,
142
- groupKey: metadata?.pageGroupKey ?? metadata?.groupKey,
143
- icon: metadata?.icon,
144
- order: metadata?.pageOrder ?? metadata?.order,
145
- priority: metadata?.pagePriority ?? metadata?.priority,
146
- navHidden: metadata?.navHidden,
147
- visible: metadata?.visible,
148
- enabled: metadata?.enabled,
149
- breadcrumb: metadata?.breadcrumb,
150
- pageContext: metadata?.pageContext,
151
- placement: metadata?.placement
152
- };
153
- }
130
+ import { resolvePageRouteMetadata } from "./pageRouteMetadata.js";
154
131
  let _backendRouteManifests = null;
155
132
  function registerBackendRouteManifests(routes) {
156
133
  const pageOverrides = composePageRouteOverrides();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/modules/registry.ts"],
4
- "sourcesContent": ["import type { ReactNode } from 'react'\nimport type { OpenApiRouteDoc, OpenApiMethodDoc } from '@open-mercato/shared/lib/openapi/types'\nimport type { SyncCrudEventResult } from '../lib/crud/sync-event-types'\nimport type { DashboardWidgetModule } from './dashboard/widgets'\nimport type { InjectionAnyWidgetModule, ModuleInjectionTable } from './widgets/injection'\nimport type { IntegrationBundle, IntegrationDefinition } from './integrations/types'\nimport { createLogger } from '../lib/logger'\nimport {\n applyApiOverridesToManifests,\n applyModuleOverridesToModules,\n applyPageOverridesToManifests,\n composeApiRouteOverrides,\n composePageRouteOverrides,\n} from './overrides'\n\nconst logger = createLogger('shared').child({ component: 'cli-registry' })\n\n// Context passed to dynamic metadata guards\nexport type RouteVisibilityContext = { path?: string; auth?: any }\n\n/**\n * Portal sidebar navigation hint. When declared on a portal page's metadata,\n * the page is auto-listed in the portal sidebar (subject to RBAC) by the\n * `/api/customer_accounts/portal/nav` endpoint.\n *\n * Absence of `nav` means the page is routable but not auto-listed (useful for\n * detail pages, create forms, etc.).\n */\nexport type PortalNavMetadata = {\n label: string\n labelKey?: string\n group?: 'main' | 'account'\n order?: number\n icon?: string\n}\n\n// Metadata you can export from page.meta.ts or directly from a server page\nexport type PageMetadata = {\n requireAuth?: boolean\n /** @deprecated Use `requireFeatures` instead \u2014 role names are mutable and can be spoofed */\n requireRoles?: readonly string[]\n // Optional fine-grained feature requirements\n requireFeatures?: readonly string[]\n // Portal: require customer (portal user) authentication instead of staff auth\n requireCustomerAuth?: boolean\n // Portal: require customer-specific features (checked against CustomerRbacService)\n requireCustomerFeatures?: readonly string[]\n // Portal: optional sidebar presentation hint (auto-listed by portal nav endpoint)\n nav?: PortalNavMetadata\n // Titles and grouping (aliases supported)\n title?: string\n titleKey?: string\n pageTitle?: string\n pageTitleKey?: string\n group?: string\n groupKey?: string\n pageGroup?: string\n pageGroupKey?: string\n // Ordering and visuals\n order?: number\n pageOrder?: number\n priority?: number\n pagePriority?: number\n icon?: ReactNode\n navHidden?: boolean\n // Dynamic flags\n visible?: (ctx: RouteVisibilityContext) => boolean | Promise<boolean>\n enabled?: (ctx: RouteVisibilityContext) => boolean | Promise<boolean>\n // Optional static breadcrumb trail for header\n breadcrumb?: Array<{ label: string; labelKey?: string; href?: string }>\n // Navigation context for tiered navigation:\n // - 'main' (default): Main sidebar business operations\n // - 'admin': Collapsible \"Settings & Admin\" section at bottom of sidebar\n // - 'settings': Hidden from sidebar, only accessible via Settings hub page\n // - 'profile': Profile dropdown items\n pageContext?: 'main' | 'admin' | 'settings' | 'profile'\n placement?: {\n section: string\n sectionLabel?: string\n sectionLabelKey?: string\n order?: number\n }\n}\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n\nexport type ApiHandler = (req: Request, ctx?: any) => Promise<Response> | Response\n\nexport type ModuleSubscriberHandler = (\n payload: any,\n ctx: any\n) => Promise<void | SyncCrudEventResult> | void | SyncCrudEventResult\n\nexport type ModuleWorkerHandler = (job: unknown, ctx: unknown) => Promise<void> | void\n\nexport type ModuleRoute = {\n pattern?: string\n path?: string\n requireAuth?: boolean\n /** @deprecated Use `requireFeatures` instead \u2014 role names are mutable and can be spoofed */\n requireRoles?: string[]\n // Optional fine-grained feature requirements\n requireFeatures?: string[]\n // Portal: require customer (portal user) authentication instead of staff auth\n requireCustomerAuth?: boolean\n // Portal: require customer-specific features (checked against CustomerRbacService)\n requireCustomerFeatures?: string[]\n // Portal: optional sidebar presentation hint (auto-listed by portal nav endpoint)\n nav?: PortalNavMetadata\n title?: string\n titleKey?: string\n group?: string\n groupKey?: string\n icon?: ReactNode\n order?: number\n priority?: number\n navHidden?: boolean\n visible?: (ctx: RouteVisibilityContext) => boolean | Promise<boolean>\n enabled?: (ctx: RouteVisibilityContext) => boolean | Promise<boolean>\n breadcrumb?: Array<{ label: string; labelKey?: string; href?: string }>\n pageContext?: 'main' | 'admin' | 'settings' | 'profile'\n placement?: {\n section: string\n sectionLabel?: string\n sectionLabelKey?: string\n order?: number\n }\n Component: (props: any) => ReactNode | Promise<ReactNode>\n}\n\nexport type ModuleRouteMetadata = Omit<ModuleRoute, 'Component'>\n\nexport type ModuleApiLegacy = {\n method: HttpMethod\n path: string\n handler: ApiHandler\n metadata?: Record<string, unknown>\n docs?: OpenApiMethodDoc\n}\n\nexport type ModuleApiRouteFile = {\n path: string\n handlers: Partial<Record<HttpMethod, ApiHandler>>\n requireAuth?: boolean\n /** @deprecated Use `requireFeatures` instead \u2014 role names are mutable and can be spoofed */\n requireRoles?: string[]\n // Optional fine-grained feature requirements for the entire route file\n // Note: per-method feature requirements should be expressed inside metadata\n requireFeatures?: string[]\n docs?: OpenApiRouteDoc\n metadata?: Partial<Record<HttpMethod, unknown>>\n}\n\nexport type ModuleApi = ModuleApiLegacy | ModuleApiRouteFile\n\nexport type RouteMatchParams = Record<string, string | string[]>\n\nexport type FrontendRouteManifestEntry = Omit<ModuleRoute, 'Component'> & {\n moduleId: string\n load: () => Promise<ModuleRoute['Component']>\n}\n\nexport type BackendRouteManifestEntry = Omit<ModuleRoute, 'Component'> & {\n moduleId: string\n load: () => Promise<ModuleRoute['Component']>\n}\n\nexport type ApiRouteManifestEntry = {\n moduleId: string\n kind: 'route-file' | 'legacy'\n path: string\n methods: HttpMethod[]\n method?: HttpMethod\n load: () => Promise<Record<string, unknown>>\n}\n\nexport type ModuleCli = {\n command: string\n run: (argv: string[]) => Promise<void> | void\n}\n\nexport type ModuleSubscriber = {\n id: string\n moduleId?: string\n event: string\n persistent?: boolean\n sync?: boolean\n priority?: number\n handler: ModuleSubscriberHandler\n}\n\nexport type ModuleWorker = {\n id: string\n moduleId?: string\n queue: string\n concurrency: number\n lockDuration?: number\n maxStalledCount?: number\n handler: ModuleWorkerHandler\n}\n\nexport type ModuleInfo = {\n name?: string\n title?: string\n version?: string\n description?: string\n author?: string\n license?: string\n homepage?: string\n copyright?: string\n // Optional hard dependencies: module ids that must be enabled\n requires?: string[]\n // Whether this module can be ejected into the app's src/modules/ for customization\n ejectable?: boolean\n}\n\nexport type ModuleDashboardWidgetEntry = {\n moduleId: string\n key: string\n source: 'app' | 'package'\n loader: () => Promise<DashboardWidgetModule<any>>\n}\n\nexport type ModuleInjectionWidgetEntry = {\n moduleId: string\n key: string\n source: 'app' | 'package'\n widgetId?: string\n loader: () => Promise<InjectionAnyWidgetModule<any, any>>\n}\n\nexport type Module = {\n id: string\n info?: ModuleInfo\n backendRoutes?: ModuleRoute[]\n frontendRoutes?: ModuleRoute[]\n apis?: ModuleApi[]\n cli?: ModuleCli[]\n translations?: Record<string, Record<string, string>>\n // Optional: per-module feature declarations discovered from acl.ts (module root)\n features?: Array<{ id: string; title: string; module: string }>\n // Auto-discovered event subscribers\n subscribers?: ModuleSubscriber[]\n // Auto-discovered queue workers\n workers?: ModuleWorker[]\n // Optional: per-module declared entity extensions and custom fields (static)\n // Extensions discovered from data/extensions.ts; Custom fields discovered from ce.ts (entities[].fields)\n entityExtensions?: import('./entities').EntityExtension[]\n customFieldSets?: import('./entities').CustomFieldSet[]\n // Optional: per-module declared custom entities (virtual/logical entities)\n // Discovered from ce.ts (module root). Each entry represents an entityId with optional label/description.\n customEntities?: Array<{ id: string; label?: string; description?: string }>\n dashboardWidgets?: ModuleDashboardWidgetEntry[]\n injectionWidgets?: ModuleInjectionWidgetEntry[]\n injectionTable?: ModuleInjectionTable\n // Optional: per-module vector search configuration (discovered from vector.ts)\n vector?: import('./vector').VectorModuleConfig\n // Optional: module-specific tenant setup configuration (from setup.ts)\n setup?: import('./setup').ModuleSetupConfig\n // Optional: default encryption maps owned by the module (from encryption.ts)\n defaultEncryptionMaps?: import('./encryption').ModuleEncryptionMap[]\n // Optional: integration marketplace declarations discovered from integration.ts\n integrations?: IntegrationDefinition[]\n bundles?: IntegrationBundle[]\n}\n\nfunction normPath(s: string) {\n return (s.startsWith('/') ? s : '/' + s).replace(/\\/+$/, '') || '/'\n}\n\n// 0 = literal (most specific), 1 = dynamic [param], 2 = catch-all [...param] or [[...param]]\nfunction segmentSpecificity(seg: string): 0 | 1 | 2 {\n if (seg.startsWith('[[...') || seg.startsWith('[...')) return 2\n if (seg.startsWith('[')) return 1\n return 0\n}\n\nfunction compareRouteSpecificity(aPattern: string, bPattern: string): number {\n const aSegs = aPattern.split('/')\n const bSegs = bPattern.split('/')\n const len = Math.max(aSegs.length, bSegs.length)\n for (let i = 0; i < len; i++) {\n const av = i < aSegs.length ? segmentSpecificity(aSegs[i]) : -1\n const bv = i < bSegs.length ? segmentSpecificity(bSegs[i]) : -1\n if (av !== bv) return av - bv\n }\n return 0\n}\n\nexport function sortRoutesBySpecificity<T extends { pattern?: string; path?: string }>(routes: T[]): T[] {\n return [...routes].sort((a, b) =>\n compareRouteSpecificity(a.pattern ?? a.path ?? '/', b.pattern ?? b.path ?? '/'),\n )\n}\n\n// Memoized per-array sorted view, so direct callers (e.g., the Next.js catch-all\n// routes that import generated `frontendRoutes`/`backendRoutes`/`apiRoutes`\n// arrays) match against a specificity-sorted view even if they never call\n// `register*RouteManifests`. Keyed by array reference; generated arrays are\n// module-level constants so this caches once per process.\nconst sortedRoutesCache = new WeakMap<object, readonly unknown[]>()\n\nfunction ensureSortedRoutes<T extends { pattern?: string; path?: string }>(routes: readonly T[]): readonly T[] {\n const cached = sortedRoutesCache.get(routes) as readonly T[] | undefined\n if (cached) return cached\n const sorted = sortRoutesBySpecificity([...routes])\n sortedRoutesCache.set(routes, sorted)\n return sorted\n}\n\nexport function matchRoutePattern(pattern: string, pathname: string): RouteMatchParams | undefined {\n const p = normPath(pattern)\n const u = normPath(pathname)\n const pSegs = p.split('/').slice(1)\n const uSegs = u.split('/').slice(1)\n const params: Record<string, string | string[]> = {}\n let i = 0\n for (let j = 0; j < pSegs.length; j++, i++) {\n const seg = pSegs[j]\n const mCatchAll = seg.match(/^\\[\\.\\.\\.(.+)\\]$/)\n const mOptCatch = seg.match(/^\\[\\[\\.\\.\\.(.+)\\]\\]$/)\n const mDyn = seg.match(/^\\[(.+)\\]$/)\n if (mCatchAll) {\n const key = mCatchAll[1]\n if (i >= uSegs.length) return undefined\n params[key] = uSegs.slice(i)\n return params\n } else if (mOptCatch) {\n const key = mOptCatch[1]\n params[key] = i < uSegs.length ? uSegs.slice(i) : []\n return params\n } else if (mDyn) {\n if (i >= uSegs.length) return undefined\n params[mDyn[1]] = uSegs[i]\n } else {\n if (i >= uSegs.length || uSegs[i].toLowerCase() !== seg.toLowerCase()) return undefined\n }\n }\n if (i !== uSegs.length) return undefined\n return params\n}\n\nfunction getPattern(r: ModuleRoute) {\n return r.pattern ?? r.path ?? '/'\n}\n\nexport function findFrontendMatch(modules: Module[], pathname: string): { route: ModuleRoute; params: Record<string, string | string[]> } | undefined {\n for (const m of modules) {\n const routes = m.frontendRoutes ?? []\n for (const r of routes) {\n const params = matchRoutePattern(getPattern(r), pathname)\n if (params) return { route: r, params }\n }\n }\n}\n\nexport function findBackendMatch(modules: Module[], pathname: string): { route: ModuleRoute; params: Record<string, string | string[]> } | undefined {\n for (const m of modules) {\n const routes = m.backendRoutes ?? []\n for (const r of routes) {\n const params = matchRoutePattern(getPattern(r), pathname)\n if (params) return { route: r, params }\n }\n }\n}\n\nexport function findApi(modules: Module[], method: HttpMethod, pathname: string): { handler: ApiHandler; params: Record<string, string | string[]>; requireAuth?: boolean; requireRoles?: string[]; metadata?: any } | undefined {\n for (const m of modules) {\n const apis = m.apis ?? []\n for (const a of apis) {\n if ('handlers' in a) {\n const params = matchRoutePattern(a.path, pathname)\n const handler = (a.handlers as any)[method]\n if (params && handler) return { handler, params, requireAuth: a.requireAuth, requireRoles: (a as any).requireRoles, metadata: (a as any).metadata }\n } else {\n const al = a as ModuleApiLegacy\n if (al.method !== method) continue\n const params = matchRoutePattern(al.path, pathname)\n if (params) {\n return { handler: al.handler, params, metadata: al.metadata }\n }\n }\n }\n }\n}\n\nexport function findRouteManifestMatch<T extends { pattern?: string; path?: string }>(\n routes: T[],\n pathname: string\n): { route: T; params: RouteMatchParams } | undefined {\n for (const route of ensureSortedRoutes(routes)) {\n const params = matchRoutePattern(route.pattern ?? route.path ?? '/', pathname)\n if (params) {\n return { route, params }\n }\n }\n}\n\nexport function findApiRouteManifestMatch<T extends { path: string; methods: HttpMethod[] }>(\n routes: T[],\n method: HttpMethod,\n pathname: string\n): { route: T; params: RouteMatchParams } | undefined {\n for (const route of ensureSortedRoutes(routes)) {\n if (!route.methods.includes(method)) continue\n const params = matchRoutePattern(route.path, pathname)\n if (params) {\n return { route, params }\n }\n }\n}\n\nexport function resolvePageRouteMetadata(pattern: string, metadata: PageMetadata | null | undefined): ModuleRouteMetadata {\n return {\n pattern: pattern || '/',\n requireAuth: metadata?.requireAuth,\n requireRoles: metadata?.requireRoles ? [...metadata.requireRoles] : undefined,\n requireFeatures: metadata?.requireFeatures ? [...metadata.requireFeatures] : undefined,\n requireCustomerAuth: metadata?.requireCustomerAuth,\n requireCustomerFeatures: metadata?.requireCustomerFeatures ? [...metadata.requireCustomerFeatures] : undefined,\n nav: metadata?.nav,\n title: metadata?.pageTitle ?? metadata?.title,\n titleKey: metadata?.pageTitleKey ?? metadata?.titleKey,\n group: metadata?.pageGroup ?? metadata?.group,\n groupKey: metadata?.pageGroupKey ?? metadata?.groupKey,\n icon: metadata?.icon,\n order: metadata?.pageOrder ?? metadata?.order,\n priority: metadata?.pagePriority ?? metadata?.priority,\n navHidden: metadata?.navHidden,\n visible: metadata?.visible,\n enabled: metadata?.enabled,\n breadcrumb: metadata?.breadcrumb,\n pageContext: metadata?.pageContext,\n placement: metadata?.placement,\n }\n}\n\nlet _backendRouteManifests: BackendRouteManifestEntry[] | null = null\n\nexport function registerBackendRouteManifests(routes: BackendRouteManifestEntry[]) {\n const pageOverrides = composePageRouteOverrides()\n const finalRoutes = Object.keys(pageOverrides).length === 0\n ? routes\n : applyPageOverridesToManifests(routes, pageOverrides, 'backend')\n _backendRouteManifests = sortRoutesBySpecificity(finalRoutes)\n}\n\nexport function getBackendRouteManifests(): BackendRouteManifestEntry[] {\n return _backendRouteManifests ?? []\n}\n\nlet _frontendRouteManifests: FrontendRouteManifestEntry[] | null = null\n\nexport function registerFrontendRouteManifests(routes: FrontendRouteManifestEntry[]) {\n const pageOverrides = composePageRouteOverrides()\n const finalRoutes = Object.keys(pageOverrides).length === 0\n ? routes\n : applyPageOverridesToManifests(routes, pageOverrides, 'frontend')\n _frontendRouteManifests = sortRoutesBySpecificity(finalRoutes)\n}\n\nexport function getFrontendRouteManifests(): FrontendRouteManifestEntry[] {\n return _frontendRouteManifests ?? []\n}\n\nlet _apiRouteManifests: ApiRouteManifestEntry[] | null = null\n\nexport function registerApiRouteManifests(routes: ApiRouteManifestEntry[]) {\n // Apply any `entry.overrides.routes.api` overrides registered through the\n // unified `modules.ts` dispatcher or programmatic API before storing the\n // manifest. The composer is cheap and returns an empty object when no\n // overrides exist, so this is a no-op for apps that do not opt in.\n const routeOverrides = composeApiRouteOverrides()\n const finalRoutes = Object.keys(routeOverrides).length === 0\n ? routes\n : applyApiOverridesToManifests(routes, routeOverrides)\n _apiRouteManifests = sortRoutesBySpecificity(finalRoutes)\n}\n\nexport function getApiRouteManifests(): ApiRouteManifestEntry[] {\n return _apiRouteManifests ?? []\n}\n\n// CLI modules registry - shared between CLI and module workers\nlet _cliModules: Module[] | null = null\n\nexport function registerCliModules(modules: Module[]) {\n if (_cliModules !== null && process.env.NODE_ENV === 'development') {\n logger.debug('CLI modules re-registered (this may occur during HMR)')\n }\n _cliModules = applyModuleOverridesToModules(modules)\n}\n\nexport function getCliModules(): Module[] {\n // Return empty array if not registered - allows generate command to work without bootstrap\n return _cliModules ?? []\n}\n\nexport function hasCliModules(): boolean {\n return _cliModules !== null && _cliModules.length > 0\n}\n\nexport function getDefaultEncryptionMaps(modules: Module[]): import('./encryption').ModuleEncryptionMap[] {\n const byEntityId = new Map<string, { moduleId: string; map: import('./encryption').ModuleEncryptionMap }>()\n\n for (const mod of modules) {\n for (const entry of mod.defaultEncryptionMaps ?? []) {\n const previous = byEntityId.get(entry.entityId)\n if (previous) {\n throw new Error(\n `[registry] Duplicate default encryption map for \"${entry.entityId}\" declared by \"${previous.moduleId}\" and \"${mod.id}\"`\n )\n }\n byEntityId.set(entry.entityId, {\n moduleId: mod.id,\n map: {\n entityId: entry.entityId,\n ...(entry.keyScope ? { keyScope: entry.keyScope } : {}),\n fields: entry.fields.map((field) => ({\n field: field.field,\n hashField: field.hashField ?? null,\n })),\n },\n })\n }\n }\n\n return Array.from(byEntityId.values(), ({ map }) => map)\n}\n\nfunction ensureLazyHandler<T extends (...args: any[]) => any>(\n loaded: unknown,\n kind: 'subscriber' | 'worker',\n id: string\n): T {\n const handler = typeof loaded === 'function'\n ? loaded\n : loaded && typeof loaded === 'object' && 'default' in loaded\n ? (loaded as Record<string, unknown>).default\n : null\n if (typeof handler !== 'function') {\n throw new Error(`[registry] Invalid ${kind} module \"${id}\" (missing default export handler)`)\n }\n return handler as T\n}\n\nexport function createLazyModuleSubscriber(\n loadModule: () => Promise<unknown>,\n id: string\n): ModuleSubscriberHandler {\n let handlerPromise: Promise<ModuleSubscriberHandler> | null = null\n return async (payload, ctx) => {\n handlerPromise ??= loadModule().then((loaded) =>\n ensureLazyHandler<ModuleSubscriberHandler>(loaded, 'subscriber', id)\n )\n const handler = await handlerPromise\n return handler(payload, ctx)\n }\n}\n\nexport function createLazyModuleWorker(\n loadModule: () => Promise<unknown>,\n id: string\n): ModuleWorkerHandler {\n let handlerPromise: Promise<ModuleWorkerHandler> | null = null\n return async (job, ctx) => {\n handlerPromise ??= loadModule().then((loaded) =>\n ensureLazyHandler<ModuleWorkerHandler>(loaded, 'worker', id)\n )\n const handler = await handlerPromise\n return handler(job, ctx)\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { ReactNode } from 'react'\nimport type { OpenApiRouteDoc, OpenApiMethodDoc } from '@open-mercato/shared/lib/openapi/types'\nimport type { SyncCrudEventResult } from '../lib/crud/sync-event-types'\nimport type { DashboardWidgetModule } from './dashboard/widgets'\nimport type { InjectionAnyWidgetModule, ModuleInjectionTable } from './widgets/injection'\nimport type { IntegrationBundle, IntegrationDefinition } from './integrations/types'\nimport { createLogger } from '../lib/logger'\nimport {\n applyApiOverridesToManifests,\n applyModuleOverridesToModules,\n applyPageOverridesToManifests,\n composeApiRouteOverrides,\n composePageRouteOverrides,\n} from './overrides'\n\nconst logger = createLogger('shared').child({ component: 'cli-registry' })\n\n// Context passed to dynamic metadata guards\nexport type RouteVisibilityContext = { path?: string; auth?: any }\n\n/**\n * Portal sidebar navigation hint. When declared on a portal page's metadata,\n * the page is auto-listed in the portal sidebar (subject to RBAC) by the\n * `/api/customer_accounts/portal/nav` endpoint.\n *\n * Absence of `nav` means the page is routable but not auto-listed (useful for\n * detail pages, create forms, etc.).\n */\nexport type PortalNavMetadata = {\n label: string\n labelKey?: string\n group?: 'main' | 'account'\n order?: number\n icon?: string\n}\n\n// Metadata you can export from page.meta.ts or directly from a server page\nexport type PageMetadata = {\n requireAuth?: boolean\n /** @deprecated Use `requireFeatures` instead \u2014 role names are mutable and can be spoofed */\n requireRoles?: readonly string[]\n // Optional fine-grained feature requirements\n requireFeatures?: readonly string[]\n // Portal: require customer (portal user) authentication instead of staff auth\n requireCustomerAuth?: boolean\n // Portal: require customer-specific features (checked against CustomerRbacService)\n requireCustomerFeatures?: readonly string[]\n // Portal: optional sidebar presentation hint (auto-listed by portal nav endpoint)\n nav?: PortalNavMetadata\n // Titles and grouping (aliases supported)\n title?: string\n titleKey?: string\n pageTitle?: string\n pageTitleKey?: string\n group?: string\n groupKey?: string\n pageGroup?: string\n pageGroupKey?: string\n // Ordering and visuals\n order?: number\n pageOrder?: number\n priority?: number\n pagePriority?: number\n icon?: ReactNode\n navHidden?: boolean\n // Dynamic flags\n visible?: (ctx: RouteVisibilityContext) => boolean | Promise<boolean>\n enabled?: (ctx: RouteVisibilityContext) => boolean | Promise<boolean>\n // Optional static breadcrumb trail for header\n breadcrumb?: Array<{ label: string; labelKey?: string; href?: string }>\n // Navigation context for tiered navigation:\n // - 'main' (default): Main sidebar business operations\n // - 'admin': Collapsible \"Settings & Admin\" section at bottom of sidebar\n // - 'settings': Hidden from sidebar, only accessible via Settings hub page\n // - 'profile': Profile dropdown items\n pageContext?: 'main' | 'admin' | 'settings' | 'profile'\n placement?: {\n section: string\n sectionLabel?: string\n sectionLabelKey?: string\n order?: number\n }\n}\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n\nexport type ApiHandler = (req: Request, ctx?: any) => Promise<Response> | Response\n\nexport type ModuleSubscriberHandler = (\n payload: any,\n ctx: any\n) => Promise<void | SyncCrudEventResult> | void | SyncCrudEventResult\n\nexport type ModuleWorkerHandler = (job: unknown, ctx: unknown) => Promise<void> | void\n\nexport type ModuleRoute = {\n pattern?: string\n path?: string\n requireAuth?: boolean\n /** @deprecated Use `requireFeatures` instead \u2014 role names are mutable and can be spoofed */\n requireRoles?: string[]\n // Optional fine-grained feature requirements\n requireFeatures?: string[]\n // Portal: require customer (portal user) authentication instead of staff auth\n requireCustomerAuth?: boolean\n // Portal: require customer-specific features (checked against CustomerRbacService)\n requireCustomerFeatures?: string[]\n // Portal: optional sidebar presentation hint (auto-listed by portal nav endpoint)\n nav?: PortalNavMetadata\n title?: string\n titleKey?: string\n group?: string\n groupKey?: string\n icon?: ReactNode\n order?: number\n priority?: number\n navHidden?: boolean\n visible?: (ctx: RouteVisibilityContext) => boolean | Promise<boolean>\n enabled?: (ctx: RouteVisibilityContext) => boolean | Promise<boolean>\n breadcrumb?: Array<{ label: string; labelKey?: string; href?: string }>\n pageContext?: 'main' | 'admin' | 'settings' | 'profile'\n placement?: {\n section: string\n sectionLabel?: string\n sectionLabelKey?: string\n order?: number\n }\n Component: (props: any) => ReactNode | Promise<ReactNode>\n}\n\nexport type ModuleRouteMetadata = Omit<ModuleRoute, 'Component'>\n\nexport type ModuleApiLegacy = {\n method: HttpMethod\n path: string\n handler: ApiHandler\n metadata?: Record<string, unknown>\n docs?: OpenApiMethodDoc\n}\n\nexport type ModuleApiRouteFile = {\n path: string\n handlers: Partial<Record<HttpMethod, ApiHandler>>\n requireAuth?: boolean\n /** @deprecated Use `requireFeatures` instead \u2014 role names are mutable and can be spoofed */\n requireRoles?: string[]\n // Optional fine-grained feature requirements for the entire route file\n // Note: per-method feature requirements should be expressed inside metadata\n requireFeatures?: string[]\n docs?: OpenApiRouteDoc\n metadata?: Partial<Record<HttpMethod, unknown>>\n}\n\nexport type ModuleApi = ModuleApiLegacy | ModuleApiRouteFile\n\nexport type RouteMatchParams = Record<string, string | string[]>\n\nexport type FrontendRouteManifestEntry = Omit<ModuleRoute, 'Component'> & {\n moduleId: string\n load: () => Promise<ModuleRoute['Component']>\n}\n\nexport type BackendRouteManifestEntry = Omit<ModuleRoute, 'Component'> & {\n moduleId: string\n load: () => Promise<ModuleRoute['Component']>\n}\n\nexport type ApiRouteManifestEntry = {\n moduleId: string\n kind: 'route-file' | 'legacy'\n path: string\n methods: HttpMethod[]\n method?: HttpMethod\n load: () => Promise<Record<string, unknown>>\n}\n\nexport type ModuleCli = {\n command: string\n run: (argv: string[]) => Promise<void> | void\n}\n\nexport type ModuleSubscriber = {\n id: string\n moduleId?: string\n event: string\n persistent?: boolean\n sync?: boolean\n priority?: number\n handler: ModuleSubscriberHandler\n}\n\nexport type ModuleWorker = {\n id: string\n moduleId?: string\n queue: string\n concurrency: number\n lockDuration?: number\n maxStalledCount?: number\n handler: ModuleWorkerHandler\n}\n\nexport type ModuleInfo = {\n name?: string\n title?: string\n version?: string\n description?: string\n author?: string\n license?: string\n homepage?: string\n copyright?: string\n // Optional hard dependencies: module ids that must be enabled\n requires?: string[]\n // Whether this module can be ejected into the app's src/modules/ for customization\n ejectable?: boolean\n}\n\nexport type ModuleDashboardWidgetEntry = {\n moduleId: string\n key: string\n source: 'app' | 'package'\n loader: () => Promise<DashboardWidgetModule<any>>\n}\n\nexport type ModuleInjectionWidgetEntry = {\n moduleId: string\n key: string\n source: 'app' | 'package'\n widgetId?: string\n loader: () => Promise<InjectionAnyWidgetModule<any, any>>\n}\n\nexport type Module = {\n id: string\n info?: ModuleInfo\n backendRoutes?: ModuleRoute[]\n frontendRoutes?: ModuleRoute[]\n apis?: ModuleApi[]\n cli?: ModuleCli[]\n translations?: Record<string, Record<string, string>>\n // Optional: per-module feature declarations discovered from acl.ts (module root)\n features?: Array<{ id: string; title: string; module: string }>\n // Auto-discovered event subscribers\n subscribers?: ModuleSubscriber[]\n // Auto-discovered queue workers\n workers?: ModuleWorker[]\n // Optional: per-module declared entity extensions and custom fields (static)\n // Extensions discovered from data/extensions.ts; Custom fields discovered from ce.ts (entities[].fields)\n entityExtensions?: import('./entities').EntityExtension[]\n customFieldSets?: import('./entities').CustomFieldSet[]\n // Optional: per-module declared custom entities (virtual/logical entities)\n // Discovered from ce.ts (module root). Each entry represents an entityId with optional label/description.\n customEntities?: Array<{ id: string; label?: string; description?: string }>\n dashboardWidgets?: ModuleDashboardWidgetEntry[]\n injectionWidgets?: ModuleInjectionWidgetEntry[]\n injectionTable?: ModuleInjectionTable\n // Optional: per-module vector search configuration (discovered from vector.ts)\n vector?: import('./vector').VectorModuleConfig\n // Optional: module-specific tenant setup configuration (from setup.ts)\n setup?: import('./setup').ModuleSetupConfig\n // Optional: default encryption maps owned by the module (from encryption.ts)\n defaultEncryptionMaps?: import('./encryption').ModuleEncryptionMap[]\n // Optional: integration marketplace declarations discovered from integration.ts\n integrations?: IntegrationDefinition[]\n bundles?: IntegrationBundle[]\n}\n\nfunction normPath(s: string) {\n return (s.startsWith('/') ? s : '/' + s).replace(/\\/+$/, '') || '/'\n}\n\n// 0 = literal (most specific), 1 = dynamic [param], 2 = catch-all [...param] or [[...param]]\nfunction segmentSpecificity(seg: string): 0 | 1 | 2 {\n if (seg.startsWith('[[...') || seg.startsWith('[...')) return 2\n if (seg.startsWith('[')) return 1\n return 0\n}\n\nfunction compareRouteSpecificity(aPattern: string, bPattern: string): number {\n const aSegs = aPattern.split('/')\n const bSegs = bPattern.split('/')\n const len = Math.max(aSegs.length, bSegs.length)\n for (let i = 0; i < len; i++) {\n const av = i < aSegs.length ? segmentSpecificity(aSegs[i]) : -1\n const bv = i < bSegs.length ? segmentSpecificity(bSegs[i]) : -1\n if (av !== bv) return av - bv\n }\n return 0\n}\n\nexport function sortRoutesBySpecificity<T extends { pattern?: string; path?: string }>(routes: T[]): T[] {\n return [...routes].sort((a, b) =>\n compareRouteSpecificity(a.pattern ?? a.path ?? '/', b.pattern ?? b.path ?? '/'),\n )\n}\n\n// Memoized per-array sorted view, so direct callers (e.g., the Next.js catch-all\n// routes that import generated `frontendRoutes`/`backendRoutes`/`apiRoutes`\n// arrays) match against a specificity-sorted view even if they never call\n// `register*RouteManifests`. Keyed by array reference; generated arrays are\n// module-level constants so this caches once per process.\nconst sortedRoutesCache = new WeakMap<object, readonly unknown[]>()\n\nfunction ensureSortedRoutes<T extends { pattern?: string; path?: string }>(routes: readonly T[]): readonly T[] {\n const cached = sortedRoutesCache.get(routes) as readonly T[] | undefined\n if (cached) return cached\n const sorted = sortRoutesBySpecificity([...routes])\n sortedRoutesCache.set(routes, sorted)\n return sorted\n}\n\nexport function matchRoutePattern(pattern: string, pathname: string): RouteMatchParams | undefined {\n const p = normPath(pattern)\n const u = normPath(pathname)\n const pSegs = p.split('/').slice(1)\n const uSegs = u.split('/').slice(1)\n const params: Record<string, string | string[]> = {}\n let i = 0\n for (let j = 0; j < pSegs.length; j++, i++) {\n const seg = pSegs[j]\n const mCatchAll = seg.match(/^\\[\\.\\.\\.(.+)\\]$/)\n const mOptCatch = seg.match(/^\\[\\[\\.\\.\\.(.+)\\]\\]$/)\n const mDyn = seg.match(/^\\[(.+)\\]$/)\n if (mCatchAll) {\n const key = mCatchAll[1]\n if (i >= uSegs.length) return undefined\n params[key] = uSegs.slice(i)\n return params\n } else if (mOptCatch) {\n const key = mOptCatch[1]\n params[key] = i < uSegs.length ? uSegs.slice(i) : []\n return params\n } else if (mDyn) {\n if (i >= uSegs.length) return undefined\n params[mDyn[1]] = uSegs[i]\n } else {\n if (i >= uSegs.length || uSegs[i].toLowerCase() !== seg.toLowerCase()) return undefined\n }\n }\n if (i !== uSegs.length) return undefined\n return params\n}\n\nfunction getPattern(r: ModuleRoute) {\n return r.pattern ?? r.path ?? '/'\n}\n\nexport function findFrontendMatch(modules: Module[], pathname: string): { route: ModuleRoute; params: Record<string, string | string[]> } | undefined {\n for (const m of modules) {\n const routes = m.frontendRoutes ?? []\n for (const r of routes) {\n const params = matchRoutePattern(getPattern(r), pathname)\n if (params) return { route: r, params }\n }\n }\n}\n\nexport function findBackendMatch(modules: Module[], pathname: string): { route: ModuleRoute; params: Record<string, string | string[]> } | undefined {\n for (const m of modules) {\n const routes = m.backendRoutes ?? []\n for (const r of routes) {\n const params = matchRoutePattern(getPattern(r), pathname)\n if (params) return { route: r, params }\n }\n }\n}\n\nexport function findApi(modules: Module[], method: HttpMethod, pathname: string): { handler: ApiHandler; params: Record<string, string | string[]>; requireAuth?: boolean; requireRoles?: string[]; metadata?: any } | undefined {\n for (const m of modules) {\n const apis = m.apis ?? []\n for (const a of apis) {\n if ('handlers' in a) {\n const params = matchRoutePattern(a.path, pathname)\n const handler = (a.handlers as any)[method]\n if (params && handler) return { handler, params, requireAuth: a.requireAuth, requireRoles: (a as any).requireRoles, metadata: (a as any).metadata }\n } else {\n const al = a as ModuleApiLegacy\n if (al.method !== method) continue\n const params = matchRoutePattern(al.path, pathname)\n if (params) {\n return { handler: al.handler, params, metadata: al.metadata }\n }\n }\n }\n }\n}\n\nexport function findRouteManifestMatch<T extends { pattern?: string; path?: string }>(\n routes: T[],\n pathname: string\n): { route: T; params: RouteMatchParams } | undefined {\n for (const route of ensureSortedRoutes(routes)) {\n const params = matchRoutePattern(route.pattern ?? route.path ?? '/', pathname)\n if (params) {\n return { route, params }\n }\n }\n}\n\nexport function findApiRouteManifestMatch<T extends { path: string; methods: HttpMethod[] }>(\n routes: T[],\n method: HttpMethod,\n pathname: string\n): { route: T; params: RouteMatchParams } | undefined {\n for (const route of ensureSortedRoutes(routes)) {\n if (!route.methods.includes(method)) continue\n const params = matchRoutePattern(route.path, pathname)\n if (params) {\n return { route, params }\n }\n }\n}\n\nexport { resolvePageRouteMetadata } from './pageRouteMetadata'\n\nlet _backendRouteManifests: BackendRouteManifestEntry[] | null = null\n\nexport function registerBackendRouteManifests(routes: BackendRouteManifestEntry[]) {\n const pageOverrides = composePageRouteOverrides()\n const finalRoutes = Object.keys(pageOverrides).length === 0\n ? routes\n : applyPageOverridesToManifests(routes, pageOverrides, 'backend')\n _backendRouteManifests = sortRoutesBySpecificity(finalRoutes)\n}\n\nexport function getBackendRouteManifests(): BackendRouteManifestEntry[] {\n return _backendRouteManifests ?? []\n}\n\nlet _frontendRouteManifests: FrontendRouteManifestEntry[] | null = null\n\nexport function registerFrontendRouteManifests(routes: FrontendRouteManifestEntry[]) {\n const pageOverrides = composePageRouteOverrides()\n const finalRoutes = Object.keys(pageOverrides).length === 0\n ? routes\n : applyPageOverridesToManifests(routes, pageOverrides, 'frontend')\n _frontendRouteManifests = sortRoutesBySpecificity(finalRoutes)\n}\n\nexport function getFrontendRouteManifests(): FrontendRouteManifestEntry[] {\n return _frontendRouteManifests ?? []\n}\n\nlet _apiRouteManifests: ApiRouteManifestEntry[] | null = null\n\nexport function registerApiRouteManifests(routes: ApiRouteManifestEntry[]) {\n // Apply any `entry.overrides.routes.api` overrides registered through the\n // unified `modules.ts` dispatcher or programmatic API before storing the\n // manifest. The composer is cheap and returns an empty object when no\n // overrides exist, so this is a no-op for apps that do not opt in.\n const routeOverrides = composeApiRouteOverrides()\n const finalRoutes = Object.keys(routeOverrides).length === 0\n ? routes\n : applyApiOverridesToManifests(routes, routeOverrides)\n _apiRouteManifests = sortRoutesBySpecificity(finalRoutes)\n}\n\nexport function getApiRouteManifests(): ApiRouteManifestEntry[] {\n return _apiRouteManifests ?? []\n}\n\n// CLI modules registry - shared between CLI and module workers\nlet _cliModules: Module[] | null = null\n\nexport function registerCliModules(modules: Module[]) {\n if (_cliModules !== null && process.env.NODE_ENV === 'development') {\n logger.debug('CLI modules re-registered (this may occur during HMR)')\n }\n _cliModules = applyModuleOverridesToModules(modules)\n}\n\nexport function getCliModules(): Module[] {\n // Return empty array if not registered - allows generate command to work without bootstrap\n return _cliModules ?? []\n}\n\nexport function hasCliModules(): boolean {\n return _cliModules !== null && _cliModules.length > 0\n}\n\nexport function getDefaultEncryptionMaps(modules: Module[]): import('./encryption').ModuleEncryptionMap[] {\n const byEntityId = new Map<string, { moduleId: string; map: import('./encryption').ModuleEncryptionMap }>()\n\n for (const mod of modules) {\n for (const entry of mod.defaultEncryptionMaps ?? []) {\n const previous = byEntityId.get(entry.entityId)\n if (previous) {\n throw new Error(\n `[registry] Duplicate default encryption map for \"${entry.entityId}\" declared by \"${previous.moduleId}\" and \"${mod.id}\"`\n )\n }\n byEntityId.set(entry.entityId, {\n moduleId: mod.id,\n map: {\n entityId: entry.entityId,\n ...(entry.keyScope ? { keyScope: entry.keyScope } : {}),\n fields: entry.fields.map((field) => ({\n field: field.field,\n hashField: field.hashField ?? null,\n })),\n },\n })\n }\n }\n\n return Array.from(byEntityId.values(), ({ map }) => map)\n}\n\nfunction ensureLazyHandler<T extends (...args: any[]) => any>(\n loaded: unknown,\n kind: 'subscriber' | 'worker',\n id: string\n): T {\n const handler = typeof loaded === 'function'\n ? loaded\n : loaded && typeof loaded === 'object' && 'default' in loaded\n ? (loaded as Record<string, unknown>).default\n : null\n if (typeof handler !== 'function') {\n throw new Error(`[registry] Invalid ${kind} module \"${id}\" (missing default export handler)`)\n }\n return handler as T\n}\n\nexport function createLazyModuleSubscriber(\n loadModule: () => Promise<unknown>,\n id: string\n): ModuleSubscriberHandler {\n let handlerPromise: Promise<ModuleSubscriberHandler> | null = null\n return async (payload, ctx) => {\n handlerPromise ??= loadModule().then((loaded) =>\n ensureLazyHandler<ModuleSubscriberHandler>(loaded, 'subscriber', id)\n )\n const handler = await handlerPromise\n return handler(payload, ctx)\n }\n}\n\nexport function createLazyModuleWorker(\n loadModule: () => Promise<unknown>,\n id: string\n): ModuleWorkerHandler {\n let handlerPromise: Promise<ModuleWorkerHandler> | null = null\n return async (job, ctx) => {\n handlerPromise ??= loadModule().then((loaded) =>\n ensureLazyHandler<ModuleWorkerHandler>(loaded, 'worker', id)\n )\n const handler = await handlerPromise\n return handler(job, ctx)\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/shared",
3
- "version": "0.6.8-develop.6915.1.ac6031c503",
3
+ "version": "0.6.8-develop.6916.1.f04fff3436",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -105,7 +105,7 @@
105
105
  "@mikro-orm/core": "^7.1.8",
106
106
  "@mikro-orm/decorators": "^7.1.8",
107
107
  "@mikro-orm/postgresql": "^7.1.8",
108
- "@open-mercato/cache": "0.6.8-develop.6915.1.ac6031c503",
108
+ "@open-mercato/cache": "0.6.8-develop.6916.1.f04fff3436",
109
109
  "@types/sanitize-html": "^2.16.1",
110
110
  "dotenv": "^17.4.2",
111
111
  "pino": "^10.3.1",
@@ -361,6 +361,56 @@ describe('applyPageOverridesToManifests', () => {
361
361
  await expect(frontendResult[0].load()).resolves.toBe(Replacement)
362
362
  })
363
363
 
364
+ it('applies page-prefixed metadata aliases so an override can reposition and retitle a page', () => {
365
+ const result = applyPageOverridesToManifests([makeBackendPage('/backend/example')], {
366
+ '/backend/example': {
367
+ metadata: { pageOrder: 5, pagePriority: 3, pageTitle: 'Repositioned', pageGroup: 'Operations' },
368
+ },
369
+ }, 'backend')
370
+
371
+ expect(result).toHaveLength(1)
372
+ expect(result[0].order).toBe(5)
373
+ expect(result[0].priority).toBe(3)
374
+ expect(result[0].title).toBe('Repositioned')
375
+ expect(result[0].group).toBe('Operations')
376
+ })
377
+
378
+ it('leaves an entry-declared priority winning over an overridden pageOrder', () => {
379
+ const entry = { ...makeBackendPage('/backend/example'), priority: 3 }
380
+ const result = applyPageOverridesToManifests([entry], {
381
+ '/backend/example': { metadata: { pageOrder: 5 } },
382
+ }, 'backend')
383
+
384
+ expect(result[0].order).toBe(5)
385
+ expect(result[0].priority).toBe(3)
386
+ })
387
+
388
+ it('keeps resolved metadata keys working and leaves untouched fields on the entry', () => {
389
+ const result = applyPageOverridesToManifests([makeBackendPage('/backend/example')], {
390
+ '/backend/example': { metadata: { order: 7 } },
391
+ }, 'backend')
392
+
393
+ expect(result[0].order).toBe(7)
394
+ expect(result[0].title).toBe('Original')
395
+ })
396
+
397
+ it('tolerates a malformed guard on an override instead of breaking manifest construction', () => {
398
+ const entries = [makeBackendPage('/backend/example')]
399
+
400
+ expect(() => applyPageOverridesToManifests(entries, {
401
+ // @ts-expect-error intentionally malformed: requireRoles must be an array
402
+ '/backend/example': { metadata: { requireRoles: 5, pageOrder: 5 } },
403
+ }, 'backend')).not.toThrow()
404
+
405
+ const result = applyPageOverridesToManifests(entries, {
406
+ // @ts-expect-error intentionally malformed: a bare string must not become a character array
407
+ '/backend/example': { metadata: { requireRoles: 'admin' } },
408
+ }, 'backend')
409
+
410
+ expect(result).toHaveLength(1)
411
+ expect(result[0].requireRoles).not.toEqual(['a', 'd', 'm', 'i', 'n'])
412
+ })
413
+
364
414
  it('lets programmatic page overrides supersede modules.ts inline overrides', () => {
365
415
  applyModuleOverridesFromEnabledModules([
366
416
  {
@@ -10,6 +10,17 @@ export type BackendChromeNavItem = {
10
10
  pageContext?: BackendChromePageContext
11
11
  iconName?: string
12
12
  iconMarkup?: string
13
+ /**
14
+ * The weight this item was sorted by: `pagePriority` when the page declared one, else `pageOrder`,
15
+ * else a large fallback so undeclared pages sort last. Always a number, so re-sorting by it
16
+ * reproduces the order the payload shipped in; the field exists so ordering is inspectable rather
17
+ * than implied by array position (#4845).
18
+ *
19
+ * Note this is NOT the same precedence as `BackendChromeSectionItem.order`, which resolves
20
+ * `order ?? priority ?? 100` for the settings/profile sidebars. A page rendered in both surfaces can
21
+ * legitimately report a different weight in each.
22
+ */
23
+ order?: number
13
24
  children?: BackendChromeNavItem[]
14
25
  }
15
26
 
@@ -348,6 +348,7 @@ import type {
348
348
  ModuleWorker,
349
349
  } from './registry'
350
350
  import { createLogger } from '../lib/logger'
351
+ import { resolveDeclaredPageRouteMetadata } from './pageRouteMetadata'
351
352
  import type { ModuleInjectionTable } from './widgets/injection'
352
353
  import type { ComponentOverride } from './widgets/component-registry'
353
354
  import type { NotificationHandler } from './notifications/handler'
@@ -1058,6 +1059,14 @@ export function applyApiOverridesToManifests<T extends ApiRouteManifestEntry>(
1058
1059
  return result
1059
1060
  }
1060
1061
 
1062
+ /**
1063
+ * A manifest entry holds *resolved* metadata (`order`, `title`, `group`), while an override
1064
+ * declares *authored* metadata, which may use the `page*` aliases (`pageOrder`, `pageTitle`).
1065
+ * Spreading the raw override alone left those aliases on keys nothing reads, so an override
1066
+ * could retitle a page through `pageTitleKey` yet never reposition it through `pageOrder`
1067
+ * (#4845). The raw metadata is still spread first so unrecognized keys keep reaching the
1068
+ * entry, then the resolved-and-declared subset lands on top.
1069
+ */
1061
1070
  export function applyPageOverridesToManifests<T extends BackendRouteManifestEntry | FrontendRouteManifestEntry>(
1062
1071
  routes: readonly T[],
1063
1072
  overrides: Readonly<PageRouteOverridesMap>,
@@ -1113,7 +1122,7 @@ export function applyPageOverridesToManifests<T extends BackendRouteManifestEntr
1113
1122
  ? async () => override.Component!
1114
1123
  : entry.load
1115
1124
 
1116
- result.push({ ...entry, ...metadata, load })
1125
+ result.push({ ...entry, ...metadata, ...resolveDeclaredPageRouteMetadata(metadata), load })
1117
1126
  }
1118
1127
 
1119
1128
  warnStaleOverrides('routes.pages', Object.fromEntries(
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Resolution of a page's authored `PageMetadata` into the flat `ModuleRouteMetadata`
3
+ * shape that route manifests carry.
4
+ *
5
+ * This lives in its own module rather than in `registry.ts` so `overrides.ts` can reuse
6
+ * it without an import cycle (`registry.ts` imports the override appliers). `registry.ts`
7
+ * re-exports `resolvePageRouteMetadata` so its published import path stays valid.
8
+ *
9
+ * Because `overrides.ts` feeds this module-authored override metadata it deliberately treats
10
+ * as untrusted (it warns and skips on malformed keys and values), the guard arrays are copied
11
+ * behind an `Array.isArray` check: a mistyped `requireRoles` in one app's `modules.ts` must not
12
+ * throw while route manifests are being built, nor be spread into a bogus character array.
13
+ */
14
+ import type { ModuleRouteMetadata, PageMetadata } from './registry'
15
+
16
+ export function resolvePageRouteMetadata(pattern: string, metadata: PageMetadata | null | undefined): ModuleRouteMetadata {
17
+ return {
18
+ pattern: pattern || '/',
19
+ requireAuth: metadata?.requireAuth,
20
+ requireRoles: Array.isArray(metadata?.requireRoles) ? [...metadata.requireRoles] : undefined,
21
+ requireFeatures: Array.isArray(metadata?.requireFeatures) ? [...metadata.requireFeatures] : undefined,
22
+ requireCustomerAuth: metadata?.requireCustomerAuth,
23
+ requireCustomerFeatures: Array.isArray(metadata?.requireCustomerFeatures) ? [...metadata.requireCustomerFeatures] : undefined,
24
+ nav: metadata?.nav,
25
+ title: metadata?.pageTitle ?? metadata?.title,
26
+ titleKey: metadata?.pageTitleKey ?? metadata?.titleKey,
27
+ group: metadata?.pageGroup ?? metadata?.group,
28
+ groupKey: metadata?.pageGroupKey ?? metadata?.groupKey,
29
+ icon: metadata?.icon,
30
+ order: metadata?.pageOrder ?? metadata?.order,
31
+ priority: metadata?.pagePriority ?? metadata?.priority,
32
+ navHidden: metadata?.navHidden,
33
+ visible: metadata?.visible,
34
+ enabled: metadata?.enabled,
35
+ breadcrumb: metadata?.breadcrumb,
36
+ pageContext: metadata?.pageContext,
37
+ placement: metadata?.placement,
38
+ }
39
+ }
40
+
41
+ /**
42
+ * The subset of `resolvePageRouteMetadata`'s output a caller actually declared.
43
+ *
44
+ * A page override supplies a partial `PageMetadata`, so merging the full resolved shape
45
+ * would overwrite fields the override never mentioned with `undefined`. Dropping the
46
+ * undefined entries keeps an override additive while still normalizing the `page*`
47
+ * aliases (`pageOrder` → `order`, `pageTitle` → `title`, …) that the manifest reads (#4845).
48
+ *
49
+ * `pattern` is never part of the result: an override adjusts a route's metadata, never the
50
+ * route key it was matched by.
51
+ */
52
+ export function resolveDeclaredPageRouteMetadata(
53
+ metadata: PageMetadata | null | undefined,
54
+ ): Partial<ModuleRouteMetadata> {
55
+ const { pattern: _pattern, ...resolved } = resolvePageRouteMetadata('/', metadata)
56
+ const declared: Record<string, unknown> = {}
57
+ for (const [key, value] of Object.entries(resolved)) {
58
+ if (value !== undefined) declared[key] = value
59
+ }
60
+ return declared as Partial<ModuleRouteMetadata>
61
+ }
@@ -410,30 +410,7 @@ export function findApiRouteManifestMatch<T extends { path: string; methods: Htt
410
410
  }
411
411
  }
412
412
 
413
- export function resolvePageRouteMetadata(pattern: string, metadata: PageMetadata | null | undefined): ModuleRouteMetadata {
414
- return {
415
- pattern: pattern || '/',
416
- requireAuth: metadata?.requireAuth,
417
- requireRoles: metadata?.requireRoles ? [...metadata.requireRoles] : undefined,
418
- requireFeatures: metadata?.requireFeatures ? [...metadata.requireFeatures] : undefined,
419
- requireCustomerAuth: metadata?.requireCustomerAuth,
420
- requireCustomerFeatures: metadata?.requireCustomerFeatures ? [...metadata.requireCustomerFeatures] : undefined,
421
- nav: metadata?.nav,
422
- title: metadata?.pageTitle ?? metadata?.title,
423
- titleKey: metadata?.pageTitleKey ?? metadata?.titleKey,
424
- group: metadata?.pageGroup ?? metadata?.group,
425
- groupKey: metadata?.pageGroupKey ?? metadata?.groupKey,
426
- icon: metadata?.icon,
427
- order: metadata?.pageOrder ?? metadata?.order,
428
- priority: metadata?.pagePriority ?? metadata?.priority,
429
- navHidden: metadata?.navHidden,
430
- visible: metadata?.visible,
431
- enabled: metadata?.enabled,
432
- breadcrumb: metadata?.breadcrumb,
433
- pageContext: metadata?.pageContext,
434
- placement: metadata?.placement,
435
- }
436
- }
413
+ export { resolvePageRouteMetadata } from './pageRouteMetadata'
437
414
 
438
415
  let _backendRouteManifests: BackendRouteManifestEntry[] | null = null
439
416