@open-mercato/cli 0.10.1-develop.7827.1.5c631908e4 → 0.10.1-develop.7833.1.d6cbf0e3ab
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.
- package/dist/agentic/guides/module-facts.json +162 -162
- package/dist/agentic/guides/module-facts.v2.json +162 -162
- package/dist/agentic/guides/modules/agent_orchestrator/index.md +1 -1
- package/dist/agentic/guides/modules/ai_assistant/index.md +1 -1
- package/dist/agentic/guides/modules/api_docs/index.md +1 -1
- package/dist/agentic/guides/modules/api_keys/index.md +1 -1
- package/dist/agentic/guides/modules/attachments/index.md +1 -1
- package/dist/agentic/guides/modules/audit_logs/index.md +1 -1
- package/dist/agentic/guides/modules/auth/index.md +1 -1
- package/dist/agentic/guides/modules/availability/index.md +1 -1
- package/dist/agentic/guides/modules/business_rules/index.md +1 -1
- package/dist/agentic/guides/modules/carrier_inpost/index.md +1 -1
- package/dist/agentic/guides/modules/cart/index.md +1 -1
- package/dist/agentic/guides/modules/catalog/index.md +1 -1
- package/dist/agentic/guides/modules/channel_apns/index.md +1 -1
- package/dist/agentic/guides/modules/channel_discord/index.md +1 -1
- package/dist/agentic/guides/modules/channel_expo/index.md +1 -1
- package/dist/agentic/guides/modules/channel_fcm/index.md +1 -1
- package/dist/agentic/guides/modules/channel_gmail/index.md +1 -1
- package/dist/agentic/guides/modules/channel_imap/index.md +1 -1
- package/dist/agentic/guides/modules/channel_resend/index.md +1 -1
- package/dist/agentic/guides/modules/channel_ses/index.md +1 -1
- package/dist/agentic/guides/modules/channel_smtp/index.md +1 -1
- package/dist/agentic/guides/modules/checkout/index.md +1 -1
- package/dist/agentic/guides/modules/communication_channels/index.md +1 -1
- package/dist/agentic/guides/modules/configs/index.md +1 -1
- package/dist/agentic/guides/modules/content/index.md +1 -1
- package/dist/agentic/guides/modules/currencies/index.md +1 -1
- package/dist/agentic/guides/modules/customer_accounts/index.md +1 -1
- package/dist/agentic/guides/modules/customer_groups/index.md +1 -1
- package/dist/agentic/guides/modules/customers/index.md +1 -1
- package/dist/agentic/guides/modules/dashboards/index.md +1 -1
- package/dist/agentic/guides/modules/data_sync/index.md +1 -1
- package/dist/agentic/guides/modules/design_system/index.md +1 -1
- package/dist/agentic/guides/modules/devices/index.md +1 -1
- package/dist/agentic/guides/modules/dictionaries/index.md +1 -1
- package/dist/agentic/guides/modules/directory/index.md +1 -1
- package/dist/agentic/guides/modules/documents/index.md +1 -1
- package/dist/agentic/guides/modules/ecommerce/index.md +1 -1
- package/dist/agentic/guides/modules/entities/index.md +1 -1
- package/dist/agentic/guides/modules/eudr/index.md +1 -1
- package/dist/agentic/guides/modules/events/index.md +1 -1
- package/dist/agentic/guides/modules/feature_toggles/index.md +1 -1
- package/dist/agentic/guides/modules/forms/index.md +1 -1
- package/dist/agentic/guides/modules/gateway_autopay/index.md +1 -1
- package/dist/agentic/guides/modules/gateway_stripe/index.md +1 -1
- package/dist/agentic/guides/modules/gateway_tpay/index.md +1 -1
- package/dist/agentic/guides/modules/generators/index.md +1 -1
- package/dist/agentic/guides/modules/inbox_ops/index.md +1 -1
- package/dist/agentic/guides/modules/integrations/index.md +1 -1
- package/dist/agentic/guides/modules/messages/index.md +1 -1
- package/dist/agentic/guides/modules/notifications/index.md +1 -1
- package/dist/agentic/guides/modules/onboarding/index.md +1 -1
- package/dist/agentic/guides/modules/payment_gateways/index.md +1 -1
- package/dist/agentic/guides/modules/perspectives/index.md +1 -1
- package/dist/agentic/guides/modules/phone_calls/index.md +1 -1
- package/dist/agentic/guides/modules/planner/index.md +1 -1
- package/dist/agentic/guides/modules/portal/index.md +1 -1
- package/dist/agentic/guides/modules/progress/index.md +1 -1
- package/dist/agentic/guides/modules/promotions/index.md +1 -1
- package/dist/agentic/guides/modules/push_notifications/index.md +1 -1
- package/dist/agentic/guides/modules/query_index/index.md +1 -1
- package/dist/agentic/guides/modules/record_locks/index.md +1 -1
- package/dist/agentic/guides/modules/resources/index.md +1 -1
- package/dist/agentic/guides/modules/sales/index.md +1 -1
- package/dist/agentic/guides/modules/scheduler/index.md +1 -1
- package/dist/agentic/guides/modules/search/index.md +1 -1
- package/dist/agentic/guides/modules/security/index.md +1 -1
- package/dist/agentic/guides/modules/seeds/index.md +1 -1
- package/dist/agentic/guides/modules/shipping_carriers/index.md +1 -1
- package/dist/agentic/guides/modules/sso/index.md +1 -1
- package/dist/agentic/guides/modules/staff/index.md +1 -1
- package/dist/agentic/guides/modules/storage_s3/index.md +1 -1
- package/dist/agentic/guides/modules/sync_akeneo/index.md +1 -1
- package/dist/agentic/guides/modules/sync_excel/index.md +1 -1
- package/dist/agentic/guides/modules/system_status_overlays/index.md +1 -1
- package/dist/agentic/guides/modules/telemetry/index.md +1 -1
- package/dist/agentic/guides/modules/tillio/index.md +1 -1
- package/dist/agentic/guides/modules/translations/index.md +1 -1
- package/dist/agentic/guides/modules/warranty_claims/index.md +1 -1
- package/dist/agentic/guides/modules/webhooks/index.md +1 -1
- package/dist/agentic/guides/modules/wms/index.md +1 -1
- package/dist/agentic/guides/modules/workflows/index.md +1 -1
- package/dist/agentic/guides/reference-module-facts.json +2 -2
- package/dist/agentic/guides/reference-modules/example/index.md +1 -1
- package/dist/agentic/guides/upstream/manifest.json +1 -1
- package/dist/lib/testing/integration-discovery.js +61 -21
- package/dist/lib/testing/integration-discovery.js.map +2 -2
- package/package.json +7 -7
- package/src/lib/testing/__tests__/integration-discovery.test.ts +89 -0
- 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
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
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
|
|
153
|
-
if (
|
|
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(
|
|
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
|
}
|