@open-mercato/cli 0.6.8-develop.6930.1.1e5976efc3 → 0.6.8-develop.6940.1.177ea30c6e

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 (168) hide show
  1. package/.turbo/turbo-build.log +65 -1
  2. package/build.mjs +57 -7
  3. package/dist/agentic/guides/backend-ui.md +7 -1
  4. package/dist/agentic/guides/module-facts.json +565 -224
  5. package/dist/agentic/guides/module-facts.v2.json +122933 -0
  6. package/dist/agentic/guides/modules/ai_assistant.md +2 -2
  7. package/dist/agentic/guides/modules/api_docs.md +2 -2
  8. package/dist/agentic/guides/modules/api_keys.md +2 -2
  9. package/dist/agentic/guides/modules/attachments.md +2 -2
  10. package/dist/agentic/guides/modules/audit_logs.md +2 -2
  11. package/dist/agentic/guides/modules/auth.md +2 -2
  12. package/dist/agentic/guides/modules/business_rules.md +2 -2
  13. package/dist/agentic/guides/modules/catalog.md +11 -4
  14. package/dist/agentic/guides/modules/channel_gmail.md +2 -2
  15. package/dist/agentic/guides/modules/channel_imap.md +2 -2
  16. package/dist/agentic/guides/modules/checkout.md +8 -2
  17. package/dist/agentic/guides/modules/communication_channels.md +6 -6
  18. package/dist/agentic/guides/modules/configs.md +2 -2
  19. package/dist/agentic/guides/modules/content.md +2 -2
  20. package/dist/agentic/guides/modules/currencies.md +2 -2
  21. package/dist/agentic/guides/modules/customer_accounts.md +2 -2
  22. package/dist/agentic/guides/modules/customers.md +8 -8
  23. package/dist/agentic/guides/modules/dashboards.md +12 -12
  24. package/dist/agentic/guides/modules/data_sync.md +4 -4
  25. package/dist/agentic/guides/modules/design_system.md +2 -2
  26. package/dist/agentic/guides/modules/dictionaries.md +2 -2
  27. package/dist/agentic/guides/modules/directory.md +2 -2
  28. package/dist/agentic/guides/modules/entities.md +3 -3
  29. package/dist/agentic/guides/modules/eudr.md +3 -3
  30. package/dist/agentic/guides/modules/events.md +2 -2
  31. package/dist/agentic/guides/modules/feature_toggles.md +2 -2
  32. package/dist/agentic/guides/modules/gateway_stripe.md +2 -2
  33. package/dist/agentic/guides/modules/generators.md +2 -2
  34. package/dist/agentic/guides/modules/inbox_ops.md +2 -2
  35. package/dist/agentic/guides/modules/integrations.md +5 -2
  36. package/dist/agentic/guides/modules/messages.md +2 -2
  37. package/dist/agentic/guides/modules/notifications.md +2 -2
  38. package/dist/agentic/guides/modules/onboarding.md +2 -2
  39. package/dist/agentic/guides/modules/payment_gateways.md +7 -3
  40. package/dist/agentic/guides/modules/perspectives.md +2 -2
  41. package/dist/agentic/guides/modules/planner.md +2 -2
  42. package/dist/agentic/guides/modules/portal.md +2 -2
  43. package/dist/agentic/guides/modules/progress.md +2 -2
  44. package/dist/agentic/guides/modules/query_index.md +2 -2
  45. package/dist/agentic/guides/modules/record_locks.md +3 -3
  46. package/dist/agentic/guides/modules/resources.md +2 -2
  47. package/dist/agentic/guides/modules/sales.md +13 -4
  48. package/dist/agentic/guides/modules/scheduler.md +2 -2
  49. package/dist/agentic/guides/modules/search.md +4 -4
  50. package/dist/agentic/guides/modules/security.md +3 -3
  51. package/dist/agentic/guides/modules/shipping_carriers.md +2 -2
  52. package/dist/agentic/guides/modules/sso.md +2 -2
  53. package/dist/agentic/guides/modules/staff.md +7 -4
  54. package/dist/agentic/guides/modules/storage_s3.md +2 -2
  55. package/dist/agentic/guides/modules/sync_akeneo.md +4 -4
  56. package/dist/agentic/guides/modules/sync_excel.md +2 -2
  57. package/dist/agentic/guides/modules/system_status_overlays.md +2 -2
  58. package/dist/agentic/guides/modules/translations.md +2 -2
  59. package/dist/agentic/guides/modules/webhooks.md +2 -2
  60. package/dist/agentic/guides/modules/wms.md +31 -4
  61. package/dist/agentic/guides/modules/workflows.md +2 -2
  62. package/dist/agentic/guides/reference-module-facts.json +8335 -0
  63. package/dist/agentic/guides/reference-modules/example.md +489 -0
  64. package/dist/agentic/guides/spec-delivery.md +34 -0
  65. package/dist/agentic/guides/testing-debugging.md +2 -1
  66. package/dist/agentic/guides/upstream/BACKWARD_COMPATIBILITY.md +3 -2
  67. package/dist/agentic/guides/upstream/manifest.json +2 -2
  68. package/dist/agentic/shared/AGENTS.md.template +10 -14
  69. package/dist/agentic/shared/ai/harness/README.md +4 -4
  70. package/dist/agentic/shared/ai/harness/RELEASE.md +4 -4
  71. package/dist/agentic/shared/ai/harness/cases.json +11350 -5088
  72. package/dist/agentic/shared/ai/harness/cases.schema.json +70 -7
  73. package/dist/agentic/shared/ai/harness/design-system-inventory.json +6697 -0
  74. package/dist/agentic/shared/ai/harness/fixtures/index.json +3 -1
  75. package/dist/agentic/shared/ai/harness/fixtures/seeds.json +4 -0
  76. package/dist/agentic/shared/ai/harness/knowledge-change.schema.json +228 -0
  77. package/dist/agentic/shared/ai/harness/release-matrix.json +9 -4
  78. package/dist/agentic/shared/ai/harness/result.schema.json +60 -0
  79. package/dist/agentic/shared/ai/harness/routing-response.schema.json +10 -0
  80. package/dist/agentic/shared/ai/harness/source-link-inventory.json +3231 -0
  81. package/dist/agentic/shared/ai/harness/validators.json +8 -4
  82. package/dist/agentic/shared/ai/harness/writable-ast-oracles.mjs +5 -2
  83. package/dist/agentic/shared/ai/harness/writable-behavior-oracles.mjs +3 -0
  84. package/dist/agentic/shared/ai/harness/writable-spec-oracles.mjs +879 -0
  85. package/dist/agentic/shared/ai/skills/om-auto-upgrade-0.6.7-to-0.7.0/SKILL.md +102 -0
  86. package/dist/agentic/shared/ai/skills/om-backend-ui-design/SKILL.md +1 -0
  87. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/crud-surfaces.md +15 -0
  88. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/frontend-and-design-system.md +6 -0
  89. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/page-and-navigation.md +4 -0
  90. package/dist/agentic/shared/ai/skills/om-data-model-design/SKILL.md +1 -0
  91. package/dist/agentic/shared/ai/skills/om-data-model-design/references/integrity-and-concurrency.md +2 -0
  92. package/dist/agentic/shared/ai/skills/om-data-model-design/references/migration-workflow.md +2 -0
  93. package/dist/agentic/shared/ai/skills/om-data-model-design/references/schema-design.md +3 -1
  94. package/dist/agentic/shared/ai/skills/om-eject-and-customize/SKILL.md +1 -0
  95. package/dist/agentic/shared/ai/skills/om-eject-and-customize/references/decision-and-procedure.md +2 -0
  96. package/dist/agentic/shared/ai/skills/om-evolve-harness/SKILL.md +2 -0
  97. package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-template.md +3 -3
  98. package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-workflow.md +1 -1
  99. package/dist/agentic/shared/ai/skills/om-evolve-harness/references/knowledge-change.md +133 -0
  100. package/dist/agentic/shared/ai/skills/om-integration-builder/SKILL.md +1 -0
  101. package/dist/agentic/shared/ai/skills/om-integration-builder/references/provider-families.md +11 -0
  102. package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/judge-workflow.md +1 -1
  103. package/dist/agentic/shared/ai/skills/om-module-scaffold/SKILL.md +2 -2
  104. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/api-and-domain.md +14 -1
  105. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/data-and-migrations.md +2 -0
  106. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/module-surfaces.md +19 -0
  107. package/dist/agentic/shared/ai/skills/om-share-this-session/scripts/prepare-share-bundle.mjs +1 -4
  108. package/dist/agentic/shared/ai/skills/om-system-extension/SKILL.md +1 -0
  109. package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-branches.md +24 -0
  110. package/dist/agentic/shared/ai/skills/om-system-extension/references/unified-overrides.md +3 -1
  111. package/dist/agentic/shared/ai/skills/om-troubleshooter/SKILL.md +1 -0
  112. package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnosis-map.md +13 -0
  113. package/dist/agentic/shared/ai/skills/tiers.json +2 -1
  114. package/dist/agentic/shared/ai/specs/2026-08-06-reference-module-activation.md +248 -0
  115. package/dist/agentic/shared/scripts/agent-harness-tool-server.mjs +39 -2
  116. package/dist/agentic/shared/scripts/design-source-contract.mjs +108 -0
  117. package/dist/agentic/shared/scripts/evaluate-agent-harness.mjs +935 -28
  118. package/dist/agentic/shared/scripts/framework-context.mjs +4 -1
  119. package/dist/agentic/shared/scripts/run-agent-harness-release.mjs +1 -1
  120. package/dist/agentic/shared/scripts/validate-knowledge-change.mjs +1511 -0
  121. package/dist/lib/__integration__/TC-INT-008.spec.js +1 -0
  122. package/dist/lib/__integration__/TC-INT-008.spec.js.map +2 -2
  123. package/dist/lib/agentic-setup.js +9 -1
  124. package/dist/lib/agentic-setup.js.map +2 -2
  125. package/dist/lib/generators/module-extension-facts.js +93 -26
  126. package/dist/lib/generators/module-extension-facts.js.map +3 -3
  127. package/dist/lib/generators/module-facts-discovery.js +23 -0
  128. package/dist/lib/generators/module-facts-discovery.js.map +2 -2
  129. package/dist/lib/generators/module-facts.js +969 -41
  130. package/dist/lib/generators/module-facts.js.map +2 -2
  131. package/dist/lib/generators/module-override-targets.js +35 -11
  132. package/dist/lib/generators/module-override-targets.js.map +2 -2
  133. package/dist/lib/generators/module-registry.js +105 -2
  134. package/dist/lib/generators/module-registry.js.map +2 -2
  135. package/dist/lib/resolver.js +5 -0
  136. package/dist/lib/resolver.js.map +2 -2
  137. package/dist/lib/testing/integration-discovery.js +34 -0
  138. package/dist/lib/testing/integration-discovery.js.map +2 -2
  139. package/dist/lib/testing/integration.js +10 -2
  140. package/dist/lib/testing/integration.js.map +2 -2
  141. package/dist/mercato.js +4 -4
  142. package/dist/mercato.js.map +2 -2
  143. package/package.json +6 -6
  144. package/src/lib/__integration__/TC-INT-008.spec.ts +4 -2
  145. package/src/lib/__tests__/resolve-environment.test.ts +18 -0
  146. package/src/lib/agentic-setup.ts +10 -2
  147. package/src/lib/generators/__tests__/helpers/override-target-diagnostic-fixtures.ts +150 -0
  148. package/src/lib/generators/__tests__/module-extension-facts.test.ts +290 -0
  149. package/src/lib/generators/__tests__/module-facts.bc-guard.test.ts +72 -7
  150. package/src/lib/generators/__tests__/module-facts.computed-di-token.test.ts +88 -0
  151. package/src/lib/generators/__tests__/module-facts.example-fact-coverage.test.ts +502 -0
  152. package/src/lib/generators/__tests__/module-facts.local-reference.test.ts +414 -0
  153. package/src/lib/generators/__tests__/module-facts.search-entity-id.test.ts +151 -0
  154. package/src/lib/generators/__tests__/module-facts.source-links.test.ts +42 -1
  155. package/src/lib/generators/__tests__/module-override-targets.diagnostic-wiring.test.ts +92 -0
  156. package/src/lib/generators/__tests__/module-override-targets.test.ts +24 -0
  157. package/src/lib/generators/__tests__/module-override-targets.unknown-mode.test.ts +117 -0
  158. package/src/lib/generators/__tests__/module-subset.test.ts +60 -0
  159. package/src/lib/generators/module-extension-facts.ts +181 -25
  160. package/src/lib/generators/module-facts-discovery.ts +46 -0
  161. package/src/lib/generators/module-facts.ts +1330 -86
  162. package/src/lib/generators/module-override-targets.ts +70 -26
  163. package/src/lib/generators/module-registry.ts +135 -2
  164. package/src/lib/resolver.ts +6 -1
  165. package/src/lib/testing/__tests__/integration-discovery.test.ts +35 -0
  166. package/src/lib/testing/integration-discovery.ts +50 -0
  167. package/src/lib/testing/integration.ts +10 -2
  168. package/src/mercato.ts +3 -3
