@open-mercato/cli 0.7.1-develop.7185.1.0f280ef1f1 → 0.7.1-develop.7191.1.3c9346566b

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.
Files changed (92) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/AGENTS.md +1 -1
  3. package/dist/agentic/guides/module-facts.json +137 -137
  4. package/dist/agentic/guides/module-facts.v2.json +137 -137
  5. package/dist/agentic/guides/modules/ai_assistant/index.md +1 -1
  6. package/dist/agentic/guides/modules/api_docs/index.md +1 -1
  7. package/dist/agentic/guides/modules/api_keys/index.md +1 -1
  8. package/dist/agentic/guides/modules/attachments/index.md +1 -1
  9. package/dist/agentic/guides/modules/audit_logs/index.md +1 -1
  10. package/dist/agentic/guides/modules/auth/index.md +1 -1
  11. package/dist/agentic/guides/modules/business_rules/index.md +1 -1
  12. package/dist/agentic/guides/modules/catalog/index.md +1 -1
  13. package/dist/agentic/guides/modules/channel_apns/index.md +1 -1
  14. package/dist/agentic/guides/modules/channel_discord/index.md +1 -1
  15. package/dist/agentic/guides/modules/channel_expo/index.md +1 -1
  16. package/dist/agentic/guides/modules/channel_fcm/index.md +1 -1
  17. package/dist/agentic/guides/modules/channel_gmail/index.md +1 -1
  18. package/dist/agentic/guides/modules/channel_imap/index.md +1 -1
  19. package/dist/agentic/guides/modules/channel_resend/index.md +1 -1
  20. package/dist/agentic/guides/modules/channel_ses/index.md +1 -1
  21. package/dist/agentic/guides/modules/checkout/index.md +1 -1
  22. package/dist/agentic/guides/modules/communication_channels/index.md +1 -1
  23. package/dist/agentic/guides/modules/configs/index.md +1 -1
  24. package/dist/agentic/guides/modules/content/index.md +1 -1
  25. package/dist/agentic/guides/modules/currencies/index.md +1 -1
  26. package/dist/agentic/guides/modules/customer_accounts/index.md +1 -1
  27. package/dist/agentic/guides/modules/customers/active-extension-bindings.md +1 -1
  28. package/dist/agentic/guides/modules/customers/index.md +1 -1
  29. package/dist/agentic/guides/modules/dashboards/index.md +1 -1
  30. package/dist/agentic/guides/modules/data_sync/index.md +1 -1
  31. package/dist/agentic/guides/modules/design_system/index.md +1 -1
  32. package/dist/agentic/guides/modules/devices/index.md +1 -1
  33. package/dist/agentic/guides/modules/dictionaries/index.md +1 -1
  34. package/dist/agentic/guides/modules/directory/index.md +1 -1
  35. package/dist/agentic/guides/modules/documents/index.md +1 -1
  36. package/dist/agentic/guides/modules/entities/index.md +1 -1
  37. package/dist/agentic/guides/modules/eudr/index.md +1 -1
  38. package/dist/agentic/guides/modules/events/index.md +1 -1
  39. package/dist/agentic/guides/modules/feature_toggles/index.md +1 -1
  40. package/dist/agentic/guides/modules/gateway_stripe/index.md +1 -1
  41. package/dist/agentic/guides/modules/generators/index.md +1 -1
  42. package/dist/agentic/guides/modules/inbox_ops/index.md +1 -1
  43. package/dist/agentic/guides/modules/integrations/index.md +1 -1
  44. package/dist/agentic/guides/modules/messages/index.md +1 -1
  45. package/dist/agentic/guides/modules/notifications/index.md +1 -1
  46. package/dist/agentic/guides/modules/onboarding/index.md +1 -1
  47. package/dist/agentic/guides/modules/payment_gateways/index.md +1 -1
  48. package/dist/agentic/guides/modules/perspectives/index.md +1 -1
  49. package/dist/agentic/guides/modules/phone_calls/index.md +1 -1
  50. package/dist/agentic/guides/modules/planner/index.md +1 -1
  51. package/dist/agentic/guides/modules/portal/index.md +1 -1
  52. package/dist/agentic/guides/modules/progress/index.md +1 -1
  53. package/dist/agentic/guides/modules/push_notifications/index.md +1 -1
  54. package/dist/agentic/guides/modules/query_index/index.md +1 -1
  55. package/dist/agentic/guides/modules/record_locks/index.md +1 -1
  56. package/dist/agentic/guides/modules/resources/index.md +1 -1
  57. package/dist/agentic/guides/modules/sales/index.md +1 -1
  58. package/dist/agentic/guides/modules/scheduler/index.md +1 -1
  59. package/dist/agentic/guides/modules/search/index.md +1 -1
  60. package/dist/agentic/guides/modules/security/index.md +1 -1
  61. package/dist/agentic/guides/modules/shipping_carriers/index.md +1 -1
  62. package/dist/agentic/guides/modules/sso/index.md +1 -1
  63. package/dist/agentic/guides/modules/staff/index.md +1 -1
  64. package/dist/agentic/guides/modules/storage_s3/index.md +1 -1
  65. package/dist/agentic/guides/modules/sync_akeneo/index.md +1 -1
  66. package/dist/agentic/guides/modules/sync_excel/index.md +1 -1
  67. package/dist/agentic/guides/modules/system_status_overlays/index.md +1 -1
  68. package/dist/agentic/guides/modules/tillio/index.md +1 -1
  69. package/dist/agentic/guides/modules/translations/index.md +1 -1
  70. package/dist/agentic/guides/modules/warranty_claims/index.md +1 -1
  71. package/dist/agentic/guides/modules/webhooks/index.md +1 -1
  72. package/dist/agentic/guides/modules/wms/index.md +1 -1
  73. package/dist/agentic/guides/modules/workflows/index.md +1 -1
  74. package/dist/agentic/guides/reference-module-facts.json +1 -1
  75. package/dist/agentic/guides/upstream/BACKWARD_COMPATIBILITY.md +1 -0
  76. package/dist/agentic/guides/upstream/manifest.json +2 -2
  77. package/dist/lib/generate-watch-structure.js +1 -0
  78. package/dist/lib/generate-watch-structure.js.map +2 -2
  79. package/dist/lib/generators/module-registry.js +45 -0
  80. package/dist/lib/generators/module-registry.js.map +2 -2
  81. package/dist/lib/module-runtimes.js +99 -0
  82. package/dist/lib/module-runtimes.js.map +7 -0
  83. package/dist/mercato.js +9 -0
  84. package/dist/mercato.js.map +2 -2
  85. package/package.json +6 -6
  86. package/src/__tests__/module-runtimes.test.ts +267 -0
  87. package/src/lib/__tests__/generate-watch-structure.test.ts +18 -0
  88. package/src/lib/generate-watch-structure.ts +1 -0
  89. package/src/lib/generators/__tests__/registry-variant-parity.test.ts +28 -1
  90. package/src/lib/generators/module-registry.ts +52 -0
  91. package/src/lib/module-runtimes.ts +195 -0
  92. package/src/mercato.ts +20 -0
