@open-mercato/cli 0.6.2-develop.3467.1.2a1818709d → 0.6.2

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.
@@ -78,6 +78,7 @@ const resolveBuildCacheFingerprint = async (
78
78
  }
79
79
 
80
80
  describe('integration cache and options', () => {
81
+ const REUSE_ENV_TEST_TIMEOUT_MS = 60000
81
82
  const ephemeralEnvFilePath = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.json')
82
83
  const ephemeralLegacyEnvFilePath = path.join(projectRootDirectory, '.ai', 'qa', 'ephemeral-env.md')
83
84
  const originalCacheTtl = process.env[CACHE_TTL_ENV_VAR]
@@ -130,12 +131,20 @@ describe('integration cache and options', () => {
130
131
  await writeEphemeralEnvironmentState({
131
132
  baseUrl,
132
133
  port: 5001,
134
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
135
+ queueBaseDir: '/tmp/open-mercato-queue',
133
136
  logPrefix: 'integration',
134
137
  captureScreenshots: true,
135
138
  })
136
139
 
137
140
  const state = await readEphemeralEnvironmentState()
138
- expect(state).toMatchObject({ baseUrl, port: 5001, captureScreenshots: true })
141
+ expect(state).toMatchObject({
142
+ baseUrl,
143
+ port: 5001,
144
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
145
+ queueBaseDir: '/tmp/open-mercato-queue',
146
+ captureScreenshots: true,
147
+ })
139
148
 
140
149
  const environment = await tryReuseExistingEnvironment({
141
150
  verbose: false,
@@ -151,12 +160,16 @@ describe('integration cache and options', () => {
151
160
  ownedByCurrentProcess: false,
152
161
  })
153
162
  expect(environment?.commandEnvironment.OM_INTEGRATION_TEST).toBe('true')
163
+ expect(environment?.commandEnvironment.DATABASE_URL).toBe(
164
+ 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
165
+ )
166
+ expect(environment?.commandEnvironment.QUEUE_BASE_DIR).toBe('/tmp/open-mercato-queue')
154
167
  expect(environment?.commandEnvironment.PW_CAPTURE_SCREENSHOTS).toBe('1')
155
168
  expect(environment?.commandEnvironment.NEXT_PUBLIC_OM_EXAMPLE_CHECKOUT_TEST_INJECTIONS_ENABLED).toBeUndefined()
156
169
  } finally {
157
170
  fetchSpy.mockRestore()
158
171
  }
159
- }, 20000)
172
+ }, REUSE_ENV_TEST_TIMEOUT_MS)
160
173
 
161
174
  it('reuses an existing environment with checkout wrapper injections only when explicitly enabled', async () => {
162
175
  const baseUrl = 'http://127.0.0.1:5001'
@@ -167,6 +180,8 @@ describe('integration cache and options', () => {
167
180
  await writeEphemeralEnvironmentState({
168
181
  baseUrl,
169
182
  port: 5001,
183
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
184
+ queueBaseDir: '/tmp/open-mercato-queue',
170
185
  logPrefix: 'integration',
171
186
  captureScreenshots: true,
172
187
  })
@@ -184,7 +199,7 @@ describe('integration cache and options', () => {
184
199
  } finally {
185
200
  fetchSpy.mockRestore()
186
201
  }
187
- }, 20000)
202
+ }, REUSE_ENV_TEST_TIMEOUT_MS)
188
203
 
189
204
  it('reuses an existing environment when /login returns a redirect status other than 302', async () => {
190
205
  const baseUrl = 'http://127.0.0.1:5001'
@@ -196,6 +211,8 @@ describe('integration cache and options', () => {
196
211
  await writeEphemeralEnvironmentState({
197
212
  baseUrl,
198
213
  port: 5001,
214
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
215
+ queueBaseDir: '/tmp/open-mercato-queue',
199
216
  logPrefix: 'integration',
200
217
  captureScreenshots: true,
201
218
  })
@@ -216,7 +233,7 @@ describe('integration cache and options', () => {
216
233
  } finally {
217
234
  fetchSpy.mockRestore()
218
235
  }
219
- }, 20000)
236
+ }, REUSE_ENV_TEST_TIMEOUT_MS)
220
237
 
221
238
  it('reuses an existing environment when /login returns healthy HTML without static asset references', async () => {
222
239
  const baseUrl = 'http://127.0.0.1:5001'
@@ -231,6 +248,8 @@ describe('integration cache and options', () => {
231
248
  await writeEphemeralEnvironmentState({
232
249
  baseUrl,
233
250
  port: 5001,
251
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
252
+ queueBaseDir: '/tmp/open-mercato-queue',
234
253
  logPrefix: 'integration',
235
254
  captureScreenshots: false,
236
255
  })
@@ -251,7 +270,7 @@ describe('integration cache and options', () => {
251
270
  } finally {
252
271
  fetchSpy.mockRestore()
253
272
  }
254
- }, 20000)
273
+ }, REUSE_ENV_TEST_TIMEOUT_MS)
255
274
 
256
275
  it('falls back to rebuilding when the ephemeral environment state is unreachable', async () => {
257
276
  const baseUrl = 'http://127.0.0.1:5001'
@@ -261,6 +280,8 @@ describe('integration cache and options', () => {
261
280
  await writeEphemeralEnvironmentState({
262
281
  baseUrl,
263
282
  port: 5001,
283
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
284
+ queueBaseDir: '/tmp/open-mercato-queue',
264
285
  logPrefix: 'integration',
265
286
  captureScreenshots: false,
266
287
  })
@@ -289,6 +310,8 @@ describe('integration cache and options', () => {
289
310
  await writeEphemeralEnvironmentState({
290
311
  baseUrl,
291
312
  port: 5001,
313
+ databaseUrl: 'postgres://integration:integration@127.0.0.1:5432/open_mercato',
314
+ queueBaseDir: '/tmp/open-mercato-queue',
292
315
  logPrefix: 'integration',
293
316
  captureScreenshots: true,
294
317
  })
@@ -138,6 +138,8 @@ type EphemeralEnvironmentState = {
138
138
  status: 'running'
139
139
  baseUrl: string
140
140
  port: number
141
+ databaseUrl: string
142
+ queueBaseDir: string
141
143
  source: string
142
144
  captureScreenshots: boolean
143
145
  startedAt: string
@@ -1168,6 +1170,8 @@ async function getPreferredPort(preferredPort: number): Promise<number> {
1168
1170
  export async function writeEphemeralEnvironmentState(input: {
1169
1171
  baseUrl: string
1170
1172
  port: number
1173
+ databaseUrl: string
1174
+ queueBaseDir: string
1171
1175
  logPrefix: string
1172
1176
  captureScreenshots: boolean
1173
1177
  }): Promise<void> {
@@ -1175,6 +1179,8 @@ export async function writeEphemeralEnvironmentState(input: {
1175
1179
  status: 'running',
1176
1180
  baseUrl: input.baseUrl,
1177
1181
  port: input.port,
1182
+ databaseUrl: input.databaseUrl,
1183
+ queueBaseDir: input.queueBaseDir,
1178
1184
  source: input.logPrefix,
1179
1185
  captureScreenshots: input.captureScreenshots,
1180
1186
  startedAt: new Date().toISOString(),
@@ -1219,6 +1225,12 @@ export async function readEphemeralEnvironmentState(): Promise<EphemeralEnvironm
1219
1225
  if (typeof record.port !== 'number' || !Number.isFinite(record.port) || record.port < 1) {
1220
1226
  return null
1221
1227
  }
1228
+ if (typeof record.databaseUrl !== 'string' || record.databaseUrl.length === 0) {
1229
+ return null
1230
+ }
1231
+ if (typeof record.queueBaseDir !== 'string' || record.queueBaseDir.length === 0) {
1232
+ return null
1233
+ }
1222
1234
  if (typeof record.source !== 'string' || record.source.length === 0) {
1223
1235
  return null
1224
1236
  }
@@ -1233,6 +1245,8 @@ export async function readEphemeralEnvironmentState(): Promise<EphemeralEnvironm
1233
1245
  status: 'running',
1234
1246
  baseUrl: record.baseUrl,
1235
1247
  port: record.port,
1248
+ databaseUrl: record.databaseUrl,
1249
+ queueBaseDir: record.queueBaseDir,
1236
1250
  source: record.source,
1237
1251
  captureScreenshots: record.captureScreenshots,
1238
1252
  startedAt: record.startedAt,
@@ -1614,9 +1628,15 @@ export async function acquireEphemeralRuntimeLock(
1614
1628
  }
1615
1629
  }
1616
1630
 
1617
- function buildReusableEnvironment(baseUrl: string, captureScreenshots: boolean): NodeJS.ProcessEnv {
1631
+ function buildReusableEnvironment(
1632
+ baseUrl: string,
1633
+ databaseUrl: string,
1634
+ queueBaseDir: string,
1635
+ captureScreenshots: boolean,
1636
+ ): NodeJS.ProcessEnv {
1618
1637
  const enterpriseModulesFlag = process.env.OM_ENABLE_ENTERPRISE_MODULES ?? 'false'
1619
1638
  return buildEnvironment({
1639
+ DATABASE_URL: databaseUrl,
1620
1640
  BASE_URL: baseUrl,
1621
1641
  APP_URL: baseUrl,
1622
1642
  NEXT_PUBLIC_APP_URL: baseUrl,
@@ -1639,6 +1659,7 @@ function buildReusableEnvironment(baseUrl: string, captureScreenshots: boolean):
1639
1659
  TENANT_DATA_ENCRYPTION_FALLBACK_KEY: process.env.TENANT_DATA_ENCRYPTION_FALLBACK_KEY ?? 'om-ephemeral-integration-fallback-key',
1640
1660
  OM_CLI_QUIET: '1',
1641
1661
  MERCATO_QUIET: '1',
1662
+ QUEUE_BASE_DIR: queueBaseDir,
1642
1663
  NODE_NO_WARNINGS: '1',
1643
1664
  PW_CAPTURE_SCREENSHOTS: captureScreenshots ? '1' : '0',
1644
1665
  })
@@ -1695,8 +1716,13 @@ export async function tryReuseExistingEnvironment(options: EphemeralRuntimeOptio
1695
1716
  return {
1696
1717
  baseUrl: state.baseUrl,
1697
1718
  port: state.port,
1698
- databaseUrl: '',
1699
- commandEnvironment: buildReusableEnvironment(state.baseUrl, state.captureScreenshots),
1719
+ databaseUrl: state.databaseUrl,
1720
+ commandEnvironment: buildReusableEnvironment(
1721
+ state.baseUrl,
1722
+ state.databaseUrl,
1723
+ state.queueBaseDir,
1724
+ state.captureScreenshots,
1725
+ ),
1700
1726
  ownedByCurrentProcess: false,
1701
1727
  stop: async () => {},
1702
1728
  }
@@ -2880,10 +2906,19 @@ export async function startEphemeralEnvironment(options: EphemeralRuntimeOptions
2880
2906
  JWT_SECRET: process.env.JWT_SECRET ?? 'om-ephemeral-integration-jwt-secret',
2881
2907
  OM_SECURITY_MFA_SETUP_SECRET: process.env.OM_SECURITY_MFA_SETUP_SECRET ?? 'om-ephemeral-integration-mfa-setup-secret',
2882
2908
  NODE_ENV: 'production',
2883
- DB_POOL_MIN: '0',
2884
- DB_POOL_MAX: '5',
2885
- DB_POOL_IDLE_TIMEOUT: '1000',
2886
- DB_POOL_ACQUIRE_TIMEOUT: '10000',
2909
+ // Pool sizing for the ephemeral integration runtime. Defaults were once
2910
+ // very aggressive (max=5, idle=1000) which exposed flaky 'timeout exceeded
2911
+ // when trying to connect' errors on `progressService.createJob`-backed
2912
+ // endpoints (sync_excel.import, data_sync.run, progress.jobs) — each
2913
+ // request acquires a transaction connection plus a separate connection
2914
+ // for the encryption subscriber's fetchMap probe, and with 1s idle close
2915
+ // the pool thrashes faster than pg-pool can repopulate. These values
2916
+ // still keep the pool tighter than production but give enough headroom
2917
+ // for the legitimate query bursts.
2918
+ DB_POOL_MIN: '2',
2919
+ DB_POOL_MAX: '20',
2920
+ DB_POOL_IDLE_TIMEOUT: '10000',
2921
+ DB_POOL_ACQUIRE_TIMEOUT: '15000',
2887
2922
  DB_IDLE_SESSION_TIMEOUT_MS: '30000',
2888
2923
  DB_IDLE_IN_TRANSACTION_TIMEOUT_MS: '30000',
2889
2924
  OM_INTEGRATION_TEST: 'true',
@@ -3030,6 +3065,8 @@ export async function startEphemeralEnvironment(options: EphemeralRuntimeOptions
3030
3065
  await writeEphemeralEnvironmentState({
3031
3066
  baseUrl: applicationBaseUrl,
3032
3067
  port: applicationPort,
3068
+ databaseUrl,
3069
+ queueBaseDir: EPHEMERAL_QUEUE_BASE_DIR,
3033
3070
  logPrefix: options.logPrefix,
3034
3071
  captureScreenshots: options.captureScreenshots,
3035
3072
  })