@@ -340,6 +340,10 @@ function detectMonorepoFromNodeModules(appDir) {
340
340
  return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot: null };
341
341
  }
342
342
  const corePkgPath = path.join(nodeModulesRoot, "node_modules", "@open-mercato", "core");
343
+ const workspaceCoreModules = path.join(nodeModulesRoot, "packages", "core", "src", "modules");
344
+ if (fs.existsSync(workspaceCoreModules)) {
345
+ return { isMonorepo: true, monorepoRoot: nodeModulesRoot, nodeModulesRoot };
346
+ }
343
347
  try {
344
348
  const stat = fs.lstatSync(corePkgPath);
345
349
  if (stat.isSymbolicLink()) {
@@ -409,6 +413,7 @@ function resolveEnvironment(cwd = process.cwd()) {
409
413
  }
410
414
  export {
411
415
  createResolver,
416
+ readEnabledModulesFromConfig,
412
417
  resolveEnvironment
413
418
  };
414
419
  //# sourceMappingURL=resolver.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/resolver.ts"],
4
- "sourcesContent": ["import path from 'node:path'\nimport fs from 'node:fs'\nimport ts from 'typescript-js'\nimport { parseBooleanWithDefault } from '@open-mercato/shared/lib/boolean'\n\n/**\n * Resolved execution environment for the CLI.\n * Produced once by resolveEnvironment() and consumed by all subsystems.\n * Eliminates per-subsystem isMonorepo() branching and hardcoded path segments.\n */\nexport type CliEnvironment = {\n /** Whether the CLI is running inside a Yarn/npm workspace monorepo. */\n mode: 'monorepo' | 'standalone'\n /** Workspace or project root (where package.json / node_modules live). */\n rootDir: string\n /** Next.js application directory (contains src/, package.json, next.config.*). */\n appDir: string\n /**\n * Resolve the root directory of an installed @open-mercato package.\n * Monorepo: packages/<pkg>/ Standalone: node_modules/<pkg>/\n */\n packageRoot: (packageName: string) => string\n}\n\nexport type ModuleEntry = {\n id: string\n from?: '@open-mercato/core' | '@app' | string\n devSupervisorRequiresFullBootstrap?: boolean\n}\n\nexport type PackageInfo = {\n name: string\n version?: string | null\n path: string\n modulesPath: string\n}\n\nexport interface PackageResolver {\n isMonorepo(): boolean\n getRootDir(): string\n getAppDir(): string\n getOutputDir(): string\n getModulesConfigPath(): string\n discoverPackages(): PackageInfo[]\n loadEnabledModules(): ModuleEntry[]\n getModulePaths(entry: ModuleEntry): { appBase: string; pkgBase: string }\n getModuleImportBase(entry: ModuleEntry): { appBase: string; pkgBase: string }\n getPackageOutputDir(packageName: string): string\n getPackageRoot(from?: string): string\n}\n\nfunction pkgDirFor(rootDir: string, from?: string, isMonorepo = true): string {\n if (!isMonorepo) {\n const pkgName = from || '@open-mercato/core'\n const pkgRoot = path.join(rootDir, 'node_modules', pkgName)\n const distModules = path.join(pkgRoot, 'dist', 'modules')\n if (fs.existsSync(distModules)) return distModules\n return path.join(pkgRoot, 'src', 'modules')\n }\n\n // Monorepo mode - read from src/modules (TypeScript source)\n if (!from || from === '@open-mercato/core') {\n return path.resolve(rootDir, 'packages/core/src/modules')\n }\n // Support other local packages like '@open-mercato/onboarding' => packages/onboarding/src/modules\n const m = from.match(/^@open-mercato\\/(.+)$/)\n if (m) {\n return path.resolve(rootDir, `packages/${m[1]}/src/modules`)\n }\n // Fallback to core modules path\n return path.resolve(rootDir, 'packages/core/src/modules')\n}\n\nfunction pkgRootFor(rootDir: string, from?: string, isMonorepo = true): string {\n if (!isMonorepo) {\n const pkgName = from || '@open-mercato/core'\n return path.join(rootDir, 'node_modules', pkgName)\n }\n\n if (!from || from === '@open-mercato/core') {\n return path.resolve(rootDir, 'packages/core')\n }\n const m = from.match(/^@open-mercato\\/(.+)$/)\n if (m) {\n return path.resolve(rootDir, `packages/${m[1]}`)\n }\n return path.resolve(rootDir, 'packages/core')\n}\n\nfunction parseModuleEntryFromObjectLiteral(node: ts.ObjectLiteralExpression): ModuleEntry | null {\n let id: string | null = null\n let from: string | null = null\n let devSupervisorRequiresFullBootstrap = false\n for (const property of node.properties) {\n if (!ts.isPropertyAssignment(property)) continue\n const key = ts.isIdentifier(property.name) || ts.isStringLiteralLike(property.name)\n ? property.name.text\n : null\n if (key === 'id' && ts.isStringLiteralLike(property.initializer)) {\n id = property.initializer.text\n }\n if (key === 'from' && ts.isStringLiteralLike(property.initializer)) {\n from = property.initializer.text\n }\n if (key === 'overrides') {\n if (!ts.isObjectLiteralExpression(property.initializer)) {\n devSupervisorRequiresFullBootstrap = true\n continue\n }\n for (const overrideProperty of property.initializer.properties) {\n if (ts.isSpreadAssignment(overrideProperty)) {\n devSupervisorRequiresFullBootstrap = true\n break\n }\n if (!ts.isPropertyAssignment(overrideProperty)) continue\n const overrideKey = ts.isIdentifier(overrideProperty.name) || ts.isStringLiteralLike(overrideProperty.name)\n ? overrideProperty.name.text\n : null\n if (overrideKey === 'workers' || overrideKey === 'cli') {\n devSupervisorRequiresFullBootstrap = true\n break\n }\n }\n }\n }\n if (!id) return null\n return {\n id,\n from: from ?? '@open-mercato/core',\n ...(devSupervisorRequiresFullBootstrap ? { devSupervisorRequiresFullBootstrap: true } : {}),\n }\n}\n\nfunction parseProcessEnvAccess(\n node: ts.Expression,\n env: NodeJS.ProcessEnv,\n): { matched: boolean; value: string | undefined } {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name)) {\n const target = node.expression\n if (\n ts.isPropertyAccessExpression(target)\n && ts.isIdentifier(target.expression)\n && target.expression.text === 'process'\n && target.name.text === 'env'\n ) {\n return { matched: true, value: env[node.name.text] }\n }\n }\n if (\n ts.isElementAccessExpression(node)\n && ts.isPropertyAccessExpression(node.expression)\n && ts.isIdentifier(node.expression.expression)\n && node.expression.expression.text === 'process'\n && node.expression.name.text === 'env'\n && ts.isStringLiteralLike(node.argumentExpression)\n ) {\n return { matched: true, value: env[node.argumentExpression.text] }\n }\n return { matched: false, value: undefined }\n}\n\nfunction evaluateStaticExpression(node: ts.Expression, env: NodeJS.ProcessEnv): unknown {\n return evaluateStaticExpressionWithScope(node, env, new Map())\n}\n\nfunction evaluateStaticExpressionWithScope(\n node: ts.Expression,\n env: NodeJS.ProcessEnv,\n scope: Map<string, unknown>,\n): unknown {\n if (ts.isParenthesizedExpression(node)) return evaluateStaticExpressionWithScope(node.expression, env, scope)\n if (ts.isIdentifier(node)) {\n return scope.get(node.text)\n }\n if (ts.isStringLiteralLike(node) || ts.isNoSubstitutionTemplateLiteral(node)) return node.text\n if (ts.isNumericLiteral(node)) return Number(node.text)\n if (node.kind === ts.SyntaxKind.TrueKeyword) return true\n if (node.kind === ts.SyntaxKind.FalseKeyword) return false\n if (node.kind === ts.SyntaxKind.NullKeyword) return null\n\n const envAccess = parseProcessEnvAccess(node, env)\n if (envAccess.matched) return envAccess.value\n\n if (ts.isPropertyAccessExpression(node)) {\n const target = evaluateStaticExpressionWithScope(node.expression, env, scope)\n if (target && typeof target === 'object' && node.name.text in target) {\n return (target as Record<string, unknown>)[node.name.text]\n }\n return undefined\n }\n\n if (ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.ExclamationToken) {\n return !Boolean(evaluateStaticExpressionWithScope(node.operand, env, scope))\n }\n\n if (ts.isBinaryExpression(node)) {\n if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {\n return Boolean(evaluateStaticExpressionWithScope(node.left, env, scope))\n && Boolean(evaluateStaticExpressionWithScope(node.right, env, scope))\n }\n if (node.operatorToken.kind === ts.SyntaxKind.BarBarToken) {\n return Boolean(evaluateStaticExpressionWithScope(node.left, env, scope))\n || Boolean(evaluateStaticExpressionWithScope(node.right, env, scope))\n }\n if (node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken) {\n return evaluateStaticExpressionWithScope(node.left, env, scope) === evaluateStaticExpressionWithScope(node.right, env, scope)\n }\n if (node.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken) {\n return evaluateStaticExpressionWithScope(node.left, env, scope) !== evaluateStaticExpressionWithScope(node.right, env, scope)\n }\n }\n\n if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'parseBooleanWithDefault') {\n const rawValueNode = node.arguments[0]\n const fallbackNode = node.arguments[1]\n const rawValue = rawValueNode ? evaluateStaticExpressionWithScope(rawValueNode, env, scope) : undefined\n const fallbackValue = fallbackNode ? evaluateStaticExpressionWithScope(fallbackNode, env, scope) : false\n return parseBooleanWithDefault(typeof rawValue === 'string' ? rawValue : undefined, Boolean(fallbackValue))\n }\n\n if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === 'some') {\n const target = evaluateStaticExpressionWithScope(node.expression.expression, env, scope)\n const predicate = node.arguments[0]\n if (!Array.isArray(target) || !predicate) return undefined\n\n return target.some((entry) => {\n if (!ts.isArrowFunction(predicate) && !ts.isFunctionExpression(predicate)) return false\n\n const localScope = new Map(scope)\n const parameter = predicate.parameters[0]\n if (parameter && ts.isIdentifier(parameter.name)) {\n localScope.set(parameter.name.text, entry)\n }\n\n if (ts.isBlock(predicate.body)) {\n const returnStatement = predicate.body.statements.find((statement): statement is ts.ReturnStatement =>\n ts.isReturnStatement(statement),\n )\n if (!returnStatement?.expression) return false\n return Boolean(evaluateStaticExpressionWithScope(returnStatement.expression, env, localScope))\n }\n\n return Boolean(evaluateStaticExpressionWithScope(predicate.body, env, localScope))\n })\n }\n\n return undefined\n}\n\nfunction evaluateStaticCondition(\n node: ts.Expression,\n env: NodeJS.ProcessEnv,\n scope: Map<string, unknown>,\n): boolean {\n const evaluated = evaluateStaticExpressionWithScope(node, env, scope)\n return Boolean(evaluated)\n}\n\nfunction collectPushEntriesFromStatement(\n statement: ts.Statement,\n env: NodeJS.ProcessEnv,\n targetVariableName: string,\n scope: Map<string, unknown>,\n): ModuleEntry[] {\n if (ts.isBlock(statement)) {\n return statement.statements.flatMap((child) => collectPushEntriesFromStatement(child, env, targetVariableName, scope))\n }\n\n if (ts.isIfStatement(statement)) {\n if (evaluateStaticCondition(statement.expression, env, scope)) {\n return collectPushEntriesFromStatement(statement.thenStatement, env, targetVariableName, scope)\n }\n if (statement.elseStatement) {\n return collectPushEntriesFromStatement(statement.elseStatement, env, targetVariableName, scope)\n }\n return []\n }\n\n if (!ts.isExpressionStatement(statement)) return []\n const expression = statement.expression\n if (!ts.isCallExpression(expression)) return []\n if (!ts.isPropertyAccessExpression(expression.expression)) return []\n const pushTarget = expression.expression.expression\n const pushMethod = expression.expression.name\n if (!ts.isIdentifier(pushTarget) || pushTarget.text !== targetVariableName) return []\n if (pushMethod.text !== 'push') return []\n\n return expression.arguments.flatMap((argument) => {\n if (!ts.isObjectLiteralExpression(argument)) return []\n const entry = parseModuleEntryFromObjectLiteral(argument)\n return entry ? [entry] : []\n })\n}\n\nfunction parseModulesFromSource(source: string, env: NodeJS.ProcessEnv = process.env): ModuleEntry[] {\n const sourceFile = ts.createSourceFile('modules.ts', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS)\n const modules: ModuleEntry[] = []\n const variableName = 'enabledModules'\n const scope = new Map<string, unknown>()\n let foundDeclaration = false\n\n for (const statement of sourceFile.statements) {\n if (ts.isVariableStatement(statement)) {\n for (const declaration of statement.declarationList.declarations) {\n if (!ts.isIdentifier(declaration.name)) continue\n if (declaration.name.text === variableName) {\n if (!declaration.initializer || !ts.isArrayLiteralExpression(declaration.initializer)) continue\n const fromArray = declaration.initializer.elements.flatMap((element) => {\n if (!ts.isObjectLiteralExpression(element)) return []\n const entry = parseModuleEntryFromObjectLiteral(element)\n return entry ? [entry] : []\n })\n modules.push(...fromArray)\n scope.set(variableName, [...modules])\n foundDeclaration = true\n continue\n }\n if (!declaration.initializer) continue\n scope.set(\n declaration.name.text,\n evaluateStaticExpressionWithScope(declaration.initializer, env, scope),\n )\n }\n continue\n }\n if (!foundDeclaration) continue\n const pushedEntries = collectPushEntriesFromStatement(statement, env, variableName, scope)\n if (pushedEntries.length > 0) {\n modules.push(...pushedEntries)\n scope.set(variableName, [...modules])\n }\n }\n\n return modules\n}\n\nfunction readEnabledModulesFromConfig(cfgPath: string): ModuleEntry[] {\n const source = fs.readFileSync(cfgPath, 'utf8')\n return parseModulesFromSource(source)\n}\n\nfunction loadEnabledModulesFromConfig(appDir: string): ModuleEntry[] {\n const cfgPath = path.resolve(appDir, 'src/modules.ts')\n if (fs.existsSync(cfgPath)) {\n try {\n const loadedModules = readEnabledModulesFromConfig(cfgPath)\n if (loadedModules.length > 0) return loadedModules\n } catch (error) {\n console.warn(\n '[resolver] Failed to read enabled modules from src/modules.ts, falling back to src/modules scan:',\n error,\n )\n }\n }\n // Fallback: scan src/modules/* to keep backward compatibility\n const modulesRoot = path.resolve(appDir, 'src/modules')\n if (!fs.existsSync(modulesRoot)) return []\n const scannedModules = fs\n .readdirSync(modulesRoot, { withFileTypes: true })\n .filter((e) => e.isDirectory() && !e.name.startsWith('.'))\n .map((e) => ({ id: e.name, from: '@app' as const }))\n\n return scannedModules\n}\n\nfunction discoverPackagesInMonorepo(rootDir: string): PackageInfo[] {\n const packagesDir = path.join(rootDir, 'packages')\n if (!fs.existsSync(packagesDir)) return []\n\n const packages: PackageInfo[] = []\n const entries = fs.readdirSync(packagesDir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const pkgPath = path.join(packagesDir, entry.name)\n const pkgJsonPath = path.join(pkgPath, 'package.json')\n\n if (!fs.existsSync(pkgJsonPath)) continue\n\n try {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))\n // Read from src/modules (TypeScript source)\n const modulesPath = path.join(pkgPath, 'src', 'modules')\n\n if (fs.existsSync(modulesPath)) {\n packages.push({\n name: pkgJson.name || `@open-mercato/${entry.name}`,\n version: typeof pkgJson.version === 'string' ? pkgJson.version : null,\n path: pkgPath,\n modulesPath,\n })\n }\n } catch {\n // Skip invalid packages\n }\n }\n\n return packages\n}\n\nfunction discoverPackagesInNodeModules(rootDir: string): PackageInfo[] {\n const nodeModulesPath = path.join(rootDir, 'node_modules', '@open-mercato')\n if (!fs.existsSync(nodeModulesPath)) return []\n\n const packages: PackageInfo[] = []\n const entries = fs.readdirSync(nodeModulesPath, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const pkgPath = path.join(nodeModulesPath, entry.name)\n const pkgJsonPath = path.join(pkgPath, 'package.json')\n\n if (!fs.existsSync(pkgJsonPath)) continue\n\n try {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))\n const distModulesPath = path.join(pkgPath, 'dist', 'modules')\n const srcModulesPath = path.join(pkgPath, 'src', 'modules')\n const modulesPath = fs.existsSync(distModulesPath) ? distModulesPath : srcModulesPath\n\n if (fs.existsSync(modulesPath)) {\n packages.push({\n name: pkgJson.name || `@open-mercato/${entry.name}`,\n version: typeof pkgJson.version === 'string' ? pkgJson.version : null,\n path: pkgPath,\n modulesPath,\n })\n }\n } catch {\n // Skip invalid packages\n }\n }\n\n return packages\n}\n\nfunction detectAppDir(rootDir: string, isMonorepo: boolean): string {\n if (!isMonorepo) {\n // Production mode: app is at root\n return rootDir\n }\n\n // Monorepo mode: look for app in apps/mercato/ or apps/app/\n const mercatoApp = path.join(rootDir, 'apps', 'mercato')\n if (fs.existsSync(mercatoApp)) {\n return mercatoApp\n }\n\n const defaultApp = path.join(rootDir, 'apps', 'app')\n if (fs.existsSync(defaultApp)) {\n return defaultApp\n }\n\n // Fallback: check if apps directory exists and has any app\n const appsDir = path.join(rootDir, 'apps')\n if (fs.existsSync(appsDir)) {\n const entries = fs.readdirSync(appsDir, { withFileTypes: true })\n const appEntry = entries.find(\n (e) => e.isDirectory() && !e.name.startsWith('.') && e.name !== 'docs'\n )\n if (appEntry) {\n return path.join(appsDir, appEntry.name)\n }\n }\n\n // Final fallback for legacy structure: root is the app\n return rootDir\n}\n\nfunction findNodeModulesRoot(startDir: string): string | null {\n // Walk up to find node_modules/@open-mercato/core\n let dir = startDir\n while (dir !== path.dirname(dir)) {\n const corePkgPath = path.join(dir, 'node_modules', '@open-mercato', 'core')\n if (fs.existsSync(corePkgPath)) {\n return dir\n }\n dir = path.dirname(dir)\n }\n return null\n}\n\nfunction detectMonorepoFromNodeModules(appDir: string): { isMonorepo: boolean; monorepoRoot: string | null; nodeModulesRoot: string | null } {\n // Find where node_modules/@open-mercato/core is located (may be hoisted)\n const nodeModulesRoot = findNodeModulesRoot(appDir)\n if (!nodeModulesRoot) {\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot: null }\n }\n\n const corePkgPath = path.join(nodeModulesRoot, 'node_modules', '@open-mercato', 'core')\n\n try {\n const stat = fs.lstatSync(corePkgPath)\n if (stat.isSymbolicLink()) {\n // It's a symlink - we're in monorepo dev mode\n // Resolve the symlink to find the monorepo root\n const realPath = fs.realpathSync(corePkgPath)\n // realPath is something like /path/to/monorepo/packages/core\n // monorepo root is 2 levels up\n const monorepoRoot = path.dirname(path.dirname(realPath))\n return { isMonorepo: true, monorepoRoot, nodeModulesRoot }\n }\n // It's a real directory - production mode\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot }\n } catch {\n // Package doesn't exist yet or error reading - assume production mode\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot }\n }\n}\n\nexport function createResolver(cwd: string = process.cwd()): PackageResolver {\n // First detect if we're in a monorepo by checking if node_modules packages are symlinks\n const { isMonorepo: _isMonorepo, monorepoRoot, nodeModulesRoot } = detectMonorepoFromNodeModules(cwd)\n // In workspaces with hoisted real directories, package sources live under the discovered node_modules root.\n const rootDir = monorepoRoot ?? nodeModulesRoot ?? cwd\n\n // shouldResolveAppFromRoot: true when we have a workspace/install root that differs from cwd\n // (monorepo symlinks detected, or node_modules root found above cwd)\n const shouldResolveAppFromRoot =\n _isMonorepo || (nodeModulesRoot !== null && path.resolve(nodeModulesRoot) !== path.resolve(cwd))\n\n // The app directory depends on context:\n // - In monorepo: use detectAppDir to find apps/mercato or similar\n // - When symlinks not detected (e.g. Docker volume node_modules): still use apps/mercato if present at rootDir\n // - Otherwise: app is at cwd\n const candidateAppDir = shouldResolveAppFromRoot ? detectAppDir(rootDir, true) : rootDir\n const appDir =\n _isMonorepo\n ? candidateAppDir\n : shouldResolveAppFromRoot && candidateAppDir !== rootDir && fs.existsSync(candidateAppDir)\n ? candidateAppDir\n : cwd\n\n return {\n isMonorepo: () => _isMonorepo,\n\n getRootDir: () => rootDir,\n\n getAppDir: () => appDir,\n\n getOutputDir: () => {\n // Output is ALWAYS .mercato/generated relative to app directory\n return path.join(appDir, '.mercato', 'generated')\n },\n\n getModulesConfigPath: () => path.join(appDir, 'src', 'modules.ts'),\n\n discoverPackages: () => {\n return _isMonorepo\n ? discoverPackagesInMonorepo(rootDir)\n : discoverPackagesInNodeModules(rootDir)\n },\n\n loadEnabledModules: () => loadEnabledModulesFromConfig(appDir),\n\n getModulePaths: (entry: ModuleEntry) => {\n const appBase = path.resolve(appDir, 'src/modules', entry.id)\n const pkgModulesRoot = pkgDirFor(rootDir, entry.from, _isMonorepo)\n const pkgBase = path.join(pkgModulesRoot, entry.id)\n return { appBase, pkgBase }\n },\n\n getModuleImportBase: (entry: ModuleEntry) => {\n // Prefer @app overrides at import-time; fall back to provided package alias\n const from = entry.from || '@open-mercato/core'\n return {\n appBase: `@/modules/${entry.id}`,\n pkgBase: `${from}/modules/${entry.id}`,\n }\n },\n\n getPackageOutputDir: (packageName: string) => {\n if (packageName === '@app') {\n // App output goes to .mercato/generated\n return path.join(appDir, '.mercato', 'generated')\n }\n const pkgRoot = pkgRootFor(rootDir, packageName, _isMonorepo)\n return path.join(pkgRoot, 'generated')\n },\n\n getPackageRoot: (from?: string) => {\n return pkgRootFor(rootDir, from, _isMonorepo)\n },\n }\n}\n\n/**\n * Resolve the CLI execution environment as a plain value-object.\n * Call once at subsystem init; use the returned object for all path decisions.\n */\nexport function resolveEnvironment(cwd: string = process.cwd()): CliEnvironment {\n const resolver = createResolver(cwd)\n const _isMonorepo = resolver.isMonorepo()\n const rootDir = resolver.getRootDir()\n const appDir = resolver.getAppDir()\n return {\n mode: _isMonorepo ? 'monorepo' : 'standalone',\n rootDir,\n appDir,\n packageRoot: (packageName: string) => pkgRootFor(rootDir, packageName, _isMonorepo),\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import path from 'node:path'\nimport fs from 'node:fs'\nimport ts from 'typescript-js'\nimport { parseBooleanWithDefault } from '@open-mercato/shared/lib/boolean'\n\n/**\n * Resolved execution environment for the CLI.\n * Produced once by resolveEnvironment() and consumed by all subsystems.\n * Eliminates per-subsystem isMonorepo() branching and hardcoded path segments.\n */\nexport type CliEnvironment = {\n /** Whether the CLI is running inside a Yarn/npm workspace monorepo. */\n mode: 'monorepo' | 'standalone'\n /** Workspace or project root (where package.json / node_modules live). */\n rootDir: string\n /** Next.js application directory (contains src/, package.json, next.config.*). */\n appDir: string\n /**\n * Resolve the root directory of an installed @open-mercato package.\n * Monorepo: packages/<pkg>/ Standalone: node_modules/<pkg>/\n */\n packageRoot: (packageName: string) => string\n}\n\nexport type ModuleEntry = {\n id: string\n from?: '@open-mercato/core' | '@app' | string\n devSupervisorRequiresFullBootstrap?: boolean\n}\n\nexport type PackageInfo = {\n name: string\n version?: string | null\n path: string\n modulesPath: string\n}\n\nexport interface PackageResolver {\n isMonorepo(): boolean\n getRootDir(): string\n getAppDir(): string\n getOutputDir(): string\n getModulesConfigPath(): string\n discoverPackages(): PackageInfo[]\n loadEnabledModules(): ModuleEntry[]\n getModulePaths(entry: ModuleEntry): { appBase: string; pkgBase: string }\n getModuleImportBase(entry: ModuleEntry): { appBase: string; pkgBase: string }\n getPackageOutputDir(packageName: string): string\n getPackageRoot(from?: string): string\n}\n\nfunction pkgDirFor(rootDir: string, from?: string, isMonorepo = true): string {\n if (!isMonorepo) {\n const pkgName = from || '@open-mercato/core'\n const pkgRoot = path.join(rootDir, 'node_modules', pkgName)\n const distModules = path.join(pkgRoot, 'dist', 'modules')\n if (fs.existsSync(distModules)) return distModules\n return path.join(pkgRoot, 'src', 'modules')\n }\n\n // Monorepo mode - read from src/modules (TypeScript source)\n if (!from || from === '@open-mercato/core') {\n return path.resolve(rootDir, 'packages/core/src/modules')\n }\n // Support other local packages like '@open-mercato/onboarding' => packages/onboarding/src/modules\n const m = from.match(/^@open-mercato\\/(.+)$/)\n if (m) {\n return path.resolve(rootDir, `packages/${m[1]}/src/modules`)\n }\n // Fallback to core modules path\n return path.resolve(rootDir, 'packages/core/src/modules')\n}\n\nfunction pkgRootFor(rootDir: string, from?: string, isMonorepo = true): string {\n if (!isMonorepo) {\n const pkgName = from || '@open-mercato/core'\n return path.join(rootDir, 'node_modules', pkgName)\n }\n\n if (!from || from === '@open-mercato/core') {\n return path.resolve(rootDir, 'packages/core')\n }\n const m = from.match(/^@open-mercato\\/(.+)$/)\n if (m) {\n return path.resolve(rootDir, `packages/${m[1]}`)\n }\n return path.resolve(rootDir, 'packages/core')\n}\n\nfunction parseModuleEntryFromObjectLiteral(node: ts.ObjectLiteralExpression): ModuleEntry | null {\n let id: string | null = null\n let from: string | null = null\n let devSupervisorRequiresFullBootstrap = false\n for (const property of node.properties) {\n if (!ts.isPropertyAssignment(property)) continue\n const key = ts.isIdentifier(property.name) || ts.isStringLiteralLike(property.name)\n ? property.name.text\n : null\n if (key === 'id' && ts.isStringLiteralLike(property.initializer)) {\n id = property.initializer.text\n }\n if (key === 'from' && ts.isStringLiteralLike(property.initializer)) {\n from = property.initializer.text\n }\n if (key === 'overrides') {\n if (!ts.isObjectLiteralExpression(property.initializer)) {\n devSupervisorRequiresFullBootstrap = true\n continue\n }\n for (const overrideProperty of property.initializer.properties) {\n if (ts.isSpreadAssignment(overrideProperty)) {\n devSupervisorRequiresFullBootstrap = true\n break\n }\n if (!ts.isPropertyAssignment(overrideProperty)) continue\n const overrideKey = ts.isIdentifier(overrideProperty.name) || ts.isStringLiteralLike(overrideProperty.name)\n ? overrideProperty.name.text\n : null\n if (overrideKey === 'workers' || overrideKey === 'cli') {\n devSupervisorRequiresFullBootstrap = true\n break\n }\n }\n }\n }\n if (!id) return null\n return {\n id,\n from: from ?? '@open-mercato/core',\n ...(devSupervisorRequiresFullBootstrap ? { devSupervisorRequiresFullBootstrap: true } : {}),\n }\n}\n\nfunction parseProcessEnvAccess(\n node: ts.Expression,\n env: NodeJS.ProcessEnv,\n): { matched: boolean; value: string | undefined } {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name)) {\n const target = node.expression\n if (\n ts.isPropertyAccessExpression(target)\n && ts.isIdentifier(target.expression)\n && target.expression.text === 'process'\n && target.name.text === 'env'\n ) {\n return { matched: true, value: env[node.name.text] }\n }\n }\n if (\n ts.isElementAccessExpression(node)\n && ts.isPropertyAccessExpression(node.expression)\n && ts.isIdentifier(node.expression.expression)\n && node.expression.expression.text === 'process'\n && node.expression.name.text === 'env'\n && ts.isStringLiteralLike(node.argumentExpression)\n ) {\n return { matched: true, value: env[node.argumentExpression.text] }\n }\n return { matched: false, value: undefined }\n}\n\nfunction evaluateStaticExpression(node: ts.Expression, env: NodeJS.ProcessEnv): unknown {\n return evaluateStaticExpressionWithScope(node, env, new Map())\n}\n\nfunction evaluateStaticExpressionWithScope(\n node: ts.Expression,\n env: NodeJS.ProcessEnv,\n scope: Map<string, unknown>,\n): unknown {\n if (ts.isParenthesizedExpression(node)) return evaluateStaticExpressionWithScope(node.expression, env, scope)\n if (ts.isIdentifier(node)) {\n return scope.get(node.text)\n }\n if (ts.isStringLiteralLike(node) || ts.isNoSubstitutionTemplateLiteral(node)) return node.text\n if (ts.isNumericLiteral(node)) return Number(node.text)\n if (node.kind === ts.SyntaxKind.TrueKeyword) return true\n if (node.kind === ts.SyntaxKind.FalseKeyword) return false\n if (node.kind === ts.SyntaxKind.NullKeyword) return null\n\n const envAccess = parseProcessEnvAccess(node, env)\n if (envAccess.matched) return envAccess.value\n\n if (ts.isPropertyAccessExpression(node)) {\n const target = evaluateStaticExpressionWithScope(node.expression, env, scope)\n if (target && typeof target === 'object' && node.name.text in target) {\n return (target as Record<string, unknown>)[node.name.text]\n }\n return undefined\n }\n\n if (ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.ExclamationToken) {\n return !Boolean(evaluateStaticExpressionWithScope(node.operand, env, scope))\n }\n\n if (ts.isBinaryExpression(node)) {\n if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {\n return Boolean(evaluateStaticExpressionWithScope(node.left, env, scope))\n && Boolean(evaluateStaticExpressionWithScope(node.right, env, scope))\n }\n if (node.operatorToken.kind === ts.SyntaxKind.BarBarToken) {\n return Boolean(evaluateStaticExpressionWithScope(node.left, env, scope))\n || Boolean(evaluateStaticExpressionWithScope(node.right, env, scope))\n }\n if (node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken) {\n return evaluateStaticExpressionWithScope(node.left, env, scope) === evaluateStaticExpressionWithScope(node.right, env, scope)\n }\n if (node.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken) {\n return evaluateStaticExpressionWithScope(node.left, env, scope) !== evaluateStaticExpressionWithScope(node.right, env, scope)\n }\n }\n\n if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'parseBooleanWithDefault') {\n const rawValueNode = node.arguments[0]\n const fallbackNode = node.arguments[1]\n const rawValue = rawValueNode ? evaluateStaticExpressionWithScope(rawValueNode, env, scope) : undefined\n const fallbackValue = fallbackNode ? evaluateStaticExpressionWithScope(fallbackNode, env, scope) : false\n return parseBooleanWithDefault(typeof rawValue === 'string' ? rawValue : undefined, Boolean(fallbackValue))\n }\n\n if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === 'some') {\n const target = evaluateStaticExpressionWithScope(node.expression.expression, env, scope)\n const predicate = node.arguments[0]\n if (!Array.isArray(target) || !predicate) return undefined\n\n return target.some((entry) => {\n if (!ts.isArrowFunction(predicate) && !ts.isFunctionExpression(predicate)) return false\n\n const localScope = new Map(scope)\n const parameter = predicate.parameters[0]\n if (parameter && ts.isIdentifier(parameter.name)) {\n localScope.set(parameter.name.text, entry)\n }\n\n if (ts.isBlock(predicate.body)) {\n const returnStatement = predicate.body.statements.find((statement): statement is ts.ReturnStatement =>\n ts.isReturnStatement(statement),\n )\n if (!returnStatement?.expression) return false\n return Boolean(evaluateStaticExpressionWithScope(returnStatement.expression, env, localScope))\n }\n\n return Boolean(evaluateStaticExpressionWithScope(predicate.body, env, localScope))\n })\n }\n\n return undefined\n}\n\nfunction evaluateStaticCondition(\n node: ts.Expression,\n env: NodeJS.ProcessEnv,\n scope: Map<string, unknown>,\n): boolean {\n const evaluated = evaluateStaticExpressionWithScope(node, env, scope)\n return Boolean(evaluated)\n}\n\nfunction collectPushEntriesFromStatement(\n statement: ts.Statement,\n env: NodeJS.ProcessEnv,\n targetVariableName: string,\n scope: Map<string, unknown>,\n): ModuleEntry[] {\n if (ts.isBlock(statement)) {\n return statement.statements.flatMap((child) => collectPushEntriesFromStatement(child, env, targetVariableName, scope))\n }\n\n if (ts.isIfStatement(statement)) {\n if (evaluateStaticCondition(statement.expression, env, scope)) {\n return collectPushEntriesFromStatement(statement.thenStatement, env, targetVariableName, scope)\n }\n if (statement.elseStatement) {\n return collectPushEntriesFromStatement(statement.elseStatement, env, targetVariableName, scope)\n }\n return []\n }\n\n if (!ts.isExpressionStatement(statement)) return []\n const expression = statement.expression\n if (!ts.isCallExpression(expression)) return []\n if (!ts.isPropertyAccessExpression(expression.expression)) return []\n const pushTarget = expression.expression.expression\n const pushMethod = expression.expression.name\n if (!ts.isIdentifier(pushTarget) || pushTarget.text !== targetVariableName) return []\n if (pushMethod.text !== 'push') return []\n\n return expression.arguments.flatMap((argument) => {\n if (!ts.isObjectLiteralExpression(argument)) return []\n const entry = parseModuleEntryFromObjectLiteral(argument)\n return entry ? [entry] : []\n })\n}\n\nfunction parseModulesFromSource(source: string, env: NodeJS.ProcessEnv = process.env): ModuleEntry[] {\n const sourceFile = ts.createSourceFile('modules.ts', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS)\n const modules: ModuleEntry[] = []\n const variableName = 'enabledModules'\n const scope = new Map<string, unknown>()\n let foundDeclaration = false\n\n for (const statement of sourceFile.statements) {\n if (ts.isVariableStatement(statement)) {\n for (const declaration of statement.declarationList.declarations) {\n if (!ts.isIdentifier(declaration.name)) continue\n if (declaration.name.text === variableName) {\n if (!declaration.initializer || !ts.isArrayLiteralExpression(declaration.initializer)) continue\n const fromArray = declaration.initializer.elements.flatMap((element) => {\n if (!ts.isObjectLiteralExpression(element)) return []\n const entry = parseModuleEntryFromObjectLiteral(element)\n return entry ? [entry] : []\n })\n modules.push(...fromArray)\n scope.set(variableName, [...modules])\n foundDeclaration = true\n continue\n }\n if (!declaration.initializer) continue\n scope.set(\n declaration.name.text,\n evaluateStaticExpressionWithScope(declaration.initializer, env, scope),\n )\n }\n continue\n }\n if (!foundDeclaration) continue\n const pushedEntries = collectPushEntriesFromStatement(statement, env, variableName, scope)\n if (pushedEntries.length > 0) {\n modules.push(...pushedEntries)\n scope.set(variableName, [...modules])\n }\n }\n\n return modules\n}\n\nexport function readEnabledModulesFromConfig(cfgPath: string): ModuleEntry[] {\n const source = fs.readFileSync(cfgPath, 'utf8')\n return parseModulesFromSource(source)\n}\n\nfunction loadEnabledModulesFromConfig(appDir: string): ModuleEntry[] {\n const cfgPath = path.resolve(appDir, 'src/modules.ts')\n if (fs.existsSync(cfgPath)) {\n try {\n const loadedModules = readEnabledModulesFromConfig(cfgPath)\n if (loadedModules.length > 0) return loadedModules\n } catch (error) {\n console.warn(\n '[resolver] Failed to read enabled modules from src/modules.ts, falling back to src/modules scan:',\n error,\n )\n }\n }\n // Fallback: scan src/modules/* to keep backward compatibility\n const modulesRoot = path.resolve(appDir, 'src/modules')\n if (!fs.existsSync(modulesRoot)) return []\n const scannedModules = fs\n .readdirSync(modulesRoot, { withFileTypes: true })\n .filter((e) => e.isDirectory() && !e.name.startsWith('.'))\n .map((e) => ({ id: e.name, from: '@app' as const }))\n\n return scannedModules\n}\n\nfunction discoverPackagesInMonorepo(rootDir: string): PackageInfo[] {\n const packagesDir = path.join(rootDir, 'packages')\n if (!fs.existsSync(packagesDir)) return []\n\n const packages: PackageInfo[] = []\n const entries = fs.readdirSync(packagesDir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const pkgPath = path.join(packagesDir, entry.name)\n const pkgJsonPath = path.join(pkgPath, 'package.json')\n\n if (!fs.existsSync(pkgJsonPath)) continue\n\n try {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))\n // Read from src/modules (TypeScript source)\n const modulesPath = path.join(pkgPath, 'src', 'modules')\n\n if (fs.existsSync(modulesPath)) {\n packages.push({\n name: pkgJson.name || `@open-mercato/${entry.name}`,\n version: typeof pkgJson.version === 'string' ? pkgJson.version : null,\n path: pkgPath,\n modulesPath,\n })\n }\n } catch {\n // Skip invalid packages\n }\n }\n\n return packages\n}\n\nfunction discoverPackagesInNodeModules(rootDir: string): PackageInfo[] {\n const nodeModulesPath = path.join(rootDir, 'node_modules', '@open-mercato')\n if (!fs.existsSync(nodeModulesPath)) return []\n\n const packages: PackageInfo[] = []\n const entries = fs.readdirSync(nodeModulesPath, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const pkgPath = path.join(nodeModulesPath, entry.name)\n const pkgJsonPath = path.join(pkgPath, 'package.json')\n\n if (!fs.existsSync(pkgJsonPath)) continue\n\n try {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))\n const distModulesPath = path.join(pkgPath, 'dist', 'modules')\n const srcModulesPath = path.join(pkgPath, 'src', 'modules')\n const modulesPath = fs.existsSync(distModulesPath) ? distModulesPath : srcModulesPath\n\n if (fs.existsSync(modulesPath)) {\n packages.push({\n name: pkgJson.name || `@open-mercato/${entry.name}`,\n version: typeof pkgJson.version === 'string' ? pkgJson.version : null,\n path: pkgPath,\n modulesPath,\n })\n }\n } catch {\n // Skip invalid packages\n }\n }\n\n return packages\n}\n\nfunction detectAppDir(rootDir: string, isMonorepo: boolean): string {\n if (!isMonorepo) {\n // Production mode: app is at root\n return rootDir\n }\n\n // Monorepo mode: look for app in apps/mercato/ or apps/app/\n const mercatoApp = path.join(rootDir, 'apps', 'mercato')\n if (fs.existsSync(mercatoApp)) {\n return mercatoApp\n }\n\n const defaultApp = path.join(rootDir, 'apps', 'app')\n if (fs.existsSync(defaultApp)) {\n return defaultApp\n }\n\n // Fallback: check if apps directory exists and has any app\n const appsDir = path.join(rootDir, 'apps')\n if (fs.existsSync(appsDir)) {\n const entries = fs.readdirSync(appsDir, { withFileTypes: true })\n const appEntry = entries.find(\n (e) => e.isDirectory() && !e.name.startsWith('.') && e.name !== 'docs'\n )\n if (appEntry) {\n return path.join(appsDir, appEntry.name)\n }\n }\n\n // Final fallback for legacy structure: root is the app\n return rootDir\n}\n\nfunction findNodeModulesRoot(startDir: string): string | null {\n // Walk up to find node_modules/@open-mercato/core\n let dir = startDir\n while (dir !== path.dirname(dir)) {\n const corePkgPath = path.join(dir, 'node_modules', '@open-mercato', 'core')\n if (fs.existsSync(corePkgPath)) {\n return dir\n }\n dir = path.dirname(dir)\n }\n return null\n}\n\nfunction detectMonorepoFromNodeModules(appDir: string): { isMonorepo: boolean; monorepoRoot: string | null; nodeModulesRoot: string | null } {\n // Find where node_modules/@open-mercato/core is located (may be hoisted)\n const nodeModulesRoot = findNodeModulesRoot(appDir)\n if (!nodeModulesRoot) {\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot: null }\n }\n\n const corePkgPath = path.join(nodeModulesRoot, 'node_modules', '@open-mercato', 'core')\n\n const workspaceCoreModules = path.join(nodeModulesRoot, 'packages', 'core', 'src', 'modules')\n if (fs.existsSync(workspaceCoreModules)) {\n return { isMonorepo: true, monorepoRoot: nodeModulesRoot, nodeModulesRoot }\n }\n\n try {\n const stat = fs.lstatSync(corePkgPath)\n if (stat.isSymbolicLink()) {\n // It's a symlink - we're in monorepo dev mode\n // Resolve the symlink to find the monorepo root\n const realPath = fs.realpathSync(corePkgPath)\n // realPath is something like /path/to/monorepo/packages/core\n // monorepo root is 2 levels up\n const monorepoRoot = path.dirname(path.dirname(realPath))\n return { isMonorepo: true, monorepoRoot, nodeModulesRoot }\n }\n // It's a real directory - production mode\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot }\n } catch {\n // Package doesn't exist yet or error reading - assume production mode\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot }\n }\n}\n\nexport function createResolver(cwd: string = process.cwd()): PackageResolver {\n // First detect if we're in a monorepo by checking if node_modules packages are symlinks\n const { isMonorepo: _isMonorepo, monorepoRoot, nodeModulesRoot } = detectMonorepoFromNodeModules(cwd)\n // In workspaces with hoisted real directories, package sources live under the discovered node_modules root.\n const rootDir = monorepoRoot ?? nodeModulesRoot ?? cwd\n\n // shouldResolveAppFromRoot: true when we have a workspace/install root that differs from cwd\n // (monorepo symlinks detected, or node_modules root found above cwd)\n const shouldResolveAppFromRoot =\n _isMonorepo || (nodeModulesRoot !== null && path.resolve(nodeModulesRoot) !== path.resolve(cwd))\n\n // The app directory depends on context:\n // - In monorepo: use detectAppDir to find apps/mercato or similar\n // - When symlinks not detected (e.g. Docker volume node_modules): still use apps/mercato if present at rootDir\n // - Otherwise: app is at cwd\n const candidateAppDir = shouldResolveAppFromRoot ? detectAppDir(rootDir, true) : rootDir\n const appDir =\n _isMonorepo\n ? candidateAppDir\n : shouldResolveAppFromRoot && candidateAppDir !== rootDir && fs.existsSync(candidateAppDir)\n ? candidateAppDir\n : cwd\n\n return {\n isMonorepo: () => _isMonorepo,\n\n getRootDir: () => rootDir,\n\n getAppDir: () => appDir,\n\n getOutputDir: () => {\n // Output is ALWAYS .mercato/generated relative to app directory\n return path.join(appDir, '.mercato', 'generated')\n },\n\n getModulesConfigPath: () => path.join(appDir, 'src', 'modules.ts'),\n\n discoverPackages: () => {\n return _isMonorepo\n ? discoverPackagesInMonorepo(rootDir)\n : discoverPackagesInNodeModules(rootDir)\n },\n\n loadEnabledModules: () => loadEnabledModulesFromConfig(appDir),\n\n getModulePaths: (entry: ModuleEntry) => {\n const appBase = path.resolve(appDir, 'src/modules', entry.id)\n const pkgModulesRoot = pkgDirFor(rootDir, entry.from, _isMonorepo)\n const pkgBase = path.join(pkgModulesRoot, entry.id)\n return { appBase, pkgBase }\n },\n\n getModuleImportBase: (entry: ModuleEntry) => {\n // Prefer @app overrides at import-time; fall back to provided package alias\n const from = entry.from || '@open-mercato/core'\n return {\n appBase: `@/modules/${entry.id}`,\n pkgBase: `${from}/modules/${entry.id}`,\n }\n },\n\n getPackageOutputDir: (packageName: string) => {\n if (packageName === '@app') {\n // App output goes to .mercato/generated\n return path.join(appDir, '.mercato', 'generated')\n }\n const pkgRoot = pkgRootFor(rootDir, packageName, _isMonorepo)\n return path.join(pkgRoot, 'generated')\n },\n\n getPackageRoot: (from?: string) => {\n return pkgRootFor(rootDir, from, _isMonorepo)\n },\n }\n}\n\n/**\n * Resolve the CLI execution environment as a plain value-object.\n * Call once at subsystem init; use the returned object for all path decisions.\n */\nexport function resolveEnvironment(cwd: string = process.cwd()): CliEnvironment {\n const resolver = createResolver(cwd)\n const _isMonorepo = resolver.isMonorepo()\n const rootDir = resolver.getRootDir()\n const appDir = resolver.getAppDir()\n return {\n mode: _isMonorepo ? 'monorepo' : 'standalone',\n rootDir,\n appDir,\n packageRoot: (packageName: string) => pkgRootFor(rootDir, packageName, _isMonorepo),\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,6 @@
1
1
  import { readFileSync, readdirSync } from "node:fs";
2
2
  import path from "node:path";
3
+ import ts from "typescript-js";
3
4
  const MODULE_INTEGRATION_DIRECTORY_NAME = "__integration__";
4
5
  const DISCOVERY_IGNORED_DIRS = /* @__PURE__ */ new Set([
5
6
  "node_modules",
@@ -84,7 +85,40 @@ function collectModuleIdsFromModulesRoot(modulesRoot, enabledModules) {
84
85
  enabledModules.add(normalizeModuleId(moduleName));
85
86
  }
86
87
  }
88
+ function readDeclaredModuleIdsFromConfig(registryPath) {
89
+ const source = readFileSync(registryPath, "utf8");
90
+ const sourceFile = ts.createSourceFile(
91
+ registryPath,
92
+ source,
93
+ ts.ScriptTarget.Latest,
94
+ true,
95
+ ts.ScriptKind.TS
96
+ );
97
+ for (const statement of sourceFile.statements) {
98
+ if (!ts.isVariableStatement(statement)) continue;
99
+ for (const declaration of statement.declarationList.declarations) {
100
+ if (!ts.isIdentifier(declaration.name) || declaration.name.text !== "enabledModules" || !declaration.initializer || !ts.isArrayLiteralExpression(declaration.initializer)) {
101
+ continue;
102
+ }
103
+ return declaration.initializer.elements.flatMap((element) => {
104
+ if (!ts.isObjectLiteralExpression(element)) return [];
105
+ const idProperty = element.properties.find(
106
+ (property) => ts.isPropertyAssignment(property) && (ts.isIdentifier(property.name) && property.name.text === "id" || ts.isStringLiteralLike(property.name) && property.name.text === "id")
107
+ );
108
+ return idProperty && ts.isStringLiteralLike(idProperty.initializer) ? [idProperty.initializer.text] : [];
109
+ });
110
+ }
111
+ }
112
+ return [];
113
+ }
87
114
  function resolveEnabledModuleIds(projectRoot) {
115
+ const configuredTestAppRoot = process.env.OM_TEST_APP_ROOT?.trim();
116
+ if (configuredTestAppRoot) {
117
+ const registryPath = path.join(path.resolve(configuredTestAppRoot), "src", "modules.ts");
118
+ return new Set(
119
+ readDeclaredModuleIdsFromConfig(registryPath).map(normalizeModuleId)
120
+ );
121
+ }
88
122
  const enabledModules = /* @__PURE__ */ new Set();
89
123
  const appModulesRoot = path.join(projectRoot, "src", "modules");
90
124
  const appsRoot = path.join(projectRoot, "apps");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/testing/integration-discovery.ts"],
4
- "sourcesContent": ["import { readFileSync, readdirSync } from 'node:fs'\nimport path from 'node:path'\n\nexport type IntegrationSpecDiscoveryItem = {\n path: string\n moduleName: string | null\n isOverlay: boolean\n requiredModules: string[]\n requiredEnvVars: string[]\n requiredAnyEnvVars: string[]\n}\n\nconst MODULE_INTEGRATION_DIRECTORY_NAME = '__integration__'\nconst DISCOVERY_IGNORED_DIRS = new Set([\n 'node_modules',\n '.git',\n '.next',\n 'dist',\n '.turbo',\n 'coverage',\n 'test-results',\n '.yarn',\n '.cache',\n 'tmp',\n 'temp',\n '.claude',\n '.codex',\n])\nconst INTEGRATION_META_FILE_NAMES = ['meta.ts', 'index.ts'] as const\nconst INTEGRATION_META_DEPENDENCY_KEYS = ['dependsOnModules', 'requiredModules', 'requiresModules'] as const\nconst INTEGRATION_META_REQUIRED_ENV_KEYS = ['requiredEnvVars', 'requiresEnvVars'] as const\nconst INTEGRATION_META_REQUIRED_ANY_ENV_KEYS = ['requiredAnyEnvVars', 'requiresAnyEnvVars'] as const\nconst DEFAULT_OVERLAY_ROOT = 'packages/enterprise'\n\nexport function normalizePath(filePath: string): string {\n return filePath.split(path.sep).join('/')\n}\n\nfunction normalizeModuleId(moduleId: string): string {\n return moduleId.trim().toLowerCase()\n}\n\nfunction isEnterpriseModulesEnabled(): boolean {\n const rawValue = process.env.OM_ENABLE_ENTERPRISE_MODULES?.trim().toLowerCase()\n return rawValue === 'true' || rawValue === '1' || rawValue === 'yes' || rawValue === 'on'\n}\n\nfunction collectNamedDirectories(rootPath: string, directoryName: string): string[] {\n let entries\n try {\n entries = readdirSync(rootPath, { withFileTypes: true, encoding: 'utf8' })\n } catch {\n return []\n }\n\n const collected: string[] = []\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n if (DISCOVERY_IGNORED_DIRS.has(entry.name)) continue\n const absolutePath = path.join(rootPath, entry.name)\n if (entry.name === directoryName) {\n collected.push(absolutePath)\n }\n collected.push(...collectNamedDirectories(absolutePath, directoryName))\n }\n return collected\n}\n\nfunction collectSpecFilesFromDirectory(directoryPath: string): string[] {\n let entries\n try {\n entries = readdirSync(directoryPath, { withFileTypes: true, encoding: 'utf8' })\n } catch {\n return []\n }\n\n const collected: string[] = []\n for (const entry of entries) {\n const absolutePath = path.join(directoryPath, entry.name)\n if (entry.isDirectory()) {\n collected.push(...collectSpecFilesFromDirectory(absolutePath))\n continue\n }\n if (entry.isFile() && entry.name.endsWith('.spec.ts')) {\n collected.push(absolutePath)\n }\n }\n return collected\n}\n\nfunction collectDirectDirectoryNames(directoryPath: string): string[] {\n let entries\n try {\n entries = readdirSync(directoryPath, { withFileTypes: true, encoding: 'utf8' })\n } catch {\n return []\n }\n return entries\n .filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'))\n .map((entry) => entry.name)\n}\n\nfunction collectModuleIdsFromModulesRoot(modulesRoot: string, enabledModules: Set<string>): void {\n for (const moduleName of collectDirectDirectoryNames(modulesRoot)) {\n enabledModules.add(normalizeModuleId(moduleName))\n }\n}\n\nfunction resolveEnabledModuleIds(projectRoot: string): Set<string> {\n const enabledModules = new Set<string>()\n const appModulesRoot = path.join(projectRoot, 'src', 'modules')\n const appsRoot = path.join(projectRoot, 'apps')\n const packagesRoot = path.join(projectRoot, 'packages')\n const installedPackagesRoot = path.join(projectRoot, 'node_modules', '@open-mercato')\n const enterpriseEnabled = isEnterpriseModulesEnabled()\n\n // Standalone app: src/modules at project root\n collectModuleIdsFromModulesRoot(appModulesRoot, enabledModules)\n\n for (const appName of collectDirectDirectoryNames(appsRoot)) {\n const moduleRoot = path.join(appsRoot, appName, 'src', 'modules')\n collectModuleIdsFromModulesRoot(moduleRoot, enabledModules)\n }\n for (const packageName of collectDirectDirectoryNames(packagesRoot)) {\n if (packageName === 'enterprise' && !enterpriseEnabled) {\n continue\n }\n const moduleRoot = path.join(packagesRoot, packageName, 'src', 'modules')\n collectModuleIdsFromModulesRoot(moduleRoot, enabledModules)\n }\n // Standalone app: installed @open-mercato packages in node_modules\n for (const packageName of collectDirectDirectoryNames(installedPackagesRoot)) {\n if (packageName === 'enterprise' && !enterpriseEnabled) {\n continue\n }\n const moduleRoot = path.join(installedPackagesRoot, packageName, 'src', 'modules')\n collectModuleIdsFromModulesRoot(moduleRoot, enabledModules)\n }\n const createAppTemplateModulesRoot = path.join(projectRoot, 'packages', 'create-app', 'template', 'src', 'modules')\n collectModuleIdsFromModulesRoot(createAppTemplateModulesRoot, enabledModules)\n\n return enabledModules\n}\n\nfunction extractModuleNameFromIntegrationPath(relativePath: string): string | null {\n const segments = normalizePath(relativePath).split('/')\n const integrationDirectoryIndex = segments.indexOf(MODULE_INTEGRATION_DIRECTORY_NAME)\n if (integrationDirectoryIndex <= 0) {\n return null\n }\n const moduleSegment = segments[integrationDirectoryIndex - 1]\n return moduleSegment && moduleSegment.length > 0 ? moduleSegment : null\n}\n\nfunction resolveOverlayRootPath(): string {\n const configured = process.env.OM_INTEGRATION_OVERLAY_ROOT?.trim()\n if (!configured) {\n return DEFAULT_OVERLAY_ROOT\n }\n return configured.replace(/\\/+$/, '')\n}\n\nfunction isOverlayIntegrationPath(relativePath: string, overlayRoot: string): boolean {\n return normalizePath(relativePath).startsWith(`${normalizePath(overlayRoot)}/`)\n}\n\nfunction extractStringArrayFromSource(source: string, keys: readonly string[]): string[] {\n const collected = new Set<string>()\n for (const key of keys) {\n const keyPattern = new RegExp(`${key}\\\\s*:\\\\s*\\\\[([\\\\s\\\\S]*?)\\\\]`, 'm')\n const keyMatch = source.match(keyPattern)\n if (!keyMatch?.[1]) continue\n const valuesPattern = /['\"`]([a-zA-Z0-9_.-]+)['\"`]/g\n for (const valueMatch of keyMatch[1].matchAll(valuesPattern)) {\n const value = String(valueMatch[1] ?? '').trim()\n if (value) {\n collected.add(value)\n }\n }\n }\n return Array.from(collected)\n}\n\nfunction extractDependencyListFromSource(source: string): string[] {\n return extractStringArrayFromSource(source, INTEGRATION_META_DEPENDENCY_KEYS).map(normalizeModuleId)\n}\n\nfunction extractRequiredEnvVarsFromSource(source: string): string[] {\n return extractStringArrayFromSource(source, INTEGRATION_META_REQUIRED_ENV_KEYS)\n}\n\nfunction extractRequiredAnyEnvVarsFromSource(source: string): string[] {\n return extractStringArrayFromSource(source, INTEGRATION_META_REQUIRED_ANY_ENV_KEYS)\n}\n\nfunction readDependenciesFromMetadataFile(absolutePath: string): string[] {\n try {\n return extractDependencyListFromSource(readFileSync(absolutePath, 'utf8'))\n } catch {\n return []\n }\n}\n\nfunction readRequiredEnvVarsFromMetadataFile(absolutePath: string): string[] {\n try {\n return extractRequiredEnvVarsFromSource(readFileSync(absolutePath, 'utf8'))\n } catch {\n return []\n }\n}\n\nfunction readRequiredAnyEnvVarsFromMetadataFile(absolutePath: string): string[] {\n try {\n return extractRequiredAnyEnvVarsFromSource(readFileSync(absolutePath, 'utf8'))\n } catch {\n return []\n }\n}\n\nfunction resolveIntegrationRootDirectory(relativeSpecPath: string): string | null {\n const segments = normalizePath(relativeSpecPath).split('/')\n const integrationDirectoryIndex = segments.indexOf(MODULE_INTEGRATION_DIRECTORY_NAME)\n if (integrationDirectoryIndex === -1) {\n return null\n }\n return segments.slice(0, integrationDirectoryIndex + 1).join('/')\n}\n\nfunction resolveRequiredModulesForSpec(projectRoot: string, relativeSpecPath: string): string[] {\n const requiredModules = new Set<string>()\n const normalizedSpecPath = normalizePath(relativeSpecPath)\n const absoluteSpecPath = path.join(projectRoot, normalizedSpecPath)\n const integrationRoot = resolveIntegrationRootDirectory(normalizedSpecPath)\n\n if (integrationRoot) {\n const relativeDirectory = normalizePath(path.dirname(normalizedSpecPath))\n const integrationRootAbsolute = path.join(projectRoot, integrationRoot)\n const directoryAbsolute = path.join(projectRoot, relativeDirectory)\n const relativeFromIntegrationRoot = normalizePath(path.relative(integrationRootAbsolute, directoryAbsolute))\n const pathSegments = relativeFromIntegrationRoot === '.'\n ? []\n : relativeFromIntegrationRoot.split('/').filter(Boolean)\n\n let currentDirectory = integrationRootAbsolute\n const traversal = [currentDirectory, ...pathSegments.map((segment) => {\n currentDirectory = path.join(currentDirectory, segment)\n return currentDirectory\n })]\n\n for (const directoryPath of traversal) {\n for (const metadataFileName of INTEGRATION_META_FILE_NAMES) {\n const metadataPath = path.join(directoryPath, metadataFileName)\n readDependenciesFromMetadataFile(metadataPath).forEach((dependency) => requiredModules.add(dependency))\n }\n }\n }\n\n readDependenciesFromMetadataFile(absoluteSpecPath).forEach((dependency) => requiredModules.add(dependency))\n const specFileName = path.basename(normalizedSpecPath, '.spec.ts')\n const perTestMetadataPath = path.join(path.dirname(absoluteSpecPath), `${specFileName}.meta.ts`)\n readDependenciesFromMetadataFile(perTestMetadataPath).forEach((dependency) => requiredModules.add(dependency))\n\n return Array.from(requiredModules)\n}\n\nfunction resolveRequiredEnvVarsForSpec(projectRoot: string, relativeSpecPath: string): string[] {\n const requiredEnvVars = new Set<string>()\n const normalizedSpecPath = normalizePath(relativeSpecPath)\n const absoluteSpecPath = path.join(projectRoot, normalizedSpecPath)\n const integrationRoot = resolveIntegrationRootDirectory(normalizedSpecPath)\n\n if (integrationRoot) {\n const relativeDirectory = normalizePath(path.dirname(normalizedSpecPath))\n const integrationRootAbsolute = path.join(projectRoot, integrationRoot)\n const directoryAbsolute = path.join(projectRoot, relativeDirectory)\n const relativeFromIntegrationRoot = normalizePath(path.relative(integrationRootAbsolute, directoryAbsolute))\n const pathSegments = relativeFromIntegrationRoot === '.'\n ? []\n : relativeFromIntegrationRoot.split('/').filter(Boolean)\n\n let currentDirectory = integrationRootAbsolute\n const traversal = [currentDirectory, ...pathSegments.map((segment) => {\n currentDirectory = path.join(currentDirectory, segment)\n return currentDirectory\n })]\n\n for (const directoryPath of traversal) {\n for (const metadataFileName of INTEGRATION_META_FILE_NAMES) {\n const metadataPath = path.join(directoryPath, metadataFileName)\n readRequiredEnvVarsFromMetadataFile(metadataPath).forEach((envVar) => requiredEnvVars.add(envVar))\n }\n }\n }\n\n readRequiredEnvVarsFromMetadataFile(absoluteSpecPath).forEach((envVar) => requiredEnvVars.add(envVar))\n const specFileName = path.basename(normalizedSpecPath, '.spec.ts')\n const perTestMetadataPath = path.join(path.dirname(absoluteSpecPath), `${specFileName}.meta.ts`)\n readRequiredEnvVarsFromMetadataFile(perTestMetadataPath).forEach((envVar) => requiredEnvVars.add(envVar))\n\n return Array.from(requiredEnvVars)\n}\n\nfunction resolveRequiredAnyEnvVarsForSpec(projectRoot: string, relativeSpecPath: string): string[] {\n const requiredAnyEnvVars = new Set<string>()\n const normalizedSpecPath = normalizePath(relativeSpecPath)\n const absoluteSpecPath = path.join(projectRoot, normalizedSpecPath)\n const integrationRoot = resolveIntegrationRootDirectory(normalizedSpecPath)\n\n if (integrationRoot) {\n const relativeDirectory = normalizePath(path.dirname(normalizedSpecPath))\n const integrationRootAbsolute = path.join(projectRoot, integrationRoot)\n const directoryAbsolute = path.join(projectRoot, relativeDirectory)\n const relativeFromIntegrationRoot = normalizePath(path.relative(integrationRootAbsolute, directoryAbsolute))\n const pathSegments = relativeFromIntegrationRoot === '.'\n ? []\n : relativeFromIntegrationRoot.split('/').filter(Boolean)\n\n let currentDirectory = integrationRootAbsolute\n const traversal = [currentDirectory, ...pathSegments.map((segment) => {\n currentDirectory = path.join(currentDirectory, segment)\n return currentDirectory\n })]\n\n for (const directoryPath of traversal) {\n for (const metadataFileName of INTEGRATION_META_FILE_NAMES) {\n const metadataPath = path.join(directoryPath, metadataFileName)\n readRequiredAnyEnvVarsFromMetadataFile(metadataPath).forEach((envVar) => requiredAnyEnvVars.add(envVar))\n }\n }\n }\n\n readRequiredAnyEnvVarsFromMetadataFile(absoluteSpecPath).forEach((envVar) => requiredAnyEnvVars.add(envVar))\n const specFileName = path.basename(normalizedSpecPath, '.spec.ts')\n const perTestMetadataPath = path.join(path.dirname(absoluteSpecPath), `${specFileName}.meta.ts`)\n readRequiredAnyEnvVarsFromMetadataFile(perTestMetadataPath).forEach((envVar) => requiredAnyEnvVars.add(envVar))\n\n return Array.from(requiredAnyEnvVars)\n}\n\nfunction isEnvironmentVariableConfigured(name: string): boolean {\n const value = process.env[name]\n return typeof value === 'string' && value.trim().length > 0\n}\n\nexport function discoverIntegrationSpecFiles(projectRoot: string, legacyIntegrationRoot: string): IntegrationSpecDiscoveryItem[] {\n const discoveredByPath = new Map<string, IntegrationSpecDiscoveryItem>()\n const overlayRoot = resolveOverlayRootPath()\n const enterpriseEnabled = isEnterpriseModulesEnabled()\n const discoveryRoots = [\n path.join(projectRoot, 'src', 'modules'),\n path.join(projectRoot, 'apps'),\n path.join(projectRoot, 'packages'),\n path.join(projectRoot, 'node_modules', '@open-mercato'),\n ]\n\n for (const specFile of collectSpecFilesFromDirectory(legacyIntegrationRoot)) {\n const relativePath = normalizePath(path.relative(projectRoot, specFile))\n discoveredByPath.set(relativePath, {\n path: relativePath,\n moduleName: extractModuleNameFromIntegrationPath(relativePath),\n isOverlay: isOverlayIntegrationPath(relativePath, overlayRoot),\n requiredModules: resolveRequiredModulesForSpec(projectRoot, relativePath),\n requiredEnvVars: resolveRequiredEnvVarsForSpec(projectRoot, relativePath),\n requiredAnyEnvVars: resolveRequiredAnyEnvVarsForSpec(projectRoot, relativePath),\n })\n }\n\n for (const root of discoveryRoots) {\n for (const integrationDirectory of collectNamedDirectories(root, MODULE_INTEGRATION_DIRECTORY_NAME)) {\n for (const specFile of collectSpecFilesFromDirectory(integrationDirectory)) {\n const relativePath = normalizePath(path.relative(projectRoot, specFile))\n discoveredByPath.set(relativePath, {\n path: relativePath,\n moduleName: extractModuleNameFromIntegrationPath(relativePath),\n isOverlay: isOverlayIntegrationPath(relativePath, overlayRoot),\n requiredModules: resolveRequiredModulesForSpec(projectRoot, relativePath),\n requiredEnvVars: resolveRequiredEnvVarsForSpec(projectRoot, relativePath),\n requiredAnyEnvVars: resolveRequiredAnyEnvVarsForSpec(projectRoot, relativePath),\n })\n }\n }\n }\n\n const discovered = Array.from(discoveredByPath.values())\n const enabledModules = resolveEnabledModuleIds(projectRoot)\n const enabledModuleNames = new Set<string>()\n for (const file of discovered) {\n if (!file.isOverlay && file.moduleName) {\n enabledModuleNames.add(file.moduleName)\n }\n }\n\n return discovered\n .filter((file) => {\n if (file.requiredModules.some((moduleId) => !enabledModules.has(normalizeModuleId(moduleId)))) {\n return false\n }\n if (file.requiredEnvVars.some((envVar) => !isEnvironmentVariableConfigured(envVar))) {\n return false\n }\n if (\n file.requiredAnyEnvVars.length > 0 &&\n !file.requiredAnyEnvVars.some((envVar) => isEnvironmentVariableConfigured(envVar))\n ) {\n return false\n }\n if (!file.isOverlay) {\n return true\n }\n if (!enterpriseEnabled) {\n return false\n }\n if (!file.moduleName) {\n return true\n }\n if (enabledModuleNames.has(file.moduleName)) {\n return true\n }\n return enabledModules.has(normalizeModuleId(file.moduleName))\n })\n .sort((left, right) => left.path.localeCompare(right.path))\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { readFileSync, readdirSync } from 'node:fs'\nimport path from 'node:path'\nimport ts from 'typescript-js'\n\nexport type IntegrationSpecDiscoveryItem = {\n path: string\n moduleName: string | null\n isOverlay: boolean\n requiredModules: string[]\n requiredEnvVars: string[]\n requiredAnyEnvVars: string[]\n}\n\nconst MODULE_INTEGRATION_DIRECTORY_NAME = '__integration__'\nconst DISCOVERY_IGNORED_DIRS = new Set([\n 'node_modules',\n '.git',\n '.next',\n 'dist',\n '.turbo',\n 'coverage',\n 'test-results',\n '.yarn',\n '.cache',\n 'tmp',\n 'temp',\n '.claude',\n '.codex',\n])\nconst INTEGRATION_META_FILE_NAMES = ['meta.ts', 'index.ts'] as const\nconst INTEGRATION_META_DEPENDENCY_KEYS = ['dependsOnModules', 'requiredModules', 'requiresModules'] as const\nconst INTEGRATION_META_REQUIRED_ENV_KEYS = ['requiredEnvVars', 'requiresEnvVars'] as const\nconst INTEGRATION_META_REQUIRED_ANY_ENV_KEYS = ['requiredAnyEnvVars', 'requiresAnyEnvVars'] as const\nconst DEFAULT_OVERLAY_ROOT = 'packages/enterprise'\n\nexport function normalizePath(filePath: string): string {\n return filePath.split(path.sep).join('/')\n}\n\nfunction normalizeModuleId(moduleId: string): string {\n return moduleId.trim().toLowerCase()\n}\n\nfunction isEnterpriseModulesEnabled(): boolean {\n const rawValue = process.env.OM_ENABLE_ENTERPRISE_MODULES?.trim().toLowerCase()\n return rawValue === 'true' || rawValue === '1' || rawValue === 'yes' || rawValue === 'on'\n}\n\nfunction collectNamedDirectories(rootPath: string, directoryName: string): string[] {\n let entries\n try {\n entries = readdirSync(rootPath, { withFileTypes: true, encoding: 'utf8' })\n } catch {\n return []\n }\n\n const collected: string[] = []\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n if (DISCOVERY_IGNORED_DIRS.has(entry.name)) continue\n const absolutePath = path.join(rootPath, entry.name)\n if (entry.name === directoryName) {\n collected.push(absolutePath)\n }\n collected.push(...collectNamedDirectories(absolutePath, directoryName))\n }\n return collected\n}\n\nfunction collectSpecFilesFromDirectory(directoryPath: string): string[] {\n let entries\n try {\n entries = readdirSync(directoryPath, { withFileTypes: true, encoding: 'utf8' })\n } catch {\n return []\n }\n\n const collected: string[] = []\n for (const entry of entries) {\n const absolutePath = path.join(directoryPath, entry.name)\n if (entry.isDirectory()) {\n collected.push(...collectSpecFilesFromDirectory(absolutePath))\n continue\n }\n if (entry.isFile() && entry.name.endsWith('.spec.ts')) {\n collected.push(absolutePath)\n }\n }\n return collected\n}\n\nfunction collectDirectDirectoryNames(directoryPath: string): string[] {\n let entries\n try {\n entries = readdirSync(directoryPath, { withFileTypes: true, encoding: 'utf8' })\n } catch {\n return []\n }\n return entries\n .filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'))\n .map((entry) => entry.name)\n}\n\nfunction collectModuleIdsFromModulesRoot(modulesRoot: string, enabledModules: Set<string>): void {\n for (const moduleName of collectDirectDirectoryNames(modulesRoot)) {\n enabledModules.add(normalizeModuleId(moduleName))\n }\n}\n\nfunction readDeclaredModuleIdsFromConfig(registryPath: string): string[] {\n const source = readFileSync(registryPath, 'utf8')\n const sourceFile = ts.createSourceFile(\n registryPath,\n source,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TS,\n )\n\n for (const statement of sourceFile.statements) {\n if (!ts.isVariableStatement(statement)) continue\n for (const declaration of statement.declarationList.declarations) {\n if (\n !ts.isIdentifier(declaration.name)\n || declaration.name.text !== 'enabledModules'\n || !declaration.initializer\n || !ts.isArrayLiteralExpression(declaration.initializer)\n ) {\n continue\n }\n\n return declaration.initializer.elements.flatMap((element) => {\n if (!ts.isObjectLiteralExpression(element)) return []\n const idProperty = element.properties.find((property): property is ts.PropertyAssignment =>\n ts.isPropertyAssignment(property)\n && (\n (ts.isIdentifier(property.name) && property.name.text === 'id')\n || (ts.isStringLiteralLike(property.name) && property.name.text === 'id')\n ),\n )\n return idProperty && ts.isStringLiteralLike(idProperty.initializer)\n ? [idProperty.initializer.text]\n : []\n })\n }\n }\n\n return []\n}\n\nfunction resolveEnabledModuleIds(projectRoot: string): Set<string> {\n const configuredTestAppRoot = process.env.OM_TEST_APP_ROOT?.trim()\n if (configuredTestAppRoot) {\n const registryPath = path.join(path.resolve(configuredTestAppRoot), 'src', 'modules.ts')\n return new Set(\n readDeclaredModuleIdsFromConfig(registryPath).map(normalizeModuleId),\n )\n }\n\n const enabledModules = new Set<string>()\n const appModulesRoot = path.join(projectRoot, 'src', 'modules')\n const appsRoot = path.join(projectRoot, 'apps')\n const packagesRoot = path.join(projectRoot, 'packages')\n const installedPackagesRoot = path.join(projectRoot, 'node_modules', '@open-mercato')\n const enterpriseEnabled = isEnterpriseModulesEnabled()\n\n // Standalone app: src/modules at project root\n collectModuleIdsFromModulesRoot(appModulesRoot, enabledModules)\n\n for (const appName of collectDirectDirectoryNames(appsRoot)) {\n const moduleRoot = path.join(appsRoot, appName, 'src', 'modules')\n collectModuleIdsFromModulesRoot(moduleRoot, enabledModules)\n }\n for (const packageName of collectDirectDirectoryNames(packagesRoot)) {\n if (packageName === 'enterprise' && !enterpriseEnabled) {\n continue\n }\n const moduleRoot = path.join(packagesRoot, packageName, 'src', 'modules')\n collectModuleIdsFromModulesRoot(moduleRoot, enabledModules)\n }\n // Standalone app: installed @open-mercato packages in node_modules\n for (const packageName of collectDirectDirectoryNames(installedPackagesRoot)) {\n if (packageName === 'enterprise' && !enterpriseEnabled) {\n continue\n }\n const moduleRoot = path.join(installedPackagesRoot, packageName, 'src', 'modules')\n collectModuleIdsFromModulesRoot(moduleRoot, enabledModules)\n }\n const createAppTemplateModulesRoot = path.join(projectRoot, 'packages', 'create-app', 'template', 'src', 'modules')\n collectModuleIdsFromModulesRoot(createAppTemplateModulesRoot, enabledModules)\n\n return enabledModules\n}\n\nfunction extractModuleNameFromIntegrationPath(relativePath: string): string | null {\n const segments = normalizePath(relativePath).split('/')\n const integrationDirectoryIndex = segments.indexOf(MODULE_INTEGRATION_DIRECTORY_NAME)\n if (integrationDirectoryIndex <= 0) {\n return null\n }\n const moduleSegment = segments[integrationDirectoryIndex - 1]\n return moduleSegment && moduleSegment.length > 0 ? moduleSegment : null\n}\n\nfunction resolveOverlayRootPath(): string {\n const configured = process.env.OM_INTEGRATION_OVERLAY_ROOT?.trim()\n if (!configured) {\n return DEFAULT_OVERLAY_ROOT\n }\n return configured.replace(/\\/+$/, '')\n}\n\nfunction isOverlayIntegrationPath(relativePath: string, overlayRoot: string): boolean {\n return normalizePath(relativePath).startsWith(`${normalizePath(overlayRoot)}/`)\n}\n\nfunction extractStringArrayFromSource(source: string, keys: readonly string[]): string[] {\n const collected = new Set<string>()\n for (const key of keys) {\n const keyPattern = new RegExp(`${key}\\\\s*:\\\\s*\\\\[([\\\\s\\\\S]*?)\\\\]`, 'm')\n const keyMatch = source.match(keyPattern)\n if (!keyMatch?.[1]) continue\n const valuesPattern = /['\"`]([a-zA-Z0-9_.-]+)['\"`]/g\n for (const valueMatch of keyMatch[1].matchAll(valuesPattern)) {\n const value = String(valueMatch[1] ?? '').trim()\n if (value) {\n collected.add(value)\n }\n }\n }\n return Array.from(collected)\n}\n\nfunction extractDependencyListFromSource(source: string): string[] {\n return extractStringArrayFromSource(source, INTEGRATION_META_DEPENDENCY_KEYS).map(normalizeModuleId)\n}\n\nfunction extractRequiredEnvVarsFromSource(source: string): string[] {\n return extractStringArrayFromSource(source, INTEGRATION_META_REQUIRED_ENV_KEYS)\n}\n\nfunction extractRequiredAnyEnvVarsFromSource(source: string): string[] {\n return extractStringArrayFromSource(source, INTEGRATION_META_REQUIRED_ANY_ENV_KEYS)\n}\n\nfunction readDependenciesFromMetadataFile(absolutePath: string): string[] {\n try {\n return extractDependencyListFromSource(readFileSync(absolutePath, 'utf8'))\n } catch {\n return []\n }\n}\n\nfunction readRequiredEnvVarsFromMetadataFile(absolutePath: string): string[] {\n try {\n return extractRequiredEnvVarsFromSource(readFileSync(absolutePath, 'utf8'))\n } catch {\n return []\n }\n}\n\nfunction readRequiredAnyEnvVarsFromMetadataFile(absolutePath: string): string[] {\n try {\n return extractRequiredAnyEnvVarsFromSource(readFileSync(absolutePath, 'utf8'))\n } catch {\n return []\n }\n}\n\nfunction resolveIntegrationRootDirectory(relativeSpecPath: string): string | null {\n const segments = normalizePath(relativeSpecPath).split('/')\n const integrationDirectoryIndex = segments.indexOf(MODULE_INTEGRATION_DIRECTORY_NAME)\n if (integrationDirectoryIndex === -1) {\n return null\n }\n return segments.slice(0, integrationDirectoryIndex + 1).join('/')\n}\n\nfunction resolveRequiredModulesForSpec(projectRoot: string, relativeSpecPath: string): string[] {\n const requiredModules = new Set<string>()\n const normalizedSpecPath = normalizePath(relativeSpecPath)\n const absoluteSpecPath = path.join(projectRoot, normalizedSpecPath)\n const integrationRoot = resolveIntegrationRootDirectory(normalizedSpecPath)\n\n if (integrationRoot) {\n const relativeDirectory = normalizePath(path.dirname(normalizedSpecPath))\n const integrationRootAbsolute = path.join(projectRoot, integrationRoot)\n const directoryAbsolute = path.join(projectRoot, relativeDirectory)\n const relativeFromIntegrationRoot = normalizePath(path.relative(integrationRootAbsolute, directoryAbsolute))\n const pathSegments = relativeFromIntegrationRoot === '.'\n ? []\n : relativeFromIntegrationRoot.split('/').filter(Boolean)\n\n let currentDirectory = integrationRootAbsolute\n const traversal = [currentDirectory, ...pathSegments.map((segment) => {\n currentDirectory = path.join(currentDirectory, segment)\n return currentDirectory\n })]\n\n for (const directoryPath of traversal) {\n for (const metadataFileName of INTEGRATION_META_FILE_NAMES) {\n const metadataPath = path.join(directoryPath, metadataFileName)\n readDependenciesFromMetadataFile(metadataPath).forEach((dependency) => requiredModules.add(dependency))\n }\n }\n }\n\n readDependenciesFromMetadataFile(absoluteSpecPath).forEach((dependency) => requiredModules.add(dependency))\n const specFileName = path.basename(normalizedSpecPath, '.spec.ts')\n const perTestMetadataPath = path.join(path.dirname(absoluteSpecPath), `${specFileName}.meta.ts`)\n readDependenciesFromMetadataFile(perTestMetadataPath).forEach((dependency) => requiredModules.add(dependency))\n\n return Array.from(requiredModules)\n}\n\nfunction resolveRequiredEnvVarsForSpec(projectRoot: string, relativeSpecPath: string): string[] {\n const requiredEnvVars = new Set<string>()\n const normalizedSpecPath = normalizePath(relativeSpecPath)\n const absoluteSpecPath = path.join(projectRoot, normalizedSpecPath)\n const integrationRoot = resolveIntegrationRootDirectory(normalizedSpecPath)\n\n if (integrationRoot) {\n const relativeDirectory = normalizePath(path.dirname(normalizedSpecPath))\n const integrationRootAbsolute = path.join(projectRoot, integrationRoot)\n const directoryAbsolute = path.join(projectRoot, relativeDirectory)\n const relativeFromIntegrationRoot = normalizePath(path.relative(integrationRootAbsolute, directoryAbsolute))\n const pathSegments = relativeFromIntegrationRoot === '.'\n ? []\n : relativeFromIntegrationRoot.split('/').filter(Boolean)\n\n let currentDirectory = integrationRootAbsolute\n const traversal = [currentDirectory, ...pathSegments.map((segment) => {\n currentDirectory = path.join(currentDirectory, segment)\n return currentDirectory\n })]\n\n for (const directoryPath of traversal) {\n for (const metadataFileName of INTEGRATION_META_FILE_NAMES) {\n const metadataPath = path.join(directoryPath, metadataFileName)\n readRequiredEnvVarsFromMetadataFile(metadataPath).forEach((envVar) => requiredEnvVars.add(envVar))\n }\n }\n }\n\n readRequiredEnvVarsFromMetadataFile(absoluteSpecPath).forEach((envVar) => requiredEnvVars.add(envVar))\n const specFileName = path.basename(normalizedSpecPath, '.spec.ts')\n const perTestMetadataPath = path.join(path.dirname(absoluteSpecPath), `${specFileName}.meta.ts`)\n readRequiredEnvVarsFromMetadataFile(perTestMetadataPath).forEach((envVar) => requiredEnvVars.add(envVar))\n\n return Array.from(requiredEnvVars)\n}\n\nfunction resolveRequiredAnyEnvVarsForSpec(projectRoot: string, relativeSpecPath: string): string[] {\n const requiredAnyEnvVars = new Set<string>()\n const normalizedSpecPath = normalizePath(relativeSpecPath)\n const absoluteSpecPath = path.join(projectRoot, normalizedSpecPath)\n const integrationRoot = resolveIntegrationRootDirectory(normalizedSpecPath)\n\n if (integrationRoot) {\n const relativeDirectory = normalizePath(path.dirname(normalizedSpecPath))\n const integrationRootAbsolute = path.join(projectRoot, integrationRoot)\n const directoryAbsolute = path.join(projectRoot, relativeDirectory)\n const relativeFromIntegrationRoot = normalizePath(path.relative(integrationRootAbsolute, directoryAbsolute))\n const pathSegments = relativeFromIntegrationRoot === '.'\n ? []\n : relativeFromIntegrationRoot.split('/').filter(Boolean)\n\n let currentDirectory = integrationRootAbsolute\n const traversal = [currentDirectory, ...pathSegments.map((segment) => {\n currentDirectory = path.join(currentDirectory, segment)\n return currentDirectory\n })]\n\n for (const directoryPath of traversal) {\n for (const metadataFileName of INTEGRATION_META_FILE_NAMES) {\n const metadataPath = path.join(directoryPath, metadataFileName)\n readRequiredAnyEnvVarsFromMetadataFile(metadataPath).forEach((envVar) => requiredAnyEnvVars.add(envVar))\n }\n }\n }\n\n readRequiredAnyEnvVarsFromMetadataFile(absoluteSpecPath).forEach((envVar) => requiredAnyEnvVars.add(envVar))\n const specFileName = path.basename(normalizedSpecPath, '.spec.ts')\n const perTestMetadataPath = path.join(path.dirname(absoluteSpecPath), `${specFileName}.meta.ts`)\n readRequiredAnyEnvVarsFromMetadataFile(perTestMetadataPath).forEach((envVar) => requiredAnyEnvVars.add(envVar))\n\n return Array.from(requiredAnyEnvVars)\n}\n\nfunction isEnvironmentVariableConfigured(name: string): boolean {\n const value = process.env[name]\n return typeof value === 'string' && value.trim().length > 0\n}\n\nexport function discoverIntegrationSpecFiles(projectRoot: string, legacyIntegrationRoot: string): IntegrationSpecDiscoveryItem[] {\n const discoveredByPath = new Map<string, IntegrationSpecDiscoveryItem>()\n const overlayRoot = resolveOverlayRootPath()\n const enterpriseEnabled = isEnterpriseModulesEnabled()\n const discoveryRoots = [\n path.join(projectRoot, 'src', 'modules'),\n path.join(projectRoot, 'apps'),\n path.join(projectRoot, 'packages'),\n path.join(projectRoot, 'node_modules', '@open-mercato'),\n ]\n\n for (const specFile of collectSpecFilesFromDirectory(legacyIntegrationRoot)) {\n const relativePath = normalizePath(path.relative(projectRoot, specFile))\n discoveredByPath.set(relativePath, {\n path: relativePath,\n moduleName: extractModuleNameFromIntegrationPath(relativePath),\n isOverlay: isOverlayIntegrationPath(relativePath, overlayRoot),\n requiredModules: resolveRequiredModulesForSpec(projectRoot, relativePath),\n requiredEnvVars: resolveRequiredEnvVarsForSpec(projectRoot, relativePath),\n requiredAnyEnvVars: resolveRequiredAnyEnvVarsForSpec(projectRoot, relativePath),\n })\n }\n\n for (const root of discoveryRoots) {\n for (const integrationDirectory of collectNamedDirectories(root, MODULE_INTEGRATION_DIRECTORY_NAME)) {\n for (const specFile of collectSpecFilesFromDirectory(integrationDirectory)) {\n const relativePath = normalizePath(path.relative(projectRoot, specFile))\n discoveredByPath.set(relativePath, {\n path: relativePath,\n moduleName: extractModuleNameFromIntegrationPath(relativePath),\n isOverlay: isOverlayIntegrationPath(relativePath, overlayRoot),\n requiredModules: resolveRequiredModulesForSpec(projectRoot, relativePath),\n requiredEnvVars: resolveRequiredEnvVarsForSpec(projectRoot, relativePath),\n requiredAnyEnvVars: resolveRequiredAnyEnvVarsForSpec(projectRoot, relativePath),\n })\n }\n }\n }\n\n const discovered = Array.from(discoveredByPath.values())\n const enabledModules = resolveEnabledModuleIds(projectRoot)\n const enabledModuleNames = new Set<string>()\n for (const file of discovered) {\n if (!file.isOverlay && file.moduleName) {\n enabledModuleNames.add(file.moduleName)\n }\n }\n\n return discovered\n .filter((file) => {\n if (file.requiredModules.some((moduleId) => !enabledModules.has(normalizeModuleId(moduleId)))) {\n return false\n }\n if (file.requiredEnvVars.some((envVar) => !isEnvironmentVariableConfigured(envVar))) {\n return false\n }\n if (\n file.requiredAnyEnvVars.length > 0 &&\n !file.requiredAnyEnvVars.some((envVar) => isEnvironmentVariableConfigured(envVar))\n ) {\n return false\n }\n if (!file.isOverlay) {\n return true\n }\n if (!enterpriseEnabled) {\n return false\n }\n if (!file.moduleName) {\n return true\n }\n if (enabledModuleNames.has(file.moduleName)) {\n return true\n }\n return enabledModules.has(normalizeModuleId(file.moduleName))\n })\n .sort((left, right) => left.path.localeCompare(right.path))\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1472,6 +1472,12 @@ function buildReusableEnvironment(baseUrl, databaseUrl, queueBaseDir, captureScr
1472
1472
  // not have to call flushPendingCrudAccessLogs() explicitly.
1473
1473
  OM_CRUD_ACCESS_LOG_BLOCKING: process.env.OM_CRUD_ACCESS_LOG_BLOCKING ?? "1",
1474
1474
  OM_WEBHOOKS_ALLOW_PRIVATE_URLS: process.env.OM_WEBHOOKS_ALLOW_PRIVATE_URLS ?? "1",
1475
+ // TC-ONB-001/002 drive the self-service signup flow, whose routes are not
1476
+ // mounted while the feature is off. `apps/mercato/.env` ships it disabled,
1477
+ // so both specs 404'd on every local run while CI stayed green — it exports
1478
+ // the var at the workflow level, the same gap the MOCK_INBOUND_WEBHOOK_SECRET
1479
+ // note below describes. Keep in sync with the app-server env block.
1480
+ SELF_SERVICE_ONBOARDING_ENABLED: process.env.SELF_SERVICE_ONBOARDING_ENABLED ?? "true",
1475
1481
  // Keep the bus in the Playwright process (used by in-test queue-drain helpers)
1476
1482
  // on the same delivery mode as the app server it drives: inline persistent
1477
1483
  // delivery so event side effects are deterministic for assertions. See the
@@ -1481,7 +1487,6 @@ function buildReusableEnvironment(baseUrl, databaseUrl, queueBaseDir, captureScr
1481
1487
  MOCK_GATEWAY_WEBHOOK_SECRET: "open-mercato-mock-dev-webhook-secret",
1482
1488
  MOCK_CARRIER_WEBHOOK_SECRET: "open-mercato-mock-dev-carrier-webhook-secret",
1483
1489
  MOCK_INBOUND_WEBHOOK_SECRET: "open-mercato-mock-dev-inbound-webhook-secret",
1484
- NEXT_PUBLIC_OM_EXAMPLE_INJECTION_WIDGETS_ENABLED: "true",
1485
1490
  NEXT_PUBLIC_UMES_DEVTOOLS: "true",
1486
1491
  CI: "true",
1487
1492
  TENANT_DATA_ENCRYPTION_FALLBACK_KEY: process.env.TENANT_DATA_ENCRYPTION_FALLBACK_KEY ?? "om-ephemeral-integration-fallback-key",
@@ -2645,6 +2650,10 @@ async function startEphemeralEnvironment(options) {
2645
2650
  OM_TEST_AUTH_RATE_LIMIT_MODE: "opt-in",
2646
2651
  OM_DISABLE_EMAIL_DELIVERY: "1",
2647
2652
  OM_WEBHOOKS_ALLOW_PRIVATE_URLS: process.env.OM_WEBHOOKS_ALLOW_PRIVATE_URLS ?? "1",
2653
+ // Read at build time as well as at runtime, so this block has to carry it:
2654
+ // the app build and `yarn start` both run with this environment. See the
2655
+ // matching note on the Playwright-process env block above.
2656
+ SELF_SERVICE_ONBOARDING_ENABLED: process.env.SELF_SERVICE_ONBOARDING_ENABLED ?? "true",
2648
2657
  ENABLE_CRUD_API_CACHE: "true",
2649
2658
  MOCK_GATEWAY_WEBHOOK_SECRET: "open-mercato-mock-dev-webhook-secret",
2650
2659
  MOCK_CARRIER_WEBHOOK_SECRET: "open-mercato-mock-dev-carrier-webhook-secret",
@@ -2654,7 +2663,6 @@ async function startEphemeralEnvironment(options) {
2654
2663
  // var at the workflow level, masking the gap). Keep in sync with the
2655
2664
  // Playwright-process env block above.
2656
2665
  MOCK_INBOUND_WEBHOOK_SECRET: "open-mercato-mock-dev-inbound-webhook-secret",
2657
- NEXT_PUBLIC_OM_EXAMPLE_INJECTION_WIDGETS_ENABLED: "true",
2658
2666
  NEXT_PUBLIC_UMES_DEVTOOLS: "true",
2659
2667
  CI: "true",
2660
2668
  TENANT_DATA_ENCRYPTION_FALLBACK_KEY: process.env.TENANT_DATA_ENCRYPTION_FALLBACK_KEY ?? "om-ephemeral-integration-fallback-key",