@@ -1,5 +1,5 @@
1
1
  # workflows — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/core 0.7.1-develop.7185.1.0f280ef1f1; core 0.7.1-develop.7185.1.0f280ef1f1 — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/core 0.7.1-develop.7191.1.3c9346566b; core 0.7.1-develop.7191.1.3c9346566b — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/core/src/modules/workflows
4
4
 
5
5
  ## Sections
@@ -1185,7 +1185,7 @@
1185
1185
  "facts": {
1186
1186
  "title": "Example Module",
1187
1187
  "description": "Demonstrates pages, APIs, entities and DI.",
1188
- "coreVersion": "0.7.1-develop.7185.1.0f280ef1f1",
1188
+ "coreVersion": "0.7.1-develop.7191.1.3c9346566b",
1189
1189
  "sourcePackage": null,
1190
1190
  "sourceVersion": null,
1191
1191
  "sourceRoot": "src/modules/example",
@@ -37,6 +37,7 @@ The following file names, their expected export names, and their role in module
37
37
  | `index.ts` | `metadata: ModuleInfo` | MUST NOT rename export or change `ModuleInfo` shape in a breaking way |
38
38
  | `acl.ts` | `features: Array<{id,title,module}>` | MUST NOT change array item shape; may add optional fields |
39
39
  | `setup.ts` | `setup: ModuleSetupConfig` | MUST NOT remove hooks (`onTenantCreated`, `seedDefaults`, `seedExamples`, `defaultRoleFeatures`); may add optional hooks |
40
+ | `runtime.ts` | `runtime: ModuleRuntime` (or default export) | MUST NOT change `ModuleRuntime` required members (`start`) or the `ModuleRuntimeContext` / `ModuleRuntimeHandle` shape; may add optional fields and additional `ModuleRuntimeRole` values |
40
41
  | `ce.ts` | `entities: CustomEntitySpec[]` | MUST NOT change `CustomEntitySpec` required fields; may add optional fields |
41
42
  | `search.ts` | `searchConfig: SearchModuleConfig` | MUST NOT change `SearchEntityConfig` required fields; may add optional fields |
42
43
  | `events.ts` | `eventsConfig` via `createModuleEvents()` | MUST NOT change `EventDefinition` required fields (`id`, `label`); may add optional fields |
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": 1,
3
- "generator": "@open-mercato/cli@0.7.1-develop.7185.1.0f280ef1f1",
3
+ "generator": "@open-mercato/cli@0.7.1-develop.7191.1.3c9346566b",
4
4
  "files": {
5
5
  "AGENTS.md": "daa3d6b384da85bf926c4a1dd6448f8776fca4956203769bc6f590f0338495b6",
6
- "BACKWARD_COMPATIBILITY.md": "25a4f2a9e63b4da9f142067b75205159e2b46ddc5d0c5372a9f214cb4e29c34e"
6
+ "BACKWARD_COMPATIBILITY.md": "89a54c0b08f043967f284052d2e1d9f16e406e4a70dd68078749831334e3dcc2"
7
7
  }
8
8
  }
