@open-mercato/cli 0.10.1-develop.7827.1.5c631908e4 → 0.10.1-develop.7836.1.0ef0f453c6

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 (91) hide show
  1. package/dist/agentic/guides/module-facts.json +162 -162
  2. package/dist/agentic/guides/module-facts.v2.json +162 -162
  3. package/dist/agentic/guides/modules/agent_orchestrator/index.md +1 -1
  4. package/dist/agentic/guides/modules/ai_assistant/index.md +1 -1
  5. package/dist/agentic/guides/modules/api_docs/index.md +1 -1
  6. package/dist/agentic/guides/modules/api_keys/index.md +1 -1
  7. package/dist/agentic/guides/modules/attachments/index.md +1 -1
  8. package/dist/agentic/guides/modules/audit_logs/index.md +1 -1
  9. package/dist/agentic/guides/modules/auth/index.md +1 -1
  10. package/dist/agentic/guides/modules/availability/index.md +1 -1
  11. package/dist/agentic/guides/modules/business_rules/index.md +1 -1
  12. package/dist/agentic/guides/modules/carrier_inpost/index.md +1 -1
  13. package/dist/agentic/guides/modules/cart/index.md +1 -1
  14. package/dist/agentic/guides/modules/catalog/index.md +1 -1
  15. package/dist/agentic/guides/modules/channel_apns/index.md +1 -1
  16. package/dist/agentic/guides/modules/channel_discord/index.md +1 -1
  17. package/dist/agentic/guides/modules/channel_expo/index.md +1 -1
  18. package/dist/agentic/guides/modules/channel_fcm/index.md +1 -1
  19. package/dist/agentic/guides/modules/channel_gmail/index.md +1 -1
  20. package/dist/agentic/guides/modules/channel_imap/index.md +1 -1
  21. package/dist/agentic/guides/modules/channel_resend/index.md +1 -1
  22. package/dist/agentic/guides/modules/channel_ses/index.md +1 -1
  23. package/dist/agentic/guides/modules/channel_smtp/index.md +1 -1
  24. package/dist/agentic/guides/modules/checkout/index.md +1 -1
  25. package/dist/agentic/guides/modules/communication_channels/index.md +1 -1
  26. package/dist/agentic/guides/modules/configs/index.md +1 -1
  27. package/dist/agentic/guides/modules/content/index.md +1 -1
  28. package/dist/agentic/guides/modules/currencies/index.md +1 -1
  29. package/dist/agentic/guides/modules/customer_accounts/index.md +1 -1
  30. package/dist/agentic/guides/modules/customer_groups/index.md +1 -1
  31. package/dist/agentic/guides/modules/customers/index.md +1 -1
  32. package/dist/agentic/guides/modules/dashboards/index.md +1 -1
  33. package/dist/agentic/guides/modules/data_sync/index.md +1 -1
  34. package/dist/agentic/guides/modules/design_system/index.md +1 -1
  35. package/dist/agentic/guides/modules/devices/index.md +1 -1
  36. package/dist/agentic/guides/modules/dictionaries/index.md +1 -1
  37. package/dist/agentic/guides/modules/directory/index.md +1 -1
  38. package/dist/agentic/guides/modules/documents/index.md +1 -1
  39. package/dist/agentic/guides/modules/ecommerce/index.md +1 -1
  40. package/dist/agentic/guides/modules/entities/index.md +1 -1
  41. package/dist/agentic/guides/modules/eudr/index.md +1 -1
  42. package/dist/agentic/guides/modules/events/index.md +1 -1
  43. package/dist/agentic/guides/modules/feature_toggles/index.md +1 -1
  44. package/dist/agentic/guides/modules/forms/index.md +1 -1
  45. package/dist/agentic/guides/modules/gateway_autopay/index.md +1 -1
  46. package/dist/agentic/guides/modules/gateway_stripe/index.md +1 -1
  47. package/dist/agentic/guides/modules/gateway_tpay/index.md +1 -1
  48. package/dist/agentic/guides/modules/generators/index.md +1 -1
  49. package/dist/agentic/guides/modules/inbox_ops/index.md +1 -1
  50. package/dist/agentic/guides/modules/integrations/index.md +1 -1
  51. package/dist/agentic/guides/modules/messages/index.md +1 -1
  52. package/dist/agentic/guides/modules/notifications/index.md +1 -1
  53. package/dist/agentic/guides/modules/onboarding/index.md +1 -1
  54. package/dist/agentic/guides/modules/payment_gateways/index.md +1 -1
  55. package/dist/agentic/guides/modules/perspectives/index.md +1 -1
  56. package/dist/agentic/guides/modules/phone_calls/index.md +1 -1
  57. package/dist/agentic/guides/modules/planner/index.md +1 -1
  58. package/dist/agentic/guides/modules/portal/index.md +1 -1
  59. package/dist/agentic/guides/modules/progress/index.md +1 -1
  60. package/dist/agentic/guides/modules/promotions/index.md +1 -1
  61. package/dist/agentic/guides/modules/push_notifications/index.md +1 -1
  62. package/dist/agentic/guides/modules/query_index/index.md +1 -1
  63. package/dist/agentic/guides/modules/record_locks/index.md +1 -1
  64. package/dist/agentic/guides/modules/resources/index.md +1 -1
  65. package/dist/agentic/guides/modules/sales/index.md +1 -1
  66. package/dist/agentic/guides/modules/scheduler/index.md +1 -1
  67. package/dist/agentic/guides/modules/search/index.md +1 -1
  68. package/dist/agentic/guides/modules/security/index.md +1 -1
  69. package/dist/agentic/guides/modules/seeds/index.md +1 -1
  70. package/dist/agentic/guides/modules/shipping_carriers/index.md +1 -1
  71. package/dist/agentic/guides/modules/sso/index.md +1 -1
  72. package/dist/agentic/guides/modules/staff/index.md +1 -1
  73. package/dist/agentic/guides/modules/storage_s3/index.md +1 -1
  74. package/dist/agentic/guides/modules/sync_akeneo/index.md +1 -1
  75. package/dist/agentic/guides/modules/sync_excel/index.md +1 -1
  76. package/dist/agentic/guides/modules/system_status_overlays/index.md +1 -1
  77. package/dist/agentic/guides/modules/telemetry/index.md +1 -1
  78. package/dist/agentic/guides/modules/tillio/index.md +1 -1
  79. package/dist/agentic/guides/modules/translations/index.md +1 -1
  80. package/dist/agentic/guides/modules/warranty_claims/index.md +1 -1
  81. package/dist/agentic/guides/modules/webhooks/index.md +1 -1
  82. package/dist/agentic/guides/modules/wms/index.md +1 -1
  83. package/dist/agentic/guides/modules/workflows/index.md +1 -1
  84. package/dist/agentic/guides/reference-module-facts.json +2 -2
  85. package/dist/agentic/guides/reference-modules/example/index.md +1 -1
  86. package/dist/agentic/guides/upstream/manifest.json +1 -1
  87. package/dist/lib/testing/integration-discovery.js +61 -21
  88. package/dist/lib/testing/integration-discovery.js.map +2 -2
  89. package/package.json +7 -7
  90. package/src/lib/testing/__tests__/integration-discovery.test.ts +89 -0
  91. package/src/lib/testing/integration-discovery.ts +101 -32
