@open-mercato/cli 0.4.2-canary-b3b9723b95 → 0.4.2-canary-3f5eaf79f7
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/lib/db/commands.js +4 -15
- package/dist/lib/db/commands.js.map +2 -2
- package/dist/lib/generators/module-registry.js +61 -52
- package/dist/lib/generators/module-registry.js.map +2 -2
- package/dist/lib/resolver.js +2 -2
- package/dist/lib/resolver.js.map +2 -2
- package/package.json +2 -2
- package/src/lib/db/commands.ts +7 -17
- package/src/lib/generators/module-registry.ts +67 -52
- package/src/lib/resolver.ts +4 -5
package/dist/lib/resolver.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/resolver.ts"],
|
|
4
|
-
"sourcesContent": ["import path from 'node:path'\nimport fs from 'node:fs'\n\nexport type ModuleEntry = {\n id: string\n from?: '@open-mercato/core' | '@app' | string\n}\n\nexport type PackageInfo = {\n name: string\n path: string\n modulesPath: string\n}\n\nexport interface PackageResolver {\n isMonorepo(): boolean\n getRootDir(): string\n getAppDir(): string\n getOutputDir(): string\n getModulesConfigPath(): string\n discoverPackages(): PackageInfo[]\n loadEnabledModules(): ModuleEntry[]\n getModulePaths(entry: ModuleEntry): { appBase: string; pkgBase: string }\n getModuleImportBase(entry: ModuleEntry): { appBase: string; pkgBase: string }\n getPackageOutputDir(packageName: string): string\n getPackageRoot(from?: string): string\n}\n\nfunction pkgDirFor(rootDir: string, from?: string, isMonorepo = true): string {\n if (!isMonorepo) {\n // Production mode: look in node_modules\n // Packages include source TypeScript files in src/modules\n const pkgName = from || '@open-mercato/core'\n return path.join(rootDir, 'node_modules', pkgName, 'src', 'modules')\n }\n\n // Monorepo mode\n if (!from || from === '@open-mercato/core') {\n return path.resolve(rootDir, 'packages/core/src/modules')\n }\n // Support other local packages like '@open-mercato/onboarding' => packages/onboarding/src/modules\n const m = from.match(/^@open-mercato\\/(.+)$/)\n if (m) {\n return path.resolve(rootDir, `packages/${m[1]}/src/modules`)\n }\n // Fallback to core modules path\n return path.resolve(rootDir, 'packages/core/src/modules')\n}\n\nfunction pkgRootFor(rootDir: string, from?: string, isMonorepo = true): string {\n if (!isMonorepo) {\n const pkgName = from || '@open-mercato/core'\n return path.join(rootDir, 'node_modules', pkgName)\n }\n\n if (!from || from === '@open-mercato/core') {\n return path.resolve(rootDir, 'packages/core')\n }\n const m = from.match(/^@open-mercato\\/(.+)$/)\n if (m) {\n return path.resolve(rootDir, `packages/${m[1]}`)\n }\n return path.resolve(rootDir, 'packages/core')\n}\n\nfunction parseModulesFromSource(source: string): ModuleEntry[] {\n // Parse the enabledModules array from TypeScript source\n // This is more reliable than trying to require() a .ts file\n const match = source.match(/export\\s+const\\s+enabledModules[^=]*=\\s*\\[([\\s\\S]*?)\\]/)\n if (!match) return []\n\n const arrayContent = match[1]\n const modules: ModuleEntry[] = []\n\n // Match each object in the array: { id: '...', from: '...' }\n const objectRegex = /\\{\\s*id:\\s*['\"]([^'\"]+)['\"]\\s*(?:,\\s*from:\\s*['\"]([^'\"]+)['\"])?\\s*\\}/g\n let objMatch\n while ((objMatch = objectRegex.exec(arrayContent)) !== null) {\n const [, id, from] = objMatch\n modules.push({ id, from: from || '@open-mercato/core' })\n }\n\n return modules\n}\n\nfunction loadEnabledModulesFromConfig(appDir: string): ModuleEntry[] {\n const cfgPath = path.resolve(appDir, 'src/modules.ts')\n if (fs.existsSync(cfgPath)) {\n try {\n const source = fs.readFileSync(cfgPath, 'utf8')\n const list = parseModulesFromSource(source)\n if (list.length) return list\n } catch {\n // Fall through to fallback\n }\n }\n // Fallback: scan src/modules/* to keep backward compatibility\n const modulesRoot = path.resolve(appDir, 'src/modules')\n if (!fs.existsSync(modulesRoot)) return []\n return fs\n .readdirSync(modulesRoot, { withFileTypes: true })\n .filter((e) => e.isDirectory() && !e.name.startsWith('.'))\n .map((e) => ({ id: e.name, from: '@app' as const }))\n}\n\nfunction discoverPackagesInMonorepo(rootDir: string): PackageInfo[] {\n const packagesDir = path.join(rootDir, 'packages')\n if (!fs.existsSync(packagesDir)) return []\n\n const packages: PackageInfo[] = []\n const entries = fs.readdirSync(packagesDir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const pkgPath = path.join(packagesDir, entry.name)\n const pkgJsonPath = path.join(pkgPath, 'package.json')\n\n if (!fs.existsSync(pkgJsonPath)) continue\n\n try {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))\n const modulesPath = path.join(pkgPath, 'src', 'modules')\n\n if (fs.existsSync(modulesPath)) {\n packages.push({\n name: pkgJson.name || `@open-mercato/${entry.name}`,\n path: pkgPath,\n modulesPath,\n })\n }\n } catch {\n // Skip invalid packages\n }\n }\n\n return packages\n}\n\nfunction discoverPackagesInNodeModules(rootDir: string): PackageInfo[] {\n const nodeModulesPath = path.join(rootDir, 'node_modules', '@open-mercato')\n if (!fs.existsSync(nodeModulesPath)) return []\n\n const packages: PackageInfo[] = []\n const entries = fs.readdirSync(nodeModulesPath, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const pkgPath = path.join(nodeModulesPath, entry.name)\n const pkgJsonPath = path.join(pkgPath, 'package.json')\n\n if (!fs.existsSync(pkgJsonPath)) continue\n\n try {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))\n // Packages include source TypeScript files in src/modules\n const modulesPath = path.join(pkgPath, 'src', 'modules')\n\n if (fs.existsSync(modulesPath)) {\n packages.push({\n name: pkgJson.name || `@open-mercato/${entry.name}`,\n path: pkgPath,\n modulesPath,\n })\n }\n } catch {\n // Skip invalid packages\n }\n }\n\n return packages\n}\n\nfunction detectAppDir(rootDir: string, isMonorepo: boolean): string {\n if (!isMonorepo) {\n // Production mode: app is at root\n return rootDir\n }\n\n // Monorepo mode: look for app in apps/mercato/ or apps/app/\n const mercatoApp = path.join(rootDir, 'apps', 'mercato')\n if (fs.existsSync(mercatoApp)) {\n return mercatoApp\n }\n\n const defaultApp = path.join(rootDir, 'apps', 'app')\n if (fs.existsSync(defaultApp)) {\n return defaultApp\n }\n\n // Fallback: check if apps directory exists and has any app\n const appsDir = path.join(rootDir, 'apps')\n if (fs.existsSync(appsDir)) {\n const entries = fs.readdirSync(appsDir, { withFileTypes: true })\n const appEntry = entries.find(\n (e) => e.isDirectory() && !e.name.startsWith('.') && e.name !== 'docs'\n )\n if (appEntry) {\n return path.join(appsDir, appEntry.name)\n }\n }\n\n // Final fallback for legacy structure: root is the app\n return rootDir\n}\n\nfunction findNodeModulesRoot(startDir: string): string | null {\n // Walk up to find node_modules/@open-mercato/core\n let dir = startDir\n while (dir !== path.dirname(dir)) {\n const corePkgPath = path.join(dir, 'node_modules', '@open-mercato', 'core')\n if (fs.existsSync(corePkgPath)) {\n return dir\n }\n dir = path.dirname(dir)\n }\n return null\n}\n\nfunction detectMonorepoFromNodeModules(appDir: string): { isMonorepo: boolean; monorepoRoot: string | null; nodeModulesRoot: string | null } {\n // Find where node_modules/@open-mercato/core is located (may be hoisted)\n const nodeModulesRoot = findNodeModulesRoot(appDir)\n if (!nodeModulesRoot) {\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot: null }\n }\n\n const corePkgPath = path.join(nodeModulesRoot, 'node_modules', '@open-mercato', 'core')\n\n try {\n const stat = fs.lstatSync(corePkgPath)\n if (stat.isSymbolicLink()) {\n // It's a symlink - we're in monorepo dev mode\n // Resolve the symlink to find the monorepo root\n const realPath = fs.realpathSync(corePkgPath)\n // realPath is something like /path/to/monorepo/packages/core\n // monorepo root is 2 levels up\n const monorepoRoot = path.dirname(path.dirname(realPath))\n return { isMonorepo: true, monorepoRoot, nodeModulesRoot }\n }\n // It's a real directory - production mode\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot }\n } catch {\n // Package doesn't exist yet or error reading - assume production mode\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot }\n }\n}\n\nexport function createResolver(cwd: string = process.cwd()): PackageResolver {\n // First detect if we're in a monorepo by checking if node_modules packages are symlinks\n const { isMonorepo: _isMonorepo, monorepoRoot } = detectMonorepoFromNodeModules(cwd)\n const rootDir = monorepoRoot ?? cwd\n\n // The app directory depends on context:\n // - In monorepo: use detectAppDir to find apps/mercato or similar\n // - In production: app is at cwd\n const appDir = _isMonorepo ? detectAppDir(rootDir, true) : cwd\n\n return {\n isMonorepo: () => _isMonorepo,\n\n getRootDir: () => rootDir,\n\n getAppDir: () => appDir,\n\n getOutputDir: () => {\n // Output is ALWAYS .mercato/generated relative to app directory\n return path.join(appDir, '.mercato', 'generated')\n },\n\n getModulesConfigPath: () => path.join(appDir, 'src', 'modules.ts'),\n\n discoverPackages: () => {\n return _isMonorepo\n ? discoverPackagesInMonorepo(rootDir)\n : discoverPackagesInNodeModules(rootDir)\n },\n\n loadEnabledModules: () => loadEnabledModulesFromConfig(appDir),\n\n getModulePaths: (entry: ModuleEntry) => {\n const appBase = path.resolve(appDir, 'src/modules', entry.id)\n const pkgModulesRoot = pkgDirFor(rootDir, entry.from, _isMonorepo)\n const pkgBase = path.join(pkgModulesRoot, entry.id)\n return { appBase, pkgBase }\n },\n\n getModuleImportBase: (entry: ModuleEntry) => {\n // Prefer @app overrides at import-time; fall back to provided package alias\n const from = entry.from || '@open-mercato/core'\n return {\n appBase: `@/modules/${entry.id}`,\n pkgBase: `${from}/modules/${entry.id}`,\n }\n },\n\n getPackageOutputDir: (packageName: string) => {\n if (packageName === '@app') {\n // App output goes to .mercato/generated\n return path.join(appDir, '.mercato', 'generated')\n }\n const pkgRoot = pkgRootFor(rootDir, packageName, _isMonorepo)\n return path.join(pkgRoot, 'generated')\n },\n\n getPackageRoot: (from?: string) => {\n return pkgRootFor(rootDir, from, _isMonorepo)\n },\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AA2Bf,SAAS,UAAU,SAAiB,MAAe,aAAa,MAAc;AAC5E,MAAI,CAAC,YAAY;
|
|
4
|
+
"sourcesContent": ["import path from 'node:path'\nimport fs from 'node:fs'\n\nexport type ModuleEntry = {\n id: string\n from?: '@open-mercato/core' | '@app' | string\n}\n\nexport type PackageInfo = {\n name: string\n path: string\n modulesPath: string\n}\n\nexport interface PackageResolver {\n isMonorepo(): boolean\n getRootDir(): string\n getAppDir(): string\n getOutputDir(): string\n getModulesConfigPath(): string\n discoverPackages(): PackageInfo[]\n loadEnabledModules(): ModuleEntry[]\n getModulePaths(entry: ModuleEntry): { appBase: string; pkgBase: string }\n getModuleImportBase(entry: ModuleEntry): { appBase: string; pkgBase: string }\n getPackageOutputDir(packageName: string): string\n getPackageRoot(from?: string): string\n}\n\nfunction pkgDirFor(rootDir: string, from?: string, isMonorepo = true): string {\n if (!isMonorepo) {\n // Production mode: look in node_modules dist (compiled JS)\n const pkgName = from || '@open-mercato/core'\n return path.join(rootDir, 'node_modules', pkgName, 'dist', 'modules')\n }\n\n // Monorepo mode\n if (!from || from === '@open-mercato/core') {\n return path.resolve(rootDir, 'packages/core/src/modules')\n }\n // Support other local packages like '@open-mercato/onboarding' => packages/onboarding/src/modules\n const m = from.match(/^@open-mercato\\/(.+)$/)\n if (m) {\n return path.resolve(rootDir, `packages/${m[1]}/src/modules`)\n }\n // Fallback to core modules path\n return path.resolve(rootDir, 'packages/core/src/modules')\n}\n\nfunction pkgRootFor(rootDir: string, from?: string, isMonorepo = true): string {\n if (!isMonorepo) {\n const pkgName = from || '@open-mercato/core'\n return path.join(rootDir, 'node_modules', pkgName)\n }\n\n if (!from || from === '@open-mercato/core') {\n return path.resolve(rootDir, 'packages/core')\n }\n const m = from.match(/^@open-mercato\\/(.+)$/)\n if (m) {\n return path.resolve(rootDir, `packages/${m[1]}`)\n }\n return path.resolve(rootDir, 'packages/core')\n}\n\nfunction parseModulesFromSource(source: string): ModuleEntry[] {\n // Parse the enabledModules array from TypeScript source\n // This is more reliable than trying to require() a .ts file\n const match = source.match(/export\\s+const\\s+enabledModules[^=]*=\\s*\\[([\\s\\S]*?)\\]/)\n if (!match) return []\n\n const arrayContent = match[1]\n const modules: ModuleEntry[] = []\n\n // Match each object in the array: { id: '...', from: '...' }\n const objectRegex = /\\{\\s*id:\\s*['\"]([^'\"]+)['\"]\\s*(?:,\\s*from:\\s*['\"]([^'\"]+)['\"])?\\s*\\}/g\n let objMatch\n while ((objMatch = objectRegex.exec(arrayContent)) !== null) {\n const [, id, from] = objMatch\n modules.push({ id, from: from || '@open-mercato/core' })\n }\n\n return modules\n}\n\nfunction loadEnabledModulesFromConfig(appDir: string): ModuleEntry[] {\n const cfgPath = path.resolve(appDir, 'src/modules.ts')\n if (fs.existsSync(cfgPath)) {\n try {\n const source = fs.readFileSync(cfgPath, 'utf8')\n const list = parseModulesFromSource(source)\n if (list.length) return list\n } catch {\n // Fall through to fallback\n }\n }\n // Fallback: scan src/modules/* to keep backward compatibility\n const modulesRoot = path.resolve(appDir, 'src/modules')\n if (!fs.existsSync(modulesRoot)) return []\n return fs\n .readdirSync(modulesRoot, { withFileTypes: true })\n .filter((e) => e.isDirectory() && !e.name.startsWith('.'))\n .map((e) => ({ id: e.name, from: '@app' as const }))\n}\n\nfunction discoverPackagesInMonorepo(rootDir: string): PackageInfo[] {\n const packagesDir = path.join(rootDir, 'packages')\n if (!fs.existsSync(packagesDir)) return []\n\n const packages: PackageInfo[] = []\n const entries = fs.readdirSync(packagesDir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const pkgPath = path.join(packagesDir, entry.name)\n const pkgJsonPath = path.join(pkgPath, 'package.json')\n\n if (!fs.existsSync(pkgJsonPath)) continue\n\n try {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))\n const modulesPath = path.join(pkgPath, 'src', 'modules')\n\n if (fs.existsSync(modulesPath)) {\n packages.push({\n name: pkgJson.name || `@open-mercato/${entry.name}`,\n path: pkgPath,\n modulesPath,\n })\n }\n } catch {\n // Skip invalid packages\n }\n }\n\n return packages\n}\n\nfunction discoverPackagesInNodeModules(rootDir: string): PackageInfo[] {\n const nodeModulesPath = path.join(rootDir, 'node_modules', '@open-mercato')\n if (!fs.existsSync(nodeModulesPath)) return []\n\n const packages: PackageInfo[] = []\n const entries = fs.readdirSync(nodeModulesPath, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const pkgPath = path.join(nodeModulesPath, entry.name)\n const pkgJsonPath = path.join(pkgPath, 'package.json')\n\n if (!fs.existsSync(pkgJsonPath)) continue\n\n try {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))\n // Production mode: use compiled JS files from dist/modules\n const modulesPath = path.join(pkgPath, 'dist', 'modules')\n\n if (fs.existsSync(modulesPath)) {\n packages.push({\n name: pkgJson.name || `@open-mercato/${entry.name}`,\n path: pkgPath,\n modulesPath,\n })\n }\n } catch {\n // Skip invalid packages\n }\n }\n\n return packages\n}\n\nfunction detectAppDir(rootDir: string, isMonorepo: boolean): string {\n if (!isMonorepo) {\n // Production mode: app is at root\n return rootDir\n }\n\n // Monorepo mode: look for app in apps/mercato/ or apps/app/\n const mercatoApp = path.join(rootDir, 'apps', 'mercato')\n if (fs.existsSync(mercatoApp)) {\n return mercatoApp\n }\n\n const defaultApp = path.join(rootDir, 'apps', 'app')\n if (fs.existsSync(defaultApp)) {\n return defaultApp\n }\n\n // Fallback: check if apps directory exists and has any app\n const appsDir = path.join(rootDir, 'apps')\n if (fs.existsSync(appsDir)) {\n const entries = fs.readdirSync(appsDir, { withFileTypes: true })\n const appEntry = entries.find(\n (e) => e.isDirectory() && !e.name.startsWith('.') && e.name !== 'docs'\n )\n if (appEntry) {\n return path.join(appsDir, appEntry.name)\n }\n }\n\n // Final fallback for legacy structure: root is the app\n return rootDir\n}\n\nfunction findNodeModulesRoot(startDir: string): string | null {\n // Walk up to find node_modules/@open-mercato/core\n let dir = startDir\n while (dir !== path.dirname(dir)) {\n const corePkgPath = path.join(dir, 'node_modules', '@open-mercato', 'core')\n if (fs.existsSync(corePkgPath)) {\n return dir\n }\n dir = path.dirname(dir)\n }\n return null\n}\n\nfunction detectMonorepoFromNodeModules(appDir: string): { isMonorepo: boolean; monorepoRoot: string | null; nodeModulesRoot: string | null } {\n // Find where node_modules/@open-mercato/core is located (may be hoisted)\n const nodeModulesRoot = findNodeModulesRoot(appDir)\n if (!nodeModulesRoot) {\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot: null }\n }\n\n const corePkgPath = path.join(nodeModulesRoot, 'node_modules', '@open-mercato', 'core')\n\n try {\n const stat = fs.lstatSync(corePkgPath)\n if (stat.isSymbolicLink()) {\n // It's a symlink - we're in monorepo dev mode\n // Resolve the symlink to find the monorepo root\n const realPath = fs.realpathSync(corePkgPath)\n // realPath is something like /path/to/monorepo/packages/core\n // monorepo root is 2 levels up\n const monorepoRoot = path.dirname(path.dirname(realPath))\n return { isMonorepo: true, monorepoRoot, nodeModulesRoot }\n }\n // It's a real directory - production mode\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot }\n } catch {\n // Package doesn't exist yet or error reading - assume production mode\n return { isMonorepo: false, monorepoRoot: null, nodeModulesRoot }\n }\n}\n\nexport function createResolver(cwd: string = process.cwd()): PackageResolver {\n // First detect if we're in a monorepo by checking if node_modules packages are symlinks\n const { isMonorepo: _isMonorepo, monorepoRoot } = detectMonorepoFromNodeModules(cwd)\n const rootDir = monorepoRoot ?? cwd\n\n // The app directory depends on context:\n // - In monorepo: use detectAppDir to find apps/mercato or similar\n // - In production: app is at cwd\n const appDir = _isMonorepo ? detectAppDir(rootDir, true) : cwd\n\n return {\n isMonorepo: () => _isMonorepo,\n\n getRootDir: () => rootDir,\n\n getAppDir: () => appDir,\n\n getOutputDir: () => {\n // Output is ALWAYS .mercato/generated relative to app directory\n return path.join(appDir, '.mercato', 'generated')\n },\n\n getModulesConfigPath: () => path.join(appDir, 'src', 'modules.ts'),\n\n discoverPackages: () => {\n return _isMonorepo\n ? discoverPackagesInMonorepo(rootDir)\n : discoverPackagesInNodeModules(rootDir)\n },\n\n loadEnabledModules: () => loadEnabledModulesFromConfig(appDir),\n\n getModulePaths: (entry: ModuleEntry) => {\n const appBase = path.resolve(appDir, 'src/modules', entry.id)\n const pkgModulesRoot = pkgDirFor(rootDir, entry.from, _isMonorepo)\n const pkgBase = path.join(pkgModulesRoot, entry.id)\n return { appBase, pkgBase }\n },\n\n getModuleImportBase: (entry: ModuleEntry) => {\n // Prefer @app overrides at import-time; fall back to provided package alias\n const from = entry.from || '@open-mercato/core'\n return {\n appBase: `@/modules/${entry.id}`,\n pkgBase: `${from}/modules/${entry.id}`,\n }\n },\n\n getPackageOutputDir: (packageName: string) => {\n if (packageName === '@app') {\n // App output goes to .mercato/generated\n return path.join(appDir, '.mercato', 'generated')\n }\n const pkgRoot = pkgRootFor(rootDir, packageName, _isMonorepo)\n return path.join(pkgRoot, 'generated')\n },\n\n getPackageRoot: (from?: string) => {\n return pkgRootFor(rootDir, from, _isMonorepo)\n },\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/cli",
|
|
3
|
-
"version": "0.4.2-canary-
|
|
3
|
+
"version": "0.4.2-canary-3f5eaf79f7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@mikro-orm/core": "^6.6.2",
|
|
56
56
|
"@mikro-orm/migrations": "^6.6.2",
|
|
57
57
|
"@mikro-orm/postgresql": "^6.6.2",
|
|
58
|
-
"@open-mercato/shared": "0.4.2-canary-
|
|
58
|
+
"@open-mercato/shared": "0.4.2-canary-3f5eaf79f7",
|
|
59
59
|
"pg": "^8.16.3",
|
|
60
60
|
"typescript": "^5.9.3"
|
|
61
61
|
},
|
package/src/lib/db/commands.ts
CHANGED
|
@@ -107,25 +107,15 @@ async function loadModuleEntities(entry: ModuleEntry, resolver: PackageResolver)
|
|
|
107
107
|
|
|
108
108
|
function getMigrationsPath(entry: ModuleEntry, resolver: PackageResolver): string {
|
|
109
109
|
const from = entry.from || '@open-mercato/core'
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
} else if (/^@open-mercato\//.test(from)) {
|
|
115
|
-
const segs = from.split('/')
|
|
116
|
-
if (segs.length > 1 && segs[1]) {
|
|
117
|
-
pkgModRoot = path.join(resolver.getRootDir(), `packages/${segs[1]}/src/modules`, entry.id)
|
|
118
|
-
} else {
|
|
119
|
-
pkgModRoot = path.join(resolver.getRootDir(), 'packages/core/src/modules', entry.id)
|
|
120
|
-
}
|
|
121
|
-
} else if (from === '@app') {
|
|
122
|
-
// For @app modules, use the app directory not the monorepo root
|
|
123
|
-
pkgModRoot = path.join(resolver.getAppDir(), 'src/modules', entry.id)
|
|
124
|
-
} else {
|
|
125
|
-
pkgModRoot = path.join(resolver.getRootDir(), 'packages/core/src/modules', entry.id)
|
|
110
|
+
|
|
111
|
+
if (from === '@app') {
|
|
112
|
+
// For @app modules, use the app directory
|
|
113
|
+
return path.join(resolver.getAppDir(), 'src/modules', entry.id, 'migrations')
|
|
126
114
|
}
|
|
127
115
|
|
|
128
|
-
|
|
116
|
+
// Use resolver's getModulePaths which handles monorepo vs production mode
|
|
117
|
+
const { pkgBase } = resolver.getModulePaths(entry)
|
|
118
|
+
return path.join(pkgBase, 'migrations')
|
|
129
119
|
}
|
|
130
120
|
|
|
131
121
|
export interface DbOptions {
|
|
@@ -15,6 +15,21 @@ import {
|
|
|
15
15
|
|
|
16
16
|
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Find a module file, checking for both .ts (src) and .js (dist) extensions.
|
|
20
|
+
* Supports both simple names (e.g., 'cli') and nested paths (e.g., 'data/extensions').
|
|
21
|
+
* Returns the path if found, null otherwise.
|
|
22
|
+
*/
|
|
23
|
+
function findModuleFile(basePath: string, ...segments: string[]): string | null {
|
|
24
|
+
const name = segments.pop()!
|
|
25
|
+
const dir = segments.length ? path.join(basePath, ...segments) : basePath
|
|
26
|
+
const tsPath = path.join(dir, `${name}.ts`)
|
|
27
|
+
if (fs.existsSync(tsPath)) return tsPath
|
|
28
|
+
const jsPath = path.join(dir, `${name}.js`)
|
|
29
|
+
if (fs.existsSync(jsPath)) return jsPath
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
|
|
18
33
|
export interface ModuleRegistryOptions {
|
|
19
34
|
resolver: PackageResolver
|
|
20
35
|
quiet?: boolean
|
|
@@ -79,9 +94,9 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
|
|
|
79
94
|
let injectionTableImportName: string | null = null
|
|
80
95
|
|
|
81
96
|
// Module metadata: index.ts (overrideable)
|
|
82
|
-
const appIndex =
|
|
83
|
-
const pkgIndex =
|
|
84
|
-
const indexTs =
|
|
97
|
+
const appIndex = findModuleFile(roots.appBase, 'index')
|
|
98
|
+
const pkgIndex = findModuleFile(roots.pkgBase, 'index')
|
|
99
|
+
const indexTs = appIndex ?? pkgIndex
|
|
85
100
|
if (indexTs) {
|
|
86
101
|
infoImportName = `I${importId++}_${toVar(modId)}`
|
|
87
102
|
const importPath = indexTs.startsWith(roots.appBase) ? `${appImportBase}/index` : `${imps.pkgBase}/index`
|
|
@@ -190,10 +205,10 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
|
|
|
190
205
|
|
|
191
206
|
// Entity extensions: src/modules/<module>/data/extensions.ts
|
|
192
207
|
{
|
|
193
|
-
const appFile =
|
|
194
|
-
const pkgFile =
|
|
195
|
-
const hasApp =
|
|
196
|
-
const hasPkg =
|
|
208
|
+
const appFile = findModuleFile(roots.appBase, 'data', 'extensions')
|
|
209
|
+
const pkgFile = findModuleFile(roots.pkgBase, 'data', 'extensions')
|
|
210
|
+
const hasApp = !!appFile
|
|
211
|
+
const hasPkg = !!pkgFile
|
|
197
212
|
if (hasApp || hasPkg) {
|
|
198
213
|
const importName = `X_${toVar(modId)}_${importId++}`
|
|
199
214
|
const importPath = hasApp ? `${appImportBase}/data/extensions` : `${imps.pkgBase}/data/extensions`
|
|
@@ -204,12 +219,12 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
|
|
|
204
219
|
|
|
205
220
|
// RBAC feature declarations: module root acl.ts
|
|
206
221
|
{
|
|
207
|
-
const rootApp =
|
|
208
|
-
const rootPkg =
|
|
209
|
-
const hasRoot =
|
|
222
|
+
const rootApp = findModuleFile(roots.appBase, 'acl')
|
|
223
|
+
const rootPkg = findModuleFile(roots.pkgBase, 'acl')
|
|
224
|
+
const hasRoot = rootApp || rootPkg
|
|
210
225
|
if (hasRoot) {
|
|
211
226
|
const importName = `ACL_${toVar(modId)}_${importId++}`
|
|
212
|
-
const useApp =
|
|
227
|
+
const useApp = rootApp ?? rootPkg!
|
|
213
228
|
const importPath = useApp.startsWith(roots.appBase) ? `${appImportBase}/acl` : `${imps.pkgBase}/acl`
|
|
214
229
|
imports.push(`import * as ${importName} from '${importPath}'`)
|
|
215
230
|
featuresImportName = importName
|
|
@@ -218,10 +233,10 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
|
|
|
218
233
|
|
|
219
234
|
// Custom entities declarations: module root ce.ts
|
|
220
235
|
{
|
|
221
|
-
const appFile =
|
|
222
|
-
const pkgFile =
|
|
223
|
-
const hasApp =
|
|
224
|
-
const hasPkg =
|
|
236
|
+
const appFile = findModuleFile(roots.appBase, 'ce')
|
|
237
|
+
const pkgFile = findModuleFile(roots.pkgBase, 'ce')
|
|
238
|
+
const hasApp = !!appFile
|
|
239
|
+
const hasPkg = !!pkgFile
|
|
225
240
|
if (hasApp || hasPkg) {
|
|
226
241
|
const importName = `CE_${toVar(modId)}_${importId++}`
|
|
227
242
|
const importPath = hasApp ? `${appImportBase}/ce` : `${imps.pkgBase}/ce`
|
|
@@ -232,10 +247,10 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
|
|
|
232
247
|
|
|
233
248
|
// Search module configuration: module root search.ts
|
|
234
249
|
{
|
|
235
|
-
const appFile =
|
|
236
|
-
const pkgFile =
|
|
237
|
-
const hasApp =
|
|
238
|
-
const hasPkg =
|
|
250
|
+
const appFile = findModuleFile(roots.appBase, 'search')
|
|
251
|
+
const pkgFile = findModuleFile(roots.pkgBase, 'search')
|
|
252
|
+
const hasApp = !!appFile
|
|
253
|
+
const hasPkg = !!pkgFile
|
|
239
254
|
if (hasApp || hasPkg) {
|
|
240
255
|
const importName = `SEARCH_${toVar(modId)}_${importId++}`
|
|
241
256
|
const importPath = hasApp ? `${appImportBase}/search` : `${imps.pkgBase}/search`
|
|
@@ -248,10 +263,10 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
|
|
|
248
263
|
|
|
249
264
|
// Custom field declarations: src/modules/<module>/data/fields.ts
|
|
250
265
|
{
|
|
251
|
-
const appFile =
|
|
252
|
-
const pkgFile =
|
|
253
|
-
const hasApp =
|
|
254
|
-
const hasPkg =
|
|
266
|
+
const appFile = findModuleFile(roots.appBase, 'data', 'fields')
|
|
267
|
+
const pkgFile = findModuleFile(roots.pkgBase, 'data', 'fields')
|
|
268
|
+
const hasApp = !!appFile
|
|
269
|
+
const hasPkg = !!pkgFile
|
|
255
270
|
if (hasApp || hasPkg) {
|
|
256
271
|
const importName = `F_${toVar(modId)}_${importId++}`
|
|
257
272
|
const importPath = hasApp ? `${appImportBase}/data/fields` : `${imps.pkgBase}/data/fields`
|
|
@@ -468,9 +483,9 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
|
|
|
468
483
|
}
|
|
469
484
|
|
|
470
485
|
// CLI
|
|
471
|
-
const cliApp =
|
|
472
|
-
const cliPkg =
|
|
473
|
-
const cliPath =
|
|
486
|
+
const cliApp = findModuleFile(roots.appBase, 'cli')
|
|
487
|
+
const cliPkg = findModuleFile(roots.pkgBase, 'cli')
|
|
488
|
+
const cliPath = cliApp ?? cliPkg
|
|
474
489
|
if (cliPath) {
|
|
475
490
|
const importName = `CLI_${toVar(modId)}`
|
|
476
491
|
const importPath = cliPath.startsWith(roots.appBase) ? `${appImportBase}/cli` : `${imps.pkgBase}/cli`
|
|
@@ -930,9 +945,9 @@ export async function generateModuleRegistryCli(options: ModuleRegistryOptions):
|
|
|
930
945
|
let customFieldSetsExpr: string = '[]'
|
|
931
946
|
|
|
932
947
|
// Module metadata: index.ts (overrideable)
|
|
933
|
-
const appIndex =
|
|
934
|
-
const pkgIndex =
|
|
935
|
-
const indexTs =
|
|
948
|
+
const appIndex = findModuleFile(roots.appBase, 'index')
|
|
949
|
+
const pkgIndex = findModuleFile(roots.pkgBase, 'index')
|
|
950
|
+
const indexTs = appIndex ?? pkgIndex
|
|
936
951
|
if (indexTs) {
|
|
937
952
|
infoImportName = `I${importId++}_${toVar(modId)}`
|
|
938
953
|
const importPath = indexTs.startsWith(roots.appBase) ? `${appImportBase}/index` : `${imps.pkgBase}/index`
|
|
@@ -949,10 +964,10 @@ export async function generateModuleRegistryCli(options: ModuleRegistryOptions):
|
|
|
949
964
|
|
|
950
965
|
// Entity extensions: src/modules/<module>/data/extensions.ts
|
|
951
966
|
{
|
|
952
|
-
const appFile =
|
|
953
|
-
const pkgFile =
|
|
954
|
-
const hasApp =
|
|
955
|
-
const hasPkg =
|
|
967
|
+
const appFile = findModuleFile(roots.appBase, 'data', 'extensions')
|
|
968
|
+
const pkgFile = findModuleFile(roots.pkgBase, 'data', 'extensions')
|
|
969
|
+
const hasApp = !!appFile
|
|
970
|
+
const hasPkg = !!pkgFile
|
|
956
971
|
if (hasApp || hasPkg) {
|
|
957
972
|
const importName = `X_${toVar(modId)}_${importId++}`
|
|
958
973
|
const importPath = hasApp ? `${appImportBase}/data/extensions` : `${imps.pkgBase}/data/extensions`
|
|
@@ -963,12 +978,12 @@ export async function generateModuleRegistryCli(options: ModuleRegistryOptions):
|
|
|
963
978
|
|
|
964
979
|
// RBAC feature declarations: module root acl.ts
|
|
965
980
|
{
|
|
966
|
-
const rootApp =
|
|
967
|
-
const rootPkg =
|
|
968
|
-
const hasRoot =
|
|
981
|
+
const rootApp = findModuleFile(roots.appBase, 'acl')
|
|
982
|
+
const rootPkg = findModuleFile(roots.pkgBase, 'acl')
|
|
983
|
+
const hasRoot = rootApp || rootPkg
|
|
969
984
|
if (hasRoot) {
|
|
970
985
|
const importName = `ACL_${toVar(modId)}_${importId++}`
|
|
971
|
-
const useApp =
|
|
986
|
+
const useApp = rootApp ?? rootPkg!
|
|
972
987
|
const importPath = useApp.startsWith(roots.appBase) ? `${appImportBase}/acl` : `${imps.pkgBase}/acl`
|
|
973
988
|
imports.push(`import * as ${importName} from '${importPath}'`)
|
|
974
989
|
featuresImportName = importName
|
|
@@ -977,10 +992,10 @@ export async function generateModuleRegistryCli(options: ModuleRegistryOptions):
|
|
|
977
992
|
|
|
978
993
|
// Custom entities declarations: module root ce.ts
|
|
979
994
|
{
|
|
980
|
-
const appFile =
|
|
981
|
-
const pkgFile =
|
|
982
|
-
const hasApp =
|
|
983
|
-
const hasPkg =
|
|
995
|
+
const appFile = findModuleFile(roots.appBase, 'ce')
|
|
996
|
+
const pkgFile = findModuleFile(roots.pkgBase, 'ce')
|
|
997
|
+
const hasApp = !!appFile
|
|
998
|
+
const hasPkg = !!pkgFile
|
|
984
999
|
if (hasApp || hasPkg) {
|
|
985
1000
|
const importName = `CE_${toVar(modId)}_${importId++}`
|
|
986
1001
|
const importPath = hasApp ? `${appImportBase}/ce` : `${imps.pkgBase}/ce`
|
|
@@ -991,10 +1006,10 @@ export async function generateModuleRegistryCli(options: ModuleRegistryOptions):
|
|
|
991
1006
|
|
|
992
1007
|
// Vector search configuration: module root vector.ts
|
|
993
1008
|
{
|
|
994
|
-
const appFile =
|
|
995
|
-
const pkgFile =
|
|
996
|
-
const hasApp =
|
|
997
|
-
const hasPkg =
|
|
1009
|
+
const appFile = findModuleFile(roots.appBase, 'vector')
|
|
1010
|
+
const pkgFile = findModuleFile(roots.pkgBase, 'vector')
|
|
1011
|
+
const hasApp = !!appFile
|
|
1012
|
+
const hasPkg = !!pkgFile
|
|
998
1013
|
if (hasApp || hasPkg) {
|
|
999
1014
|
const importName = `VECTOR_${toVar(modId)}_${importId++}`
|
|
1000
1015
|
const importPath = hasApp ? `${appImportBase}/vector` : `${imps.pkgBase}/vector`
|
|
@@ -1005,10 +1020,10 @@ export async function generateModuleRegistryCli(options: ModuleRegistryOptions):
|
|
|
1005
1020
|
|
|
1006
1021
|
// Custom field declarations: src/modules/<module>/data/fields.ts
|
|
1007
1022
|
{
|
|
1008
|
-
const appFile =
|
|
1009
|
-
const pkgFile =
|
|
1010
|
-
const hasApp =
|
|
1011
|
-
const hasPkg =
|
|
1023
|
+
const appFile = findModuleFile(roots.appBase, 'data', 'fields')
|
|
1024
|
+
const pkgFile = findModuleFile(roots.pkgBase, 'data', 'fields')
|
|
1025
|
+
const hasApp = !!appFile
|
|
1026
|
+
const hasPkg = !!pkgFile
|
|
1012
1027
|
if (hasApp || hasPkg) {
|
|
1013
1028
|
const importName = `F_${toVar(modId)}_${importId++}`
|
|
1014
1029
|
const importPath = hasApp ? `${appImportBase}/data/fields` : `${imps.pkgBase}/data/fields`
|
|
@@ -1018,9 +1033,9 @@ export async function generateModuleRegistryCli(options: ModuleRegistryOptions):
|
|
|
1018
1033
|
}
|
|
1019
1034
|
|
|
1020
1035
|
// CLI
|
|
1021
|
-
const cliApp =
|
|
1022
|
-
const cliPkg =
|
|
1023
|
-
const cliPath =
|
|
1036
|
+
const cliApp = findModuleFile(roots.appBase, 'cli')
|
|
1037
|
+
const cliPkg = findModuleFile(roots.pkgBase, 'cli')
|
|
1038
|
+
const cliPath = cliApp ?? cliPkg
|
|
1024
1039
|
if (cliPath) {
|
|
1025
1040
|
const importName = `CLI_${toVar(modId)}`
|
|
1026
1041
|
const importPath = cliPath.startsWith(roots.appBase) ? `${appImportBase}/cli` : `${imps.pkgBase}/cli`
|
package/src/lib/resolver.ts
CHANGED
|
@@ -28,10 +28,9 @@ export interface PackageResolver {
|
|
|
28
28
|
|
|
29
29
|
function pkgDirFor(rootDir: string, from?: string, isMonorepo = true): string {
|
|
30
30
|
if (!isMonorepo) {
|
|
31
|
-
// Production mode: look in node_modules
|
|
32
|
-
// Packages include source TypeScript files in src/modules
|
|
31
|
+
// Production mode: look in node_modules dist (compiled JS)
|
|
33
32
|
const pkgName = from || '@open-mercato/core'
|
|
34
|
-
return path.join(rootDir, 'node_modules', pkgName, '
|
|
33
|
+
return path.join(rootDir, 'node_modules', pkgName, 'dist', 'modules')
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
// Monorepo mode
|
|
@@ -152,8 +151,8 @@ function discoverPackagesInNodeModules(rootDir: string): PackageInfo[] {
|
|
|
152
151
|
|
|
153
152
|
try {
|
|
154
153
|
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))
|
|
155
|
-
//
|
|
156
|
-
const modulesPath = path.join(pkgPath, '
|
|
154
|
+
// Production mode: use compiled JS files from dist/modules
|
|
155
|
+
const modulesPath = path.join(pkgPath, 'dist', 'modules')
|
|
157
156
|
|
|
158
157
|
if (fs.existsSync(modulesPath)) {
|
|
159
158
|
packages.push({
|