@open-mercato/cli 0.4.9-develop-94fb251ed3 → 0.4.9-develop-8d8db18714

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 (58) hide show
  1. package/dist/agentic/shared/AGENTS.md.template +2 -0
  2. package/dist/agentic/shared/ai/skills/eject-and-customize/SKILL.md +3 -1
  3. package/dist/bin.js +1 -0
  4. package/dist/bin.js.map +2 -2
  5. package/dist/lib/__fixtures__/official-module-package/src/index.js +1 -0
  6. package/dist/lib/__fixtures__/official-module-package/src/index.js.map +7 -0
  7. package/dist/lib/__fixtures__/official-module-package/src/modules/test_package/index.js +10 -0
  8. package/dist/lib/__fixtures__/official-module-package/src/modules/test_package/index.js.map +7 -0
  9. package/dist/lib/eject.js +30 -38
  10. package/dist/lib/eject.js.map +2 -2
  11. package/dist/lib/generators/index.js +2 -0
  12. package/dist/lib/generators/index.js.map +2 -2
  13. package/dist/lib/generators/module-package-sources.js +45 -0
  14. package/dist/lib/generators/module-package-sources.js.map +7 -0
  15. package/dist/lib/module-install-args.js +40 -0
  16. package/dist/lib/module-install-args.js.map +7 -0
  17. package/dist/lib/module-install.js +157 -0
  18. package/dist/lib/module-install.js.map +7 -0
  19. package/dist/lib/module-package.js +245 -0
  20. package/dist/lib/module-package.js.map +7 -0
  21. package/dist/lib/modules-config.js +255 -0
  22. package/dist/lib/modules-config.js.map +7 -0
  23. package/dist/lib/resolver.js +19 -5
  24. package/dist/lib/resolver.js.map +2 -2
  25. package/dist/lib/testing/integration-discovery.js +20 -9
  26. package/dist/lib/testing/integration-discovery.js.map +2 -2
  27. package/dist/lib/testing/integration.js +86 -47
  28. package/dist/lib/testing/integration.js.map +2 -2
  29. package/dist/mercato.js +120 -43
  30. package/dist/mercato.js.map +3 -3
  31. package/package.json +5 -4
  32. package/src/__tests__/mercato.test.ts +6 -1
  33. package/src/bin.ts +1 -0
  34. package/src/lib/__fixtures__/official-module-package/dist/modules/test_package/index.js +2 -0
  35. package/src/lib/__fixtures__/official-module-package/package.json +33 -0
  36. package/src/lib/__fixtures__/official-module-package/src/index.ts +1 -0
  37. package/src/lib/__fixtures__/official-module-package/src/modules/test_package/index.ts +6 -0
  38. package/src/lib/__fixtures__/official-module-package/src/modules/test_package/widgets/injection/test/widget.tsx +3 -0
  39. package/src/lib/__tests__/eject.test.ts +107 -1
  40. package/src/lib/__tests__/module-install-args.test.ts +35 -0
  41. package/src/lib/__tests__/module-install.test.ts +217 -0
  42. package/src/lib/__tests__/module-package.test.ts +215 -0
  43. package/src/lib/__tests__/modules-config.test.ts +104 -0
  44. package/src/lib/__tests__/resolve-environment.test.ts +141 -0
  45. package/src/lib/eject.ts +45 -55
  46. package/src/lib/generators/__tests__/generators.test.ts +11 -0
  47. package/src/lib/generators/__tests__/module-package-sources.test.ts +121 -0
  48. package/src/lib/generators/index.ts +1 -0
  49. package/src/lib/generators/module-package-sources.ts +59 -0
  50. package/src/lib/module-install-args.ts +50 -0
  51. package/src/lib/module-install.ts +234 -0
  52. package/src/lib/module-package.ts +355 -0
  53. package/src/lib/modules-config.ts +393 -0
  54. package/src/lib/resolver.ts +46 -4
  55. package/src/lib/testing/__tests__/integration-discovery.test.ts +30 -0
  56. package/src/lib/testing/integration-discovery.ts +23 -8
  57. package/src/lib/testing/integration.ts +97 -57
  58. package/src/mercato.ts +128 -49
package/dist/mercato.js CHANGED
@@ -5,6 +5,7 @@ import { parseBooleanToken } from "@open-mercato/shared/lib/boolean";
5
5
  import { getSslConfig } from "@open-mercato/shared/lib/db/ssl";
6
6
  import { getRedisUrl } from "@open-mercato/shared/lib/redis/connection";
7
7
  import { resolveInitDerivedSecrets } from "./lib/init-secrets.js";
8
+ import { parseModuleInstallArgs } from "./lib/module-install-args.js";
8
9
  const lazyIntegration = () => import("./lib/testing/integration.js");
9
10
  import path from "node:path";
10
11
  import fs from "node:fs";