@@ -1,4 +1,4 @@
1
- import { readFileSync, readdirSync } from 'node:fs'
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import ts from 'typescript-js'
4
4
 
@@ -107,7 +107,40 @@ function collectModuleIdsFromModulesRoot(modulesRoot: string, enabledModules: Se
107
107
  }
108
108
  }
109
109
 
110
- function readDeclaredModuleIdsFromConfig(registryPath: string): string[] {
110
+ function readModuleEntryId(element: ts.Expression): string[] {
111
+ if (!ts.isObjectLiteralExpression(element)) return []
112
+ const idProperty = element.properties.find((property): property is ts.PropertyAssignment =>
113
+ ts.isPropertyAssignment(property)
114
+ && (
115
+ (ts.isIdentifier(property.name) && property.name.text === 'id')
116
+ || (ts.isStringLiteralLike(property.name) && property.name.text === 'id')
117
+ ),
118
+ )
119
+ return idProperty && ts.isStringLiteralLike(idProperty.initializer)
120
+ ? [idProperty.initializer.text]
121
+ : []
122
+ }
123
+
124
+ function isPushOntoVariable(node: ts.Node, variableName: string): node is ts.CallExpression {
125
+ return ts.isCallExpression(node)
126
+ && ts.isPropertyAccessExpression(node.expression)
127
+ && node.expression.name.text === 'push'
128
+ && ts.isIdentifier(node.expression.expression)
129
+ && node.expression.expression.text === variableName
130
+ }
131
+
132
+ /**
133
+ * Module ids a registry file declares for `variableName`: the entries of its array
134
+ * literal initializer and, with `includePushes`, every `variableName.push({ id })` call.
135
+ * Pushes are usually conditional (enterprise or env-gated modules), so including them
136
+ * yields an upper bound of what the app can register, never narrower than the runtime set.
137
+ */
138
+ function readDeclaredModuleIdsFromConfig(
139
+ registryPath: string,
140
+ options: { variableName?: string; includePushes?: boolean; optional?: boolean } = {},
141
+ ): string[] {
142
+ const variableName = options.variableName ?? 'enabledModules'
143
+ if (options.optional && !existsSync(registryPath)) return []
111
144
  const source = readFileSync(registryPath, 'utf8')
112
145
  const sourceFile = ts.createSourceFile(
113
146
  registryPath,
@@ -117,43 +150,55 @@ function readDeclaredModuleIdsFromConfig(registryPath: string): string[] {
117
150
  ts.ScriptKind.TS,
118
151
  )
119
152
 
120
- for (const statement of sourceFile.statements) {
121
- if (!ts.isVariableStatement(statement)) continue
122
- for (const declaration of statement.declarationList.declarations) {
123
- if (
124
- !ts.isIdentifier(declaration.name)
125
- || declaration.name.text !== 'enabledModules'
126
- || !declaration.initializer
127
- || !ts.isArrayLiteralExpression(declaration.initializer)
128
- ) {
129
- continue
130
- }
131
-
132
- return declaration.initializer.elements.flatMap((element) => {
133
- if (!ts.isObjectLiteralExpression(element)) return []
134
- const idProperty = element.properties.find((property): property is ts.PropertyAssignment =>
135
- ts.isPropertyAssignment(property)
136
- && (
137
- (ts.isIdentifier(property.name) && property.name.text === 'id')
138
- || (ts.isStringLiteralLike(property.name) && property.name.text === 'id')
139
- ),
140
- )
141
- return idProperty && ts.isStringLiteralLike(idProperty.initializer)
142
- ? [idProperty.initializer.text]
143
- : []
144
- })
153
+ const declared: string[] = []
154
+ const visit = (node: ts.Node): void => {
155
+ if (
156
+ ts.isVariableDeclaration(node)
157
+ && ts.isVariableStatement(node.parent.parent)
158
+ && node.parent.parent.parent === sourceFile
159
+ && ts.isIdentifier(node.name)
160
+ && node.name.text === variableName
161
+ && node.initializer
162
+ && ts.isArrayLiteralExpression(node.initializer)
163
+ ) {
164
+ declared.push(...node.initializer.elements.flatMap(readModuleEntryId))
145
165
  }
166
+ if (options.includePushes && isPushOntoVariable(node, variableName)) {
167
+ declared.push(...node.arguments.flatMap(readModuleEntryId))
168
+ }
169
+ ts.forEachChild(node, visit)
146
170
  }
171
+ visit(sourceFile)
172
+ return declared
173
+ }
147
174
 
148
- return []
175
+ function resolveTestAppRoot(): string | null {
176
+ const configuredTestAppRoot = process.env.OM_TEST_APP_ROOT?.trim()
177
+ return configuredTestAppRoot ? path.resolve(configuredTestAppRoot) : null
178
+ }
179
+
180
+ /**
181
+ * Every module a standalone test app may register: its `enabledModules` literal, its
182
+ * conditional `enabledModules.push(...)` entries, and its official-module activations.
183
+ * Used to skip specs whose owning module the app does not ship at all.
184
+ */
185
+ function resolvePossiblyEnabledTestAppModuleIds(testAppRoot: string): Set<string> {
186
+ return new Set(
187
+ [
188
+ ...readDeclaredModuleIdsFromConfig(path.join(testAppRoot, 'src', 'modules.ts'), { includePushes: true }),
189
+ ...readDeclaredModuleIdsFromConfig(
190
+ path.join(testAppRoot, 'src', 'official-modules.generated.ts'),
191
+ { variableName: 'officialModuleEntries', includePushes: true, optional: true },
192
+ ),
193
+ ].map(normalizeModuleId),
194
+ )
149
195
  }
150
196
 
151
197
  function resolveEnabledModuleIds(projectRoot: string): Set<string> {
152
- const configuredTestAppRoot = process.env.OM_TEST_APP_ROOT?.trim()
153
- if (configuredTestAppRoot) {
154
- const registryPath = path.join(path.resolve(configuredTestAppRoot), 'src', 'modules.ts')
198
+ const testAppRoot = resolveTestAppRoot()
199
+ if (testAppRoot) {
155
200
  return new Set(
156
- readDeclaredModuleIdsFromConfig(registryPath).map(normalizeModuleId),
201
+ readDeclaredModuleIdsFromConfig(path.join(testAppRoot, 'src', 'modules.ts')).map(normalizeModuleId),
157
202
  )
158
203
  }
159
204
 
@@ -202,6 +247,22 @@ function extractModuleNameFromIntegrationPath(relativePath: string): string | nu
202
247
  return moduleSegment && moduleSegment.length > 0 ? moduleSegment : null
203
248
  }
204
249
 
250
+ /**
251
+ * The module a spec belongs to: the directory directly under the closest `modules/`
252
+ * ancestor of `__integration__`, provided that directory is a real module (it ships an
253
+ * `index.ts`/`index.js`). Returns null for specs outside a module, e.g. `packages/ui`.
254
+ */
255
+ function resolveOwningModuleId(projectRoot: string, relativeSpecPath: string): string | null {
256
+ const segments = normalizePath(relativeSpecPath).split('/')
257
+ const integrationDirectoryIndex = segments.indexOf(MODULE_INTEGRATION_DIRECTORY_NAME)
258
+ if (integrationDirectoryIndex <= 0) return null
259
+ const modulesSegmentIndex = segments.lastIndexOf('modules', integrationDirectoryIndex - 1)
260
+ if (modulesSegmentIndex === -1 || modulesSegmentIndex + 1 >= integrationDirectoryIndex) return null
261
+ const moduleRoot = path.join(projectRoot, ...segments.slice(0, modulesSegmentIndex + 2))
262
+ const isRealModule = ['index.ts', 'index.js'].some((fileName) => existsSync(path.join(moduleRoot, fileName)))
263
+ return isRealModule ? normalizeModuleId(segments[modulesSegmentIndex + 1]) : null
264
+ }
265
+
205
266
  function resolveOverlayRootPath(): string {
206
267
  const configured = process.env.OM_INTEGRATION_OVERLAY_ROOT?.trim()
207
268
  if (!configured) {
@@ -433,6 +494,8 @@ export function discoverIntegrationSpecFiles(projectRoot: string, legacyIntegrat
433
494
 
434
495
  const discovered = Array.from(discoveredByPath.values())
435
496
  const enabledModules = resolveEnabledModuleIds(projectRoot)
497
+ const testAppRoot = resolveTestAppRoot()
498
+ const testAppModules = testAppRoot ? resolvePossiblyEnabledTestAppModuleIds(testAppRoot) : null
436
499
  const enabledModuleNames = new Set<string>()
437
500
  for (const file of discovered) {
438
501
  if (!file.isOverlay && file.moduleName) {
@@ -445,6 +508,12 @@ export function discoverIntegrationSpecFiles(projectRoot: string, legacyIntegrat
445
508
  if (file.requiredModules.some((moduleId) => !enabledModules.has(normalizeModuleId(moduleId)))) {
446
509
  return false
447
510
  }
511
+ if (testAppModules && !file.isOverlay) {
512
+ const owningModuleId = resolveOwningModuleId(projectRoot, file.path)
513
+ if (owningModuleId && !testAppModules.has(owningModuleId)) {
514
+ return false
515
+ }
516
+ }
448
517
  if (file.requiredEnvVars.some((envVar) => !isEnvironmentVariableConfigured(envVar))) {
449
518
  return false
450
519
  }