@@ -13,6 +13,7 @@ const STRUCTURAL_CONVENTION_FILES = [
13
13
  "di.ts",
14
14
  "acl.ts",
15
15
  "setup.ts",
16
+ "runtime.ts",
16
17
  "encryption.ts",
17
18
  "ce.ts",
18
19
  "search.ts",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/generate-watch-structure.ts"],
4
- "sourcesContent": ["import crypto from 'node:crypto'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport {\n MODULE_CODE_EXTENSIONS,\n SCAN_CONFIGS,\n scanModuleDir,\n stripModuleCodeExtension,\n type ModuleRoots,\n} from './generators/scanner'\n\nconst STRUCTURAL_CONVENTION_FILES = [\n 'index.ts',\n 'cli.ts',\n 'di.ts',\n 'acl.ts',\n 'setup.ts',\n 'encryption.ts',\n 'ce.ts',\n 'search.ts',\n 'events.ts',\n 'notifications.ts',\n 'notifications.client.ts',\n 'notifications.handlers.ts',\n 'translations.ts',\n 'generators.ts',\n 'ai-tools.ts',\n 'ai-agents.ts',\n 'analytics.ts',\n 'workflows.ts',\n 'inbox-actions.ts',\n 'message-types.ts',\n 'message-objects.ts',\n 'integration.ts',\n 'security.mfa-providers.ts',\n 'security.sudo.ts',\n 'data/entities.ts',\n 'data/extensions.ts',\n 'data/fields.ts',\n 'data/enrichers.ts',\n 'data/guards.ts',\n 'api/interceptors.ts',\n 'commands/interceptors.ts',\n 'widgets/components.ts',\n 'widgets/injection-table.ts',\n 'frontend/middleware.ts',\n 'backend/middleware.ts',\n] as const\n\nconst CONTENT_SENSITIVE_SCAN_CONFIGS = [\n SCAN_CONFIGS.apiRoutes,\n SCAN_CONFIGS.apiPlainFiles,\n SCAN_CONFIGS.subscribers,\n SCAN_CONFIGS.workers,\n SCAN_CONFIGS.dashboardWidgets,\n SCAN_CONFIGS.injectionWidgets,\n] as const\n\nconst ROUTE_SHAPE_SCAN_CONFIGS = [\n SCAN_CONFIGS.frontendPages,\n SCAN_CONFIGS.backendPages,\n] as const\n\nfunction checksum(value: string): string {\n return crypto.createHash('md5').update(value).digest('hex')\n}\n\nfunction fileRecord(filePath: string, base: string, mode: 'content' | 'shape'): string | null {\n if (!fs.existsSync(filePath)) return null\n let stat: fs.Stats\n try {\n stat = fs.statSync(filePath)\n } catch {\n return null\n }\n if (!stat.isFile()) return null\n const rel = path.relative(base, filePath).replace(/\\\\/g, '/')\n if (mode === 'shape') {\n return `file:${rel}`\n }\n try {\n return `file:${rel}:${stat.size}:${checksum(fs.readFileSync(filePath, 'utf8'))}`\n } catch {\n return `file:${rel}:unreadable`\n }\n}\n\nfunction resolveCodeFile(base: string, relativePath: string): string | null {\n const stripped = stripModuleCodeExtension(relativePath)\n const candidates = MODULE_CODE_EXTENSIONS.map((extension) => `${stripped}${extension}`)\n for (const candidate of candidates) {\n const filePath = path.join(base, ...candidate.split('/'))\n if (fs.existsSync(filePath)) return filePath\n }\n return null\n}\n\nfunction hasInlinePageMetadata(filePath: string): boolean {\n try {\n const source = fs.readFileSync(filePath, 'utf8')\n return /\\bexport\\s+(?:const|let|var|function|class)\\s+metadata\\b/.test(source)\n || /\\bexport\\s+\\{[^}]*\\bmetadata\\b[^}]*\\}/.test(source)\n } catch {\n return false\n }\n}\n\nfunction addConventionRecords(records: string[], roots: ModuleRoots): void {\n for (const base of [roots.pkgBase, roots.appBase]) {\n records.push(`module-root:${base}:${fs.existsSync(base) ? 'present' : 'missing'}`)\n for (const relativePath of STRUCTURAL_CONVENTION_FILES) {\n const filePath = resolveCodeFile(base, relativePath)\n if (!filePath) {\n records.push(`missing:${base}:${relativePath}`)\n continue\n }\n const record = fileRecord(filePath, base, 'content')\n if (record) records.push(record)\n }\n }\n}\n\nfunction addScannedRecords(records: string[], roots: ModuleRoots): void {\n for (const config of CONTENT_SENSITIVE_SCAN_CONFIGS) {\n for (const scanned of scanModuleDir(roots, config)) {\n const base = scanned.fromApp ? roots.appBase : roots.pkgBase\n const filePath = path.join(base, ...config.folder.split('/'), ...scanned.relPath.split('/'))\n const record = fileRecord(filePath, base, 'content')\n if (record) records.push(`${config.folder}:${record}`)\n }\n }\n\n for (const config of ROUTE_SHAPE_SCAN_CONFIGS) {\n for (const scanned of scanModuleDir(roots, config)) {\n const base = scanned.fromApp ? roots.appBase : roots.pkgBase\n const folderPath = path.join(base, ...config.folder.split('/'))\n const filePath = path.join(folderPath, ...scanned.relPath.split('/'))\n const pageRecord = fileRecord(filePath, base, hasInlinePageMetadata(filePath) ? 'content' : 'shape')\n if (pageRecord) records.push(`${config.folder}:${pageRecord}`)\n\n const dir = path.dirname(filePath)\n const stem = stripModuleCodeExtension(path.basename(filePath))\n const metaCandidates = stem === 'page'\n ? ['page.meta', 'meta']\n : [`${stem}.meta`, 'meta']\n for (const candidate of metaCandidates) {\n const metaPath = resolveCodeFile(dir, candidate)\n if (!metaPath) continue\n const record = fileRecord(metaPath, base, 'content')\n if (record) records.push(`${config.folder}:meta:${record}`)\n }\n }\n }\n}\n\nexport function calculateGenerateWatchStructureChecksum(options: {\n modulesFile: string\n moduleRoots: ModuleRoots[]\n}): string {\n const records: string[] = []\n const modulesRecord = fileRecord(options.modulesFile, path.dirname(options.modulesFile), 'content')\n records.push(modulesRecord ?? `missing:${options.modulesFile}`)\n\n for (const roots of options.moduleRoots) {\n addConventionRecords(records, roots)\n addScannedRecords(records, roots)\n }\n\n return checksum(records.sort((a, b) => a.localeCompare(b)).join('\\n'))\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import crypto from 'node:crypto'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport {\n MODULE_CODE_EXTENSIONS,\n SCAN_CONFIGS,\n scanModuleDir,\n stripModuleCodeExtension,\n type ModuleRoots,\n} from './generators/scanner'\n\nconst STRUCTURAL_CONVENTION_FILES = [\n 'index.ts',\n 'cli.ts',\n 'di.ts',\n 'acl.ts',\n 'setup.ts',\n 'runtime.ts',\n 'encryption.ts',\n 'ce.ts',\n 'search.ts',\n 'events.ts',\n 'notifications.ts',\n 'notifications.client.ts',\n 'notifications.handlers.ts',\n 'translations.ts',\n 'generators.ts',\n 'ai-tools.ts',\n 'ai-agents.ts',\n 'analytics.ts',\n 'workflows.ts',\n 'inbox-actions.ts',\n 'message-types.ts',\n 'message-objects.ts',\n 'integration.ts',\n 'security.mfa-providers.ts',\n 'security.sudo.ts',\n 'data/entities.ts',\n 'data/extensions.ts',\n 'data/fields.ts',\n 'data/enrichers.ts',\n 'data/guards.ts',\n 'api/interceptors.ts',\n 'commands/interceptors.ts',\n 'widgets/components.ts',\n 'widgets/injection-table.ts',\n 'frontend/middleware.ts',\n 'backend/middleware.ts',\n] as const\n\nconst CONTENT_SENSITIVE_SCAN_CONFIGS = [\n SCAN_CONFIGS.apiRoutes,\n SCAN_CONFIGS.apiPlainFiles,\n SCAN_CONFIGS.subscribers,\n SCAN_CONFIGS.workers,\n SCAN_CONFIGS.dashboardWidgets,\n SCAN_CONFIGS.injectionWidgets,\n] as const\n\nconst ROUTE_SHAPE_SCAN_CONFIGS = [\n SCAN_CONFIGS.frontendPages,\n SCAN_CONFIGS.backendPages,\n] as const\n\nfunction checksum(value: string): string {\n return crypto.createHash('md5').update(value).digest('hex')\n}\n\nfunction fileRecord(filePath: string, base: string, mode: 'content' | 'shape'): string | null {\n if (!fs.existsSync(filePath)) return null\n let stat: fs.Stats\n try {\n stat = fs.statSync(filePath)\n } catch {\n return null\n }\n if (!stat.isFile()) return null\n const rel = path.relative(base, filePath).replace(/\\\\/g, '/')\n if (mode === 'shape') {\n return `file:${rel}`\n }\n try {\n return `file:${rel}:${stat.size}:${checksum(fs.readFileSync(filePath, 'utf8'))}`\n } catch {\n return `file:${rel}:unreadable`\n }\n}\n\nfunction resolveCodeFile(base: string, relativePath: string): string | null {\n const stripped = stripModuleCodeExtension(relativePath)\n const candidates = MODULE_CODE_EXTENSIONS.map((extension) => `${stripped}${extension}`)\n for (const candidate of candidates) {\n const filePath = path.join(base, ...candidate.split('/'))\n if (fs.existsSync(filePath)) return filePath\n }\n return null\n}\n\nfunction hasInlinePageMetadata(filePath: string): boolean {\n try {\n const source = fs.readFileSync(filePath, 'utf8')\n return /\\bexport\\s+(?:const|let|var|function|class)\\s+metadata\\b/.test(source)\n || /\\bexport\\s+\\{[^}]*\\bmetadata\\b[^}]*\\}/.test(source)\n } catch {\n return false\n }\n}\n\nfunction addConventionRecords(records: string[], roots: ModuleRoots): void {\n for (const base of [roots.pkgBase, roots.appBase]) {\n records.push(`module-root:${base}:${fs.existsSync(base) ? 'present' : 'missing'}`)\n for (const relativePath of STRUCTURAL_CONVENTION_FILES) {\n const filePath = resolveCodeFile(base, relativePath)\n if (!filePath) {\n records.push(`missing:${base}:${relativePath}`)\n continue\n }\n const record = fileRecord(filePath, base, 'content')\n if (record) records.push(record)\n }\n }\n}\n\nfunction addScannedRecords(records: string[], roots: ModuleRoots): void {\n for (const config of CONTENT_SENSITIVE_SCAN_CONFIGS) {\n for (const scanned of scanModuleDir(roots, config)) {\n const base = scanned.fromApp ? roots.appBase : roots.pkgBase\n const filePath = path.join(base, ...config.folder.split('/'), ...scanned.relPath.split('/'))\n const record = fileRecord(filePath, base, 'content')\n if (record) records.push(`${config.folder}:${record}`)\n }\n }\n\n for (const config of ROUTE_SHAPE_SCAN_CONFIGS) {\n for (const scanned of scanModuleDir(roots, config)) {\n const base = scanned.fromApp ? roots.appBase : roots.pkgBase\n const folderPath = path.join(base, ...config.folder.split('/'))\n const filePath = path.join(folderPath, ...scanned.relPath.split('/'))\n const pageRecord = fileRecord(filePath, base, hasInlinePageMetadata(filePath) ? 'content' : 'shape')\n if (pageRecord) records.push(`${config.folder}:${pageRecord}`)\n\n const dir = path.dirname(filePath)\n const stem = stripModuleCodeExtension(path.basename(filePath))\n const metaCandidates = stem === 'page'\n ? ['page.meta', 'meta']\n : [`${stem}.meta`, 'meta']\n for (const candidate of metaCandidates) {\n const metaPath = resolveCodeFile(dir, candidate)\n if (!metaPath) continue\n const record = fileRecord(metaPath, base, 'content')\n if (record) records.push(`${config.folder}:meta:${record}`)\n }\n }\n }\n}\n\nexport function calculateGenerateWatchStructureChecksum(options: {\n modulesFile: string\n moduleRoots: ModuleRoots[]\n}): string {\n const records: string[] = []\n const modulesRecord = fileRecord(options.modulesFile, path.dirname(options.modulesFile), 'content')\n records.push(modulesRecord ?? `missing:${options.modulesFile}`)\n\n for (const roots of options.moduleRoots) {\n addConventionRecords(records, roots)\n addScannedRecords(records, roots)\n }\n\n return checksum(records.sort((a, b) => a.localeCompare(b)).join('\\n'))\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1999,6 +1999,12 @@ function buildLegacyModuleSetupValue(importName) {
1999
1999
  identifier("undefined")
2000
2000
  ]);