@@ -34,6 +35,49 @@ async function ensureEnvLoaded() {
34
35
  } catch {
35
36
  }
36
37
  }
38
+ function resolveInstalledBinary(baseDirs, relativeBinPath) {
39
+ const checked = /* @__PURE__ */ new Set();
40
+ for (const baseDir of baseDirs) {
41
+ const candidate = path.join(baseDir, "node_modules", relativeBinPath);
42
+ checked.add(candidate);
43
+ if (fs.existsSync(candidate)) return candidate;
44
+ }
45
+ throw new Error(
46
+ `Could not find installed binary "${relativeBinPath}". Checked: ${Array.from(checked).join(", ")}`
47
+ );
48
+ }
49
+ async function handleDirectEjectCommand(args) {
50
+ const { createResolver } = await import("./lib/resolver.js");
51
+ const { listEjectableModules, ejectModule } = await import("./lib/eject.js");
52
+ const resolver = createResolver();
53
+ const commandArgs = args.filter(Boolean);
54
+ const isList = commandArgs.includes("--list") || commandArgs.includes("-l");
55
+ const moduleId = isList ? void 0 : commandArgs.find((arg) => !arg.startsWith("-"));
56
+ if (isList || !moduleId) {
57
+ const ejectable = listEjectableModules(resolver);
58
+ if (ejectable.length === 0) {
59
+ console.log("No ejectable modules found.");
60
+ } else {
61
+ console.log("Ejectable modules:\n");
62
+ for (const mod of ejectable) {
63
+ const desc = mod.description ? ` \u2014 ${mod.description}` : "";
64
+ console.log(` ${mod.id} (from: ${mod.from})${desc}`);
65
+ }
66
+ console.log("\nUsage: yarn mercato eject <moduleId>");
67
+ }
68
+ return 0;
69
+ }
70
+ console.log(`Ejecting module "${moduleId}"...`);
71
+ ejectModule(resolver, moduleId);
72
+ console.log(`
73
+ \u2705 Module "${moduleId}" ejected successfully!
74
+ `);
75
+ console.log("Next steps:");
76
+ console.log(" 1. Run generators: yarn mercato generate all");
77
+ console.log(` 2. Customize: edit src/modules/${moduleId}/`);
78
+ console.log(" 3. Start dev: yarn dev");
79
+ return 0;
80
+ }
37
81
  async function runModuleCommand(allModules, moduleName, commandName, args = [], options = {}) {
38
82
  const mod = allModules.find((m) => m.id === moduleName);
39
83
  if (!mod) {
@@ -226,13 +270,14 @@ async function run(argv = process.argv) {
226
270
  }
227
271
  console.log("\u{1F527} Preparing modules (registry, entities, DI)...");
228
272
  const { createResolver } = await import("./lib/resolver.js");
229
- const { generateEntityIds, generateModuleRegistry, generateModuleRegistryCli, generateModuleEntities, generateModuleDi, generateOpenApi } = await import("./lib/generators/index.js");
273
+ const { generateEntityIds, generateModuleRegistry, generateModuleRegistryCli, generateModuleEntities, generateModuleDi, generateModulePackageSources, generateOpenApi } = await import("./lib/generators/index.js");
230
274
  const resolver = createResolver();
231
275
  await generateEntityIds({ resolver, quiet: true });
232
276
  await generateModuleRegistry({ resolver, quiet: true });
233
277
  await generateModuleRegistryCli({ resolver, quiet: true });
234
278
  await generateModuleEntities({ resolver, quiet: true });
235
279
  await generateModuleDi({ resolver, quiet: true });
280
+ await generateModulePackageSources({ resolver, quiet: true });
236
281
  await generateOpenApi({ resolver, quiet: true });
237
282
  console.log("\u2705 Modules prepared\n");
238
283
  console.log("\u{1F4CA} Applying database migrations...");
@@ -439,37 +484,66 @@ async function run(argv = process.argv) {
439
484
  const exitCode = await runAgenticInit(parts.slice(1));
440
485
  return exitCode;
441
486
  }
442
- if (first === "eject") {
487
+ if (first === "module") {
443
488
  try {
444
- const { createResolver } = await import("./lib/resolver.js");
445
- const { listEjectableModules, ejectModule } = await import("./lib/eject.js");
446
- const resolver = createResolver();
447
- const isList = second === "--list" || second === "-l";
448
- const moduleId = !isList ? second : void 0;
449
- if (isList || !moduleId) {
450
- const ejectable = listEjectableModules(resolver);
451
- if (ejectable.length === 0) {
452
- console.log("No ejectable modules found.");
453
- } else {
454
- console.log("Ejectable modules:\n");
455
- for (const mod2 of ejectable) {
456
- const desc = mod2.description ? ` \u2014 ${mod2.description}` : "";
457
- console.log(` ${mod2.id} (from: ${mod2.from})${desc}`);
458
- }
459
- console.log("\nUsage: yarn mercato eject <moduleId>");
489
+ const subcommand = second;
490
+ const commandArgs = remaining.filter(Boolean);
491
+ if (!subcommand || subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
492
+ console.log("Usage: yarn mercato module <add|enable|eject> ...");
493
+ console.log(" yarn mercato module add <packageSpec> [--module <moduleId>] [--eject]");
494
+ console.log(" yarn mercato module enable <packageName> [--module <moduleId>] [--eject]");
495
+ console.log(" yarn mercato module eject <moduleId>");
496
+ return 0;
497
+ }
498
+ if (subcommand === "add") {
499
+ const { createResolver } = await import("./lib/resolver.js");
500
+ const { addOfficialModule } = await import("./lib/module-install.js");
501
+ const { packageSpec, eject, moduleId } = parseModuleInstallArgs(commandArgs);
502
+ if (!packageSpec) {
503
+ console.error("Usage: yarn mercato module add <packageSpec> [--module <moduleId>] [--eject]");
504
+ return 1;
460
505
  }
506
+ const result = await addOfficialModule(createResolver(), packageSpec, eject, moduleId ?? void 0);
507
+ console.log(`
508
+ \u2705 Module "${result.moduleId}" enabled from ${result.from}.
509
+ `);
510
+ console.log("Next steps:");
511
+ console.log(" 1. Review generated files if needed: .mercato/generated/");
512
+ console.log(" 2. Start dev: yarn dev");
461
513
  return 0;
462
514
  }
463
- console.log(`Ejecting module "${moduleId}"...`);
464
- ejectModule(resolver, moduleId);
465
- console.log(`
466
- \u2705 Module "${moduleId}" ejected successfully!
515
+ if (subcommand === "enable") {
516
+ const packageName = commandArgs.find((arg) => !arg.startsWith("-"));
517
+ if (!packageName) {
518
+ console.error("Usage: yarn mercato module enable <packageName> [--module <moduleId>] [--eject]");
519
+ return 1;
520
+ }
521
+ const { createResolver } = await import("./lib/resolver.js");
522
+ const { enableOfficialModule } = await import("./lib/module-install.js");
523
+ const { moduleId, eject } = parseModuleInstallArgs(commandArgs);
524
+ const result = await enableOfficialModule(createResolver(), packageName, moduleId ?? void 0, eject);
525
+ console.log(`
526
+ \u2705 Module "${result.moduleId}" enabled from ${result.from}.
467
527
  `);
468
- console.log("Next steps:");
469
- console.log(" 1. Run generators: yarn mercato generate all");
470
- console.log(` 2. Customize: edit src/modules/${moduleId}/`);
471
- console.log(" 3. Start dev: yarn dev");
472
- return 0;
528
+ console.log("Next steps:");
529
+ console.log(" 1. Review generated files if needed: .mercato/generated/");
530
+ console.log(" 2. Start dev: yarn dev");
531
+ return 0;
532
+ }
533
+ if (subcommand === "eject") {
534
+ return handleDirectEjectCommand(commandArgs);
535
+ }
536
+ console.error(`Unknown module subcommand "${subcommand}".`);
537
+ return 1;
538
+ } catch (error) {
539
+ const message = error instanceof Error ? error.message : String(error);
540
+ console.error(`\u274C Module command failed: ${message}`);
541
+ return 1;
542
+ }
543
+ }
544
+ if (first === "eject") {
545
+ try {
546
+ return handleDirectEjectCommand(parts.slice(1));
473
547
  } catch (error) {
474
548
  const message = error instanceof Error ? error.message : String(error);
475
549
  console.error(`\u274C Eject failed: ${message}`);
@@ -735,7 +809,7 @@ async function run(argv = process.argv) {
735
809
  command: "all",
736
810
  run: async (args) => {
737
811
  const { createResolver } = await import("./lib/resolver.js");
738
- const { generateEntityIds, generateModuleRegistry, generateModuleRegistryCli, generateModuleEntities, generateModuleDi, generateOpenApi } = await import("./lib/generators/index.js");
812
+ const { generateEntityIds, generateModuleRegistry, generateModuleRegistryCli, generateModuleEntities, generateModuleDi, generateModulePackageSources, generateOpenApi } = await import("./lib/generators/index.js");
739
813
  const resolver = createResolver();
740
814
  const quiet = args.includes("--quiet") || args.includes("-q");
741
815
  console.log("Running all generators...");
@@ -744,6 +818,7 @@ async function run(argv = process.argv) {
744
818
  await generateModuleRegistryCli({ resolver, quiet });
745
819
  await generateModuleEntities({ resolver, quiet });
746
820
  await generateModuleDi({ resolver, quiet });
821
+ await generateModulePackageSources({ resolver, quiet });
747
822
  await generateOpenApi({ resolver, quiet });
748
823
  console.log("All generators completed.");
749
824
  }
@@ -761,9 +836,10 @@ async function run(argv = process.argv) {
761
836
  command: "registry",
762
837
  run: async (args) => {
763
838
  const { createResolver } = await import("./lib/resolver.js");
764
- const { generateModuleRegistry } = await import("./lib/generators/index.js");
839
+ const { generateModulePackageSources, generateModuleRegistry } = await import("./lib/generators/index.js");
765
840
  const resolver = createResolver();
766
841
  await generateModuleRegistry({ resolver, quiet: args.includes("--quiet") });
842
+ await generateModulePackageSources({ resolver, quiet: args.includes("--quiet") });
767
843
  }
768
844
  },
769
845
  {
@@ -826,11 +902,10 @@ async function run(argv = process.argv) {
826
902
  command: "dev",
827
903
  run: async () => {
828
904
  const { spawn } = await import("child_process");
829
- const path2 = await import("path");
830
- const { createResolver } = await import("./lib/resolver.js");
831
- const resolver = createResolver();
832
- const appDir = resolver.getAppDir();
833
- const nodeModulesBase = resolver.isMonorepo() ? resolver.getRootDir() : appDir;
905
+ const { resolveEnvironment } = await import("./lib/resolver.js");
906
+ const env = resolveEnvironment();
907
+ const appDir = env.appDir;
908
+ const nodeModulesBases = Array.from(/* @__PURE__ */ new Set([env.rootDir, appDir]));
834
909
  const processes = [];
835
910
  const autoSpawnWorkers = process.env.AUTO_SPAWN_WORKERS !== "false";
836
911
  const autoSpawnScheduler = process.env.AUTO_SPAWN_SCHEDULER !== "false";
@@ -846,8 +921,11 @@ async function run(argv = process.argv) {
846
921
  process.on("SIGTERM", cleanup);
847
922
  process.on("SIGINT", cleanup);
848
923
  console.log("[server] Starting Open Mercato in dev mode...");
849
- const nextBin = path2.join(nodeModulesBase, "node_modules/next/dist/bin/next");
850
- const mercatoBin = path2.join(nodeModulesBase, "node_modules/@open-mercato/cli/bin/mercato");
924
+ const { createResolver: createResolverForSources } = await import("./lib/resolver.js");
925
+ const { generateModulePackageSources } = await import("./lib/generators/index.js");
926
+ await generateModulePackageSources({ resolver: createResolverForSources(), quiet: true });
927
+ const nextBin = resolveInstalledBinary(nodeModulesBases, "next/dist/bin/next");
928
+ const mercatoBin = resolveInstalledBinary(nodeModulesBases, "@open-mercato/cli/bin/mercato");
851
929
  const nextProcess = spawn("node", [nextBin, "dev", "--turbopack"], {
852
930
  stdio: "inherit",
853
931
  env: process.env,
@@ -886,11 +964,10 @@ async function run(argv = process.argv) {
886
964
  command: "start",
887
965
  run: async () => {
888
966
  const { spawn } = await import("child_process");
889
- const path2 = await import("path");
890
- const { createResolver } = await import("./lib/resolver.js");
891
- const resolver = createResolver();
892
- const appDir = resolver.getAppDir();
893
- const nodeModulesBase = resolver.isMonorepo() ? resolver.getRootDir() : appDir;
967
+ const { resolveEnvironment } = await import("./lib/resolver.js");
968
+ const env = resolveEnvironment();
969
+ const appDir = env.appDir;
970
+ const nodeModulesBases = Array.from(/* @__PURE__ */ new Set([env.rootDir, appDir]));
894
971
  const processes = [];
895
972
  const autoSpawnWorkers = process.env.AUTO_SPAWN_WORKERS !== "false";
896
973
  const autoSpawnScheduler = process.env.AUTO_SPAWN_SCHEDULER !== "false";
@@ -906,8 +983,8 @@ async function run(argv = process.argv) {
906
983
  process.on("SIGTERM", cleanup);
907
984
  process.on("SIGINT", cleanup);
908
985
  console.log("[server] Starting Open Mercato in production mode...");
909
- const nextBin = path2.join(nodeModulesBase, "node_modules/next/dist/bin/next");
910
- const mercatoBin = path2.join(nodeModulesBase, "node_modules/@open-mercato/cli/bin/mercato");
986
+ const nextBin = resolveInstalledBinary(nodeModulesBases, "next/dist/bin/next");
987
+ const mercatoBin = resolveInstalledBinary(nodeModulesBases, "@open-mercato/cli/bin/mercato");
911
988
  const nextProcess = spawn("node", [nextBin, "start"], {
912
989
  stdio: "inherit",
913
990
  env: process.env,