@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.
- package/dist/agentic/shared/AGENTS.md.template +2 -0
- package/dist/agentic/shared/ai/skills/eject-and-customize/SKILL.md +3 -1
- package/dist/bin.js +1 -0
- package/dist/bin.js.map +2 -2
- package/dist/lib/__fixtures__/official-module-package/src/index.js +1 -0
- package/dist/lib/__fixtures__/official-module-package/src/index.js.map +7 -0
- package/dist/lib/__fixtures__/official-module-package/src/modules/test_package/index.js +10 -0
- package/dist/lib/__fixtures__/official-module-package/src/modules/test_package/index.js.map +7 -0
- package/dist/lib/eject.js +30 -38
- package/dist/lib/eject.js.map +2 -2
- package/dist/lib/generators/index.js +2 -0
- package/dist/lib/generators/index.js.map +2 -2
- package/dist/lib/generators/module-package-sources.js +45 -0
- package/dist/lib/generators/module-package-sources.js.map +7 -0
- package/dist/lib/module-install-args.js +40 -0
- package/dist/lib/module-install-args.js.map +7 -0
- package/dist/lib/module-install.js +157 -0
- package/dist/lib/module-install.js.map +7 -0
- package/dist/lib/module-package.js +245 -0
- package/dist/lib/module-package.js.map +7 -0
- package/dist/lib/modules-config.js +255 -0
- package/dist/lib/modules-config.js.map +7 -0
- package/dist/lib/resolver.js +19 -5
- package/dist/lib/resolver.js.map +2 -2
- package/dist/lib/testing/integration-discovery.js +20 -9
- package/dist/lib/testing/integration-discovery.js.map +2 -2
- package/dist/lib/testing/integration.js +86 -47
- package/dist/lib/testing/integration.js.map +2 -2
- package/dist/mercato.js +120 -43
- package/dist/mercato.js.map +3 -3
- package/package.json +5 -4
- package/src/__tests__/mercato.test.ts +6 -1
- package/src/bin.ts +1 -0
- package/src/lib/__fixtures__/official-module-package/dist/modules/test_package/index.js +2 -0
- package/src/lib/__fixtures__/official-module-package/package.json +33 -0
- package/src/lib/__fixtures__/official-module-package/src/index.ts +1 -0
- package/src/lib/__fixtures__/official-module-package/src/modules/test_package/index.ts +6 -0
- package/src/lib/__fixtures__/official-module-package/src/modules/test_package/widgets/injection/test/widget.tsx +3 -0
- package/src/lib/__tests__/eject.test.ts +107 -1
- package/src/lib/__tests__/module-install-args.test.ts +35 -0
- package/src/lib/__tests__/module-install.test.ts +217 -0
- package/src/lib/__tests__/module-package.test.ts +215 -0
- package/src/lib/__tests__/modules-config.test.ts +104 -0
- package/src/lib/__tests__/resolve-environment.test.ts +141 -0
- package/src/lib/eject.ts +45 -55
- package/src/lib/generators/__tests__/generators.test.ts +11 -0
- package/src/lib/generators/__tests__/module-package-sources.test.ts +121 -0
- package/src/lib/generators/index.ts +1 -0
- package/src/lib/generators/module-package-sources.ts +59 -0
- package/src/lib/module-install-args.ts +50 -0
- package/src/lib/module-install.ts +234 -0
- package/src/lib/module-package.ts +355 -0
- package/src/lib/modules-config.ts +393 -0
- package/src/lib/resolver.ts +46 -4
- package/src/lib/testing/__tests__/integration-discovery.test.ts +30 -0
- package/src/lib/testing/integration-discovery.ts +23 -8
- package/src/lib/testing/integration.ts +97 -57
- package/src/mercato.ts +128 -49
|
@@ -7,6 +7,7 @@ Do NOT load the entire src/ tree — Open Mercato apps can have many modules.
|
|
|
7
7
|
|
|
8
8
|
A standalone Open Mercato application built ON TOP of the framework.
|
|
9
9
|
The framework lives in `node_modules/@open-mercato/*`. Never edit `node_modules` directly.
|
|
10
|
+
Install official packages with `yarn mercato module add @open-mercato/<package>`.
|
|
10
11
|
To customise a built-in module beyond extensions, eject with `yarn mercato eject <module>`.
|
|
11
12
|
|
|
12
13
|
## Task → Context Map
|
|
@@ -158,6 +159,7 @@ import type { ApiInterceptor } from '@open-mercato/shared/lib/crud/api-intercept
|
|
|
158
159
|
|---|---|
|
|
159
160
|
| `yarn dev` | Start dev server |
|
|
160
161
|
| `yarn generate` | Regenerate `.mercato/generated/` |
|
|
162
|
+
| `yarn mercato module add <package>` | Install and enable an official module package |
|
|
161
163
|
| `yarn db:generate` | Create migration for entity changes |
|
|
162
164
|
| `yarn db:migrate` | Apply pending migrations |
|
|
163
165
|
| `yarn initialize` | Bootstrap DB + first admin account |
|
|
@@ -99,11 +99,13 @@ Save this in `.ai/specs/` or a project README for future reference.
|
|
|
99
99
|
### Run the Eject Command
|
|
100
100
|
|
|
101
101
|
```bash
|
|
102
|
-
yarn mercato eject <module-id>
|
|
102
|
+
yarn mercato module eject <module-id>
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
This copies the module from `node_modules/@open-mercato/core/dist/modules/<module-id>/` to `src/modules/<module-id>/`.
|
|
106
106
|
|
|
107
|
+
The legacy alias `yarn mercato eject <module-id>` remains supported.
|
|
108
|
+
|
|
107
109
|
### Post-Ejection Steps
|
|
108
110
|
|
|
109
111
|
```bash
|
package/dist/bin.js
CHANGED
package/dist/bin.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/bin.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * CLI binary entry point for @open-mercato/cli package.\n *\n * Called from within a Next.js app directory as: yarn mercato <command>\n * Uses dynamic app resolution to find generated files at .mercato/generated/\n */\nimport { run } from './mercato.js'\n\n// Commands that can run without bootstrap (without generated files)\n// - generate: creates the generated files\n// - db: uses resolver directly to find modules and migrations\n// - init: runs yarn commands to set up the app\n// - help: just shows help text\nconst BOOTSTRAP_FREE_COMMANDS = [\n 'generate',\n 'db',\n 'init',\n 'eject',\n 'test',\n 'test:integration',\n 'test:integration:coverage',\n 'test:integration:spec-coverage',\n 'test:ephemeral',\n 'test:integration:interactive',\n 'umes:list',\n 'umes:inspect',\n 'umes:check',\n 'help',\n '--help',\n '-h',\n]\n\nfunction assertNode24Runtime(): void {\n const detectedNodeVersion = process.versions.node\n const majorVersion = Number.parseInt(detectedNodeVersion.split('.')[0] ?? '0', 10)\n if (majorVersion >= 24) {\n return\n }\n throw new Error(\n [\n 'Unsupported Node.js runtime.',\n `Cause: Detected Node ${detectedNodeVersion}, but Open Mercato requires Node 24.x.`,\n 'What to do: switch your shell to Node 24 (for example `nvm use 24`), run `yarn install`, then retry.',\n ].join(' '),\n )\n}\n\nfunction needsBootstrap(argv: string[]): boolean {\n const [, , first] = argv\n if (!first) return false // help screen\n return !BOOTSTRAP_FREE_COMMANDS.includes(first)\n}\n\nasync function tryBootstrap(): Promise<boolean> {\n try {\n const { bootstrapFromAppRoot } = await import('@open-mercato/shared/lib/bootstrap/dynamicLoader')\n const { registerCliModules } = await import('./mercato.js')\n // Use the CLI resolver to find the app directory (handles monorepo detection)\n const { createResolver } = await import('./lib/resolver.js')\n const resolver = createResolver()\n const appDir = resolver.getAppDir()\n const data = await bootstrapFromAppRoot(appDir)\n // Register CLI modules directly to avoid module resolution issues\n registerCliModules(data.modules)\n return true\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n // Check if the error is about missing generated files\n if (\n message.includes('Cannot find module') &&\n (message.includes('/generated/') || message.includes('.generated') || message.includes('.mercato'))\n ) {\n return false\n }\n // Re-throw other errors\n throw err\n }\n}\n\nasync function main(): Promise<void> {\n assertNode24Runtime()\n const requiresBootstrap = needsBootstrap(process.argv)\n\n if (requiresBootstrap) {\n const bootstrapSucceeded = await tryBootstrap()\n if (!bootstrapSucceeded) {\n console.error('\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557')\n console.error('\u2551 Generated files not found! \u2551')\n console.error('\u2551 \u2551')\n console.error('\u2551 The CLI requires generated files to discover modules. \u2551')\n console.error('\u2551 Please run the following command first: \u2551')\n console.error('\u2551 \u2551')\n console.error('\u2551 yarn mercato generate \u2551')\n console.error('\u2551 \u2551')\n console.error('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D')\n process.exit(1)\n }\n }\n\n const code = await run(process.argv)\n process.exit(code ?? 0)\n}\n\nmain().catch((error: unknown) => {\n if (error instanceof Error) {\n console.error(error.message)\n } else {\n console.error(error)\n }\n process.exit(1)\n})\n"],
|
|
5
|
-
"mappings": "AAMA,SAAS,WAAW;AAOpB,MAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,sBAA4B;AACnC,QAAM,sBAAsB,QAAQ,SAAS;AAC7C,QAAM,eAAe,OAAO,SAAS,oBAAoB,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE;AACjF,MAAI,gBAAgB,IAAI;AACtB;AAAA,EACF;AACA,QAAM,IAAI;AAAA,IACR;AAAA,MACE;AAAA,MACA,wBAAwB,mBAAmB;AAAA,MAC3C;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,EACZ;AACF;AAEA,SAAS,eAAe,MAAyB;AAC/C,QAAM,CAAC,EAAE,EAAE,KAAK,IAAI;AACpB,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,CAAC,wBAAwB,SAAS,KAAK;AAChD;AAEA,eAAe,eAAiC;AAC9C,MAAI;AACF,UAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,kDAAkD;AAChG,UAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,cAAc;AAE1D,UAAM,EAAE,eAAe,IAAI,MAAM,OAAO,mBAAmB;AAC3D,UAAM,WAAW,eAAe;AAChC,UAAM,SAAS,SAAS,UAAU;AAClC,UAAM,OAAO,MAAM,qBAAqB,MAAM;AAE9C,uBAAmB,KAAK,OAAO;AAC/B,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAE/D,QACE,QAAQ,SAAS,oBAAoB,MACpC,QAAQ,SAAS,aAAa,KAAK,QAAQ,SAAS,YAAY,KAAK,QAAQ,SAAS,UAAU,IACjG;AACA,aAAO;AAAA,IACT;AAEA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,OAAsB;AACnC,sBAAoB;AACpB,QAAM,oBAAoB,eAAe,QAAQ,IAAI;AAErD,MAAI,mBAAmB;AACrB,UAAM,qBAAqB,MAAM,aAAa;AAC9C,QAAI,CAAC,oBAAoB;AACvB,cAAQ,MAAM,gaAAuE;AACrF,cAAQ,MAAM,iFAAuE;AACrF,cAAQ,MAAM,iFAAuE;AACrF,cAAQ,MAAM,gFAAsE;AACpF,cAAQ,MAAM,gFAAsE;AACpF,cAAQ,MAAM,iFAAuE;AACrF,cAAQ,MAAM,gFAAsE;AACpF,cAAQ,MAAM,iFAAuE;AACrF,cAAQ,MAAM,gaAAuE;AACrF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,IAAI,QAAQ,IAAI;AACnC,UAAQ,KAAK,QAAQ,CAAC;AACxB;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,MAAI,iBAAiB,OAAO;AAC1B,YAAQ,MAAM,MAAM,OAAO;AAAA,EAC7B,OAAO;AACL,YAAQ,MAAM,KAAK;AAAA,EACrB;AACA,UAAQ,KAAK,CAAC;AAChB,CAAC;",
|
|
4
|
+
"sourcesContent": ["/**\n * CLI binary entry point for @open-mercato/cli package.\n *\n * Called from within a Next.js app directory as: yarn mercato <command>\n * Uses dynamic app resolution to find generated files at .mercato/generated/\n */\nimport { run } from './mercato.js'\n\n// Commands that can run without bootstrap (without generated files)\n// - generate: creates the generated files\n// - db: uses resolver directly to find modules and migrations\n// - init: runs yarn commands to set up the app\n// - help: just shows help text\nconst BOOTSTRAP_FREE_COMMANDS = [\n 'generate',\n 'module',\n 'db',\n 'init',\n 'eject',\n 'test',\n 'test:integration',\n 'test:integration:coverage',\n 'test:integration:spec-coverage',\n 'test:ephemeral',\n 'test:integration:interactive',\n 'umes:list',\n 'umes:inspect',\n 'umes:check',\n 'help',\n '--help',\n '-h',\n]\n\nfunction assertNode24Runtime(): void {\n const detectedNodeVersion = process.versions.node\n const majorVersion = Number.parseInt(detectedNodeVersion.split('.')[0] ?? '0', 10)\n if (majorVersion >= 24) {\n return\n }\n throw new Error(\n [\n 'Unsupported Node.js runtime.',\n `Cause: Detected Node ${detectedNodeVersion}, but Open Mercato requires Node 24.x.`,\n 'What to do: switch your shell to Node 24 (for example `nvm use 24`), run `yarn install`, then retry.',\n ].join(' '),\n )\n}\n\nfunction needsBootstrap(argv: string[]): boolean {\n const [, , first] = argv\n if (!first) return false // help screen\n return !BOOTSTRAP_FREE_COMMANDS.includes(first)\n}\n\nasync function tryBootstrap(): Promise<boolean> {\n try {\n const { bootstrapFromAppRoot } = await import('@open-mercato/shared/lib/bootstrap/dynamicLoader')\n const { registerCliModules } = await import('./mercato.js')\n // Use the CLI resolver to find the app directory (handles monorepo detection)\n const { createResolver } = await import('./lib/resolver.js')\n const resolver = createResolver()\n const appDir = resolver.getAppDir()\n const data = await bootstrapFromAppRoot(appDir)\n // Register CLI modules directly to avoid module resolution issues\n registerCliModules(data.modules)\n return true\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n // Check if the error is about missing generated files\n if (\n message.includes('Cannot find module') &&\n (message.includes('/generated/') || message.includes('.generated') || message.includes('.mercato'))\n ) {\n return false\n }\n // Re-throw other errors\n throw err\n }\n}\n\nasync function main(): Promise<void> {\n assertNode24Runtime()\n const requiresBootstrap = needsBootstrap(process.argv)\n\n if (requiresBootstrap) {\n const bootstrapSucceeded = await tryBootstrap()\n if (!bootstrapSucceeded) {\n console.error('\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557')\n console.error('\u2551 Generated files not found! \u2551')\n console.error('\u2551 \u2551')\n console.error('\u2551 The CLI requires generated files to discover modules. \u2551')\n console.error('\u2551 Please run the following command first: \u2551')\n console.error('\u2551 \u2551')\n console.error('\u2551 yarn mercato generate \u2551')\n console.error('\u2551 \u2551')\n console.error('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D')\n process.exit(1)\n }\n }\n\n const code = await run(process.argv)\n process.exit(code ?? 0)\n}\n\nmain().catch((error: unknown) => {\n if (error instanceof Error) {\n console.error(error.message)\n } else {\n console.error(error)\n }\n process.exit(1)\n})\n"],
|
|
5
|
+
"mappings": "AAMA,SAAS,WAAW;AAOpB,MAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,sBAA4B;AACnC,QAAM,sBAAsB,QAAQ,SAAS;AAC7C,QAAM,eAAe,OAAO,SAAS,oBAAoB,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE;AACjF,MAAI,gBAAgB,IAAI;AACtB;AAAA,EACF;AACA,QAAM,IAAI;AAAA,IACR;AAAA,MACE;AAAA,MACA,wBAAwB,mBAAmB;AAAA,MAC3C;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,EACZ;AACF;AAEA,SAAS,eAAe,MAAyB;AAC/C,QAAM,CAAC,EAAE,EAAE,KAAK,IAAI;AACpB,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,CAAC,wBAAwB,SAAS,KAAK;AAChD;AAEA,eAAe,eAAiC;AAC9C,MAAI;AACF,UAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,kDAAkD;AAChG,UAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,cAAc;AAE1D,UAAM,EAAE,eAAe,IAAI,MAAM,OAAO,mBAAmB;AAC3D,UAAM,WAAW,eAAe;AAChC,UAAM,SAAS,SAAS,UAAU;AAClC,UAAM,OAAO,MAAM,qBAAqB,MAAM;AAE9C,uBAAmB,KAAK,OAAO;AAC/B,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAE/D,QACE,QAAQ,SAAS,oBAAoB,MACpC,QAAQ,SAAS,aAAa,KAAK,QAAQ,SAAS,YAAY,KAAK,QAAQ,SAAS,UAAU,IACjG;AACA,aAAO;AAAA,IACT;AAEA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,OAAsB;AACnC,sBAAoB;AACpB,QAAM,oBAAoB,eAAe,QAAQ,IAAI;AAErD,MAAI,mBAAmB;AACrB,UAAM,qBAAqB,MAAM,aAAa;AAC9C,QAAI,CAAC,oBAAoB;AACvB,cAAQ,MAAM,gaAAuE;AACrF,cAAQ,MAAM,iFAAuE;AACrF,cAAQ,MAAM,iFAAuE;AACrF,cAAQ,MAAM,gFAAsE;AACpF,cAAQ,MAAM,gFAAsE;AACpF,cAAQ,MAAM,iFAAuE;AACrF,cAAQ,MAAM,gFAAsE;AACpF,cAAQ,MAAM,iFAAuE;AACrF,cAAQ,MAAM,gaAAuE;AACrF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,IAAI,QAAQ,IAAI;AACnC,UAAQ,KAAK,QAAQ,CAAC;AACxB;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,MAAI,iBAAiB,OAAO;AAC1B,YAAQ,MAAM,MAAM,OAAO;AAAA,EAC7B,OAAO;AACL,YAAQ,MAAM,KAAK;AAAA,EACrB;AACA,UAAQ,KAAK,CAAC;AAChB,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../../src/lib/__fixtures__/official-module-package/src/modules/test_package/index.ts"],
|
|
4
|
+
"sourcesContent": ["export const metadata = {\n id: 'test_package',\n title: 'Test Package',\n description: 'Fixture official module package for CLI install tests.',\n ejectable: true,\n}\n"],
|
|
5
|
+
"mappings": "AAAO,MAAM,WAAW;AAAA,EACtB,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,aAAa;AAAA,EACb,WAAW;AACb;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/lib/eject.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
+
import { setModuleRegistrationSource } from "./modules-config.js";
|
|
4
|
+
import { resolveInstalledOfficialModulePackage } from "./module-package.js";
|
|
3
5
|
const SKIP_DIRS = /* @__PURE__ */ new Set(["__tests__", "__mocks__", "node_modules"]);
|
|
4
6
|
const SOURCE_FILE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
7
|
+
function shouldSkipEntryName(name) {
|
|
8
|
+
return SKIP_DIRS.has(name) || name === ".DS_Store" || name.startsWith("._");
|
|
9
|
+
}
|
|
5
10
|
function collectSourceFiles(dir) {
|
|
6
11
|
const files = [];
|
|
7
12
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
8
13
|
for (const entry of entries) {
|
|
9
|
-
if (
|
|
14
|
+
if (shouldSkipEntryName(entry.name)) continue;
|
|
10
15
|
const fullPath = path.join(dir, entry.name);
|
|
11
16
|
if (entry.isDirectory()) {
|
|
12
17
|
files.push(...collectSourceFiles(fullPath));
|
|
@@ -114,7 +119,7 @@ function copyDirRecursive(src, dest) {
|
|
|
114
119
|
fs.mkdirSync(dest, { recursive: true });
|
|
115
120
|
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
116
121
|
for (const entry of entries) {
|
|
117
|
-
if (
|
|
122
|
+
if (shouldSkipEntryName(entry.name)) continue;
|
|
118
123
|
const srcPath = path.join(src, entry.name);
|
|
119
124
|
const destPath = path.join(dest, entry.name);
|
|
120
125
|
if (entry.isDirectory()) {
|
|
@@ -125,47 +130,35 @@ function copyDirRecursive(src, dest) {
|
|
|
125
130
|
}
|
|
126
131
|
}
|
|
127
132
|
function updateModulesTs(modulesPath, moduleId) {
|
|
128
|
-
|
|
129
|
-
throw new Error(`modules.ts not found at ${modulesPath}`);
|
|
130
|
-
}
|
|
131
|
-
const source = fs.readFileSync(modulesPath, "utf8");
|
|
132
|
-
const objectPattern = /\{[^{}]*\}/g;
|
|
133
|
-
let match;
|
|
134
|
-
let updatedSource = null;
|
|
135
|
-
while ((match = objectPattern.exec(source)) !== null) {
|
|
136
|
-
const objectLiteral = match[0];
|
|
137
|
-
const idMatch = objectLiteral.match(/\bid\s*:\s*(['"])([^'"]+)\1/);
|
|
138
|
-
if (!idMatch || idMatch[2] !== moduleId) {
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
const updatedObject = upsertModuleSource(objectLiteral);
|
|
142
|
-
updatedSource = source.slice(0, match.index) + updatedObject + source.slice(match.index + objectLiteral.length);
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
if (!updatedSource) {
|
|
146
|
-
throw new Error(
|
|
147
|
-
`Could not find module entry for "${moduleId}" in ${modulesPath}. Expected a pattern like: { id: '${moduleId}', from: '...' } or { id: '${moduleId}' }`
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
fs.writeFileSync(modulesPath, updatedSource);
|
|
133
|
+
setModuleRegistrationSource(modulesPath, moduleId, "@app");
|
|
151
134
|
}
|
|
152
|
-
function
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if (
|
|
157
|
-
return
|
|
135
|
+
function resolveModuleSource(resolver, entry) {
|
|
136
|
+
const { pkgBase } = resolver.getModulePaths(entry);
|
|
137
|
+
const fallbackMetadata = parseModuleMetadata(path.join(pkgBase, "index.ts"));
|
|
138
|
+
const from = entry.from || "@open-mercato/core";
|
|
139
|
+
if (from === "@app" || from === "@open-mercato/core") {
|
|
140
|
+
return { pkgBase, metadata: fallbackMetadata };
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const modulePackage = resolveInstalledOfficialModulePackage(resolver, from, entry.id);
|
|
144
|
+
return {
|
|
145
|
+
pkgBase: modulePackage.sourceModuleDir,
|
|
146
|
+
metadata: {
|
|
147
|
+
ejectable: modulePackage.metadata.ejectable,
|
|
148
|
+
title: modulePackage.moduleInfo.title ?? modulePackage.metadata.moduleId,
|
|
149
|
+
description: modulePackage.moduleInfo.description
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
} catch {
|
|
153
|
+
return { pkgBase, metadata: fallbackMetadata };
|
|
158
154
|
}
|
|
159
|
-
return objectLiteral.replace(/\}\s*$/, ", from: '@app' }");
|
|
160
155
|
}
|
|
161
156
|
function listEjectableModules(resolver) {
|
|
162
157
|
const modules = resolver.loadEnabledModules();
|
|
163
158
|
const ejectable = [];
|
|
164
159
|
for (const entry of modules) {
|
|
165
160
|
if (entry.from === "@app") continue;
|
|
166
|
-
const {
|
|
167
|
-
const indexPath = path.join(pkgBase, "index.ts");
|
|
168
|
-
const metadata = parseModuleMetadata(indexPath);
|
|
161
|
+
const { metadata } = resolveModuleSource(resolver, entry);
|
|
169
162
|
if (metadata.ejectable) {
|
|
170
163
|
ejectable.push({
|
|
171
164
|
id: entry.id,
|
|
@@ -190,14 +183,13 @@ function ejectModule(resolver, moduleId) {
|
|
|
190
183
|
`Module "${moduleId}" is already local (from: '@app'). Nothing to eject.`
|
|
191
184
|
);
|
|
192
185
|
}
|
|
193
|
-
const {
|
|
186
|
+
const { appBase } = resolver.getModulePaths(entry);
|
|
187
|
+
const { pkgBase, metadata } = resolveModuleSource(resolver, entry);
|
|
194
188
|
if (!fs.existsSync(pkgBase)) {
|
|
195
189
|
throw new Error(
|
|
196
190
|
`Package source directory not found: ${pkgBase}. Make sure the package is installed.`
|
|
197
191
|
);
|
|
198
192
|
}
|
|
199
|
-
const indexPath = path.join(pkgBase, "index.ts");
|
|
200
|
-
const metadata = parseModuleMetadata(indexPath);
|
|
201
193
|
if (!metadata.ejectable) {
|
|
202
194
|
throw new Error(
|
|
203
195
|
`Module "${moduleId}" is not marked as ejectable. Only modules with \`ejectable: true\` in their metadata can be ejected.`
|
package/dist/lib/eject.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/eject.ts"],
|
|
4
|
-
"sourcesContent": ["import path from 'node:path'\nimport fs from 'node:fs'\nimport type { PackageResolver, ModuleEntry } from './resolver'\n\ntype ModuleMetadata = {\n ejectable?: boolean\n title?: string\n description?: string\n}\n\nconst SKIP_DIRS = new Set(['__tests__', '__mocks__', 'node_modules'])\nconst SOURCE_FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs']\n\nfunction collectSourceFiles(dir: string): string[] {\n const files: string[] = []\n const entries = fs.readdirSync(dir, { withFileTypes: true })\n for (const entry of entries) {\n if (
|
|
5
|
-
"mappings": "AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;
|
|
4
|
+
"sourcesContent": ["import path from 'node:path'\nimport fs from 'node:fs'\nimport { setModuleRegistrationSource } from './modules-config'\nimport type { PackageResolver, ModuleEntry } from './resolver'\nimport { resolveInstalledOfficialModulePackage } from './module-package'\n\ntype ModuleMetadata = {\n ejectable?: boolean\n title?: string\n description?: string\n}\n\nconst SKIP_DIRS = new Set(['__tests__', '__mocks__', 'node_modules'])\nconst SOURCE_FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs']\n\nfunction shouldSkipEntryName(name: string): boolean {\n return SKIP_DIRS.has(name) || name === '.DS_Store' || name.startsWith('._')\n}\n\nfunction collectSourceFiles(dir: string): string[] {\n const files: string[] = []\n const entries = fs.readdirSync(dir, { withFileTypes: true })\n for (const entry of entries) {\n if (shouldSkipEntryName(entry.name)) continue\n const fullPath = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n files.push(...collectSourceFiles(fullPath))\n continue\n }\n const ext = path.extname(entry.name)\n if (!SOURCE_FILE_EXTENSIONS.includes(ext)) continue\n files.push(fullPath)\n }\n return files\n}\n\nfunction resolveRelativeImportTarget(sourceFile: string, importPath: string): string | null {\n if (!importPath.startsWith('.')) return null\n\n const basePath = path.resolve(path.dirname(sourceFile), importPath)\n const candidates = [basePath]\n\n for (const ext of SOURCE_FILE_EXTENSIONS) {\n candidates.push(`${basePath}${ext}`)\n candidates.push(path.join(basePath, `index${ext}`))\n }\n\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n return candidate\n }\n }\n\n return null\n}\n\nfunction rewriteRelativeSpecifier(\n sourceFile: string,\n specifier: string,\n modulesRoot: string,\n moduleId: string,\n packageName: string,\n): string {\n const resolvedTarget = resolveRelativeImportTarget(sourceFile, specifier)\n if (!resolvedTarget) return specifier\n\n const modulesRootPrefix = `${modulesRoot}${path.sep}`\n if (!resolvedTarget.startsWith(modulesRootPrefix)) return specifier\n\n const relativeFromModules = path.relative(modulesRoot, resolvedTarget)\n let normalizedRelative = relativeFromModules.split(path.sep).join('/')\n const matchedExt = SOURCE_FILE_EXTENSIONS.find((ext) => normalizedRelative.endsWith(ext))\n if (matchedExt) {\n normalizedRelative = normalizedRelative.slice(0, -matchedExt.length)\n }\n if (normalizedRelative.endsWith('/index')) {\n normalizedRelative = normalizedRelative.slice(0, -'/index'.length)\n }\n const segments = normalizedRelative.split('/')\n const targetModuleId = segments[0]\n\n if (!targetModuleId || targetModuleId === moduleId) return specifier\n\n return `${packageName}/modules/${normalizedRelative}`\n}\n\nexport function rewriteCrossModuleImports(\n pkgBase: string,\n appBase: string,\n moduleId: string,\n packageName: string,\n): void {\n const modulesRoot = path.resolve(pkgBase, '..')\n const appFiles = collectSourceFiles(appBase)\n\n for (const appFile of appFiles) {\n const relativePath = path.relative(appBase, appFile)\n const sourceFile = path.join(pkgBase, relativePath)\n\n if (!fs.existsSync(sourceFile)) continue\n\n const content = fs.readFileSync(appFile, 'utf8')\n let updated = content\n\n updated = updated.replace(\n /(\\bfrom\\s*['\"])([^'\"]+)(['\"])/g,\n (_match, prefix: string, specifier: string, suffix: string) => {\n const rewritten = rewriteRelativeSpecifier(\n sourceFile,\n specifier,\n modulesRoot,\n moduleId,\n packageName,\n )\n return `${prefix}${rewritten}${suffix}`\n },\n )\n\n updated = updated.replace(\n /(\\bimport\\s*\\(\\s*['\"])([^'\"]+)(['\"]\\s*\\))/g,\n (_match, prefix: string, specifier: string, suffix: string) => {\n const rewritten = rewriteRelativeSpecifier(\n sourceFile,\n specifier,\n modulesRoot,\n moduleId,\n packageName,\n )\n return `${prefix}${rewritten}${suffix}`\n },\n )\n\n if (updated !== content) {\n fs.writeFileSync(appFile, updated)\n }\n }\n}\n\nexport function parseModuleMetadata(indexPath: string): ModuleMetadata {\n if (!fs.existsSync(indexPath)) return {}\n\n const source = fs.readFileSync(indexPath, 'utf8')\n const result: ModuleMetadata = {}\n\n const ejectableMatch = source.match(/ejectable\\s*:\\s*(true|false)/)\n if (ejectableMatch) {\n result.ejectable = ejectableMatch[1] === 'true'\n }\n\n const titleMatch = source.match(/title\\s*:\\s*['\"]([^'\"]+)['\"]/)\n if (titleMatch) {\n result.title = titleMatch[1]\n }\n\n const descMatch = source.match(/description\\s*:\\s*['\"]([^'\"]+)['\"]/)\n if (descMatch) {\n result.description = descMatch[1]\n }\n\n return result\n}\n\nexport function copyDirRecursive(src: string, dest: string): void {\n fs.mkdirSync(dest, { recursive: true })\n\n const entries = fs.readdirSync(src, { withFileTypes: true })\n for (const entry of entries) {\n if (shouldSkipEntryName(entry.name)) continue\n\n const srcPath = path.join(src, entry.name)\n const destPath = path.join(dest, entry.name)\n\n if (entry.isDirectory()) {\n copyDirRecursive(srcPath, destPath)\n } else {\n fs.copyFileSync(srcPath, destPath)\n }\n }\n}\n\nexport function updateModulesTs(modulesPath: string, moduleId: string): void {\n setModuleRegistrationSource(modulesPath, moduleId, '@app')\n}\n\nexport type EjectableModule = {\n id: string\n title?: string\n description?: string\n from: string\n}\n\ntype ResolvedModuleSource = {\n pkgBase: string\n metadata: ModuleMetadata\n}\n\nfunction resolveModuleSource(\n resolver: PackageResolver,\n entry: ModuleEntry,\n): ResolvedModuleSource {\n const { pkgBase } = resolver.getModulePaths(entry)\n const fallbackMetadata = parseModuleMetadata(path.join(pkgBase, 'index.ts'))\n const from = entry.from || '@open-mercato/core'\n\n if (from === '@app' || from === '@open-mercato/core') {\n return { pkgBase, metadata: fallbackMetadata }\n }\n\n try {\n const modulePackage = resolveInstalledOfficialModulePackage(resolver, from, entry.id)\n\n return {\n pkgBase: modulePackage.sourceModuleDir,\n metadata: {\n ejectable: modulePackage.metadata.ejectable,\n title: modulePackage.moduleInfo.title ?? modulePackage.metadata.moduleId,\n description: modulePackage.moduleInfo.description,\n },\n }\n } catch {\n return { pkgBase, metadata: fallbackMetadata }\n }\n}\n\nexport function listEjectableModules(resolver: PackageResolver): EjectableModule[] {\n const modules = resolver.loadEnabledModules()\n const ejectable: EjectableModule[] = []\n\n for (const entry of modules) {\n if (entry.from === '@app') continue\n\n const { metadata } = resolveModuleSource(resolver, entry)\n\n if (metadata.ejectable) {\n ejectable.push({\n id: entry.id,\n title: metadata.title,\n description: metadata.description,\n from: entry.from || '@open-mercato/core',\n })\n }\n }\n\n return ejectable\n}\n\nexport function ejectModule(resolver: PackageResolver, moduleId: string): void {\n const modules = resolver.loadEnabledModules()\n const entry = modules.find((m: ModuleEntry) => m.id === moduleId)\n\n if (!entry) {\n throw new Error(\n `Module \"${moduleId}\" is not listed in src/modules.ts. ` +\n `Available modules: ${modules.map((m: ModuleEntry) => m.id).join(', ')}`,\n )\n }\n\n if (entry.from === '@app') {\n throw new Error(\n `Module \"${moduleId}\" is already local (from: '@app'). Nothing to eject.`,\n )\n }\n\n const { appBase } = resolver.getModulePaths(entry)\n const { pkgBase, metadata } = resolveModuleSource(resolver, entry)\n\n if (!fs.existsSync(pkgBase)) {\n throw new Error(\n `Package source directory not found: ${pkgBase}. ` +\n `Make sure the package is installed.`,\n )\n }\n\n if (!metadata.ejectable) {\n throw new Error(\n `Module \"${moduleId}\" is not marked as ejectable. Only modules with \\`ejectable: true\\` in their metadata can be ejected.`,\n )\n }\n\n if (fs.existsSync(appBase)) {\n throw new Error(\n `Destination directory already exists: ${appBase}. ` +\n `Remove it first or resolve the conflict manually.`,\n )\n }\n\n copyDirRecursive(pkgBase, appBase)\n rewriteCrossModuleImports(pkgBase, appBase, moduleId, entry.from || '@open-mercato/core')\n\n const modulesPath = resolver.getModulesConfigPath()\n updateModulesTs(modulesPath, moduleId)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,11 +2,13 @@ import { generateEntityIds } from "./entity-ids.js";
|
|
|
2
2
|
import { generateModuleRegistry, generateModuleRegistryCli } from "./module-registry.js";
|
|
3
3
|
import { generateModuleEntities } from "./module-entities.js";
|
|
4
4
|
import { generateModuleDi } from "./module-di.js";
|
|
5
|
+
import { generateModulePackageSources } from "./module-package-sources.js";
|
|
5
6
|
import { generateOpenApi } from "./openapi.js";
|
|
6
7
|
export {
|
|
7
8
|
generateEntityIds,
|
|
8
9
|
generateModuleDi,
|
|
9
10
|
generateModuleEntities,
|
|
11
|
+
generateModulePackageSources,
|
|
10
12
|
generateModuleRegistry,
|
|
11
13
|
generateModuleRegistryCli,
|
|
12
14
|
generateOpenApi
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/generators/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { generateEntityIds, type EntityIdsOptions } from './entity-ids'\nexport { generateModuleRegistry, generateModuleRegistryCli, type ModuleRegistryOptions } from './module-registry'\nexport { generateModuleEntities, type ModuleEntitiesOptions } from './module-entities'\nexport { generateModuleDi, type ModuleDiOptions } from './module-di'\nexport { generateOpenApi, type GenerateOpenApiOptions } from './openapi'\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,yBAAgD;AACzD,SAAS,wBAAwB,iCAA6D;AAC9F,SAAS,8BAA0D;AACnE,SAAS,wBAA8C;AACvD,SAAS,uBAAoD;",
|
|
4
|
+
"sourcesContent": ["export { generateEntityIds, type EntityIdsOptions } from './entity-ids'\nexport { generateModuleRegistry, generateModuleRegistryCli, type ModuleRegistryOptions } from './module-registry'\nexport { generateModuleEntities, type ModuleEntitiesOptions } from './module-entities'\nexport { generateModuleDi, type ModuleDiOptions } from './module-di'\nexport { generateModulePackageSources, type ModulePackageSourcesOptions } from './module-package-sources'\nexport { generateOpenApi, type GenerateOpenApiOptions } from './openapi'\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,yBAAgD;AACzD,SAAS,wBAAwB,iCAA6D;AAC9F,SAAS,8BAA0D;AACnE,SAAS,wBAA8C;AACvD,SAAS,oCAAsE;AAC/E,SAAS,uBAAoD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { readOfficialModulePackageFromRoot, resolveInstalledPackageRoot } from "../module-package.js";
|
|
3
|
+
import { calculateStructureChecksum, createGeneratorResult, writeGeneratedFile } from "../utils.js";
|
|
4
|
+
function normalizeCssSourcePath(value) {
|
|
5
|
+
const normalized = value.split(path.sep).join("/");
|
|
6
|
+
return normalized.startsWith(".") ? normalized : `./${normalized}`;
|
|
7
|
+
}
|
|
8
|
+
async function generateModulePackageSources(options) {
|
|
9
|
+
const { resolver, quiet } = options;
|
|
10
|
+
const result = createGeneratorResult();
|
|
11
|
+
const outputDir = resolver.getOutputDir();
|
|
12
|
+
const outFile = path.join(outputDir, "module-package-sources.css");
|
|
13
|
+
const checksumFile = path.join(outputDir, "module-package-sources.checksum");
|
|
14
|
+
const sourcePaths = /* @__PURE__ */ new Set();
|
|
15
|
+
const checksumTargets = [];
|
|
16
|
+
for (const entry of resolver.loadEnabledModules()) {
|
|
17
|
+
if (!entry.from || entry.from === "@app" || entry.from === "@open-mercato/core") continue;
|
|
18
|
+
const packageRoot = resolveInstalledPackageRoot(resolver, entry.from);
|
|
19
|
+
checksumTargets.push(packageRoot);
|
|
20
|
+
let modulePackage;
|
|
21
|
+
try {
|
|
22
|
+
modulePackage = readOfficialModulePackageFromRoot(packageRoot, entry.from, entry.id);
|
|
23
|
+
} catch {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const packageSourceRoot = path.join(modulePackage.packageRoot, "src");
|
|
27
|
+
const relativeSourcePath = normalizeCssSourcePath(path.relative(path.dirname(outFile), packageSourceRoot));
|
|
28
|
+
sourcePaths.add(`@source "${relativeSourcePath}/**/*.{ts,tsx}";`);
|
|
29
|
+
}
|
|
30
|
+
const content = `${Array.from(sourcePaths).sort((left, right) => left.localeCompare(right)).join("\n")}${sourcePaths.size > 0 ? "\n" : ""}`;
|
|
31
|
+
const structureChecksum = calculateStructureChecksum(checksumTargets);
|
|
32
|
+
writeGeneratedFile({
|
|
33
|
+
outFile,
|
|
34
|
+
checksumFile,
|
|
35
|
+
content,
|
|
36
|
+
structureChecksum,
|
|
37
|
+
result,
|
|
38
|
+
quiet
|
|
39
|
+
});
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
generateModulePackageSources
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=module-package-sources.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/generators/module-package-sources.ts"],
|
|
4
|
+
"sourcesContent": ["import fs from 'node:fs'\nimport path from 'node:path'\nimport { readOfficialModulePackageFromRoot, resolveInstalledPackageRoot } from '../module-package'\nimport type { PackageResolver } from '../resolver'\nimport { calculateStructureChecksum, createGeneratorResult, type GeneratorResult, writeGeneratedFile } from '../utils'\n\nexport interface ModulePackageSourcesOptions {\n resolver: PackageResolver\n quiet?: boolean\n}\n\nfunction normalizeCssSourcePath(value: string): string {\n const normalized = value.split(path.sep).join('/')\n return normalized.startsWith('.') ? normalized : `./${normalized}`\n}\n\nexport async function generateModulePackageSources(\n options: ModulePackageSourcesOptions,\n): Promise<GeneratorResult> {\n const { resolver, quiet } = options\n const result = createGeneratorResult()\n const outputDir = resolver.getOutputDir()\n const outFile = path.join(outputDir, 'module-package-sources.css')\n const checksumFile = path.join(outputDir, 'module-package-sources.checksum')\n const sourcePaths = new Set<string>()\n const checksumTargets: string[] = []\n\n for (const entry of resolver.loadEnabledModules()) {\n if (!entry.from || entry.from === '@app' || entry.from === '@open-mercato/core') continue\n\n const packageRoot = resolveInstalledPackageRoot(resolver, entry.from)\n checksumTargets.push(packageRoot)\n\n let modulePackage\n try {\n modulePackage = readOfficialModulePackageFromRoot(packageRoot, entry.from, entry.id)\n } catch {\n continue\n }\n\n const packageSourceRoot = path.join(modulePackage.packageRoot, 'src')\n const relativeSourcePath = normalizeCssSourcePath(path.relative(path.dirname(outFile), packageSourceRoot))\n sourcePaths.add(`@source \"${relativeSourcePath}/**/*.{ts,tsx}\";`)\n }\n\n const content = `${Array.from(sourcePaths).sort((left, right) => left.localeCompare(right)).join('\\n')}${sourcePaths.size > 0 ? '\\n' : ''}`\n const structureChecksum = calculateStructureChecksum(checksumTargets)\n\n writeGeneratedFile({\n outFile,\n checksumFile,\n content,\n structureChecksum,\n result,\n quiet,\n })\n\n return result\n}\n"],
|
|
5
|
+
"mappings": "AACA,OAAO,UAAU;AACjB,SAAS,mCAAmC,mCAAmC;AAE/E,SAAS,4BAA4B,uBAA6C,0BAA0B;AAO5G,SAAS,uBAAuB,OAAuB;AACrD,QAAM,aAAa,MAAM,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AACjD,SAAO,WAAW,WAAW,GAAG,IAAI,aAAa,KAAK,UAAU;AAClE;AAEA,eAAsB,6BACpB,SAC0B;AAC1B,QAAM,EAAE,UAAU,MAAM,IAAI;AAC5B,QAAM,SAAS,sBAAsB;AACrC,QAAM,YAAY,SAAS,aAAa;AACxC,QAAM,UAAU,KAAK,KAAK,WAAW,4BAA4B;AACjE,QAAM,eAAe,KAAK,KAAK,WAAW,iCAAiC;AAC3E,QAAM,cAAc,oBAAI,IAAY;AACpC,QAAM,kBAA4B,CAAC;AAEnC,aAAW,SAAS,SAAS,mBAAmB,GAAG;AACjD,QAAI,CAAC,MAAM,QAAQ,MAAM,SAAS,UAAU,MAAM,SAAS,qBAAsB;AAEjF,UAAM,cAAc,4BAA4B,UAAU,MAAM,IAAI;AACpE,oBAAgB,KAAK,WAAW;AAEhC,QAAI;AACJ,QAAI;AACF,sBAAgB,kCAAkC,aAAa,MAAM,MAAM,MAAM,EAAE;AAAA,IACrF,QAAQ;AACN;AAAA,IACF;AAEA,UAAM,oBAAoB,KAAK,KAAK,cAAc,aAAa,KAAK;AACpE,UAAM,qBAAqB,uBAAuB,KAAK,SAAS,KAAK,QAAQ,OAAO,GAAG,iBAAiB,CAAC;AACzG,gBAAY,IAAI,YAAY,kBAAkB,kBAAkB;AAAA,EAClE;AAEA,QAAM,UAAU,GAAG,MAAM,KAAK,WAAW,EAAE,KAAK,CAAC,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG,YAAY,OAAO,IAAI,OAAO,EAAE;AACzI,QAAM,oBAAoB,2BAA2B,eAAe;AAEpE,qBAAmB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function parseModuleInstallArgs(args) {
|
|
2
|
+
let packageSpec = null;
|
|
3
|
+
let eject = false;
|
|
4
|
+
let moduleId = null;
|
|
5
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
6
|
+
const arg = args[index];
|
|
7
|
+
if (!arg) continue;
|
|
8
|
+
if (arg === "--eject") {
|
|
9
|
+
eject = true;
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
if (arg.startsWith("--eject=")) {
|
|
13
|
+
throw new Error("--eject does not accept a value");
|
|
14
|
+
}
|
|
15
|
+
if (arg === "--module") {
|
|
16
|
+
const next = args[index + 1];
|
|
17
|
+
if (next && !next.startsWith("-")) {
|
|
18
|
+
moduleId = next;
|
|
19
|
+
index += 1;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
throw new Error(`--module requires a moduleId value`);
|
|
23
|
+
}
|
|
24
|
+
if (arg.startsWith("--module=")) {
|
|
25
|
+
moduleId = arg.slice("--module=".length) || null;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (arg.startsWith("-")) {
|
|
29
|
+
throw new Error(`Unsupported option: ${arg}`);
|
|
30
|
+
}
|
|
31
|
+
if (!arg.startsWith("-") && !packageSpec) {
|
|
32
|
+
packageSpec = arg;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return { packageSpec, eject, moduleId };
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
parseModuleInstallArgs
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=module-install-args.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lib/module-install-args.ts"],
|
|
4
|
+
"sourcesContent": ["export type ParsedModuleInstallArgs = {\n packageSpec: string | null\n eject: boolean\n moduleId: string | null\n}\n\nexport function parseModuleInstallArgs(args: string[]): ParsedModuleInstallArgs {\n let packageSpec: string | null = null\n let eject = false\n let moduleId: string | null = null\n\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index]\n if (!arg) continue\n\n if (arg === '--eject') {\n eject = true\n continue\n }\n\n if (arg.startsWith('--eject=')) {\n throw new Error('--eject does not accept a value')\n }\n\n if (arg === '--module') {\n const next = args[index + 1]\n if (next && !next.startsWith('-')) {\n moduleId = next\n index += 1\n continue\n }\n throw new Error(`--module requires a moduleId value`)\n }\n\n if (arg.startsWith('--module=')) {\n moduleId = arg.slice('--module='.length) || null\n continue\n }\n\n if (arg.startsWith('-')) {\n throw new Error(`Unsupported option: ${arg}`)\n }\n\n if (!arg.startsWith('-') && !packageSpec) {\n packageSpec = arg\n }\n }\n\n return { packageSpec, eject, moduleId }\n}\n"],
|
|
5
|
+
"mappings": "AAMO,SAAS,uBAAuB,MAAyC;AAC9E,MAAI,cAA6B;AACjC,MAAI,QAAQ;AACZ,MAAI,WAA0B;AAE9B,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,UAAM,MAAM,KAAK,KAAK;AACtB,QAAI,CAAC,IAAK;AAEV,QAAI,QAAQ,WAAW;AACrB,cAAQ;AACR;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,GAAG;AAC9B,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AAEA,QAAI,QAAQ,YAAY;AACtB,YAAM,OAAO,KAAK,QAAQ,CAAC;AAC3B,UAAI,QAAQ,CAAC,KAAK,WAAW,GAAG,GAAG;AACjC,mBAAW;AACX,iBAAS;AACT;AAAA,MACF;AACA,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AAEA,QAAI,IAAI,WAAW,WAAW,GAAG;AAC/B,iBAAW,IAAI,MAAM,YAAY,MAAM,KAAK;AAC5C;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,GAAG,GAAG;AACvB,YAAM,IAAI,MAAM,uBAAuB,GAAG,EAAE;AAAA,IAC9C;AAEA,QAAI,CAAC,IAAI,WAAW,GAAG,KAAK,CAAC,aAAa;AACxC,oBAAc;AAAA,IAChB;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,OAAO,SAAS;AACxC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { copyDirRecursive, rewriteCrossModuleImports } from "./eject.js";
|
|
5
|
+
import {
|
|
6
|
+
parsePackageNameFromSpec,
|
|
7
|
+
resolveInstalledOfficialModulePackage,
|
|
8
|
+
validateEjectBoundaries
|
|
9
|
+
} from "./module-package.js";
|
|
10
|
+
import { ensureModuleRegistration } from "./modules-config.js";
|
|
11
|
+
function resolveYarnBinary() {
|
|
12
|
+
return process.platform === "win32" ? "yarn.cmd" : "yarn";
|
|
13
|
+
}
|
|
14
|
+
function readAppPackageName(appDir) {
|
|
15
|
+
const packageJsonPath = path.join(appDir, "package.json");
|
|
16
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
17
|
+
throw new Error(`App package.json not found at ${packageJsonPath}.`);
|
|
18
|
+
}
|
|
19
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
20
|
+
if (!packageJson.name) {
|
|
21
|
+
throw new Error(`App package.json at ${packageJsonPath} is missing the "name" field.`);
|
|
22
|
+
}
|
|
23
|
+
return packageJson.name;
|
|
24
|
+
}
|
|
25
|
+
function resolveInstallTarget(resolver) {
|
|
26
|
+
if (!resolver.isMonorepo()) {
|
|
27
|
+
return {
|
|
28
|
+
cwd: resolver.getAppDir(),
|
|
29
|
+
args: ["add"]
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
cwd: resolver.getRootDir(),
|
|
34
|
+
args: ["workspace", readAppPackageName(resolver.getAppDir()), "add"]
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function runCommand(command, args, cwd) {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
const child = spawn(command, args, {
|
|
40
|
+
cwd,
|
|
41
|
+
env: process.env,
|
|
42
|
+
stdio: "inherit"
|
|
43
|
+
});
|
|
44
|
+
child.on("error", reject);
|
|
45
|
+
child.on("exit", (code) => {
|
|
46
|
+
if (code === 0) {
|
|
47
|
+
resolve();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
reject(new Error(`Command failed: ${command} ${args.join(" ")} (exit ${code ?? "unknown"}).`));
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async function installPackageSpec(resolver, packageSpec) {
|
|
55
|
+
const target = resolveInstallTarget(resolver);
|
|
56
|
+
await runCommand(resolveYarnBinary(), [...target.args, packageSpec], target.cwd);
|
|
57
|
+
}
|
|
58
|
+
async function runModuleGenerators(resolver, quiet = true) {
|
|
59
|
+
const {
|
|
60
|
+
generateEntityIds,
|
|
61
|
+
generateModuleDi,
|
|
62
|
+
generateModuleEntities,
|
|
63
|
+
generateModulePackageSources,
|
|
64
|
+
generateModuleRegistry,
|
|
65
|
+
generateModuleRegistryCli,
|
|
66
|
+
generateOpenApi
|
|
67
|
+
} = await import("./generators/index.js");
|
|
68
|
+
await generateEntityIds({ resolver, quiet });
|
|
69
|
+
await generateModuleRegistry({ resolver, quiet });
|
|
70
|
+
await generateModuleRegistryCli({ resolver, quiet });
|
|
71
|
+
await generateModuleEntities({ resolver, quiet });
|
|
72
|
+
await generateModuleDi({ resolver, quiet });
|
|
73
|
+
await generateModulePackageSources({ resolver, quiet });
|
|
74
|
+
await generateOpenApi({ resolver, quiet });
|
|
75
|
+
}
|
|
76
|
+
async function runGeneratorsWithRegistrationNotice(resolver, moduleId) {
|
|
77
|
+
try {
|
|
78
|
+
await runModuleGenerators(resolver);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
81
|
+
throw new Error(
|
|
82
|
+
`Module "${moduleId}" is enabled, but generated artifacts are stale because generation failed. Rerun "yarn mercato generate" after fixing the underlying error. ${message}`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function assertPackageName(packageName) {
|
|
87
|
+
if (!packageName || !packageName.startsWith("@open-mercato/")) {
|
|
88
|
+
throw new Error('Only @open-mercato/* package specs are supported by "mercato module add".');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function validateBeforeRegistration(modulePackage, resolver, eject) {
|
|
92
|
+
const appModuleDir = path.join(resolver.getAppDir(), "src", "modules", modulePackage.metadata.moduleId);
|
|
93
|
+
if (eject && fs.existsSync(appModuleDir)) {
|
|
94
|
+
throw new Error(`Destination directory already exists: ${appModuleDir}. Remove it first or rerun without --eject.`);
|
|
95
|
+
}
|
|
96
|
+
return appModuleDir;
|
|
97
|
+
}
|
|
98
|
+
function prepareRegistrationSource(modulePackage, resolver, packageName, eject) {
|
|
99
|
+
const appModuleDir = validateBeforeRegistration(modulePackage, resolver, eject);
|
|
100
|
+
if (!eject) {
|
|
101
|
+
return packageName;
|
|
102
|
+
}
|
|
103
|
+
if (!modulePackage.metadata.ejectable) {
|
|
104
|
+
throw new Error(`Package "${packageName}" is not ejectable. --eject requires open-mercato.ejectable === true.`);
|
|
105
|
+
}
|
|
106
|
+
validateEjectBoundaries(modulePackage);
|
|
107
|
+
copyDirRecursive(modulePackage.sourceModuleDir, appModuleDir);
|
|
108
|
+
rewriteCrossModuleImports(
|
|
109
|
+
modulePackage.sourceModuleDir,
|
|
110
|
+
appModuleDir,
|
|
111
|
+
modulePackage.metadata.moduleId,
|
|
112
|
+
packageName
|
|
113
|
+
);
|
|
114
|
+
return "@app";
|
|
115
|
+
}
|
|
116
|
+
async function registerResolvedOfficialModule(resolver, modulePackage, packageName, eject) {
|
|
117
|
+
const from = prepareRegistrationSource(modulePackage, resolver, packageName, eject);
|
|
118
|
+
const registration = ensureModuleRegistration(
|
|
119
|
+
resolver.getModulesConfigPath(),
|
|
120
|
+
{
|
|
121
|
+
id: modulePackage.metadata.moduleId,
|
|
122
|
+
from
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
if (!registration.changed) {
|
|
126
|
+
throw new Error(
|
|
127
|
+
`Module "${modulePackage.metadata.moduleId}" from "${from}" is already enabled in modules.ts.`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
await runGeneratorsWithRegistrationNotice(resolver, modulePackage.metadata.moduleId);
|
|
131
|
+
return {
|
|
132
|
+
moduleId: modulePackage.metadata.moduleId,
|
|
133
|
+
packageName,
|
|
134
|
+
from,
|
|
135
|
+
registrationChanged: registration.changed
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
async function addOfficialModule(resolver, packageSpec, eject, moduleId) {
|
|
139
|
+
const packageName = parsePackageNameFromSpec(packageSpec);
|
|
140
|
+
assertPackageName(packageName);
|
|
141
|
+
await installPackageSpec(resolver, packageSpec);
|
|
142
|
+
const modulePackage = resolveInstalledOfficialModulePackage(resolver, packageName, moduleId);
|
|
143
|
+
return registerResolvedOfficialModule(resolver, modulePackage, packageName, eject);
|
|
144
|
+
}
|
|
145
|
+
async function enableOfficialModule(resolver, packageName, moduleId, eject = false) {
|
|
146
|
+
if (!packageName.startsWith("@open-mercato/")) {
|
|
147
|
+
throw new Error('Only @open-mercato/* packages can be enabled with "mercato module enable".');
|
|
148
|
+
}
|
|
149
|
+
const modulePackage = resolveInstalledOfficialModulePackage(resolver, packageName, moduleId);
|
|
150
|
+
return registerResolvedOfficialModule(resolver, modulePackage, packageName, eject);
|
|
151
|
+
}
|
|
152
|
+
export {
|
|
153
|
+
addOfficialModule,
|
|
154
|
+
enableOfficialModule,
|
|
155
|
+
runModuleGenerators
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=module-install.js.map
|