@open-mercato/cli 0.5.1-develop.2727.5af6be1c11 → 0.5.1-develop.2756.cce1739df3
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/mercato.js +74 -33
- package/dist/mercato.js.map +2 -2
- package/package.json +5 -5
- package/src/__tests__/mercato.test.ts +225 -0
- package/src/mercato.ts +87 -39
package/dist/mercato.js
CHANGED
|
@@ -226,6 +226,28 @@ function buildServerProcessEnvironment(environment) {
|
|
|
226
226
|
}
|
|
227
227
|
return runtimeEnv;
|
|
228
228
|
}
|
|
229
|
+
function waitForManagedProcessExit(proc, label) {
|
|
230
|
+
return new Promise((resolve) => {
|
|
231
|
+
proc.on("exit", (code, signal) => {
|
|
232
|
+
resolve({ label, code, signal });
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
function isExpectedManagedExitSignal(signal) {
|
|
237
|
+
return signal === "SIGINT" || signal === "SIGTERM";
|
|
238
|
+
}
|
|
239
|
+
function formatManagedProcessExitStatus(result) {
|
|
240
|
+
if (typeof result.code === "number") {
|
|
241
|
+
return `exit code ${result.code}`;
|
|
242
|
+
}
|
|
243
|
+
if (result.signal) {
|
|
244
|
+
return `signal ${result.signal}`;
|
|
245
|
+
}
|
|
246
|
+
return "an unknown status";
|
|
247
|
+
}
|
|
248
|
+
function createManagedProcessExitError(result) {
|
|
249
|
+
return new Error(`[server] ${result.label} exited unexpectedly with ${formatManagedProcessExitStatus(result)}.`);
|
|
250
|
+
}
|
|
229
251
|
function ensureNextBuildIdInConfiguredDistDir(appDir) {
|
|
230
252
|
const configuredDistDir = path.join(appDir, ".mercato", "next");
|
|
231
253
|
const configuredBuildIdPath = path.join(configuredDistDir, "BUILD_ID");
|
|
@@ -288,7 +310,7 @@ async function runModuleCommand(allModules, moduleName, commandName, args = [],
|
|
|
288
310
|
if (!options.silentOptional) {
|
|
289
311
|
console.log(`\u23ED\uFE0F Skipping "${moduleName}:${commandName}" \u2014 module not enabled`);
|
|
290
312
|
}
|
|
291
|
-
return;
|
|
313
|
+
return false;
|
|
292
314
|
}
|
|
293
315
|
throw new Error(`Module not found: "${moduleName}"`);
|
|
294
316
|
}
|
|
@@ -297,7 +319,7 @@ async function runModuleCommand(allModules, moduleName, commandName, args = [],
|
|
|
297
319
|
if (!options.silentOptional) {
|
|
298
320
|
console.log(`\u23ED\uFE0F Skipping "${moduleName}:${commandName}" \u2014 module has no CLI commands`);
|
|
299
321
|
}
|
|
300
|
-
return;
|
|
322
|
+
return false;
|
|
301
323
|
}
|
|
302
324
|
throw new Error(`Module "${moduleName}" has no CLI commands`);
|
|
303
325
|
}
|
|
@@ -307,11 +329,12 @@ async function runModuleCommand(allModules, moduleName, commandName, args = [],
|
|
|
307
329
|
if (!options.silentOptional) {
|
|
308
330
|
console.log(`\u23ED\uFE0F Skipping "${moduleName}:${commandName}" \u2014 command not found`);
|
|
309
331
|
}
|
|
310
|
-
return;
|
|
332
|
+
return false;
|
|
311
333
|
}
|
|
312
334
|
throw new Error(`Command "${commandName}" not found in module "${moduleName}"`);
|
|
313
335
|
}
|
|
314
336
|
await cmd.run(args);
|
|
337
|
+
return true;
|
|
315
338
|
}
|
|
316
339
|
async function runPostGenerateStructuralCachePurge(quiet) {
|
|
317
340
|
try {
|
|
@@ -629,8 +652,11 @@ async function run(argv = process.argv) {
|
|
|
629
652
|
}
|
|
630
653
|
console.log("\u2705 RBAC setup complete:", { tenantId, organizationId: orgId }, "\n");
|
|
631
654
|
console.log("\u{1F39B}\uFE0F Seeding feature toggle defaults...");
|
|
632
|
-
await runModuleCommand(allModules, "feature_toggles", "seed-defaults", [])
|
|
633
|
-
|
|
655
|
+
if (await runModuleCommand(allModules, "feature_toggles", "seed-defaults", [], { optional: true })) {
|
|
656
|
+
console.log("\u{1F39B}\uFE0F \u2705 Feature toggle defaults seeded\n");
|
|
657
|
+
} else {
|
|
658
|
+
console.log("");
|
|
659
|
+
}
|
|
634
660
|
if (tenantId) {
|
|
635
661
|
console.log("\u{1F465} Seeding tenant-scoped roles...");
|
|
636
662
|
await runModuleCommand(allModules, "auth", "seed-roles", ["--tenant", tenantId]);
|
|
@@ -685,32 +711,47 @@ async function run(argv = process.argv) {
|
|
|
685
711
|
);
|
|
686
712
|
const stressArgs = ["--tenant", tenantId, "--org", orgId, "--count", String(stressTestCount)];
|
|
687
713
|
if (stressTestLite) stressArgs.push("--lite");
|
|
688
|
-
await runModuleCommand(allModules, "customers", "seed-stresstest", stressArgs, { optional: true })
|
|
689
|
-
|
|
714
|
+
if (await runModuleCommand(allModules, "customers", "seed-stresstest", stressArgs, { optional: true })) {
|
|
715
|
+
console.log(`\u2705 Stress test customers seeded (requested ${stressTestCount})
|
|
690
716
|
`);
|
|
717
|
+
} else {
|
|
718
|
+
console.log("");
|
|
719
|
+
}
|
|
691
720
|
}
|
|
692
721
|
console.log("\u{1F9E9} Enabling default dashboard widgets...");
|
|
693
|
-
await runModuleCommand(allModules, "dashboards", "seed-defaults", ["--tenant", tenantId], { optional: true })
|
|
694
|
-
|
|
722
|
+
if (await runModuleCommand(allModules, "dashboards", "seed-defaults", ["--tenant", tenantId], { optional: true })) {
|
|
723
|
+
console.log("\u2705 Dashboard widgets enabled\n");
|
|
724
|
+
} else {
|
|
725
|
+
console.log("");
|
|
726
|
+
}
|
|
695
727
|
console.log("\u{1F4CA} Enabling analytics widgets for admin and employee roles...");
|
|
696
|
-
await runModuleCommand(allModules, "dashboards", "enable-analytics-widgets", [
|
|
728
|
+
if (await runModuleCommand(allModules, "dashboards", "enable-analytics-widgets", [
|
|
697
729
|
"--tenant",
|
|
698
730
|
tenantId,
|
|
699
731
|
"--roles",
|
|
700
732
|
"admin,employee"
|
|
701
|
-
])
|
|
702
|
-
|
|
733
|
+
], { optional: true })) {
|
|
734
|
+
console.log("\u2705 Analytics widgets enabled for roles\n");
|
|
735
|
+
} else {
|
|
736
|
+
console.log("");
|
|
737
|
+
}
|
|
703
738
|
} else {
|
|
704
739
|
console.log("\u26A0\uFE0F Could not get organization ID or tenant ID, skipping seeding steps\n");
|
|
705
740
|
}
|
|
706
741
|
console.log("\u{1F9E0} Building search indexes...");
|
|
707
742
|
const vectorArgs = tenantId ? ["--tenant", tenantId, ...orgId ? ["--org", orgId] : []] : ["--purgeFirst=false"];
|
|
708
|
-
await runModuleCommand(allModules, "search", "reindex", vectorArgs, { optional: true })
|
|
709
|
-
|
|
743
|
+
if (await runModuleCommand(allModules, "search", "reindex", vectorArgs, { optional: true })) {
|
|
744
|
+
console.log("\u2705 Search indexes built\n");
|
|
745
|
+
} else {
|
|
746
|
+
console.log("");
|
|
747
|
+
}
|
|
710
748
|
console.log("\u{1F50D} Rebuilding query indexes...");
|
|
711
749
|
const queryIndexArgs = ["--force", ...tenantId ? ["--tenant", tenantId] : []];
|
|
712
|
-
await runModuleCommand(allModules, "query_index", "reindex", queryIndexArgs, { optional: true })
|
|
713
|
-
|
|
750
|
+
if (await runModuleCommand(allModules, "query_index", "reindex", queryIndexArgs, { optional: true })) {
|
|
751
|
+
console.log("\u2705 Query indexes rebuilt\n");
|
|
752
|
+
} else {
|
|
753
|
+
console.log("");
|
|
754
|
+
}
|
|
714
755
|
const adminPasswordOverride = derivedSecrets.adminPassword;
|
|
715
756
|
const employeePasswordOverride = derivedSecrets.employeePassword;
|
|
716
757
|
const createdUsers = [];
|
|
@@ -1351,7 +1392,7 @@ async function run(argv = process.argv) {
|
|
|
1351
1392
|
const startNextDev = () => new Promise((resolve) => {
|
|
1352
1393
|
const nextProcess = spawn("node", [nextBin, "dev", "--turbopack"], {
|
|
1353
1394
|
stdio: ["inherit", "pipe", "pipe"],
|
|
1354
|
-
env:
|
|
1395
|
+
env: runtimeEnv,
|
|
1355
1396
|
cwd: appDir
|
|
1356
1397
|
});
|
|
1357
1398
|
processes.push(nextProcess);
|
|
@@ -1372,18 +1413,22 @@ async function run(argv = process.argv) {
|
|
|
1372
1413
|
process.stderr.write(text);
|
|
1373
1414
|
appendOutput(text);
|
|
1374
1415
|
});
|
|
1375
|
-
nextProcess.on("exit", async () => {
|
|
1416
|
+
nextProcess.on("exit", async (code, signal) => {
|
|
1376
1417
|
if (!didRetryCorruptedTurbopackCache && isTurbopackCacheCorruption(combinedOutput)) {
|
|
1377
1418
|
didRetryCorruptedTurbopackCache = true;
|
|
1378
1419
|
console.log("[server] Detected corrupted Turbopack dev cache. Clearing .mercato/next/dev and restarting Next.js once...");
|
|
1379
1420
|
removeTurbopackDevCache(appDir);
|
|
1380
|
-
await startNextDev();
|
|
1381
|
-
return resolve();
|
|
1421
|
+
return resolve(await startNextDev());
|
|
1382
1422
|
}
|
|
1383
|
-
resolve(
|
|
1423
|
+
resolve({
|
|
1424
|
+
label: "Next.js dev server",
|
|
1425
|
+
code,
|
|
1426
|
+
signal
|
|
1427
|
+
});
|
|
1384
1428
|
});
|
|
1385
1429
|
});
|
|
1386
1430
|
const nextExitPromise = startNextDev();
|
|
1431
|
+
const managedExitPromises = [nextExitPromise];
|
|
1387
1432
|
if (autoSpawnWorkers) {
|
|
1388
1433
|
const discoveredWorkerQueues = [...new Set(getRegisteredCliWorkers().map((worker) => worker.queue))];
|
|
1389
1434
|
if (discoveredWorkerQueues.length === 0) {
|
|
@@ -1392,32 +1437,28 @@ async function run(argv = process.argv) {
|
|
|
1392
1437
|
console.log("[server] Starting workers for all queues...");
|
|
1393
1438
|
const workerProcess = spawn("node", [mercatoBin, "queue", "worker", "--all"], {
|
|
1394
1439
|
stdio: "inherit",
|
|
1395
|
-
env:
|
|
1440
|
+
env: runtimeEnv,
|
|
1396
1441
|
cwd: appDir
|
|
1397
1442
|
});
|
|
1398
1443
|
processes.push(workerProcess);
|
|
1444
|
+
managedExitPromises.push(waitForManagedProcessExit(workerProcess, "Queue worker"));
|
|
1399
1445
|
}
|
|
1400
1446
|
}
|
|
1401
1447
|
if (autoSpawnScheduler && queueStrategy === "local") {
|
|
1402
1448
|
console.log("[server] Starting scheduler polling engine...");
|
|
1403
1449
|
const schedulerProcess = spawn("node", [mercatoBin, "scheduler", "start"], {
|
|
1404
1450
|
stdio: "inherit",
|
|
1405
|
-
env:
|
|
1451
|
+
env: runtimeEnv,
|
|
1406
1452
|
cwd: appDir
|
|
1407
1453
|
});
|
|
1408
1454
|
processes.push(schedulerProcess);
|
|
1455
|
+
managedExitPromises.push(waitForManagedProcessExit(schedulerProcess, "Scheduler polling engine"));
|
|
1409
1456
|
}
|
|
1410
|
-
await Promise.race(
|
|
1411
|
-
[
|
|
1412
|
-
nextExitPromise,
|
|
1413
|
-
...processes.filter((proc) => proc.spawnargs[1] !== nextBin).map(
|
|
1414
|
-
(proc) => new Promise((resolve) => {
|
|
1415
|
-
proc.on("exit", () => resolve());
|
|
1416
|
-
})
|
|
1417
|
-
)
|
|
1418
|
-
]
|
|
1419
|
-
);
|
|
1457
|
+
const firstExit = await Promise.race(managedExitPromises);
|
|
1420
1458
|
await cleanupAndWait();
|
|
1459
|
+
if (!isExpectedManagedExitSignal(firstExit.signal)) {
|
|
1460
|
+
throw createManagedProcessExitError(firstExit);
|
|
1461
|
+
}
|
|
1421
1462
|
}
|
|
1422
1463
|
},
|
|
1423
1464
|
{
|