2001
2001
  }
2002
+ function buildLegacyModuleRuntimeValue(importName) {
2003
+ return logicalOr([
2004
+ legacyNamespaceMemberFallback(importName, ["default", "runtime"]),
2005
+ identifier("undefined")
2006
+ ]);
2007
+ }
2002
2008
  function buildLegacyIntegrationListValue(importName, pluralMember, singularMember, castType) {
2003
2009
  const singular = propertyAccess(identifier(importName), singularMember);
2004
2010
  return asExpression(
@@ -2761,6 +2767,7 @@ async function generateModuleRegistryFromDiscovery(options) {
2761
2767
  let customFieldSetsExpr = "[]";
2762
2768
  const dashboardWidgets = [];
2763
2769
  let setupImportName = null;
2770
+ let moduleRuntimeImportName = null;
2764
2771
  let encryptionImportName = null;
2765
2772
  let integrationImportName = null;
2766
2773
  const indexResolved = discovered.resolve("index.ts");
@@ -2874,6 +2881,10 @@ async function generateModuleRegistryFromDiscovery(options) {
2874
2881
  integrationImportName = importName;
2875
2882
  }
2876
2883
  }
2884
+ {
2885
+ const moduleRuntime = resolveConventionFile(discovered.resolve("runtime.ts"), "RUNTIME", modId, importIdRef, imports, runtimeImports);
2886
+ if (moduleRuntime) moduleRuntimeImportName = moduleRuntime.importName;
2887
+ }
2877
2888
  {
2878
2889
  const fields = resolveConventionFile(discovered.resolve("data/fields.ts"), "F", modId, importIdRef, imports, runtimeImports);
2879
2890
  if (fields) fieldsImportName = fields.importName;
@@ -3010,6 +3021,9 @@ async function generateModuleRegistryFromDiscovery(options) {
3010
3021
  if (setupImportName) {
3011
3022
  setupAndBeyondEntries.push({ name: "setup", value: buildLegacyModuleSetupValue(setupImportName) });
3012
3023
  }
3024
+ if (moduleRuntimeImportName) {
3025
+ setupAndBeyondEntries.push({ name: "runtime", value: buildLegacyModuleRuntimeValue(moduleRuntimeImportName) });
3026
+ }
3013
3027
  if (encryptionImportName) {
3014
3028
  setupAndBeyondEntries.push({
3015
3029
  name: "defaultEncryptionMaps",
@@ -3378,6 +3392,7 @@ async function generateModuleRegistryAppFromDiscovery(options) {
3378
3392
  let customEntitiesImportName = null;
3379
3393
  let dashboardWidgetsValue = emptyArray();
3380
3394
  let setupImportName = null;
3395
+ let moduleRuntimeImportName = null;
3381
3396
  let encryptionImportName = null;
3382
3397
  let integrationImportName = null;
3383
3398
  const indexResolved = discovered.resolve("index.ts");
@@ -3398,6 +3413,11 @@ async function generateModuleRegistryAppFromDiscovery(options) {
3398
3413
  if (setup) bootstrapImports.push(buildImportStatement(`* as ${setup.importName}`, setup.importPath));
3399
3414
  if (setup) setupImportName = setup.importName;
3400
3415
  }
3416
+ {
3417
+ const moduleRuntime = resolveConventionFile(discovered.resolve("runtime.ts"), "RUNTIME", modId, importIdRef, imports);
3418
+ if (moduleRuntime) bootstrapImports.push(buildImportStatement(`* as ${moduleRuntime.importName}`, moduleRuntime.importPath));
3419
+ if (moduleRuntime) moduleRuntimeImportName = moduleRuntime.importName;
3420
+ }
3401
3421
  {
3402
3422
  const encryption = resolveConventionFile(discovered.resolve("encryption.ts"), "ENCRYPTION", modId, importIdRef, imports);
3403
3423
  if (encryption) bootstrapImports.push(buildImportStatement(`* as ${encryption.importName}`, encryption.importPath));
@@ -3576,6 +3596,16 @@ async function generateModuleRegistryAppFromDiscovery(options) {
3576
3596
  })
3577
3597
  });
3578
3598
  }
3599
+ if (moduleRuntimeImportName) {
3600
+ moduleEntries.push({
3601
+ name: "runtime",
3602
+ value: namespaceFallback({
3603
+ importName: moduleRuntimeImportName,
3604
+ members: ["default", "runtime"],
3605
+ fallback: identifier("undefined")
3606
+ })
3607
+ });
3608
+ }
3579
3609
  if (encryptionImportName) {
3580
3610
  moduleEntries.push({
3581
3611
  name: "defaultEncryptionMaps",
@@ -3752,6 +3782,7 @@ async function generateModuleRegistryCliFromDiscovery(options) {
3752
3782
  let vectorImportName = null;
3753
3783
  let dashboardWidgetsValue = emptyArray();
3754
3784
  let setupImportName = null;
3785
+ let moduleRuntimeImportName = null;
3755
3786
  let encryptionImportName = null;
3756
3787
  let integrationImportName = null;
3757
3788
  const indexResolved = discovered.resolve("index.ts");
@@ -3770,6 +3801,10 @@ async function generateModuleRegistryCliFromDiscovery(options) {
3770
3801
  const setup = resolveConventionFile(discovered.resolve("setup.ts"), "SETUP", modId, importIdRef, imports);
3771
3802
  if (setup) setupImportName = setup.importName;
3772
3803
  }
3804
+ {
3805
+ const moduleRuntime = resolveConventionFile(discovered.resolve("runtime.ts"), "RUNTIME", modId, importIdRef, imports);
3806
+ if (moduleRuntime) moduleRuntimeImportName = moduleRuntime.importName;
3807
+ }
3773
3808
  {
3774
3809
  const encryption = resolveConventionFile(discovered.resolve("encryption.ts"), "ENCRYPTION", modId, importIdRef, imports);
3775
3810
  if (encryption) encryptionImportName = encryption.importName;
@@ -3914,6 +3949,16 @@ async function generateModuleRegistryCliFromDiscovery(options) {
3914
3949
  })
3915
3950
  });
3916
3951
  }
3952
+ if (moduleRuntimeImportName) {
3953
+ moduleEntries.push({
3954
+ name: "runtime",
3955
+ value: namespaceFallback({
3956
+ importName: moduleRuntimeImportName,
3957
+ members: ["default", "runtime"],
3958
+ fallback: identifier("undefined")
3959
+ })
3960
+ });
3961
+ }
3917
3962
  if (encryptionImportName) {
3918
3963
  moduleEntries.push({
3919
3964
  name: "defaultEncryptionMaps",