@open-mercato/cli 0.4.9-develop.1038.2d16936bed → 0.4.9-develop.1045.7bcda4435a

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/cli",
3
- "version": "0.4.9-develop.1038.2d16936bed",
3
+ "version": "0.4.9-develop.1045.7bcda4435a",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
@@ -58,17 +58,17 @@
58
58
  "@mikro-orm/core": "^6.6.2",
59
59
  "@mikro-orm/migrations": "^6.6.2",
60
60
  "@mikro-orm/postgresql": "^6.6.2",
61
- "@open-mercato/shared": "0.4.9-develop.1038.2d16936bed",
61
+ "@open-mercato/shared": "0.4.9-develop.1045.7bcda4435a",
62
62
  "pg": "8.20.0",
63
63
  "semver": "^7.7.3",
64
64
  "testcontainers": "^11.12.0",
65
65
  "typescript": "^5.9.3"
66
66
  },
67
67
  "peerDependencies": {
68
- "@open-mercato/shared": "0.4.9-develop.1038.2d16936bed"
68
+ "@open-mercato/shared": "0.4.9-develop.1045.7bcda4435a"
69
69
  },
70
70
  "devDependencies": {
71
- "@open-mercato/shared": "0.4.9-develop.1038.2d16936bed",
71
+ "@open-mercato/shared": "0.4.9-develop.1045.7bcda4435a",
72
72
  "@types/jest": "^30.0.0",
73
73
  "jest": "^30.2.0",
74
74
  "ts-jest": "^29.4.6"
@@ -12,6 +12,7 @@ import {
12
12
  import {
13
13
  scanModuleDir,
14
14
  resolveModuleFile,
15
+ resolveFirstModuleFile,
15
16
  SCAN_CONFIGS,
16
17
  type ModuleRoots,
17
18
  type ModuleImports,
@@ -391,6 +392,8 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
391
392
  const notificationsChecksumFile = path.join(outputDir, 'notifications.generated.checksum')
392
393
  const notificationsClientOutFile = path.join(outputDir, 'notifications.client.generated.ts')
393
394
  const notificationsClientChecksumFile = path.join(outputDir, 'notifications.client.generated.checksum')
395
+ const paymentsClientOutFile = path.join(outputDir, 'payments.client.generated.ts')
396
+ const paymentsClientChecksumFile = path.join(outputDir, 'payments.client.generated.checksum')
394
397
  const notificationHandlersOutFile = path.join(outputDir, 'notification-handlers.generated.ts')
395
398
  const notificationHandlersChecksumFile = path.join(outputDir, 'notification-handlers.generated.checksum')
396
399
  const messageTypesOutFile = path.join(outputDir, 'message-types.generated.ts')
@@ -467,6 +470,7 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
467
470
  const notificationImports: string[] = []
468
471
  const notificationClientTypes: string[] = []
469
472
  const notificationClientImports: string[] = []
473
+ const paymentsClientImports: string[] = []
470
474
  const notificationHandlerEntries: string[] = []
471
475
  const notificationHandlerImports: string[] = []
472
476
  const messageTypeEntries: string[] = []
@@ -636,6 +640,16 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
636
640
  configExpr: (n, id) => `{ moduleId: '${id}', types: (${n}.default ?? []) }`,
637
641
  })
638
642
 
643
+ {
644
+ const resolved = resolveFirstModuleFile(roots, imps, [
645
+ 'widgets/payments/client.tsx',
646
+ 'widgets/payments/client.ts',
647
+ ])
648
+ if (resolved) {
649
+ paymentsClientImports.push(`import '${resolved.importPath}'`)
650
+ }
651
+ }
652
+
639
653
  processStandaloneConfig({
640
654
  roots, imps, modId, importIdRef,
641
655
  relativePath: 'notifications.handlers.ts',
@@ -1277,6 +1291,10 @@ ${notificationHandlersImportSection ? `\n${notificationHandlersImportSection}\n`
1277
1291
 
1278
1292
  export const notificationHandlerEntries: NotificationHandlerEntry[] = [
1279
1293
  ${notificationHandlersEntriesLiteral ? ` ${notificationHandlersEntriesLiteral}\n` : ''}]
1294
+ `
1295
+
1296
+ const paymentsClientOutput = `// AUTO-GENERATED by mercato generate registry
1297
+ ${paymentsClientImports.length ? paymentsClientImports.join('\n') + '\n' : '\n'}export const paymentGatewayClientModuleCount = ${paymentsClientImports.length}
1280
1298
  `
1281
1299
 
1282
1300
  const messageTypeEntriesLiteral = messageTypeEntries.join(',\n ')
@@ -1489,6 +1507,7 @@ export const allAiTools = aiToolConfigEntries.flatMap(e => e.tools)
1489
1507
  writeGeneratedFile({ outFile: aiToolsOutFile, checksumFile: aiToolsChecksumFile, content: aiToolsOutput, structureChecksum, result, quiet })
1490
1508
  writeGeneratedFile({ outFile: notificationsOutFile, checksumFile: notificationsChecksumFile, content: notificationsOutput, structureChecksum, result, quiet })
1491
1509
  writeGeneratedFile({ outFile: notificationsClientOutFile, checksumFile: notificationsClientChecksumFile, content: notificationsClientOutput, structureChecksum, result, quiet })
1510
+ writeGeneratedFile({ outFile: paymentsClientOutFile, checksumFile: paymentsClientChecksumFile, content: paymentsClientOutput, structureChecksum, result, quiet })
1492
1511
  writeGeneratedFile({ outFile: notificationHandlersOutFile, checksumFile: notificationHandlersChecksumFile, content: notificationHandlersOutput, structureChecksum, result, quiet })
1493
1512
  writeGeneratedFile({ outFile: messageTypesOutFile, checksumFile: messageTypesChecksumFile, content: messageTypesOutput, structureChecksum, result, quiet })
1494
1513
  writeGeneratedFile({ outFile: messageObjectsOutFile, checksumFile: messageObjectsChecksumFile, content: messageObjectsOutput, structureChecksum, result, quiet })
@@ -153,7 +153,19 @@ export function resolveModuleFile(
153
153
 
154
154
  const fromApp = hasApp
155
155
  const absolutePath = fromApp ? appFile : pkgFile
156
- const importSuffix = relativePath.replace(/\.ts$/, '')
156
+ const importSuffix = relativePath.replace(/\.tsx?$/, '')
157
157
  const importPath = `${fromApp ? imps.appBase : imps.pkgBase}/${importSuffix}`
158
158
  return { absolutePath, fromApp, importPath }
159
159
  }
160
+
161
+ export function resolveFirstModuleFile(
162
+ roots: ModuleRoots,
163
+ imps: ModuleImports,
164
+ relativePaths: string[],
165
+ ): ResolvedFile | null {
166
+ for (const relativePath of relativePaths) {
167
+ const resolved = resolveModuleFile(roots, imps, relativePath)
168
+ if (resolved) return resolved
169
+ }
170
+ return null
171
+ }
@@ -20,6 +20,7 @@ import {
20
20
 
21
21
  const CACHE_TTL_ENV_VAR = 'OM_INTEGRATION_BUILD_CACHE_TTL_SECONDS'
22
22
  const APP_READY_TIMEOUT_ENV_VAR = 'OM_INTEGRATION_APP_READY_TIMEOUT_SECONDS'
23
+ const CHECKOUT_TEST_INJECTION_FLAG = 'NEXT_PUBLIC_OM_EXAMPLE_CHECKOUT_TEST_INJECTIONS_ENABLED'
23
24
  const resolver = createResolver()
24
25
  const projectRootDirectory = resolver.getRootDir()
25
26
 
@@ -39,6 +40,7 @@ describe('integration cache and options', () => {
39
40
  const ephemeralLegacyEnvFilePath = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.md')
40
41
  const originalCacheTtl = process.env[CACHE_TTL_ENV_VAR]
41
42
  const originalAppReadyTimeout = process.env[APP_READY_TIMEOUT_ENV_VAR]
43
+ const originalCheckoutTestInjectionFlag = process.env[CHECKOUT_TEST_INJECTION_FLAG]
42
44
  let originalEphemeralEnvState: string | null = null
43
45
  let originalEphemeralLegacyEnvState: string | null = null
44
46
 
@@ -69,11 +71,17 @@ describe('integration cache and options', () => {
69
71
  } else {
70
72
  process.env[APP_READY_TIMEOUT_ENV_VAR] = originalAppReadyTimeout
71
73
  }
74
+ if (originalCheckoutTestInjectionFlag === undefined) {
75
+ delete process.env[CHECKOUT_TEST_INJECTION_FLAG]
76
+ } else {
77
+ process.env[CHECKOUT_TEST_INJECTION_FLAG] = originalCheckoutTestInjectionFlag
78
+ }
72
79
  await restoreEphemeralStateFiles(originalEphemeralEnvState, originalEphemeralLegacyEnvState)
73
80
  })
74
81
 
75
82
  it('reuses an existing reachable ephemeral environment state', async () => {
76
83
  const baseUrl = 'http://127.0.0.1:5001'
84
+ delete process.env[CHECKOUT_TEST_INJECTION_FLAG]
77
85
  const fetchSpy = jest.spyOn(global, 'fetch').mockImplementation(async (input) => {
78
86
  const url = typeof input === 'string' ? input : String(input)
79
87
  if (url.endsWith('/api/auth/login')) {
@@ -116,6 +124,49 @@ describe('integration cache and options', () => {
116
124
  ownedByCurrentProcess: false,
117
125
  })
118
126
  expect(environment?.commandEnvironment.PW_CAPTURE_SCREENSHOTS).toBe('1')
127
+ expect(environment?.commandEnvironment.NEXT_PUBLIC_OM_EXAMPLE_CHECKOUT_TEST_INJECTIONS_ENABLED).toBeUndefined()
128
+ } finally {
129
+ fetchSpy.mockRestore()
130
+ }
131
+ }, 20000)
132
+
133
+ it('reuses an existing environment with checkout wrapper injections only when explicitly enabled', async () => {
134
+ const baseUrl = 'http://127.0.0.1:5001'
135
+ process.env[CHECKOUT_TEST_INJECTION_FLAG] = 'true'
136
+ const fetchSpy = jest.spyOn(global, 'fetch').mockImplementation(async (input) => {
137
+ const url = typeof input === 'string' ? input : String(input)
138
+ if (url.endsWith('/api/auth/login')) {
139
+ return { status: 401, text: async () => '' } as unknown as Response
140
+ }
141
+ if (url.endsWith('/login')) {
142
+ return {
143
+ status: 200,
144
+ text: async () => '<!doctype html><script src="/_next/static/chunks/app-healthcheck.js"></script>',
145
+ } as unknown as Response
146
+ }
147
+ if (url.includes('/_next/static/chunks/app-healthcheck.js')) {
148
+ return { status: 200, text: async () => '' } as unknown as Response
149
+ }
150
+ return { status: 200, text: async () => '' } as unknown as Response
151
+ })
152
+
153
+ try {
154
+ await writeEphemeralEnvironmentState({
155
+ baseUrl,
156
+ port: 5001,
157
+ logPrefix: 'integration',
158
+ captureScreenshots: true,
159
+ })
160
+
161
+ const environment = await tryReuseExistingEnvironment({
162
+ verbose: false,
163
+ captureScreenshots: true,
164
+ logPrefix: 'integration',
165
+ forceRebuild: false,
166
+ })
167
+
168
+ expect(environment).not.toBeNull()
169
+ expect(environment?.commandEnvironment.NEXT_PUBLIC_OM_EXAMPLE_CHECKOUT_TEST_INJECTIONS_ENABLED).toBe('true')
119
170
  } finally {
120
171
  fetchSpy.mockRestore()
121
172
  }
@@ -1357,6 +1357,8 @@ async function clearStaleEphemeralEnvironmentLock(logPrefix: string): Promise<bo
1357
1357
  function buildReusableEnvironment(baseUrl: string, captureScreenshots: boolean): NodeJS.ProcessEnv {
1358
1358
  return buildEnvironment({
1359
1359
  BASE_URL: baseUrl,
1360
+ APP_URL: baseUrl,
1361
+ NEXT_PUBLIC_APP_URL: baseUrl,
1360
1362
  NODE_ENV: 'production',
1361
1363
  JWT_SECRET: process.env.JWT_SECRET ?? 'om-ephemeral-integration-jwt-secret',
1362
1364
  OM_SECURITY_MFA_SETUP_SECRET: process.env.OM_SECURITY_MFA_SETUP_SECRET ?? 'om-ephemeral-integration-mfa-setup-secret',
@@ -2572,6 +2574,8 @@ export async function startEphemeralEnvironment(options: EphemeralRuntimeOptions
2572
2574
  const commandEnvironment = buildEnvironment({
2573
2575
  DATABASE_URL: databaseUrl,
2574
2576
  BASE_URL: applicationBaseUrl,
2577
+ APP_URL: applicationBaseUrl,
2578
+ NEXT_PUBLIC_APP_URL: applicationBaseUrl,
2575
2579
  JWT_SECRET: process.env.JWT_SECRET ?? 'om-ephemeral-integration-jwt-secret',
2576
2580
  OM_SECURITY_MFA_SETUP_SECRET: process.env.OM_SECURITY_MFA_SETUP_SECRET ?? 'om-ephemeral-integration-mfa-setup-secret',
2577
2581
  NODE_ENV: 'production',