@open-mercato/cli 0.4.2-canary-3f5eaf79f7 โ†’ 0.4.2-canary-f4761534e7

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.
@@ -58,14 +58,16 @@ async function loadModuleEntities(entry, resolver) {
58
58
  path.join(roots.appBase, "db"),
59
59
  path.join(roots.pkgBase, "db")
60
60
  ];
61
- const candidates = ["entities.ts", "schema.ts"];
61
+ const candidates = ["entities.ts", "entities.js", "schema.ts", "schema.js"];
62
62
  for (const base of bases) {
63
63
  for (const f of candidates) {
64
64
  const p = path.join(base, f);
65
65
  if (fs.existsSync(p)) {
66
66
  const sub = path.basename(base);
67
67
  const fromApp = base.startsWith(roots.appBase);
68
- const importPath = isAppModule && fromApp ? `file://${p.replace(/\.ts$/, ".js")}` : `${fromApp ? imps.appBase : imps.pkgBase}/${sub}/${f.replace(/\.ts$/, "")}`;
68
+ const ext = path.extname(f);
69
+ const baseName = f.replace(ext, "");
70
+ const importPath = isAppModule && fromApp ? `file://${p.replace(/\.ts$/, ".js")}` : `${fromApp ? imps.appBase : imps.pkgBase}/${sub}/${baseName}`;
69
71
  try {
70
72
  const mod = await import(importPath);
71
73
  const entities = Object.values(mod).filter((v) => typeof v === "function");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/db/commands.ts"],
4
- "sourcesContent": ["import path from 'node:path'\nimport fs from 'node:fs'\nimport { MikroORM, type Logger } from '@mikro-orm/core'\nimport { Migrator } from '@mikro-orm/migrations'\nimport { PostgreSqlDriver } from '@mikro-orm/postgresql'\nimport type { PackageResolver, ModuleEntry } from '../resolver'\n\nconst QUIET_MODE = process.env.OM_CLI_QUIET === '1' || process.env.MERCATO_QUIET === '1'\nconst PROGRESS_EMOJI = ''\n\nfunction formatResult(modId: string, message: string, emoji = '\u2022') {\n return `${emoji} ${modId}: ${message}`\n}\n\nfunction createProgressRenderer(total: number) {\n const width = 20\n const normalizedTotal = total > 0 ? total : 1\n return (current: number) => {\n const clamped = Math.min(Math.max(current, 0), normalizedTotal)\n const filled = Math.round((clamped / normalizedTotal) * width)\n const bar = `${'='.repeat(filled)}${'.'.repeat(Math.max(width - filled, 0))}`\n return `[${bar}] ${clamped}/${normalizedTotal}`\n }\n}\n\nfunction createMinimalLogger(): Logger {\n return {\n log: () => {},\n error: (_namespace, message) => console.error(message),\n warn: (_namespace, message) => {\n if (!QUIET_MODE) console.warn(message)\n },\n logQuery: () => {},\n setDebugMode: () => {},\n isEnabled: () => false,\n }\n}\n\nfunction getClientUrl(): string {\n const url = process.env.DATABASE_URL\n if (!url) throw new Error('DATABASE_URL is not set')\n return url\n}\n\nfunction sortModules(mods: ModuleEntry[]): ModuleEntry[] {\n // Sort modules alphabetically since they are now isomorphic\n return mods.slice().sort((a, b) => a.id.localeCompare(b.id))\n}\n\n/**\n * Sanitizes a module ID for use in SQL identifiers (table names).\n * Replaces non-alphanumeric characters with underscores to prevent SQL injection.\n * @public Exported for testing\n */\nexport function sanitizeModuleId(modId: string): string {\n return modId.replace(/[^a-z0-9_]/gi, '_')\n}\n\n/**\n * Validates that a table name is safe for use in SQL queries.\n * @throws Error if the table name contains invalid characters.\n * @public Exported for testing\n */\nexport function validateTableName(tableName: string): void {\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tableName)) {\n throw new Error(`Invalid table name: ${tableName}. Table names must start with a letter or underscore and contain only alphanumeric characters and underscores.`)\n }\n}\n\nasync function loadModuleEntities(entry: ModuleEntry, resolver: PackageResolver): Promise<any[]> {\n const roots = resolver.getModulePaths(entry)\n const imps = resolver.getModuleImportBase(entry)\n const isAppModule = entry.from === '@app'\n const bases = [\n path.join(roots.appBase, 'data'),\n path.join(roots.pkgBase, 'data'),\n path.join(roots.appBase, 'db'),\n path.join(roots.pkgBase, 'db'),\n ]\n const candidates = ['entities.ts', 'schema.ts']\n\n for (const base of bases) {\n for (const f of candidates) {\n const p = path.join(base, f)\n if (fs.existsSync(p)) {\n const sub = path.basename(base)\n const fromApp = base.startsWith(roots.appBase)\n // For @app modules, use file:// URL since @/ alias doesn't work in Node.js runtime\n const importPath = (isAppModule && fromApp)\n ? `file://${p.replace(/\\.ts$/, '.js')}`\n : `${fromApp ? imps.appBase : imps.pkgBase}/${sub}/${f.replace(/\\.ts$/, '')}`\n try {\n const mod = await import(importPath)\n const entities = Object.values(mod).filter((v) => typeof v === 'function')\n if (entities.length) return entities as any[]\n } catch (err) {\n // For @app modules with TypeScript files, they can't be directly imported\n // Skip and let MikroORM handle entities through discovery\n if (isAppModule) continue\n throw err\n }\n }\n }\n }\n return []\n}\n\nfunction getMigrationsPath(entry: ModuleEntry, resolver: PackageResolver): string {\n const from = entry.from || '@open-mercato/core'\n\n if (from === '@app') {\n // For @app modules, use the app directory\n return path.join(resolver.getAppDir(), 'src/modules', entry.id, 'migrations')\n }\n\n // Use resolver's getModulePaths which handles monorepo vs production mode\n const { pkgBase } = resolver.getModulePaths(entry)\n return path.join(pkgBase, 'migrations')\n}\n\nexport interface DbOptions {\n quiet?: boolean\n}\n\nexport interface GreenfieldOptions extends DbOptions {\n yes: boolean\n}\n\nexport async function dbGenerate(resolver: PackageResolver, options: DbOptions = {}): Promise<void> {\n const modules = resolver.loadEnabledModules()\n const ordered = sortModules(modules)\n const results: string[] = []\n\n for (const entry of ordered) {\n const modId = entry.id\n const sanitizedModId = sanitizeModuleId(modId)\n const entities = await loadModuleEntities(entry, resolver)\n if (!entities.length) continue\n\n const migrationsPath = getMigrationsPath(entry, resolver)\n fs.mkdirSync(migrationsPath, { recursive: true })\n\n const tableName = `mikro_orm_migrations_${sanitizedModId}`\n validateTableName(tableName)\n\n const orm = await MikroORM.init<PostgreSqlDriver>({\n driver: PostgreSqlDriver,\n clientUrl: getClientUrl(),\n loggerFactory: () => createMinimalLogger(),\n entities,\n migrations: {\n path: migrationsPath,\n glob: '!(*.d).{ts,js}',\n tableName,\n dropTables: false,\n },\n schemaGenerator: {\n disableForeignKeys: true,\n },\n pool: {\n min: 1,\n max: 3,\n idleTimeoutMillis: 30000,\n acquireTimeoutMillis: 60000,\n destroyTimeoutMillis: 30000,\n },\n })\n\n const migrator = orm.getMigrator() as Migrator\n const diff = await migrator.createMigration()\n if (diff && diff.fileName) {\n try {\n const orig = diff.fileName\n const base = path.basename(orig)\n const dir = path.dirname(orig)\n const ext = path.extname(base)\n const stem = base.replace(ext, '')\n const suffix = `_${modId}`\n const newBase = stem.endsWith(suffix) ? base : `${stem}${suffix}${ext}`\n const newPath = path.join(dir, newBase)\n let content = fs.readFileSync(orig, 'utf8')\n // Rename class to ensure uniqueness as well\n content = content.replace(\n /export class (Migration\\d+)/,\n `export class $1_${modId.replace(/[^a-zA-Z0-9]/g, '_')}`\n )\n fs.writeFileSync(newPath, content, 'utf8')\n if (newPath !== orig) fs.unlinkSync(orig)\n results.push(formatResult(modId, `generated ${newBase}`, ''))\n } catch {\n results.push(formatResult(modId, `generated ${path.basename(diff.fileName)} (rename failed)`, ''))\n }\n } else {\n results.push(formatResult(modId, 'no changes', ''))\n }\n\n await orm.close(true)\n }\n\n console.log(results.join('\\n'))\n}\n\nexport async function dbMigrate(resolver: PackageResolver, options: DbOptions = {}): Promise<void> {\n const modules = resolver.loadEnabledModules()\n const ordered = sortModules(modules)\n const results: string[] = []\n\n for (const entry of ordered) {\n const modId = entry.id\n const sanitizedModId = sanitizeModuleId(modId)\n const entities = await loadModuleEntities(entry, resolver)\n\n const migrationsPath = getMigrationsPath(entry, resolver)\n\n // Skip if no entities AND no migrations directory exists\n // (allows @app modules to run migrations even if entities can't be dynamically imported)\n if (!entities.length && !fs.existsSync(migrationsPath)) continue\n fs.mkdirSync(migrationsPath, { recursive: true })\n\n const tableName = `mikro_orm_migrations_${sanitizedModId}`\n validateTableName(tableName)\n\n // For @app modules, entities may be empty since TypeScript files can't be imported at runtime\n // Use discovery.warnWhenNoEntities: false to allow running migrations without entities\n const orm = await MikroORM.init<PostgreSqlDriver>({\n driver: PostgreSqlDriver,\n clientUrl: getClientUrl(),\n loggerFactory: () => createMinimalLogger(),\n entities: entities.length ? entities : [],\n discovery: { warnWhenNoEntities: false },\n migrations: {\n path: migrationsPath,\n glob: '!(*.d).{ts,js}',\n tableName,\n dropTables: false,\n },\n schemaGenerator: {\n disableForeignKeys: true,\n },\n pool: {\n min: 1,\n max: 3,\n idleTimeoutMillis: 30000,\n acquireTimeoutMillis: 60000,\n destroyTimeoutMillis: 30000,\n },\n })\n\n const migrator = orm.getMigrator() as Migrator\n const pending = await migrator.getPendingMigrations()\n if (!pending.length) {\n results.push(formatResult(modId, 'no pending migrations', ''))\n } else {\n const renderProgress = createProgressRenderer(pending.length)\n let applied = 0\n if (!QUIET_MODE) {\n process.stdout.write(` ${PROGRESS_EMOJI} ${modId}: ${renderProgress(applied)}`)\n }\n for (const migration of pending) {\n const migrationName =\n typeof migration === 'string'\n ? migration\n : (migration as any).name ?? (migration as any).fileName\n await migrator.up(migrationName ? { migrations: [migrationName] } : undefined)\n applied += 1\n if (!QUIET_MODE) {\n process.stdout.write(`\\r ${PROGRESS_EMOJI} ${modId}: ${renderProgress(applied)}`)\n }\n }\n if (!QUIET_MODE) process.stdout.write('\\n')\n results.push(\n formatResult(modId, `${pending.length} migration${pending.length === 1 ? '' : 's'} applied`, '')\n )\n }\n\n await orm.close(true)\n }\n\n console.log(results.join('\\n'))\n}\n\nexport async function dbGreenfield(resolver: PackageResolver, options: GreenfieldOptions): Promise<void> {\n if (!options.yes) {\n console.error('This command will DELETE all data. Use --yes to confirm.')\n process.exit(1)\n }\n\n console.log('Cleaning up migrations and snapshots for greenfield setup...')\n\n const modules = resolver.loadEnabledModules()\n const ordered = sortModules(modules)\n const results: string[] = []\n const outputDir = resolver.getOutputDir()\n\n for (const entry of ordered) {\n const modId = entry.id\n const migrationsPath = getMigrationsPath(entry, resolver)\n\n if (fs.existsSync(migrationsPath)) {\n // Remove all migration files\n const migrationFiles = fs\n .readdirSync(migrationsPath)\n .filter((file) => file.endsWith('.ts') && file.startsWith('Migration'))\n\n for (const file of migrationFiles) {\n fs.unlinkSync(path.join(migrationsPath, file))\n }\n\n // Remove snapshot files\n const snapshotFiles = fs\n .readdirSync(migrationsPath)\n .filter((file) => file.endsWith('.json') && file.includes('snapshot'))\n\n for (const file of snapshotFiles) {\n fs.unlinkSync(path.join(migrationsPath, file))\n }\n\n if (migrationFiles.length > 0 || snapshotFiles.length > 0) {\n results.push(\n formatResult(modId, `cleaned ${migrationFiles.length} migrations, ${snapshotFiles.length} snapshots`, '')\n )\n } else {\n results.push(formatResult(modId, 'already clean', ''))\n }\n } else {\n results.push(formatResult(modId, 'no migrations directory', ''))\n }\n\n // Clean up checksum files using glob pattern\n if (fs.existsSync(outputDir)) {\n const files = fs.readdirSync(outputDir)\n const checksumFiles = files.filter((file) => file.endsWith('.checksum'))\n\n for (const file of checksumFiles) {\n fs.unlinkSync(path.join(outputDir, file))\n }\n\n if (checksumFiles.length > 0) {\n results.push(formatResult(modId, `cleaned ${checksumFiles.length} checksum files`, ''))\n }\n }\n }\n\n console.log(results.join('\\n'))\n\n // Drop per-module MikroORM migration tables to ensure clean slate\n console.log('Dropping per-module migration tables...')\n try {\n const { Client } = await import('pg')\n const client = new Client({ connectionString: getClientUrl() })\n await client.connect()\n try {\n await client.query('BEGIN')\n for (const entry of ordered) {\n const modId = entry.id\n const sanitizedModId = sanitizeModuleId(modId)\n const tableName = `mikro_orm_migrations_${sanitizedModId}`\n validateTableName(tableName)\n await client.query(`DROP TABLE IF EXISTS \"${tableName}\"`)\n console.log(` ${modId}: dropped table ${tableName}`)\n }\n await client.query('COMMIT')\n } catch (e) {\n await client.query('ROLLBACK')\n throw e\n } finally {\n try {\n await client.end()\n } catch {}\n }\n } catch (e) {\n console.error('Failed to drop migration tables:', (e as any)?.message || e)\n throw e\n }\n\n // Drop all existing user tables to ensure fresh CREATE-only migrations\n console.log('Dropping ALL public tables for true greenfield...')\n try {\n const { Client } = await import('pg')\n const client = new Client({ connectionString: getClientUrl() })\n await client.connect()\n try {\n const res = await client.query(`SELECT tablename FROM pg_tables WHERE schemaname = 'public'`)\n const tables: string[] = (res.rows || []).map((r: any) => String(r.tablename))\n if (tables.length) {\n await client.query('BEGIN')\n try {\n await client.query(\"SET session_replication_role = 'replica'\")\n for (const t of tables) {\n await client.query(`DROP TABLE IF EXISTS \"${t}\" CASCADE`)\n }\n await client.query(\"SET session_replication_role = 'origin'\")\n await client.query('COMMIT')\n console.log(` Dropped ${tables.length} tables.`)\n } catch (e) {\n await client.query('ROLLBACK')\n throw e\n }\n } else {\n console.log(' No tables found to drop.')\n }\n } finally {\n try {\n await client.end()\n } catch {}\n }\n } catch (e) {\n console.error('Failed to drop public tables:', (e as any)?.message || e)\n throw e\n }\n\n // Generate fresh migrations for all modules\n console.log('Generating fresh migrations for all modules...')\n await dbGenerate(resolver)\n\n // Apply migrations\n console.log('Applying migrations...')\n await dbMigrate(resolver)\n\n console.log('Greenfield reset complete! Fresh migrations generated and applied.')\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import path from 'node:path'\nimport fs from 'node:fs'\nimport { MikroORM, type Logger } from '@mikro-orm/core'\nimport { Migrator } from '@mikro-orm/migrations'\nimport { PostgreSqlDriver } from '@mikro-orm/postgresql'\nimport type { PackageResolver, ModuleEntry } from '../resolver'\n\nconst QUIET_MODE = process.env.OM_CLI_QUIET === '1' || process.env.MERCATO_QUIET === '1'\nconst PROGRESS_EMOJI = ''\n\nfunction formatResult(modId: string, message: string, emoji = '\u2022') {\n return `${emoji} ${modId}: ${message}`\n}\n\nfunction createProgressRenderer(total: number) {\n const width = 20\n const normalizedTotal = total > 0 ? total : 1\n return (current: number) => {\n const clamped = Math.min(Math.max(current, 0), normalizedTotal)\n const filled = Math.round((clamped / normalizedTotal) * width)\n const bar = `${'='.repeat(filled)}${'.'.repeat(Math.max(width - filled, 0))}`\n return `[${bar}] ${clamped}/${normalizedTotal}`\n }\n}\n\nfunction createMinimalLogger(): Logger {\n return {\n log: () => {},\n error: (_namespace, message) => console.error(message),\n warn: (_namespace, message) => {\n if (!QUIET_MODE) console.warn(message)\n },\n logQuery: () => {},\n setDebugMode: () => {},\n isEnabled: () => false,\n }\n}\n\nfunction getClientUrl(): string {\n const url = process.env.DATABASE_URL\n if (!url) throw new Error('DATABASE_URL is not set')\n return url\n}\n\nfunction sortModules(mods: ModuleEntry[]): ModuleEntry[] {\n // Sort modules alphabetically since they are now isomorphic\n return mods.slice().sort((a, b) => a.id.localeCompare(b.id))\n}\n\n/**\n * Sanitizes a module ID for use in SQL identifiers (table names).\n * Replaces non-alphanumeric characters with underscores to prevent SQL injection.\n * @public Exported for testing\n */\nexport function sanitizeModuleId(modId: string): string {\n return modId.replace(/[^a-z0-9_]/gi, '_')\n}\n\n/**\n * Validates that a table name is safe for use in SQL queries.\n * @throws Error if the table name contains invalid characters.\n * @public Exported for testing\n */\nexport function validateTableName(tableName: string): void {\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tableName)) {\n throw new Error(`Invalid table name: ${tableName}. Table names must start with a letter or underscore and contain only alphanumeric characters and underscores.`)\n }\n}\n\nasync function loadModuleEntities(entry: ModuleEntry, resolver: PackageResolver): Promise<any[]> {\n const roots = resolver.getModulePaths(entry)\n const imps = resolver.getModuleImportBase(entry)\n const isAppModule = entry.from === '@app'\n const bases = [\n path.join(roots.appBase, 'data'),\n path.join(roots.pkgBase, 'data'),\n path.join(roots.appBase, 'db'),\n path.join(roots.pkgBase, 'db'),\n ]\n // Check both .ts (src/monorepo) and .js (dist/production) extensions\n const candidates = ['entities.ts', 'entities.js', 'schema.ts', 'schema.js']\n\n for (const base of bases) {\n for (const f of candidates) {\n const p = path.join(base, f)\n if (fs.existsSync(p)) {\n const sub = path.basename(base)\n const fromApp = base.startsWith(roots.appBase)\n const ext = path.extname(f)\n const baseName = f.replace(ext, '')\n // For @app modules, use file:// URL since @/ alias doesn't work in Node.js runtime\n const importPath = (isAppModule && fromApp)\n ? `file://${p.replace(/\\.ts$/, '.js')}`\n : `${fromApp ? imps.appBase : imps.pkgBase}/${sub}/${baseName}`\n try {\n const mod = await import(importPath)\n const entities = Object.values(mod).filter((v) => typeof v === 'function')\n if (entities.length) return entities as any[]\n } catch (err) {\n // For @app modules with TypeScript files, they can't be directly imported\n // Skip and let MikroORM handle entities through discovery\n if (isAppModule) continue\n throw err\n }\n }\n }\n }\n return []\n}\n\nfunction getMigrationsPath(entry: ModuleEntry, resolver: PackageResolver): string {\n const from = entry.from || '@open-mercato/core'\n\n if (from === '@app') {\n // For @app modules, use the app directory\n return path.join(resolver.getAppDir(), 'src/modules', entry.id, 'migrations')\n }\n\n // Use resolver's getModulePaths which handles monorepo vs production mode\n const { pkgBase } = resolver.getModulePaths(entry)\n return path.join(pkgBase, 'migrations')\n}\n\nexport interface DbOptions {\n quiet?: boolean\n}\n\nexport interface GreenfieldOptions extends DbOptions {\n yes: boolean\n}\n\nexport async function dbGenerate(resolver: PackageResolver, options: DbOptions = {}): Promise<void> {\n const modules = resolver.loadEnabledModules()\n const ordered = sortModules(modules)\n const results: string[] = []\n\n for (const entry of ordered) {\n const modId = entry.id\n const sanitizedModId = sanitizeModuleId(modId)\n const entities = await loadModuleEntities(entry, resolver)\n if (!entities.length) continue\n\n const migrationsPath = getMigrationsPath(entry, resolver)\n fs.mkdirSync(migrationsPath, { recursive: true })\n\n const tableName = `mikro_orm_migrations_${sanitizedModId}`\n validateTableName(tableName)\n\n const orm = await MikroORM.init<PostgreSqlDriver>({\n driver: PostgreSqlDriver,\n clientUrl: getClientUrl(),\n loggerFactory: () => createMinimalLogger(),\n entities,\n migrations: {\n path: migrationsPath,\n glob: '!(*.d).{ts,js}',\n tableName,\n dropTables: false,\n },\n schemaGenerator: {\n disableForeignKeys: true,\n },\n pool: {\n min: 1,\n max: 3,\n idleTimeoutMillis: 30000,\n acquireTimeoutMillis: 60000,\n destroyTimeoutMillis: 30000,\n },\n })\n\n const migrator = orm.getMigrator() as Migrator\n const diff = await migrator.createMigration()\n if (diff && diff.fileName) {\n try {\n const orig = diff.fileName\n const base = path.basename(orig)\n const dir = path.dirname(orig)\n const ext = path.extname(base)\n const stem = base.replace(ext, '')\n const suffix = `_${modId}`\n const newBase = stem.endsWith(suffix) ? base : `${stem}${suffix}${ext}`\n const newPath = path.join(dir, newBase)\n let content = fs.readFileSync(orig, 'utf8')\n // Rename class to ensure uniqueness as well\n content = content.replace(\n /export class (Migration\\d+)/,\n `export class $1_${modId.replace(/[^a-zA-Z0-9]/g, '_')}`\n )\n fs.writeFileSync(newPath, content, 'utf8')\n if (newPath !== orig) fs.unlinkSync(orig)\n results.push(formatResult(modId, `generated ${newBase}`, ''))\n } catch {\n results.push(formatResult(modId, `generated ${path.basename(diff.fileName)} (rename failed)`, ''))\n }\n } else {\n results.push(formatResult(modId, 'no changes', ''))\n }\n\n await orm.close(true)\n }\n\n console.log(results.join('\\n'))\n}\n\nexport async function dbMigrate(resolver: PackageResolver, options: DbOptions = {}): Promise<void> {\n const modules = resolver.loadEnabledModules()\n const ordered = sortModules(modules)\n const results: string[] = []\n\n for (const entry of ordered) {\n const modId = entry.id\n const sanitizedModId = sanitizeModuleId(modId)\n const entities = await loadModuleEntities(entry, resolver)\n\n const migrationsPath = getMigrationsPath(entry, resolver)\n\n // Skip if no entities AND no migrations directory exists\n // (allows @app modules to run migrations even if entities can't be dynamically imported)\n if (!entities.length && !fs.existsSync(migrationsPath)) continue\n fs.mkdirSync(migrationsPath, { recursive: true })\n\n const tableName = `mikro_orm_migrations_${sanitizedModId}`\n validateTableName(tableName)\n\n // For @app modules, entities may be empty since TypeScript files can't be imported at runtime\n // Use discovery.warnWhenNoEntities: false to allow running migrations without entities\n const orm = await MikroORM.init<PostgreSqlDriver>({\n driver: PostgreSqlDriver,\n clientUrl: getClientUrl(),\n loggerFactory: () => createMinimalLogger(),\n entities: entities.length ? entities : [],\n discovery: { warnWhenNoEntities: false },\n migrations: {\n path: migrationsPath,\n glob: '!(*.d).{ts,js}',\n tableName,\n dropTables: false,\n },\n schemaGenerator: {\n disableForeignKeys: true,\n },\n pool: {\n min: 1,\n max: 3,\n idleTimeoutMillis: 30000,\n acquireTimeoutMillis: 60000,\n destroyTimeoutMillis: 30000,\n },\n })\n\n const migrator = orm.getMigrator() as Migrator\n const pending = await migrator.getPendingMigrations()\n if (!pending.length) {\n results.push(formatResult(modId, 'no pending migrations', ''))\n } else {\n const renderProgress = createProgressRenderer(pending.length)\n let applied = 0\n if (!QUIET_MODE) {\n process.stdout.write(` ${PROGRESS_EMOJI} ${modId}: ${renderProgress(applied)}`)\n }\n for (const migration of pending) {\n const migrationName =\n typeof migration === 'string'\n ? migration\n : (migration as any).name ?? (migration as any).fileName\n await migrator.up(migrationName ? { migrations: [migrationName] } : undefined)\n applied += 1\n if (!QUIET_MODE) {\n process.stdout.write(`\\r ${PROGRESS_EMOJI} ${modId}: ${renderProgress(applied)}`)\n }\n }\n if (!QUIET_MODE) process.stdout.write('\\n')\n results.push(\n formatResult(modId, `${pending.length} migration${pending.length === 1 ? '' : 's'} applied`, '')\n )\n }\n\n await orm.close(true)\n }\n\n console.log(results.join('\\n'))\n}\n\nexport async function dbGreenfield(resolver: PackageResolver, options: GreenfieldOptions): Promise<void> {\n if (!options.yes) {\n console.error('This command will DELETE all data. Use --yes to confirm.')\n process.exit(1)\n }\n\n console.log('Cleaning up migrations and snapshots for greenfield setup...')\n\n const modules = resolver.loadEnabledModules()\n const ordered = sortModules(modules)\n const results: string[] = []\n const outputDir = resolver.getOutputDir()\n\n for (const entry of ordered) {\n const modId = entry.id\n const migrationsPath = getMigrationsPath(entry, resolver)\n\n if (fs.existsSync(migrationsPath)) {\n // Remove all migration files\n const migrationFiles = fs\n .readdirSync(migrationsPath)\n .filter((file) => file.endsWith('.ts') && file.startsWith('Migration'))\n\n for (const file of migrationFiles) {\n fs.unlinkSync(path.join(migrationsPath, file))\n }\n\n // Remove snapshot files\n const snapshotFiles = fs\n .readdirSync(migrationsPath)\n .filter((file) => file.endsWith('.json') && file.includes('snapshot'))\n\n for (const file of snapshotFiles) {\n fs.unlinkSync(path.join(migrationsPath, file))\n }\n\n if (migrationFiles.length > 0 || snapshotFiles.length > 0) {\n results.push(\n formatResult(modId, `cleaned ${migrationFiles.length} migrations, ${snapshotFiles.length} snapshots`, '')\n )\n } else {\n results.push(formatResult(modId, 'already clean', ''))\n }\n } else {\n results.push(formatResult(modId, 'no migrations directory', ''))\n }\n\n // Clean up checksum files using glob pattern\n if (fs.existsSync(outputDir)) {\n const files = fs.readdirSync(outputDir)\n const checksumFiles = files.filter((file) => file.endsWith('.checksum'))\n\n for (const file of checksumFiles) {\n fs.unlinkSync(path.join(outputDir, file))\n }\n\n if (checksumFiles.length > 0) {\n results.push(formatResult(modId, `cleaned ${checksumFiles.length} checksum files`, ''))\n }\n }\n }\n\n console.log(results.join('\\n'))\n\n // Drop per-module MikroORM migration tables to ensure clean slate\n console.log('Dropping per-module migration tables...')\n try {\n const { Client } = await import('pg')\n const client = new Client({ connectionString: getClientUrl() })\n await client.connect()\n try {\n await client.query('BEGIN')\n for (const entry of ordered) {\n const modId = entry.id\n const sanitizedModId = sanitizeModuleId(modId)\n const tableName = `mikro_orm_migrations_${sanitizedModId}`\n validateTableName(tableName)\n await client.query(`DROP TABLE IF EXISTS \"${tableName}\"`)\n console.log(` ${modId}: dropped table ${tableName}`)\n }\n await client.query('COMMIT')\n } catch (e) {\n await client.query('ROLLBACK')\n throw e\n } finally {\n try {\n await client.end()\n } catch {}\n }\n } catch (e) {\n console.error('Failed to drop migration tables:', (e as any)?.message || e)\n throw e\n }\n\n // Drop all existing user tables to ensure fresh CREATE-only migrations\n console.log('Dropping ALL public tables for true greenfield...')\n try {\n const { Client } = await import('pg')\n const client = new Client({ connectionString: getClientUrl() })\n await client.connect()\n try {\n const res = await client.query(`SELECT tablename FROM pg_tables WHERE schemaname = 'public'`)\n const tables: string[] = (res.rows || []).map((r: any) => String(r.tablename))\n if (tables.length) {\n await client.query('BEGIN')\n try {\n await client.query(\"SET session_replication_role = 'replica'\")\n for (const t of tables) {\n await client.query(`DROP TABLE IF EXISTS \"${t}\" CASCADE`)\n }\n await client.query(\"SET session_replication_role = 'origin'\")\n await client.query('COMMIT')\n console.log(` Dropped ${tables.length} tables.`)\n } catch (e) {\n await client.query('ROLLBACK')\n throw e\n }\n } else {\n console.log(' No tables found to drop.')\n }\n } finally {\n try {\n await client.end()\n } catch {}\n }\n } catch (e) {\n console.error('Failed to drop public tables:', (e as any)?.message || e)\n throw e\n }\n\n // Generate fresh migrations for all modules\n console.log('Generating fresh migrations for all modules...')\n await dbGenerate(resolver)\n\n // Apply migrations\n console.log('Applying migrations...')\n await dbMigrate(resolver)\n\n console.log('Greenfield reset complete! Fresh migrations generated and applied.')\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -28,7 +28,7 @@ async function generateModuleEntities(options) {
28
28
  const appDb = path.join(roots.appBase, "db");
29
29
  const pkgDb = path.join(roots.pkgBase, "db");
30
30
  const bases = [appData, pkgData, appDb, pkgDb];
31
- const candidates = ["entities.override.ts", "entities.ts", "schema.ts"];
31
+ const candidates = ["entities.override.ts", "entities.override.js", "entities.ts", "entities.js", "schema.ts", "schema.js"];
32
32
  let found = null;
33
33
  for (const base of bases) {
34
34
  for (const f of candidates) {
@@ -46,11 +46,12 @@ async function generateModuleEntities(options) {
46
46
  const fromApp = found.base.startsWith(roots.appBase);
47
47
  const isAppModule = entry.from === "@app";
48
48
  let relImport;
49
+ const fileBaseName = found.file.replace(/\.(ts|js)$/, "");
49
50
  if (isAppModule && fromApp) {
50
- relImport = `../../src/modules/${modId}/${sub}/${found.file.replace(/\.ts$/, "")}`;
51
+ relImport = `../../src/modules/${modId}/${sub}/${fileBaseName}`;
51
52
  } else {
52
53
  const baseImport = fromApp ? imp.appBase : imp.pkgBase;
53
- relImport = `${baseImport}/${sub}/${found.file.replace(/\.ts$/, "")}`;
54
+ relImport = `${baseImport}/${sub}/${fileBaseName}`;
54
55
  }
55
56
  imports.push(`import * as ${importName} from '${relImport}'`);
56
57
  entitySources.push({ importName, moduleId: modId });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/generators/module-entities.ts"],
4
- "sourcesContent": ["import fs from 'node:fs'\nimport path from 'node:path'\nimport type { PackageResolver } from '../resolver'\nimport {\n calculateChecksum,\n readChecksumRecord,\n writeChecksumRecord,\n ensureDir,\n toVar,\n logGenerationResult,\n type GeneratorResult,\n createGeneratorResult,\n} from '../utils'\n\nexport interface ModuleEntitiesOptions {\n resolver: PackageResolver\n quiet?: boolean\n}\n\nexport async function generateModuleEntities(options: ModuleEntitiesOptions): Promise<GeneratorResult> {\n const { resolver, quiet = false } = options\n const result = createGeneratorResult()\n\n const outputDir = resolver.getOutputDir()\n const outFile = path.join(outputDir, 'entities.generated.ts')\n const checksumFile = path.join(outputDir, 'entities.generated.checksum')\n\n const mods = resolver.loadEnabledModules()\n const imports: string[] = []\n const entitySources: Array<{ importName: string; moduleId: string }> = []\n let n = 0\n\n for (const entry of mods) {\n const modId = entry.id\n const roots = resolver.getModulePaths(entry)\n const imp = resolver.getModuleImportBase(entry)\n\n // prefer app override data/, fallback to core data/, then legacy db/\n const appData = path.join(roots.appBase, 'data')\n const pkgData = path.join(roots.pkgBase, 'data')\n const appDb = path.join(roots.appBase, 'db')\n const pkgDb = path.join(roots.pkgBase, 'db')\n const bases = [appData, pkgData, appDb, pkgDb]\n const candidates = ['entities.override.ts', 'entities.ts', 'schema.ts']\n\n let found: { base: string; file: string } | null = null\n for (const base of bases) {\n for (const f of candidates) {\n const p = path.join(base, f)\n if (fs.existsSync(p)) {\n found = { base, file: f }\n break\n }\n }\n if (found) break\n }\n if (!found) continue\n\n const importName = `E_${toVar(modId)}_${n++}`\n const sub = path.basename(found.base) // 'data' or 'db'\n const fromApp = found.base.startsWith(roots.appBase)\n const isAppModule = entry.from === '@app'\n // For @app modules, use relative path to ensure it works both in Next.js and Node.js CLI context\n // From .mercato/generated/, the relative path to src/modules/ is ../src/modules/\n let relImport: string\n if (isAppModule && fromApp) {\n // From .mercato/generated/, go up two levels (../..) to reach the app root, then into src/modules/\n relImport = `../../src/modules/${modId}/${sub}/${found.file.replace(/\\.ts$/, '')}`\n } else {\n const baseImport = fromApp ? imp.appBase : imp.pkgBase\n relImport = `${baseImport}/${sub}/${found.file.replace(/\\.ts$/, '')}`\n }\n imports.push(`import * as ${importName} from '${relImport}'`)\n entitySources.push({ importName, moduleId: modId })\n }\n\n const output = `// AUTO-GENERATED by mercato generate entities\n${imports.join('\\n')}\n\nfunction enhanceEntities(namespace: Record<string, unknown>, moduleId: string): any[] {\n return Object.entries(namespace)\n .filter(([, value]) => typeof value === 'function')\n .map(([exportName, value]) => {\n const entity = value as { entityName?: string }\n if (entity && typeof entity === 'function' && !Object.prototype.hasOwnProperty.call(entity, 'entityName')) {\n Object.defineProperty(entity, 'entityName', {\n value: \\`\\${moduleId}.\\${exportName}\\`,\n configurable: true,\n enumerable: false,\n writable: false,\n })\n }\n return entity\n })\n}\n\nexport const entities = [\n ${entitySources.map(({ importName, moduleId }) => `...enhanceEntities(${importName}, '${moduleId}')`).join(',\\n ')}\n]\n`\n\n // Check if content has changed\n const newChecksum = calculateChecksum(output)\n let shouldWrite = true\n\n const existingRecord = readChecksumRecord(checksumFile)\n if (existingRecord && existingRecord.content === newChecksum) {\n shouldWrite = false\n }\n\n if (shouldWrite) {\n ensureDir(outFile)\n fs.writeFileSync(outFile, output)\n writeChecksumRecord(checksumFile, { content: newChecksum, structure: '' })\n result.filesWritten.push(outFile)\n if (!quiet) {\n logGenerationResult(path.relative(process.cwd(), outFile), true)\n }\n } else {\n result.filesUnchanged.push(outFile)\n }\n\n return result\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import fs from 'node:fs'\nimport path from 'node:path'\nimport type { PackageResolver } from '../resolver'\nimport {\n calculateChecksum,\n readChecksumRecord,\n writeChecksumRecord,\n ensureDir,\n toVar,\n logGenerationResult,\n type GeneratorResult,\n createGeneratorResult,\n} from '../utils'\n\nexport interface ModuleEntitiesOptions {\n resolver: PackageResolver\n quiet?: boolean\n}\n\nexport async function generateModuleEntities(options: ModuleEntitiesOptions): Promise<GeneratorResult> {\n const { resolver, quiet = false } = options\n const result = createGeneratorResult()\n\n const outputDir = resolver.getOutputDir()\n const outFile = path.join(outputDir, 'entities.generated.ts')\n const checksumFile = path.join(outputDir, 'entities.generated.checksum')\n\n const mods = resolver.loadEnabledModules()\n const imports: string[] = []\n const entitySources: Array<{ importName: string; moduleId: string }> = []\n let n = 0\n\n for (const entry of mods) {\n const modId = entry.id\n const roots = resolver.getModulePaths(entry)\n const imp = resolver.getModuleImportBase(entry)\n\n // prefer app override data/, fallback to core data/, then legacy db/\n const appData = path.join(roots.appBase, 'data')\n const pkgData = path.join(roots.pkgBase, 'data')\n const appDb = path.join(roots.appBase, 'db')\n const pkgDb = path.join(roots.pkgBase, 'db')\n const bases = [appData, pkgData, appDb, pkgDb]\n const candidates = ['entities.override.ts', 'entities.override.js', 'entities.ts', 'entities.js', 'schema.ts', 'schema.js']\n\n let found: { base: string; file: string } | null = null\n for (const base of bases) {\n for (const f of candidates) {\n const p = path.join(base, f)\n if (fs.existsSync(p)) {\n found = { base, file: f }\n break\n }\n }\n if (found) break\n }\n if (!found) continue\n\n const importName = `E_${toVar(modId)}_${n++}`\n const sub = path.basename(found.base) // 'data' or 'db'\n const fromApp = found.base.startsWith(roots.appBase)\n const isAppModule = entry.from === '@app'\n // For @app modules, use relative path to ensure it works both in Next.js and Node.js CLI context\n // From .mercato/generated/, the relative path to src/modules/ is ../src/modules/\n let relImport: string\n const fileBaseName = found.file.replace(/\\.(ts|js)$/, '')\n if (isAppModule && fromApp) {\n // From .mercato/generated/, go up two levels (../..) to reach the app root, then into src/modules/\n relImport = `../../src/modules/${modId}/${sub}/${fileBaseName}`\n } else {\n const baseImport = fromApp ? imp.appBase : imp.pkgBase\n relImport = `${baseImport}/${sub}/${fileBaseName}`\n }\n imports.push(`import * as ${importName} from '${relImport}'`)\n entitySources.push({ importName, moduleId: modId })\n }\n\n const output = `// AUTO-GENERATED by mercato generate entities\n${imports.join('\\n')}\n\nfunction enhanceEntities(namespace: Record<string, unknown>, moduleId: string): any[] {\n return Object.entries(namespace)\n .filter(([, value]) => typeof value === 'function')\n .map(([exportName, value]) => {\n const entity = value as { entityName?: string }\n if (entity && typeof entity === 'function' && !Object.prototype.hasOwnProperty.call(entity, 'entityName')) {\n Object.defineProperty(entity, 'entityName', {\n value: \\`\\${moduleId}.\\${exportName}\\`,\n configurable: true,\n enumerable: false,\n writable: false,\n })\n }\n return entity\n })\n}\n\nexport const entities = [\n ${entitySources.map(({ importName, moduleId }) => `...enhanceEntities(${importName}, '${moduleId}')`).join(',\\n ')}\n]\n`\n\n // Check if content has changed\n const newChecksum = calculateChecksum(output)\n let shouldWrite = true\n\n const existingRecord = readChecksumRecord(checksumFile)\n if (existingRecord && existingRecord.content === newChecksum) {\n shouldWrite = false\n }\n\n if (shouldWrite) {\n ensureDir(outFile)\n fs.writeFileSync(outFile, output)\n writeChecksumRecord(checksumFile, { content: newChecksum, structure: '' })\n result.filesWritten.push(outFile)\n if (!quiet) {\n logGenerationResult(path.relative(process.cwd(), outFile), true)\n }\n } else {\n result.filesUnchanged.push(outFile)\n }\n\n return result\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/dist/mercato.js CHANGED
@@ -39,6 +39,18 @@ async function runModuleCommand(allModules, moduleName, commandName, args = [])
39
39
  }
40
40
  await cmd.run(args);
41
41
  }
42
+ async function tryRunModuleCommand(allModules, moduleName, commandName, args = []) {
43
+ const mod = allModules.find((m) => m.id === moduleName);
44
+ if (!mod || !mod.cli || mod.cli.length === 0) {
45
+ return false;
46
+ }
47
+ const cmd = mod.cli.find((c) => c.command === commandName);
48
+ if (!cmd) {
49
+ return false;
50
+ }
51
+ await cmd.run(args);
52
+ return true;
53
+ }
42
54
  async function buildAllModules() {
43
55
  const modules = getCliModules();
44
56
  let appCli = [];
@@ -240,21 +252,21 @@ async function run(argv = process.argv) {
240
252
  console.log("\u{1F4DA} Seeding customer dictionaries...");
241
253
  await runModuleCommand(allModules, "customers", "seed-dictionaries", ["--tenant", tenantId, "--org", orgId]);
242
254
  console.log("\u{1F4DA} \u2705 Customer dictionaries seeded\n");
243
- console.log("\u{1F3E0} Seeding staff address types...");
244
- await runModuleCommand(allModules, "staff", "seed-address-types", ["--tenant", tenantId, "--org", orgId]);
245
- console.log("\u{1F3E0} \u2705 Staff address types seeded\n");
246
- console.log("\u{1F3E0} Seeding resources address types...");
247
- await runModuleCommand(allModules, "resources", "seed-address-types", ["--tenant", tenantId, "--org", orgId]);
248
- console.log("\u{1F3E0} \u2705 Resources address types seeded\n");
255
+ if (await tryRunModuleCommand(allModules, "staff", "seed-address-types", ["--tenant", tenantId, "--org", orgId])) {
256
+ console.log("\u{1F3E0} \u2705 Staff address types seeded\n");
257
+ }
258
+ if (await tryRunModuleCommand(allModules, "resources", "seed-address-types", ["--tenant", tenantId, "--org", orgId])) {
259
+ console.log("\u{1F3E0} \u2705 Resources address types seeded\n");
260
+ }
249
261
  console.log("\u{1F4DA} Seeding currencies...");
250
262
  await runModuleCommand(allModules, "currencies", "seed", ["--tenant", tenantId, "--org", orgId]);
251
263
  console.log("\u{1F4DA} \u2705 Currencies seeded\n");
252
264
  console.log("\u{1F4CF} Seeding catalog units...");
253
265
  await runModuleCommand(allModules, "catalog", "seed-units", ["--tenant", tenantId, "--org", orgId]);
254
266
  console.log("\u{1F4CF} \u2705 Catalog units seeded\n");
255
- console.log("\u{1F5D3}\uFE0F Seeding unavailability reasons...");
256
- await runModuleCommand(allModules, "planner", "seed-unavailability-reasons", ["--tenant", tenantId, "--org", orgId]);
257
- console.log("\u{1F5D3}\uFE0F \u2705 Unavailability reasons seeded\n");
267
+ if (await tryRunModuleCommand(allModules, "planner", "seed-unavailability-reasons", ["--tenant", tenantId, "--org", orgId])) {
268
+ console.log("\u{1F5D3}\uFE0F \u2705 Unavailability reasons seeded\n");
269
+ }
258
270
  const parsedEncryption = parseBooleanToken(process.env.TENANT_DATA_ENCRYPTION ?? "yes");
259
271
  const encryptionEnabled = parsedEncryption === null ? true : parsedEncryption;
260
272
  if (encryptionEnabled) {
@@ -301,18 +313,18 @@ async function run(argv = process.argv) {
301
313
  console.log("\u{1F9FE} Seeding sales examples...");
302
314
  await runModuleCommand(allModules, "sales", "seed-examples", ["--tenant", tenantId, "--org", orgId]);
303
315
  console.log("\u{1F9FE} \u2705 Sales examples seeded\n");
304
- console.log("\u{1F465} Seeding staff examples...");
305
- await runModuleCommand(allModules, "staff", "seed-examples", ["--tenant", tenantId, "--org", orgId]);
306
- console.log("\u{1F465} \u2705 Staff examples seeded\n");
307
- console.log("\u{1F4E6} Seeding resource capacity units...");
308
- await runModuleCommand(allModules, "resources", "seed-capacity-units", ["--tenant", tenantId, "--org", orgId]);
309
- console.log("\u{1F4E6} \u2705 Resource capacity units seeded\n");
310
- console.log("\u{1F9F0} Seeding resource examples...");
311
- await runModuleCommand(allModules, "resources", "seed-examples", ["--tenant", tenantId, "--org", orgId]);
312
- console.log("\u{1F9F0} \u2705 Resource examples seeded\n");
313
- console.log("\u{1F5D3}\uFE0F Seeding planner availability rulesets...");
314
- await runModuleCommand(allModules, "planner", "seed-availability-rulesets", ["--tenant", tenantId, "--org", orgId]);
315
- console.log("\u{1F5D3}\uFE0F \u2705 Planner availability rulesets seeded\n");
316
+ if (await tryRunModuleCommand(allModules, "staff", "seed-examples", ["--tenant", tenantId, "--org", orgId])) {
317
+ console.log("\u{1F465} \u2705 Staff examples seeded\n");
318
+ }
319
+ if (await tryRunModuleCommand(allModules, "resources", "seed-capacity-units", ["--tenant", tenantId, "--org", orgId])) {
320
+ console.log("\u{1F4E6} \u2705 Resource capacity units seeded\n");
321
+ }
322
+ if (await tryRunModuleCommand(allModules, "resources", "seed-examples", ["--tenant", tenantId, "--org", orgId])) {
323
+ console.log("\u{1F9F0} \u2705 Resource examples seeded\n");
324
+ }
325
+ if (await tryRunModuleCommand(allModules, "planner", "seed-availability-rulesets", ["--tenant", tenantId, "--org", orgId])) {
326
+ console.log("\u{1F5D3}\uFE0F \u2705 Planner availability rulesets seeded\n");
327
+ }
316
328
  const exampleModule = allModules.find((m) => m.id === "example");
317
329
  if (exampleModule && exampleModule.cli) {
318
330
  console.log("\u{1F4DD} Seeding example todos...");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/mercato.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\n// Note: Generated files and DI container are imported statically to avoid ESM/CJS interop issues.\n// Commands that need to run before generation (e.g., `init`) handle missing modules gracefully.\n\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { runWorker } from '@open-mercato/queue/worker'\nimport type { Module } from '@open-mercato/shared/modules/registry'\nimport { getCliModules, hasCliModules, registerCliModules } from './registry'\nexport { getCliModules, hasCliModules, registerCliModules }\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\nimport type { ChildProcess } from 'node:child_process'\nimport path from 'node:path'\nimport fs from 'node:fs'\n\nlet envLoaded = false\n\nasync function ensureEnvLoaded() {\n if (envLoaded) return\n envLoaded = true\n\n // Try to find and load .env from the app directory\n // First, try to find the app directory via resolver\n try {\n const { createResolver } = await import('./lib/resolver.js')\n const resolver = createResolver()\n const appDir = resolver.getAppDir()\n\n // Load .env from app directory if it exists\n const envPath = path.join(appDir, '.env')\n if (fs.existsSync(envPath)) {\n const dotenv = await import('dotenv')\n dotenv.config({ path: envPath })\n return\n }\n } catch {\n // Resolver might fail during early init, fall back to default behavior\n }\n\n // Fall back to default dotenv behavior (loads from cwd)\n try {\n await import('dotenv/config')\n } catch {}\n}\n\n// Helper to run a CLI command directly (without spawning a process)\nasync function runModuleCommand(\n allModules: Module[],\n moduleName: string,\n commandName: string,\n args: string[] = []\n): Promise<void> {\n const mod = allModules.find((m) => m.id === moduleName)\n if (!mod) {\n throw new Error(`Module not found: \"${moduleName}\"`)\n }\n if (!mod.cli || mod.cli.length === 0) {\n throw new Error(`Module \"${moduleName}\" has no CLI commands`)\n }\n const cmd = mod.cli.find((c) => c.command === commandName)\n if (!cmd) {\n throw new Error(`Command \"${commandName}\" not found in module \"${moduleName}\"`)\n }\n await cmd.run(args)\n}\n\n// Build all CLI modules (registered + built-in)\nasync function buildAllModules(): Promise<Module[]> {\n const modules = getCliModules()\n\n // Load optional app-level CLI commands\n let appCli: any[] = []\n try {\n const dynImport: any = (Function('return import') as any)()\n const app = await dynImport.then((f: any) => f('@/cli')).catch(() => null)\n if (app && Array.isArray(app?.default)) appCli = app.default\n } catch {}\n\n const all = modules.slice()\n\n if (appCli.length) all.push({ id: 'app', cli: appCli } as any)\n\n return all\n}\n\nexport async function run(argv = process.argv) {\n await ensureEnvLoaded()\n const [, , ...parts] = argv\n const [first, second, ...remaining] = parts\n \n // Handle init command directly\n if (first === 'init') {\n const { execSync } = await import('child_process')\n\n console.log('\uD83D\uDE80 Initializing Open Mercato app...\\n')\n\n try {\n const initArgs = parts.slice(1).filter(Boolean)\n const reinstall = initArgs.includes('--reinstall') || initArgs.includes('-r')\n const skipExamples = initArgs.includes('--no-examples') || initArgs.includes('--no-exampls')\n const stressTestEnabled =\n initArgs.includes('--stresstest') || initArgs.includes('--stress-test')\n const stressTestLite =\n initArgs.includes('--lite') ||\n initArgs.includes('--stress-lite') ||\n initArgs.some((arg) => arg.startsWith('--payload=lite') || arg.startsWith('--mode=lite'))\n let stressTestCount = 6000\n for (let i = 0; i < initArgs.length; i += 1) {\n const arg = initArgs[i]\n const countPrefixes = ['--count=', '--stress-count=', '--stresstest-count=']\n const matchedPrefix = countPrefixes.find((prefix) => arg.startsWith(prefix))\n if (matchedPrefix) {\n const value = arg.slice(matchedPrefix.length)\n const parsed = Number.parseInt(value, 10)\n if (Number.isFinite(parsed) && parsed > 0) {\n stressTestCount = parsed\n break\n }\n }\n if (arg === '--count' || arg === '--stress-count' || arg === '--stresstest-count' || arg === '-n') {\n const next = initArgs[i + 1]\n if (next && !next.startsWith('-')) {\n const parsed = Number.parseInt(next, 10)\n if (Number.isFinite(parsed) && parsed > 0) {\n stressTestCount = parsed\n break\n }\n }\n }\n if (arg.startsWith('-n=')) {\n const value = arg.slice(3)\n const parsed = Number.parseInt(value, 10)\n if (Number.isFinite(parsed) && parsed > 0) {\n stressTestCount = parsed\n break\n }\n }\n }\n console.log(`\uD83D\uDD04 Reinstall mode: ${reinstall ? 'enabled' : 'disabled'}`)\n console.log(`\uD83C\uDFA8 Example content: ${skipExamples ? 'skipped (--no-examples)' : 'enabled'}`)\n console.log(\n `\uD83C\uDFCB\uFE0F Stress test dataset: ${\n stressTestEnabled\n ? `enabled (target ${stressTestCount} contacts${stressTestLite ? ', lite payload' : ''})`\n : 'disabled'\n }`\n )\n\n if (reinstall) {\n // Load env variables so DATABASE_URL is available\n await ensureEnvLoaded()\n console.log('\u267B\uFE0F Reinstall mode enabled: dropping all database tables...')\n const { Client } = await import('pg')\n const dbUrl = process.env.DATABASE_URL\n if (!dbUrl) {\n console.error('DATABASE_URL is not set. Aborting reinstall.')\n return 1\n }\n const client = new Client({ connectionString: dbUrl })\n try {\n await client.connect()\n // Collect all user tables in public schema\n const res = await client.query(`SELECT tablename FROM pg_tables WHERE schemaname = 'public'`)\n const dropTargets = new Set<string>((res.rows || []).map((r: any) => String(r.tablename)))\n for (const forced of ['vector_search', 'vector_search_migrations']) {\n const exists = await client.query(\n `SELECT to_regclass($1) AS regclass`,\n [`public.${forced}`],\n )\n const regclass = (exists as { rows?: Array<{ regclass: string | null }> }).rows?.[0]?.regclass ?? null\n if (regclass) {\n dropTargets.add(forced)\n }\n }\n if (dropTargets.size === 0) {\n console.log(' No tables found in public schema.')\n } else {\n let dropped = 0\n await client.query('BEGIN')\n try {\n for (const t of dropTargets) {\n await client.query(`DROP TABLE IF EXISTS \"${t}\" CASCADE`)\n dropped += 1\n }\n await client.query('COMMIT')\n console.log(` Dropped ${dropped} tables.`)\n } catch (e) {\n await client.query('ROLLBACK')\n throw e\n }\n }\n } finally {\n try { await client.end() } catch {}\n }\n // Also flush Redis\n try {\n const Redis = (await import('ioredis')).default\n const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379'\n const redis = new Redis(redisUrl)\n await redis.flushall()\n await redis.quit()\n console.log(' Redis flushed.')\n } catch {}\n console.log('\u2705 Database cleared. Proceeding with fresh initialization...\\n')\n }\n\n // Step 1: Run generators directly (no process spawn)\n console.log('\uD83D\uDD27 Preparing modules (registry, entities, DI)...')\n const { createResolver } = await import('./lib/resolver')\n const { generateEntityIds, generateModuleRegistry, generateModuleRegistryCli, generateModuleEntities, generateModuleDi } = await import('./lib/generators')\n const resolver = createResolver()\n await generateEntityIds({ resolver, quiet: true })\n await generateModuleRegistry({ resolver, quiet: true })\n await generateModuleRegistryCli({ resolver, quiet: true })\n await generateModuleEntities({ resolver, quiet: true })\n await generateModuleDi({ resolver, quiet: true })\n console.log('\u2705 Modules prepared\\n')\n\n // Step 3: Apply database migrations directly\n console.log('\uD83D\uDCCA Applying database migrations...')\n const { dbMigrate } = await import('./lib/db')\n await dbMigrate(resolver)\n console.log('\u2705 Migrations applied\\n')\n\n // Step 4: Bootstrap to register modules and entity IDs\n // Use the shared dynamicLoader which compiles TypeScript files on-the-fly\n console.log('\uD83D\uDD17 Bootstrapping application...')\n const { bootstrapFromAppRoot } = await import('@open-mercato/shared/lib/bootstrap/dynamicLoader')\n const bootstrapData = await bootstrapFromAppRoot(resolver.getAppDir())\n // Register CLI modules directly (bootstrapFromAppRoot returns the data for this purpose)\n registerCliModules(bootstrapData.modules)\n console.log('\u2705 Bootstrap complete\\n')\n\n // Step 5: Build all modules for CLI commands\n const allModules = await buildAllModules()\n\n // Step 6: Restore configuration defaults\n console.log('\u2699\uFE0F Restoring module defaults...')\n await runModuleCommand(allModules, 'configs', 'restore-defaults', [])\n console.log('\u2705 Module defaults restored\\n')\n\n // Step 7: Setup RBAC (tenant/org, users, ACLs)\n const findArgValue = (names: string[], fallback: string) => {\n for (const name of names) {\n const match = initArgs.find((arg) => arg.startsWith(name))\n if (match) {\n const value = match.slice(name.length)\n if (value) return value\n }\n }\n return fallback\n }\n const orgName = findArgValue(['--org=', '--orgName='], 'Acme Corp')\n const email = findArgValue(['--email='], 'superadmin@acme.com')\n const password = findArgValue(['--password='], 'secret')\n const roles = findArgValue(['--roles='], 'superadmin,admin,employee')\n\n console.log('\uD83D\uDD10 Setting up RBAC and users...')\n // Run auth setup command via CLI\n await runModuleCommand(allModules, 'auth', 'setup', [\n '--orgName', orgName,\n '--email', email,\n '--password', password,\n '--roles', roles,\n ])\n // Query DB to get tenant/org IDs using pg directly\n const { Client } = await import('pg')\n const dbUrl = process.env.DATABASE_URL\n const pgClient = new Client({ connectionString: dbUrl })\n await pgClient.connect()\n const orgResult = await pgClient.query(\n `SELECT o.id as org_id, o.tenant_id FROM organizations o\n JOIN users u ON u.organization_id = o.id\n LIMIT 1`\n )\n await pgClient.end()\n const tenantId = orgResult?.rows?.[0]?.tenant_id ?? null\n const orgId = orgResult?.rows?.[0]?.org_id ?? null\n console.log('\u2705 RBAC setup complete:', { tenantId, organizationId: orgId }, '\\n')\n\n console.log('\uD83C\uDF9B\uFE0F Seeding feature toggle defaults...')\n await runModuleCommand(allModules, 'feature_toggles', 'seed-defaults', [])\n console.log('\uD83C\uDF9B\uFE0F \u2705 Feature toggle defaults seeded\\n')\n\n if (tenantId) {\n console.log('\uD83D\uDC65 Seeding tenant-scoped roles...')\n await runModuleCommand(allModules, 'auth', 'seed-roles', ['--tenant', tenantId])\n console.log('\uD83D\uDEE1\uFE0F \u2705 Roles seeded\\n')\n } else {\n console.log('\u26A0\uFE0F Skipping role seeding because tenant ID was not available.\\n')\n }\n\n if (orgId && tenantId) {\n if (reinstall) {\n console.log('\uD83E\uDDE9 Reinstalling custom field definitions...')\n await runModuleCommand(allModules, 'entities', 'reinstall', ['--tenant', tenantId])\n console.log('\uD83E\uDDE9 \u2705 Custom field definitions reinstalled\\n')\n }\n\n console.log('\uD83D\uDCDA Seeding customer dictionaries...')\n await runModuleCommand(allModules, 'customers', 'seed-dictionaries', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDCDA \u2705 Customer dictionaries seeded\\n')\n\n console.log('\uD83C\uDFE0 Seeding staff address types...')\n await runModuleCommand(allModules, 'staff', 'seed-address-types', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83C\uDFE0 \u2705 Staff address types seeded\\n')\n\n console.log('\uD83C\uDFE0 Seeding resources address types...')\n await runModuleCommand(allModules, 'resources', 'seed-address-types', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83C\uDFE0 \u2705 Resources address types seeded\\n')\n\n console.log('\uD83D\uDCDA Seeding currencies...')\n await runModuleCommand(allModules, 'currencies', 'seed', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDCDA \u2705 Currencies seeded\\n')\n\n console.log('\uD83D\uDCCF Seeding catalog units...')\n await runModuleCommand(allModules, 'catalog', 'seed-units', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDCCF \u2705 Catalog units seeded\\n')\n\n console.log('\uD83D\uDDD3\uFE0F Seeding unavailability reasons...')\n await runModuleCommand(allModules, 'planner', 'seed-unavailability-reasons', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDDD3\uFE0F \u2705 Unavailability reasons seeded\\n')\n\n const parsedEncryption = parseBooleanToken(process.env.TENANT_DATA_ENCRYPTION ?? 'yes')\n const encryptionEnabled = parsedEncryption === null ? true : parsedEncryption\n if (encryptionEnabled) {\n console.log('\uD83D\uDD12 Seeding encryption defaults...')\n await runModuleCommand(allModules, 'entities', 'seed-encryption', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDD12 \u2705 Encryption defaults seeded\\n')\n } else {\n console.log('\u26A0\uFE0F TENANT_DATA_ENCRYPTION disabled; skipping encryption defaults.\\n')\n }\n\n console.log('\uD83C\uDFF7\uFE0F Seeding catalog price kinds...')\n await runModuleCommand(allModules, 'catalog', 'seed-price-kinds', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83C\uDFF7\uFE0F \u2705 Catalog price kinds seeded\\n')\n\n console.log('\uD83D\uDCB6 Seeding default tax rates...')\n await runModuleCommand(allModules, 'sales', 'seed-tax-rates', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83E\uDDFE \u2705 Tax rates seeded\\n')\n\n console.log('\uD83D\uDEA6 Seeding sales statuses...')\n await runModuleCommand(allModules, 'sales', 'seed-statuses', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDEA6 \u2705 Sales statuses seeded\\n')\n\n console.log('\u2699\uFE0F Seeding adjustment kinds...')\n await runModuleCommand(allModules, 'sales', 'seed-adjustment-kinds', ['--tenant', tenantId, '--org', orgId])\n console.log('\u2699\uFE0F \u2705 Adjustment kinds seeded\\n')\n\n console.log('\uD83D\uDE9A Seeding shipping methods...')\n await runModuleCommand(allModules, 'sales', 'seed-shipping-methods', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDE9A \u2705 Shipping methods seeded\\n')\n\n console.log('\uD83D\uDCB3 Seeding payment methods...')\n await runModuleCommand(allModules, 'sales', 'seed-payment-methods', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDCB3 \u2705 Payment methods seeded\\n')\n\n console.log('\uD83D\uDD04 Seeding workflow definitions...')\n try {\n await runModuleCommand(allModules, 'workflows', 'seed-all', ['--tenant', tenantId, '--org', orgId])\n console.log('\u2705 Workflows and business rules seeded\\n')\n } catch (err) {\n console.error('\u26A0\uFE0F Workflow seeding failed (non-fatal):', err)\n }\n\n if (skipExamples) {\n console.log('\uD83D\uDEAB Example data seeding skipped (--no-examples)\\n')\n } else {\n console.log('\uD83D\uDECD\uFE0F Seeding catalog examples...')\n await runModuleCommand(allModules, 'catalog', 'seed-examples', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDECD\uFE0F \u2705 Catalog examples seeded\\n')\n\n console.log('\uD83C\uDFE2 Seeding customer examples...')\n await runModuleCommand(allModules, 'customers', 'seed-examples', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83C\uDFE2 \u2705 Customer examples seeded\\n')\n\n console.log('\uD83E\uDDFE Seeding sales examples...')\n await runModuleCommand(allModules, 'sales', 'seed-examples', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83E\uDDFE \u2705 Sales examples seeded\\n')\n\n console.log('\uD83D\uDC65 Seeding staff examples...')\n await runModuleCommand(allModules, 'staff', 'seed-examples', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDC65 \u2705 Staff examples seeded\\n')\n\n console.log('\uD83D\uDCE6 Seeding resource capacity units...')\n await runModuleCommand(allModules, 'resources', 'seed-capacity-units', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDCE6 \u2705 Resource capacity units seeded\\n')\n\n console.log('\uD83E\uDDF0 Seeding resource examples...')\n await runModuleCommand(allModules, 'resources', 'seed-examples', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83E\uDDF0 \u2705 Resource examples seeded\\n')\n\n console.log('\uD83D\uDDD3\uFE0F Seeding planner availability rulesets...')\n await runModuleCommand(allModules, 'planner', 'seed-availability-rulesets', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDDD3\uFE0F \u2705 Planner availability rulesets seeded\\n')\n\n // Optional: seed example todos if the example module is enabled\n const exampleModule = allModules.find((m) => m.id === 'example')\n if (exampleModule && exampleModule.cli) {\n console.log('\uD83D\uDCDD Seeding example todos...')\n await runModuleCommand(allModules, 'example', 'seed-todos', ['--org', orgId, '--tenant', tenantId])\n console.log('\uD83D\uDCDD \u2705 Example todos seeded\\n')\n }\n }\n\n if (stressTestEnabled) {\n console.log(\n `\uD83C\uDFCB\uFE0F Seeding stress test customers${stressTestLite ? ' (lite payload)' : ''}...`\n )\n const stressArgs = ['--tenant', tenantId, '--org', orgId, '--count', String(stressTestCount)]\n if (stressTestLite) stressArgs.push('--lite')\n await runModuleCommand(allModules, 'customers', 'seed-stresstest', stressArgs)\n console.log(`\u2705 Stress test customers seeded (requested ${stressTestCount})\\n`)\n }\n\n console.log('\uD83E\uDDE9 Enabling default dashboard widgets...')\n await runModuleCommand(allModules, 'dashboards', 'seed-defaults', ['--tenant', tenantId])\n console.log('\u2705 Dashboard widgets enabled\\n')\n\n } else {\n console.log('\u26A0\uFE0F Could not get organization ID or tenant ID, skipping seeding steps\\n')\n }\n\n console.log('\uD83E\uDDE0 Building search indexes...')\n const vectorArgs = tenantId\n ? ['--tenant', tenantId, ...(orgId ? ['--org', orgId] : [])]\n : ['--purgeFirst=false']\n await runModuleCommand(allModules, 'search', 'reindex', vectorArgs)\n console.log('\u2705 Search indexes built\\n')\n\n console.log('\uD83D\uDD0D Rebuilding query indexes...')\n const queryIndexArgs = ['--force', ...(tenantId ? ['--tenant', tenantId] : [])]\n await runModuleCommand(allModules, 'query_index', 'reindex', queryIndexArgs)\n console.log('\u2705 Query indexes rebuilt\\n')\n\n // Derive admin/employee only when the provided email is a superadmin email\n const [local, domain] = String(email).split('@')\n const isSuperadminLocal = (local || '').toLowerCase() === 'superadmin' && !!domain\n const adminEmailDerived = isSuperadminLocal ? `admin@${domain}` : null\n const employeeEmailDerived = isSuperadminLocal ? `employee@${domain}` : null\n\n // Simplified success message: we know which users were created\n console.log('\uD83C\uDF89 App initialization complete!\\n')\n console.log('\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\u2557')\n console.log('\u2551 \uD83D\uDE80 You\\'re now ready to start development! \u2551')\n console.log('\u2551 \u2551')\n console.log('\u2551 Start the dev server: \u2551')\n console.log('\u2551 yarn dev \u2551')\n console.log('\u2551 \u2551')\n console.log('\u2551 Users created: \u2551')\n console.log(`\u2551 \uD83D\uDC51 Superadmin: ${email.padEnd(42)} \u2551`)\n console.log(`\u2551 Password: ${password.padEnd(44)} \u2551`)\n if (adminEmailDerived) {\n console.log(`\u2551 \uD83E\uDDF0 Admin: ${adminEmailDerived.padEnd(42)} \u2551`)\n console.log(`\u2551 Password: ${password.padEnd(44)} \u2551`)\n }\n if (employeeEmailDerived) {\n console.log(`\u2551 \uD83D\uDC77 Employee: ${employeeEmailDerived.padEnd(42)} \u2551`)\n console.log(`\u2551 Password: ${password.padEnd(44)} \u2551`)\n }\n console.log('\u2551 \u2551')\n console.log('\u2551 Happy coding! \u2551')\n console.log('\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\u255D')\n\n return 0\n } catch (error: unknown) {\n if (error instanceof Error) {\n console.error('\u274C Initialization failed:', error.message)\n } else {\n console.error('\u274C Initialization failed:', error)\n }\n return 1\n }\n }\n\n let modName = first\n let cmdName = second\n let rest = remaining\n\n if (first === 'reindex') {\n modName = 'query_index'\n cmdName = 'reindex'\n rest = second !== undefined ? [second, ...remaining] : remaining\n }\n\n // Handle 'mercato generate' without subcommand - default to 'generate all'\n if (first === 'generate' && !second) {\n cmdName = 'all'\n rest = remaining\n }\n\n // Load modules from registered CLI modules\n const modules = getCliModules()\n \n // Load optional app-level CLI commands lazily without static import resolution\n let appCli: any[] = []\n try {\n const dynImport: any = (Function('return import') as any)()\n const app = await dynImport.then((f: any) => f('@/cli')).catch(() => null)\n if (app && Array.isArray(app?.default)) appCli = app.default\n } catch {}\n const all = modules.slice()\n \n // Built-in CLI module: queue\n all.push({\n id: 'queue',\n cli: [\n {\n command: 'worker',\n run: async (args: string[]) => {\n const isAllQueues = args.includes('--all')\n const queueName = isAllQueues ? null : args[0]\n\n // Collect all discovered workers from modules\n type WorkerEntry = {\n id: string\n queue: string\n concurrency: number\n handler: (job: unknown, ctx: unknown) => Promise<void> | void\n }\n const allWorkers: WorkerEntry[] = []\n for (const mod of getCliModules()) {\n const modWorkers = (mod as { workers?: WorkerEntry[] }).workers\n if (modWorkers) {\n allWorkers.push(...modWorkers)\n }\n }\n const discoveredQueues = [...new Set(allWorkers.map((w) => w.queue))]\n\n if (!queueName && !isAllQueues) {\n console.error('Usage: mercato queue worker <queueName> | --all')\n console.error('Example: mercato queue worker events')\n console.error('Example: mercato queue worker --all')\n if (discoveredQueues.length > 0) {\n console.error(`Discovered queues: ${discoveredQueues.join(', ')}`)\n }\n return\n }\n\n const concurrencyArg = args.find((a) => a.startsWith('--concurrency='))\n const concurrencyOverride = concurrencyArg ? Number(concurrencyArg.split('=')[1]) : undefined\n\n if (isAllQueues) {\n // Run workers for all discovered queues\n if (discoveredQueues.length === 0) {\n console.error('[worker] No queues discovered from modules')\n return\n }\n\n const container = await createRequestContainer()\n console.log(`[worker] Starting workers for all queues: ${discoveredQueues.join(', ')}`)\n\n // Start all queue workers in background mode\n const workerPromises = discoveredQueues.map(async (queue) => {\n const queueWorkers = allWorkers.filter((w) => w.queue === queue)\n const concurrency = concurrencyOverride ?? Math.max(...queueWorkers.map((w) => w.concurrency), 1)\n\n console.log(`[worker] Starting \"${queue}\" with ${queueWorkers.length} handler(s), concurrency: ${concurrency}`)\n\n await runWorker({\n queueName: queue,\n connection: { url: process.env.REDIS_URL || process.env.QUEUE_REDIS_URL },\n concurrency,\n background: true,\n handler: async (job, ctx) => {\n for (const worker of queueWorkers) {\n await worker.handler(job, { ...ctx, resolve: container.resolve.bind(container) })\n }\n },\n })\n })\n\n await Promise.all(workerPromises)\n\n console.log('[worker] All workers started. Press Ctrl+C to stop')\n\n // Keep the process alive\n await new Promise(() => {})\n } else {\n // Find workers for this specific queue\n const queueWorkers = allWorkers.filter((w) => w.queue === queueName)\n\n if (queueWorkers.length > 0) {\n // Use discovered workers\n const container = await createRequestContainer()\n const concurrency = concurrencyOverride ?? Math.max(...queueWorkers.map((w) => w.concurrency), 1)\n\n console.log(`[worker] Found ${queueWorkers.length} worker(s) for queue \"${queueName}\"`)\n\n await runWorker({\n queueName: queueName!,\n connection: { url: process.env.REDIS_URL || process.env.QUEUE_REDIS_URL },\n concurrency,\n handler: async (job, ctx) => {\n for (const worker of queueWorkers) {\n await worker.handler(job, { ...ctx, resolve: container.resolve.bind(container) })\n }\n },\n })\n } else {\n console.error(`No workers found for queue \"${queueName}\"`)\n if (discoveredQueues.length > 0) {\n console.error(`Available queues: ${discoveredQueues.join(', ')}`)\n }\n }\n }\n },\n },\n {\n command: 'clear',\n run: async (args: string[]) => {\n const queueName = args[0]\n if (!queueName) {\n console.error('Usage: mercato queue clear <queueName>')\n return\n }\n\n const strategyEnv = process.env.QUEUE_STRATEGY || 'local'\n const { createQueue } = await import('@open-mercato/queue')\n\n const queue = strategyEnv === 'async'\n ? createQueue(queueName, 'async', {\n connection: { url: process.env.REDIS_URL || process.env.QUEUE_REDIS_URL },\n })\n : createQueue(queueName, 'local')\n\n const res = await queue.clear()\n await queue.close()\n console.log(`Cleared queue \"${queueName}\", removed ${res.removed} jobs`)\n },\n },\n {\n command: 'status',\n run: async (args: string[]) => {\n const queueName = args[0]\n if (!queueName) {\n console.error('Usage: mercato queue status <queueName>')\n return\n }\n\n const strategyEnv = process.env.QUEUE_STRATEGY || 'local'\n const { createQueue } = await import('@open-mercato/queue')\n\n const queue = strategyEnv === 'async'\n ? createQueue(queueName, 'async', {\n connection: { url: process.env.REDIS_URL || process.env.QUEUE_REDIS_URL },\n })\n : createQueue(queueName, 'local')\n\n const counts = await queue.getJobCounts()\n console.log(`Queue \"${queueName}\" status:`)\n console.log(` Waiting: ${counts.waiting}`)\n console.log(` Active: ${counts.active}`)\n console.log(` Completed: ${counts.completed}`)\n console.log(` Failed: ${counts.failed}`)\n await queue.close()\n },\n },\n ],\n } as any)\n\n // Built-in CLI module: events\n all.push({\n id: 'events',\n cli: [\n {\n command: 'emit',\n run: async (args: string[]) => {\n const eventName = args[0]\n if (!eventName) {\n console.error('Usage: mercato events emit <event> [jsonPayload] [--persistent|-p]')\n return\n }\n const persistent = args.includes('--persistent') || args.includes('-p')\n const payloadArg = args[1] && !args[1].startsWith('--') ? args[1] : undefined\n let payload: any = {}\n if (payloadArg) {\n try { payload = JSON.parse(payloadArg) } catch { payload = payloadArg }\n }\n const { createRequestContainer } = await import('@open-mercato/shared/lib/di/container')\n const container = await createRequestContainer()\n const bus = (container.resolve('eventBus') as any)\n await bus.emit(eventName, payload, { persistent })\n console.log(`Emitted \"${eventName}\"${persistent ? ' (persistent)' : ''}`)\n },\n },\n {\n command: 'clear',\n run: async () => {\n const { createRequestContainer } = await import('@open-mercato/shared/lib/di/container')\n const container = await createRequestContainer()\n const bus = (container.resolve('eventBus') as any)\n const res = await bus.clearQueue()\n console.log(`Cleared events queue, removed ${res.removed} events`)\n },\n },\n ],\n } as any)\n \n // Built-in CLI module: scaffold\n all.push({\n id: 'scaffold',\n cli: [\n {\n command: 'module',\n run: async (args: string[]) => {\n const name = (args[0] || '').trim()\n if (!name) {\n console.error('Usage: mercato scaffold module <name>')\n return\n }\n const fs = await import('node:fs')\n const path = await import('node:path')\n const { execSync } = await import('node:child_process')\n const base = path.resolve('src/modules', name)\n const folders = ['api', 'backend', 'frontend', 'data', 'subscribers']\n for (const f of folders) fs.mkdirSync(path.join(base, f), { recursive: true })\n const moduleTitle = `${name[0].toUpperCase()}${name.slice(1)}`\n const indexTs = `export const metadata = { title: '${moduleTitle}', group: 'Modules' }\\n`\n fs.writeFileSync(path.join(base, 'index.ts'), indexTs, { flag: 'wx' })\n const ceTs = `export const entities = [\\n {\\n id: '${name}:sample',\\n label: '${moduleTitle} Sample',\\n description: 'Describe your custom entity',\\n showInSidebar: true,\\n fields: [\\n // { key: 'priority', kind: 'integer', label: 'Priority' },\\n ],\\n },\\n]\\n\\nexport default entities\\n`\n fs.writeFileSync(path.join(base, 'ce.ts'), ceTs, { flag: 'wx' })\n const entitiesTs = `import { Entity, PrimaryKey, Property } from '@mikro-orm/core'\\n\\n// Add your entities here. Example:\\n// @Entity({ tableName: '${name}_items' })\\n// export class ${moduleTitle}Item {\\n// @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' }) id!: string\\n// @Property({ type: 'text' }) title!: string\\n// @Property({ name: 'organization_id', type: 'uuid', nullable: true }) organizationId?: string | null\\n// @Property({ name: 'tenant_id', type: 'uuid', nullable: true }) tenantId?: string | null\\n// @Property({ name: 'created_at', type: Date, onCreate: () => new Date() }) createdAt: Date = new Date()\\n// @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() }) updatedAt: Date = new Date()\\n// @Property({ name: 'deleted_at', type: Date, nullable: true }) deletedAt?: Date | null\\n// }\\n`\n fs.writeFileSync(path.join(base, 'data', 'entities.ts'), entitiesTs, { flag: 'wx' })\n console.log(`Created module at ${path.relative(process.cwd(), base)}`)\n execSync('yarn modules:prepare', { stdio: 'inherit' })\n },\n },\n {\n command: 'entity',\n run: async () => {\n const fs = await import('node:fs')\n const path = await import('node:path')\n const readline = await import('node:readline/promises')\n const { stdin: input, stdout: output } = await import('node:process')\n const { execSync } = await import('node:child_process')\n const rl = readline.createInterface({ input, output })\n try {\n const moduleId = (await rl.question('Module id (folder under src/modules): ')).trim()\n const className = (await rl.question('Entity class name (e.g., Todo): ')).trim()\n const tableName = (await rl.question(`DB table name (default: ${className.toLowerCase()}s): `)).trim() || `${className.toLowerCase()}s`\n const extra = (await rl.question('Additional fields (comma list name:type, e.g., title:text,is_done:boolean): ')).trim()\n const extras = extra\n ? extra.split(',').map(s => s.trim()).filter(Boolean).map(s => {\n const [n,t] = s.split(':').map(x=>x.trim()); return { n, t }\n })\n : []\n const base = path.resolve('src/modules', moduleId, 'data')\n fs.mkdirSync(base, { recursive: true })\n const file = path.join(base, 'entities.ts')\n let content = fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : `import { Entity, PrimaryKey, Property } from '@mikro-orm/core'\\n\\n`\n content += `\\n@Entity({ tableName: '${tableName}' })\\nexport class ${className} {\\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\\n id!: string\\n\\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\\n organizationId?: string | null\\n\\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\\n tenantId?: string | null\\n\\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\\n createdAt: Date = new Date()\\n\\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\\n updatedAt: Date = new Date()\\n\\n @Property({ name: 'deleted_at', type: Date, nullable: true })\\n deletedAt?: Date | null\\n`\n for (const f of extras) {\n const n = f.n\n const t = f.t\n if (!n || !t) continue\n const map = {\n text: { ts: 'string', db: 'text' },\n multiline: { ts: 'string', db: 'text' },\n integer: { ts: 'number', db: 'int' },\n float: { ts: 'number', db: 'float' },\n boolean: { ts: 'boolean', db: 'boolean' },\n date: { ts: 'Date', db: 'Date' },\n } as const\n const info = map[t as keyof typeof map]\n const fallback = { ts: 'string', db: 'text' }\n const resolved = info || fallback\n const propName = n.replace(/_([a-z])/g, (_, c) => c.toUpperCase())\n const columnName = n.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`)\n const dbType = resolved.db\n const tsType = resolved.ts\n const defaultValue =\n resolved.ts === 'boolean' ? ' = false' :\n resolved.ts === 'Date' ? ' = new Date()' :\n ''\n content += `\\n @Property({ name: '${columnName}', type: ${dbType === 'Date' ? 'Date' : `'${dbType}'`}${resolved.ts === 'boolean' ? ', default: false' : ''} })\\n ${propName}${tsType === 'number' ? '?: number | null' : tsType === 'boolean' ? ': boolean' : tsType === 'Date' ? ': Date' : '!: string'}${defaultValue}\\n`\n }\n content += `}\\n`\n fs.writeFileSync(file, content)\n console.log(`Updated ${path.relative(process.cwd(), file)}`)\n console.log('Generating and applying migrations...')\n execSync('yarn modules:prepare', { stdio: 'inherit' })\n execSync('yarn db:generate', { stdio: 'inherit' })\n execSync('yarn db:migrate', { stdio: 'inherit' })\n } finally {\n rl.close()\n }\n },\n },\n {\n command: 'crud',\n run: async (args: string[]) => {\n const fs = await import('node:fs')\n const path = await import('node:path')\n const { execSync } = await import('node:child_process')\n const mod = (args[0] || '').trim()\n const entity = (args[1] || '').trim()\n const routeSeg = (args[2] || '').trim() || `${entity.toLowerCase()}s`\n if (!mod || !entity) {\n console.error('Usage: mercato scaffold crud <moduleId> <EntityClass> [routeSegment]')\n return\n }\n const baseDir = path.resolve('src/modules', mod, 'api', routeSeg)\n fs.mkdirSync(baseDir, { recursive: true })\n const entitySnake = entity.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase()\n const tmpl = `import { z } from 'zod'\\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\\nimport { ${entity} } from '@open-mercato/shared/modules/${mod}/data/entities'\\nimport { E } from '#generated/entities.ids.generated'\\nimport ceEntities from '@open-mercato/shared/modules/${mod}/ce'\\nimport { buildCustomFieldSelectorsForEntity, extractCustomFieldsFromItem, buildCustomFieldFiltersFromQuery } from '@open-mercato/shared/lib/crud/custom-fields'\\nimport type { CustomFieldSet } from '@open-mercato/shared/modules/entities'\\n\\n// Field constants - update these based on your entity's actual fields\\nconst F = {\\n id: 'id',\\n tenant_id: 'tenant_id',\\n organization_id: 'organization_id',\\n created_at: 'created_at',\\n updated_at: 'updated_at',\\n deleted_at: 'deleted_at',\\n} as const\\n\\nconst querySchema = z.object({\\n id: z.string().uuid().optional(),\\n page: z.coerce.number().min(1).default(1),\\n pageSize: z.coerce.number().min(1).max(100).default(50),\\n sortField: z.string().optional().default('id'),\\n sortDir: z.enum(['asc','desc']).optional().default('asc'),\\n withDeleted: z.coerce.boolean().optional().default(false),\\n}).passthrough()\\n\\nconst createSchema = z.object({}).passthrough()\\nconst updateSchema = z.object({ id: z.string().uuid() }).passthrough()\\n\\ntype Query = z.infer<typeof querySchema>\\n\\nconst fieldSets: CustomFieldSet[] = []\\nconst ceEntity = Array.isArray(ceEntities) ? ceEntities.find((entity) => entity?.id === '${mod}:${entitySnake}') : undefined\\nif (ceEntity?.fields?.length) {\\n fieldSets.push({ entity: ceEntity.id, fields: ceEntity.fields, source: '${mod}' })\\n}\\n\\nconst cfSel = buildCustomFieldSelectorsForEntity(E.${mod}.${entitySnake}, fieldSets)\\nconst sortFieldMap: Record<string, unknown> = { id: F.id, created_at: F.created_at, ...Object.fromEntries(cfSel.keys.map(k => [\\`cf_\\${k}\\`, \\`cf:\\${k}\\`])) }\\n\\nexport const { metadata, GET, POST, PUT, DELETE } = makeCrudRoute({\\n metadata: { GET: { requireAuth: true }, POST: { requireAuth: true }, PUT: { requireAuth: true }, DELETE: { requireAuth: true } },\\n orm: { entity: ${entity}, idField: 'id', orgField: 'organizationId', tenantField: 'tenantId', softDeleteField: 'deletedAt' },\\n events: { module: '${mod}', entity: '${entitySnake}', persistent: true },\\n indexer: { entityType: E.${mod}.${entitySnake} },\\n list: {\\n schema: querySchema,\\n entityId: E.${mod}.${entitySnake},\\n fields: [F.id, F.created_at, ...cfSel.selectors],\\n sortFieldMap,\\n buildFilters: async (q: Query, ctx) => ({\\n ...(await buildCustomFieldFiltersFromQuery({\\n entityId: E.${mod}.${entitySnake},\\n query: q as any,\\n em: ctx.container.resolve('em'),\\n tenantId: ctx.auth!.tenantId,\\n })),\\n }),\\n transformItem: (item: any) => ({ id: item.id, created_at: item.created_at, ...extractCustomFieldsFromItem(item, cfSel.keys) }),\\n },\\n create: { schema: createSchema, mapToEntity: (input: any) => ({}), customFields: { enabled: true, entityId: E.${mod}.${entitySnake}, pickPrefixed: true } },\\n update: { schema: updateSchema, applyToEntity: (entity: ${entity}, input: any) => {}, customFields: { enabled: true, entityId: E.${mod}.${entitySnake}, pickPrefixed: true } },\\n del: { idFrom: 'query', softDelete: true },\\n})\\n`\n const file = path.join(baseDir, 'route.ts')\n fs.writeFileSync(file, tmpl, { flag: 'wx' })\n console.log(`Created CRUD route: ${path.relative(process.cwd(), file)}`)\n execSync('yarn modules:prepare', { stdio: 'inherit' })\n },\n },\n ],\n } as any)\n\n // Built-in CLI module: generate\n all.push({\n id: 'generate',\n cli: [\n {\n command: 'all',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { generateEntityIds, generateModuleRegistry, generateModuleRegistryCli, generateModuleEntities, generateModuleDi } = await import('./lib/generators')\n const resolver = createResolver()\n const quiet = args.includes('--quiet') || args.includes('-q')\n\n console.log('Running all generators...')\n await generateEntityIds({ resolver, quiet })\n await generateModuleRegistry({ resolver, quiet })\n await generateModuleRegistryCli({ resolver, quiet })\n await generateModuleEntities({ resolver, quiet })\n await generateModuleDi({ resolver, quiet })\n console.log('All generators completed.')\n },\n },\n {\n command: 'entity-ids',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { generateEntityIds } = await import('./lib/generators')\n const resolver = createResolver()\n await generateEntityIds({ resolver, quiet: args.includes('--quiet') })\n },\n },\n {\n command: 'registry',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { generateModuleRegistry } = await import('./lib/generators')\n const resolver = createResolver()\n await generateModuleRegistry({ resolver, quiet: args.includes('--quiet') })\n },\n },\n {\n command: 'entities',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { generateModuleEntities } = await import('./lib/generators')\n const resolver = createResolver()\n await generateModuleEntities({ resolver, quiet: args.includes('--quiet') })\n },\n },\n {\n command: 'di',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { generateModuleDi } = await import('./lib/generators')\n const resolver = createResolver()\n await generateModuleDi({ resolver, quiet: args.includes('--quiet') })\n },\n },\n ],\n } as any)\n\n // Built-in CLI module: db\n all.push({\n id: 'db',\n cli: [\n {\n command: 'generate',\n run: async () => {\n const { createResolver } = await import('./lib/resolver')\n const { dbGenerate } = await import('./lib/db')\n const resolver = createResolver()\n await dbGenerate(resolver)\n },\n },\n {\n command: 'migrate',\n run: async () => {\n const { createResolver } = await import('./lib/resolver')\n const { dbMigrate } = await import('./lib/db')\n const resolver = createResolver()\n await dbMigrate(resolver)\n },\n },\n {\n command: 'greenfield',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { dbGreenfield } = await import('./lib/db')\n const resolver = createResolver()\n const yes = args.includes('--yes') || args.includes('-y')\n await dbGreenfield(resolver, { yes })\n },\n },\n ],\n } as any)\n\n // Built-in CLI module: server (runs Next.js + workers)\n all.push({\n id: 'server',\n cli: [\n {\n command: 'dev',\n run: async () => {\n const { spawn } = await import('child_process')\n const path = await import('path')\n const { createResolver } = await import('./lib/resolver')\n const resolver = createResolver()\n const appDir = resolver.getAppDir()\n\n // In monorepo, packages are hoisted to root; in standalone, they're in app's node_modules\n const nodeModulesBase = resolver.isMonorepo() ? resolver.getRootDir() : appDir\n\n const processes: ChildProcess[] = []\n const autoSpawnWorkers = process.env.AUTO_SPAWN_WORKERS !== 'false'\n\n function cleanup() {\n console.log('[server] Shutting down...')\n for (const proc of processes) {\n if (!proc.killed) {\n proc.kill('SIGTERM')\n }\n }\n }\n\n process.on('SIGTERM', cleanup)\n process.on('SIGINT', cleanup)\n\n console.log('[server] Starting Open Mercato in dev mode...')\n\n // Resolve paths relative to where node_modules are located\n const nextBin = path.join(nodeModulesBase, 'node_modules/next/dist/bin/next')\n const mercatoBin = path.join(nodeModulesBase, 'node_modules/@open-mercato/cli/bin/mercato')\n\n // Start Next.js dev\n const nextProcess = spawn('node', [nextBin, 'dev', '--turbopack'], {\n stdio: 'inherit',\n env: process.env,\n cwd: appDir,\n })\n processes.push(nextProcess)\n\n // Start workers if enabled\n if (autoSpawnWorkers) {\n console.log('[server] Starting workers for all queues...')\n const workerProcess = spawn('node', [mercatoBin, 'queue', 'worker', '--all'], {\n stdio: 'inherit',\n env: process.env,\n cwd: appDir,\n })\n processes.push(workerProcess)\n }\n\n // Wait for any process to exit\n await Promise.race(\n processes.map(\n (proc) =>\n new Promise<void>((resolve) => {\n proc.on('exit', () => resolve())\n })\n )\n )\n\n cleanup()\n },\n },\n {\n command: 'start',\n run: async () => {\n const { spawn } = await import('child_process')\n const path = await import('path')\n const { createResolver } = await import('./lib/resolver')\n const resolver = createResolver()\n const appDir = resolver.getAppDir()\n\n // In monorepo, packages are hoisted to root; in standalone, they're in app's node_modules\n const nodeModulesBase = resolver.isMonorepo() ? resolver.getRootDir() : appDir\n\n const processes: ChildProcess[] = []\n const autoSpawnWorkers = process.env.AUTO_SPAWN_WORKERS !== 'false'\n\n function cleanup() {\n console.log('[server] Shutting down...')\n for (const proc of processes) {\n if (!proc.killed) {\n proc.kill('SIGTERM')\n }\n }\n }\n\n process.on('SIGTERM', cleanup)\n process.on('SIGINT', cleanup)\n\n console.log('[server] Starting Open Mercato in production mode...')\n\n // Resolve paths relative to where node_modules are located\n const nextBin = path.join(nodeModulesBase, 'node_modules/next/dist/bin/next')\n const mercatoBin = path.join(nodeModulesBase, 'node_modules/@open-mercato/cli/bin/mercato')\n\n // Start Next.js production server\n const nextProcess = spawn('node', [nextBin, 'start'], {\n stdio: 'inherit',\n env: process.env,\n cwd: appDir,\n })\n processes.push(nextProcess)\n\n // Start workers if enabled\n if (autoSpawnWorkers) {\n console.log('[server] Starting workers for all queues...')\n const workerProcess = spawn('node', [mercatoBin, 'queue', 'worker', '--all'], {\n stdio: 'inherit',\n env: process.env,\n cwd: appDir,\n })\n processes.push(workerProcess)\n }\n\n // Wait for any process to exit\n await Promise.race(\n processes.map(\n (proc) =>\n new Promise<void>((resolve) => {\n proc.on('exit', () => resolve())\n })\n )\n )\n\n cleanup()\n },\n },\n ],\n } as any)\n\n if (appCli.length) all.push({ id: 'app', cli: appCli } as any)\n\n const quietBanner = process.env.OM_CLI_QUIET === '1'\n const banner = '\uD83E\uDDE9 Open Mercato CLI'\n if (!quietBanner) {\n const header = [\n '\u2554\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 `\u2551 ${banner.padEnd(21)}\u2551`,\n '\u255A\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 ].join('\\n')\n console.log(header)\n }\n const pad = (s: string) => ` ${s}`\n\n if (!modName || modName === 'help' || modName === '--help' || modName === '-h') {\n console.log(pad('Usage: \u2728 mercato <module> <command> [args]'))\n const list = all\n .filter((m) => m.cli && m.cli.length)\n .map((m) => `\u2022 ${m.id}: ${m.cli!.map((c) => `\"${c.command}\"`).join(', ')}`)\n if (list.length) {\n console.log('\\n' + pad('Available:'))\n console.log(list.map(pad).join('\\n'))\n } else {\n console.log(pad('\uD83C\uDF00 No CLI commands available'))\n }\n return 0\n }\n\n const mod = all.find((m) => m.id === modName)\n if (!mod) {\n console.error(`\u274C Module not found: \"${modName}\"`)\n return 1\n }\n if (!mod.cli || mod.cli.length === 0) {\n console.error(`\uD83D\uDEAB Module \"${modName}\" has no CLI commands`)\n return 1\n }\n if (!cmdName) {\n console.log(pad(`Commands for \"${modName}\": ${mod.cli.map((c) => c.command).join(', ')}`))\n return 1\n }\n const cmd = mod.cli.find((c) => c.command === cmdName)\n if (!cmd) {\n console.error(`\uD83E\uDD14 Unknown command \"${cmdName}\". Available: ${mod.cli.map((c) => c.command).join(', ')}`)\n return 1\n }\n\n console.log('')\n const started = Date.now()\n console.log(`\uD83D\uDE80 Running ${modName}:${cmdName} ${rest.join(' ')}`)\n try {\n await cmd.run(rest)\n const ms = Date.now() - started\n console.log(`\u23F1\uFE0F Done in ${ms}ms`)\n return 0\n } catch (e: any) {\n console.error(`\uD83D\uDCA5 Failed: ${e?.message || e}`)\n return 1\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\n// Note: Generated files and DI container are imported statically to avoid ESM/CJS interop issues.\n// Commands that need to run before generation (e.g., `init`) handle missing modules gracefully.\n\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { runWorker } from '@open-mercato/queue/worker'\nimport type { Module } from '@open-mercato/shared/modules/registry'\nimport { getCliModules, hasCliModules, registerCliModules } from './registry'\nexport { getCliModules, hasCliModules, registerCliModules }\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\nimport type { ChildProcess } from 'node:child_process'\nimport path from 'node:path'\nimport fs from 'node:fs'\n\nlet envLoaded = false\n\nasync function ensureEnvLoaded() {\n if (envLoaded) return\n envLoaded = true\n\n // Try to find and load .env from the app directory\n // First, try to find the app directory via resolver\n try {\n const { createResolver } = await import('./lib/resolver.js')\n const resolver = createResolver()\n const appDir = resolver.getAppDir()\n\n // Load .env from app directory if it exists\n const envPath = path.join(appDir, '.env')\n if (fs.existsSync(envPath)) {\n const dotenv = await import('dotenv')\n dotenv.config({ path: envPath })\n return\n }\n } catch {\n // Resolver might fail during early init, fall back to default behavior\n }\n\n // Fall back to default dotenv behavior (loads from cwd)\n try {\n await import('dotenv/config')\n } catch {}\n}\n\n// Helper to run a CLI command directly (without spawning a process)\nasync function runModuleCommand(\n allModules: Module[],\n moduleName: string,\n commandName: string,\n args: string[] = []\n): Promise<void> {\n const mod = allModules.find((m) => m.id === moduleName)\n if (!mod) {\n throw new Error(`Module not found: \"${moduleName}\"`)\n }\n if (!mod.cli || mod.cli.length === 0) {\n throw new Error(`Module \"${moduleName}\" has no CLI commands`)\n }\n const cmd = mod.cli.find((c) => c.command === commandName)\n if (!cmd) {\n throw new Error(`Command \"${commandName}\" not found in module \"${moduleName}\"`)\n }\n await cmd.run(args)\n}\n\n// Helper to run a module command, skipping silently if module is not enabled\nasync function tryRunModuleCommand(\n allModules: Module[],\n moduleName: string,\n commandName: string,\n args: string[] = []\n): Promise<boolean> {\n const mod = allModules.find((m) => m.id === moduleName)\n if (!mod || !mod.cli || mod.cli.length === 0) {\n return false\n }\n const cmd = mod.cli.find((c) => c.command === commandName)\n if (!cmd) {\n return false\n }\n await cmd.run(args)\n return true\n}\n\n// Build all CLI modules (registered + built-in)\nasync function buildAllModules(): Promise<Module[]> {\n const modules = getCliModules()\n\n // Load optional app-level CLI commands\n let appCli: any[] = []\n try {\n const dynImport: any = (Function('return import') as any)()\n const app = await dynImport.then((f: any) => f('@/cli')).catch(() => null)\n if (app && Array.isArray(app?.default)) appCli = app.default\n } catch {}\n\n const all = modules.slice()\n\n if (appCli.length) all.push({ id: 'app', cli: appCli } as any)\n\n return all\n}\n\nexport async function run(argv = process.argv) {\n await ensureEnvLoaded()\n const [, , ...parts] = argv\n const [first, second, ...remaining] = parts\n \n // Handle init command directly\n if (first === 'init') {\n const { execSync } = await import('child_process')\n\n console.log('\uD83D\uDE80 Initializing Open Mercato app...\\n')\n\n try {\n const initArgs = parts.slice(1).filter(Boolean)\n const reinstall = initArgs.includes('--reinstall') || initArgs.includes('-r')\n const skipExamples = initArgs.includes('--no-examples') || initArgs.includes('--no-exampls')\n const stressTestEnabled =\n initArgs.includes('--stresstest') || initArgs.includes('--stress-test')\n const stressTestLite =\n initArgs.includes('--lite') ||\n initArgs.includes('--stress-lite') ||\n initArgs.some((arg) => arg.startsWith('--payload=lite') || arg.startsWith('--mode=lite'))\n let stressTestCount = 6000\n for (let i = 0; i < initArgs.length; i += 1) {\n const arg = initArgs[i]\n const countPrefixes = ['--count=', '--stress-count=', '--stresstest-count=']\n const matchedPrefix = countPrefixes.find((prefix) => arg.startsWith(prefix))\n if (matchedPrefix) {\n const value = arg.slice(matchedPrefix.length)\n const parsed = Number.parseInt(value, 10)\n if (Number.isFinite(parsed) && parsed > 0) {\n stressTestCount = parsed\n break\n }\n }\n if (arg === '--count' || arg === '--stress-count' || arg === '--stresstest-count' || arg === '-n') {\n const next = initArgs[i + 1]\n if (next && !next.startsWith('-')) {\n const parsed = Number.parseInt(next, 10)\n if (Number.isFinite(parsed) && parsed > 0) {\n stressTestCount = parsed\n break\n }\n }\n }\n if (arg.startsWith('-n=')) {\n const value = arg.slice(3)\n const parsed = Number.parseInt(value, 10)\n if (Number.isFinite(parsed) && parsed > 0) {\n stressTestCount = parsed\n break\n }\n }\n }\n console.log(`\uD83D\uDD04 Reinstall mode: ${reinstall ? 'enabled' : 'disabled'}`)\n console.log(`\uD83C\uDFA8 Example content: ${skipExamples ? 'skipped (--no-examples)' : 'enabled'}`)\n console.log(\n `\uD83C\uDFCB\uFE0F Stress test dataset: ${\n stressTestEnabled\n ? `enabled (target ${stressTestCount} contacts${stressTestLite ? ', lite payload' : ''})`\n : 'disabled'\n }`\n )\n\n if (reinstall) {\n // Load env variables so DATABASE_URL is available\n await ensureEnvLoaded()\n console.log('\u267B\uFE0F Reinstall mode enabled: dropping all database tables...')\n const { Client } = await import('pg')\n const dbUrl = process.env.DATABASE_URL\n if (!dbUrl) {\n console.error('DATABASE_URL is not set. Aborting reinstall.')\n return 1\n }\n const client = new Client({ connectionString: dbUrl })\n try {\n await client.connect()\n // Collect all user tables in public schema\n const res = await client.query(`SELECT tablename FROM pg_tables WHERE schemaname = 'public'`)\n const dropTargets = new Set<string>((res.rows || []).map((r: any) => String(r.tablename)))\n for (const forced of ['vector_search', 'vector_search_migrations']) {\n const exists = await client.query(\n `SELECT to_regclass($1) AS regclass`,\n [`public.${forced}`],\n )\n const regclass = (exists as { rows?: Array<{ regclass: string | null }> }).rows?.[0]?.regclass ?? null\n if (regclass) {\n dropTargets.add(forced)\n }\n }\n if (dropTargets.size === 0) {\n console.log(' No tables found in public schema.')\n } else {\n let dropped = 0\n await client.query('BEGIN')\n try {\n for (const t of dropTargets) {\n await client.query(`DROP TABLE IF EXISTS \"${t}\" CASCADE`)\n dropped += 1\n }\n await client.query('COMMIT')\n console.log(` Dropped ${dropped} tables.`)\n } catch (e) {\n await client.query('ROLLBACK')\n throw e\n }\n }\n } finally {\n try { await client.end() } catch {}\n }\n // Also flush Redis\n try {\n const Redis = (await import('ioredis')).default\n const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379'\n const redis = new Redis(redisUrl)\n await redis.flushall()\n await redis.quit()\n console.log(' Redis flushed.')\n } catch {}\n console.log('\u2705 Database cleared. Proceeding with fresh initialization...\\n')\n }\n\n // Step 1: Run generators directly (no process spawn)\n console.log('\uD83D\uDD27 Preparing modules (registry, entities, DI)...')\n const { createResolver } = await import('./lib/resolver')\n const { generateEntityIds, generateModuleRegistry, generateModuleRegistryCli, generateModuleEntities, generateModuleDi } = await import('./lib/generators')\n const resolver = createResolver()\n await generateEntityIds({ resolver, quiet: true })\n await generateModuleRegistry({ resolver, quiet: true })\n await generateModuleRegistryCli({ resolver, quiet: true })\n await generateModuleEntities({ resolver, quiet: true })\n await generateModuleDi({ resolver, quiet: true })\n console.log('\u2705 Modules prepared\\n')\n\n // Step 3: Apply database migrations directly\n console.log('\uD83D\uDCCA Applying database migrations...')\n const { dbMigrate } = await import('./lib/db')\n await dbMigrate(resolver)\n console.log('\u2705 Migrations applied\\n')\n\n // Step 4: Bootstrap to register modules and entity IDs\n // Use the shared dynamicLoader which compiles TypeScript files on-the-fly\n console.log('\uD83D\uDD17 Bootstrapping application...')\n const { bootstrapFromAppRoot } = await import('@open-mercato/shared/lib/bootstrap/dynamicLoader')\n const bootstrapData = await bootstrapFromAppRoot(resolver.getAppDir())\n // Register CLI modules directly (bootstrapFromAppRoot returns the data for this purpose)\n registerCliModules(bootstrapData.modules)\n console.log('\u2705 Bootstrap complete\\n')\n\n // Step 5: Build all modules for CLI commands\n const allModules = await buildAllModules()\n\n // Step 6: Restore configuration defaults\n console.log('\u2699\uFE0F Restoring module defaults...')\n await runModuleCommand(allModules, 'configs', 'restore-defaults', [])\n console.log('\u2705 Module defaults restored\\n')\n\n // Step 7: Setup RBAC (tenant/org, users, ACLs)\n const findArgValue = (names: string[], fallback: string) => {\n for (const name of names) {\n const match = initArgs.find((arg) => arg.startsWith(name))\n if (match) {\n const value = match.slice(name.length)\n if (value) return value\n }\n }\n return fallback\n }\n const orgName = findArgValue(['--org=', '--orgName='], 'Acme Corp')\n const email = findArgValue(['--email='], 'superadmin@acme.com')\n const password = findArgValue(['--password='], 'secret')\n const roles = findArgValue(['--roles='], 'superadmin,admin,employee')\n\n console.log('\uD83D\uDD10 Setting up RBAC and users...')\n // Run auth setup command via CLI\n await runModuleCommand(allModules, 'auth', 'setup', [\n '--orgName', orgName,\n '--email', email,\n '--password', password,\n '--roles', roles,\n ])\n // Query DB to get tenant/org IDs using pg directly\n const { Client } = await import('pg')\n const dbUrl = process.env.DATABASE_URL\n const pgClient = new Client({ connectionString: dbUrl })\n await pgClient.connect()\n const orgResult = await pgClient.query(\n `SELECT o.id as org_id, o.tenant_id FROM organizations o\n JOIN users u ON u.organization_id = o.id\n LIMIT 1`\n )\n await pgClient.end()\n const tenantId = orgResult?.rows?.[0]?.tenant_id ?? null\n const orgId = orgResult?.rows?.[0]?.org_id ?? null\n console.log('\u2705 RBAC setup complete:', { tenantId, organizationId: orgId }, '\\n')\n\n console.log('\uD83C\uDF9B\uFE0F Seeding feature toggle defaults...')\n await runModuleCommand(allModules, 'feature_toggles', 'seed-defaults', [])\n console.log('\uD83C\uDF9B\uFE0F \u2705 Feature toggle defaults seeded\\n')\n\n if (tenantId) {\n console.log('\uD83D\uDC65 Seeding tenant-scoped roles...')\n await runModuleCommand(allModules, 'auth', 'seed-roles', ['--tenant', tenantId])\n console.log('\uD83D\uDEE1\uFE0F \u2705 Roles seeded\\n')\n } else {\n console.log('\u26A0\uFE0F Skipping role seeding because tenant ID was not available.\\n')\n }\n\n if (orgId && tenantId) {\n if (reinstall) {\n console.log('\uD83E\uDDE9 Reinstalling custom field definitions...')\n await runModuleCommand(allModules, 'entities', 'reinstall', ['--tenant', tenantId])\n console.log('\uD83E\uDDE9 \u2705 Custom field definitions reinstalled\\n')\n }\n\n console.log('\uD83D\uDCDA Seeding customer dictionaries...')\n await runModuleCommand(allModules, 'customers', 'seed-dictionaries', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDCDA \u2705 Customer dictionaries seeded\\n')\n\n if (await tryRunModuleCommand(allModules, 'staff', 'seed-address-types', ['--tenant', tenantId, '--org', orgId])) {\n console.log('\uD83C\uDFE0 \u2705 Staff address types seeded\\n')\n }\n\n if (await tryRunModuleCommand(allModules, 'resources', 'seed-address-types', ['--tenant', tenantId, '--org', orgId])) {\n console.log('\uD83C\uDFE0 \u2705 Resources address types seeded\\n')\n }\n\n console.log('\uD83D\uDCDA Seeding currencies...')\n await runModuleCommand(allModules, 'currencies', 'seed', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDCDA \u2705 Currencies seeded\\n')\n\n console.log('\uD83D\uDCCF Seeding catalog units...')\n await runModuleCommand(allModules, 'catalog', 'seed-units', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDCCF \u2705 Catalog units seeded\\n')\n\n if (await tryRunModuleCommand(allModules, 'planner', 'seed-unavailability-reasons', ['--tenant', tenantId, '--org', orgId])) {\n console.log('\uD83D\uDDD3\uFE0F \u2705 Unavailability reasons seeded\\n')\n }\n\n const parsedEncryption = parseBooleanToken(process.env.TENANT_DATA_ENCRYPTION ?? 'yes')\n const encryptionEnabled = parsedEncryption === null ? true : parsedEncryption\n if (encryptionEnabled) {\n console.log('\uD83D\uDD12 Seeding encryption defaults...')\n await runModuleCommand(allModules, 'entities', 'seed-encryption', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDD12 \u2705 Encryption defaults seeded\\n')\n } else {\n console.log('\u26A0\uFE0F TENANT_DATA_ENCRYPTION disabled; skipping encryption defaults.\\n')\n }\n\n console.log('\uD83C\uDFF7\uFE0F Seeding catalog price kinds...')\n await runModuleCommand(allModules, 'catalog', 'seed-price-kinds', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83C\uDFF7\uFE0F \u2705 Catalog price kinds seeded\\n')\n\n console.log('\uD83D\uDCB6 Seeding default tax rates...')\n await runModuleCommand(allModules, 'sales', 'seed-tax-rates', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83E\uDDFE \u2705 Tax rates seeded\\n')\n\n console.log('\uD83D\uDEA6 Seeding sales statuses...')\n await runModuleCommand(allModules, 'sales', 'seed-statuses', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDEA6 \u2705 Sales statuses seeded\\n')\n\n console.log('\u2699\uFE0F Seeding adjustment kinds...')\n await runModuleCommand(allModules, 'sales', 'seed-adjustment-kinds', ['--tenant', tenantId, '--org', orgId])\n console.log('\u2699\uFE0F \u2705 Adjustment kinds seeded\\n')\n\n console.log('\uD83D\uDE9A Seeding shipping methods...')\n await runModuleCommand(allModules, 'sales', 'seed-shipping-methods', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDE9A \u2705 Shipping methods seeded\\n')\n\n console.log('\uD83D\uDCB3 Seeding payment methods...')\n await runModuleCommand(allModules, 'sales', 'seed-payment-methods', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDCB3 \u2705 Payment methods seeded\\n')\n\n console.log('\uD83D\uDD04 Seeding workflow definitions...')\n try {\n await runModuleCommand(allModules, 'workflows', 'seed-all', ['--tenant', tenantId, '--org', orgId])\n console.log('\u2705 Workflows and business rules seeded\\n')\n } catch (err) {\n console.error('\u26A0\uFE0F Workflow seeding failed (non-fatal):', err)\n }\n\n if (skipExamples) {\n console.log('\uD83D\uDEAB Example data seeding skipped (--no-examples)\\n')\n } else {\n console.log('\uD83D\uDECD\uFE0F Seeding catalog examples...')\n await runModuleCommand(allModules, 'catalog', 'seed-examples', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83D\uDECD\uFE0F \u2705 Catalog examples seeded\\n')\n\n console.log('\uD83C\uDFE2 Seeding customer examples...')\n await runModuleCommand(allModules, 'customers', 'seed-examples', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83C\uDFE2 \u2705 Customer examples seeded\\n')\n\n console.log('\uD83E\uDDFE Seeding sales examples...')\n await runModuleCommand(allModules, 'sales', 'seed-examples', ['--tenant', tenantId, '--org', orgId])\n console.log('\uD83E\uDDFE \u2705 Sales examples seeded\\n')\n\n if (await tryRunModuleCommand(allModules, 'staff', 'seed-examples', ['--tenant', tenantId, '--org', orgId])) {\n console.log('\uD83D\uDC65 \u2705 Staff examples seeded\\n')\n }\n\n if (await tryRunModuleCommand(allModules, 'resources', 'seed-capacity-units', ['--tenant', tenantId, '--org', orgId])) {\n console.log('\uD83D\uDCE6 \u2705 Resource capacity units seeded\\n')\n }\n\n if (await tryRunModuleCommand(allModules, 'resources', 'seed-examples', ['--tenant', tenantId, '--org', orgId])) {\n console.log('\uD83E\uDDF0 \u2705 Resource examples seeded\\n')\n }\n\n if (await tryRunModuleCommand(allModules, 'planner', 'seed-availability-rulesets', ['--tenant', tenantId, '--org', orgId])) {\n console.log('\uD83D\uDDD3\uFE0F \u2705 Planner availability rulesets seeded\\n')\n }\n\n // Optional: seed example todos if the example module is enabled\n const exampleModule = allModules.find((m) => m.id === 'example')\n if (exampleModule && exampleModule.cli) {\n console.log('\uD83D\uDCDD Seeding example todos...')\n await runModuleCommand(allModules, 'example', 'seed-todos', ['--org', orgId, '--tenant', tenantId])\n console.log('\uD83D\uDCDD \u2705 Example todos seeded\\n')\n }\n }\n\n if (stressTestEnabled) {\n console.log(\n `\uD83C\uDFCB\uFE0F Seeding stress test customers${stressTestLite ? ' (lite payload)' : ''}...`\n )\n const stressArgs = ['--tenant', tenantId, '--org', orgId, '--count', String(stressTestCount)]\n if (stressTestLite) stressArgs.push('--lite')\n await runModuleCommand(allModules, 'customers', 'seed-stresstest', stressArgs)\n console.log(`\u2705 Stress test customers seeded (requested ${stressTestCount})\\n`)\n }\n\n console.log('\uD83E\uDDE9 Enabling default dashboard widgets...')\n await runModuleCommand(allModules, 'dashboards', 'seed-defaults', ['--tenant', tenantId])\n console.log('\u2705 Dashboard widgets enabled\\n')\n\n } else {\n console.log('\u26A0\uFE0F Could not get organization ID or tenant ID, skipping seeding steps\\n')\n }\n\n console.log('\uD83E\uDDE0 Building search indexes...')\n const vectorArgs = tenantId\n ? ['--tenant', tenantId, ...(orgId ? ['--org', orgId] : [])]\n : ['--purgeFirst=false']\n await runModuleCommand(allModules, 'search', 'reindex', vectorArgs)\n console.log('\u2705 Search indexes built\\n')\n\n console.log('\uD83D\uDD0D Rebuilding query indexes...')\n const queryIndexArgs = ['--force', ...(tenantId ? ['--tenant', tenantId] : [])]\n await runModuleCommand(allModules, 'query_index', 'reindex', queryIndexArgs)\n console.log('\u2705 Query indexes rebuilt\\n')\n\n // Derive admin/employee only when the provided email is a superadmin email\n const [local, domain] = String(email).split('@')\n const isSuperadminLocal = (local || '').toLowerCase() === 'superadmin' && !!domain\n const adminEmailDerived = isSuperadminLocal ? `admin@${domain}` : null\n const employeeEmailDerived = isSuperadminLocal ? `employee@${domain}` : null\n\n // Simplified success message: we know which users were created\n console.log('\uD83C\uDF89 App initialization complete!\\n')\n console.log('\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\u2557')\n console.log('\u2551 \uD83D\uDE80 You\\'re now ready to start development! \u2551')\n console.log('\u2551 \u2551')\n console.log('\u2551 Start the dev server: \u2551')\n console.log('\u2551 yarn dev \u2551')\n console.log('\u2551 \u2551')\n console.log('\u2551 Users created: \u2551')\n console.log(`\u2551 \uD83D\uDC51 Superadmin: ${email.padEnd(42)} \u2551`)\n console.log(`\u2551 Password: ${password.padEnd(44)} \u2551`)\n if (adminEmailDerived) {\n console.log(`\u2551 \uD83E\uDDF0 Admin: ${adminEmailDerived.padEnd(42)} \u2551`)\n console.log(`\u2551 Password: ${password.padEnd(44)} \u2551`)\n }\n if (employeeEmailDerived) {\n console.log(`\u2551 \uD83D\uDC77 Employee: ${employeeEmailDerived.padEnd(42)} \u2551`)\n console.log(`\u2551 Password: ${password.padEnd(44)} \u2551`)\n }\n console.log('\u2551 \u2551')\n console.log('\u2551 Happy coding! \u2551')\n console.log('\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\u255D')\n\n return 0\n } catch (error: unknown) {\n if (error instanceof Error) {\n console.error('\u274C Initialization failed:', error.message)\n } else {\n console.error('\u274C Initialization failed:', error)\n }\n return 1\n }\n }\n\n let modName = first\n let cmdName = second\n let rest = remaining\n\n if (first === 'reindex') {\n modName = 'query_index'\n cmdName = 'reindex'\n rest = second !== undefined ? [second, ...remaining] : remaining\n }\n\n // Handle 'mercato generate' without subcommand - default to 'generate all'\n if (first === 'generate' && !second) {\n cmdName = 'all'\n rest = remaining\n }\n\n // Load modules from registered CLI modules\n const modules = getCliModules()\n \n // Load optional app-level CLI commands lazily without static import resolution\n let appCli: any[] = []\n try {\n const dynImport: any = (Function('return import') as any)()\n const app = await dynImport.then((f: any) => f('@/cli')).catch(() => null)\n if (app && Array.isArray(app?.default)) appCli = app.default\n } catch {}\n const all = modules.slice()\n \n // Built-in CLI module: queue\n all.push({\n id: 'queue',\n cli: [\n {\n command: 'worker',\n run: async (args: string[]) => {\n const isAllQueues = args.includes('--all')\n const queueName = isAllQueues ? null : args[0]\n\n // Collect all discovered workers from modules\n type WorkerEntry = {\n id: string\n queue: string\n concurrency: number\n handler: (job: unknown, ctx: unknown) => Promise<void> | void\n }\n const allWorkers: WorkerEntry[] = []\n for (const mod of getCliModules()) {\n const modWorkers = (mod as { workers?: WorkerEntry[] }).workers\n if (modWorkers) {\n allWorkers.push(...modWorkers)\n }\n }\n const discoveredQueues = [...new Set(allWorkers.map((w) => w.queue))]\n\n if (!queueName && !isAllQueues) {\n console.error('Usage: mercato queue worker <queueName> | --all')\n console.error('Example: mercato queue worker events')\n console.error('Example: mercato queue worker --all')\n if (discoveredQueues.length > 0) {\n console.error(`Discovered queues: ${discoveredQueues.join(', ')}`)\n }\n return\n }\n\n const concurrencyArg = args.find((a) => a.startsWith('--concurrency='))\n const concurrencyOverride = concurrencyArg ? Number(concurrencyArg.split('=')[1]) : undefined\n\n if (isAllQueues) {\n // Run workers for all discovered queues\n if (discoveredQueues.length === 0) {\n console.error('[worker] No queues discovered from modules')\n return\n }\n\n const container = await createRequestContainer()\n console.log(`[worker] Starting workers for all queues: ${discoveredQueues.join(', ')}`)\n\n // Start all queue workers in background mode\n const workerPromises = discoveredQueues.map(async (queue) => {\n const queueWorkers = allWorkers.filter((w) => w.queue === queue)\n const concurrency = concurrencyOverride ?? Math.max(...queueWorkers.map((w) => w.concurrency), 1)\n\n console.log(`[worker] Starting \"${queue}\" with ${queueWorkers.length} handler(s), concurrency: ${concurrency}`)\n\n await runWorker({\n queueName: queue,\n connection: { url: process.env.REDIS_URL || process.env.QUEUE_REDIS_URL },\n concurrency,\n background: true,\n handler: async (job, ctx) => {\n for (const worker of queueWorkers) {\n await worker.handler(job, { ...ctx, resolve: container.resolve.bind(container) })\n }\n },\n })\n })\n\n await Promise.all(workerPromises)\n\n console.log('[worker] All workers started. Press Ctrl+C to stop')\n\n // Keep the process alive\n await new Promise(() => {})\n } else {\n // Find workers for this specific queue\n const queueWorkers = allWorkers.filter((w) => w.queue === queueName)\n\n if (queueWorkers.length > 0) {\n // Use discovered workers\n const container = await createRequestContainer()\n const concurrency = concurrencyOverride ?? Math.max(...queueWorkers.map((w) => w.concurrency), 1)\n\n console.log(`[worker] Found ${queueWorkers.length} worker(s) for queue \"${queueName}\"`)\n\n await runWorker({\n queueName: queueName!,\n connection: { url: process.env.REDIS_URL || process.env.QUEUE_REDIS_URL },\n concurrency,\n handler: async (job, ctx) => {\n for (const worker of queueWorkers) {\n await worker.handler(job, { ...ctx, resolve: container.resolve.bind(container) })\n }\n },\n })\n } else {\n console.error(`No workers found for queue \"${queueName}\"`)\n if (discoveredQueues.length > 0) {\n console.error(`Available queues: ${discoveredQueues.join(', ')}`)\n }\n }\n }\n },\n },\n {\n command: 'clear',\n run: async (args: string[]) => {\n const queueName = args[0]\n if (!queueName) {\n console.error('Usage: mercato queue clear <queueName>')\n return\n }\n\n const strategyEnv = process.env.QUEUE_STRATEGY || 'local'\n const { createQueue } = await import('@open-mercato/queue')\n\n const queue = strategyEnv === 'async'\n ? createQueue(queueName, 'async', {\n connection: { url: process.env.REDIS_URL || process.env.QUEUE_REDIS_URL },\n })\n : createQueue(queueName, 'local')\n\n const res = await queue.clear()\n await queue.close()\n console.log(`Cleared queue \"${queueName}\", removed ${res.removed} jobs`)\n },\n },\n {\n command: 'status',\n run: async (args: string[]) => {\n const queueName = args[0]\n if (!queueName) {\n console.error('Usage: mercato queue status <queueName>')\n return\n }\n\n const strategyEnv = process.env.QUEUE_STRATEGY || 'local'\n const { createQueue } = await import('@open-mercato/queue')\n\n const queue = strategyEnv === 'async'\n ? createQueue(queueName, 'async', {\n connection: { url: process.env.REDIS_URL || process.env.QUEUE_REDIS_URL },\n })\n : createQueue(queueName, 'local')\n\n const counts = await queue.getJobCounts()\n console.log(`Queue \"${queueName}\" status:`)\n console.log(` Waiting: ${counts.waiting}`)\n console.log(` Active: ${counts.active}`)\n console.log(` Completed: ${counts.completed}`)\n console.log(` Failed: ${counts.failed}`)\n await queue.close()\n },\n },\n ],\n } as any)\n\n // Built-in CLI module: events\n all.push({\n id: 'events',\n cli: [\n {\n command: 'emit',\n run: async (args: string[]) => {\n const eventName = args[0]\n if (!eventName) {\n console.error('Usage: mercato events emit <event> [jsonPayload] [--persistent|-p]')\n return\n }\n const persistent = args.includes('--persistent') || args.includes('-p')\n const payloadArg = args[1] && !args[1].startsWith('--') ? args[1] : undefined\n let payload: any = {}\n if (payloadArg) {\n try { payload = JSON.parse(payloadArg) } catch { payload = payloadArg }\n }\n const { createRequestContainer } = await import('@open-mercato/shared/lib/di/container')\n const container = await createRequestContainer()\n const bus = (container.resolve('eventBus') as any)\n await bus.emit(eventName, payload, { persistent })\n console.log(`Emitted \"${eventName}\"${persistent ? ' (persistent)' : ''}`)\n },\n },\n {\n command: 'clear',\n run: async () => {\n const { createRequestContainer } = await import('@open-mercato/shared/lib/di/container')\n const container = await createRequestContainer()\n const bus = (container.resolve('eventBus') as any)\n const res = await bus.clearQueue()\n console.log(`Cleared events queue, removed ${res.removed} events`)\n },\n },\n ],\n } as any)\n \n // Built-in CLI module: scaffold\n all.push({\n id: 'scaffold',\n cli: [\n {\n command: 'module',\n run: async (args: string[]) => {\n const name = (args[0] || '').trim()\n if (!name) {\n console.error('Usage: mercato scaffold module <name>')\n return\n }\n const fs = await import('node:fs')\n const path = await import('node:path')\n const { execSync } = await import('node:child_process')\n const base = path.resolve('src/modules', name)\n const folders = ['api', 'backend', 'frontend', 'data', 'subscribers']\n for (const f of folders) fs.mkdirSync(path.join(base, f), { recursive: true })\n const moduleTitle = `${name[0].toUpperCase()}${name.slice(1)}`\n const indexTs = `export const metadata = { title: '${moduleTitle}', group: 'Modules' }\\n`\n fs.writeFileSync(path.join(base, 'index.ts'), indexTs, { flag: 'wx' })\n const ceTs = `export const entities = [\\n {\\n id: '${name}:sample',\\n label: '${moduleTitle} Sample',\\n description: 'Describe your custom entity',\\n showInSidebar: true,\\n fields: [\\n // { key: 'priority', kind: 'integer', label: 'Priority' },\\n ],\\n },\\n]\\n\\nexport default entities\\n`\n fs.writeFileSync(path.join(base, 'ce.ts'), ceTs, { flag: 'wx' })\n const entitiesTs = `import { Entity, PrimaryKey, Property } from '@mikro-orm/core'\\n\\n// Add your entities here. Example:\\n// @Entity({ tableName: '${name}_items' })\\n// export class ${moduleTitle}Item {\\n// @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' }) id!: string\\n// @Property({ type: 'text' }) title!: string\\n// @Property({ name: 'organization_id', type: 'uuid', nullable: true }) organizationId?: string | null\\n// @Property({ name: 'tenant_id', type: 'uuid', nullable: true }) tenantId?: string | null\\n// @Property({ name: 'created_at', type: Date, onCreate: () => new Date() }) createdAt: Date = new Date()\\n// @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() }) updatedAt: Date = new Date()\\n// @Property({ name: 'deleted_at', type: Date, nullable: true }) deletedAt?: Date | null\\n// }\\n`\n fs.writeFileSync(path.join(base, 'data', 'entities.ts'), entitiesTs, { flag: 'wx' })\n console.log(`Created module at ${path.relative(process.cwd(), base)}`)\n execSync('yarn modules:prepare', { stdio: 'inherit' })\n },\n },\n {\n command: 'entity',\n run: async () => {\n const fs = await import('node:fs')\n const path = await import('node:path')\n const readline = await import('node:readline/promises')\n const { stdin: input, stdout: output } = await import('node:process')\n const { execSync } = await import('node:child_process')\n const rl = readline.createInterface({ input, output })\n try {\n const moduleId = (await rl.question('Module id (folder under src/modules): ')).trim()\n const className = (await rl.question('Entity class name (e.g., Todo): ')).trim()\n const tableName = (await rl.question(`DB table name (default: ${className.toLowerCase()}s): `)).trim() || `${className.toLowerCase()}s`\n const extra = (await rl.question('Additional fields (comma list name:type, e.g., title:text,is_done:boolean): ')).trim()\n const extras = extra\n ? extra.split(',').map(s => s.trim()).filter(Boolean).map(s => {\n const [n,t] = s.split(':').map(x=>x.trim()); return { n, t }\n })\n : []\n const base = path.resolve('src/modules', moduleId, 'data')\n fs.mkdirSync(base, { recursive: true })\n const file = path.join(base, 'entities.ts')\n let content = fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : `import { Entity, PrimaryKey, Property } from '@mikro-orm/core'\\n\\n`\n content += `\\n@Entity({ tableName: '${tableName}' })\\nexport class ${className} {\\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\\n id!: string\\n\\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\\n organizationId?: string | null\\n\\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\\n tenantId?: string | null\\n\\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\\n createdAt: Date = new Date()\\n\\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\\n updatedAt: Date = new Date()\\n\\n @Property({ name: 'deleted_at', type: Date, nullable: true })\\n deletedAt?: Date | null\\n`\n for (const f of extras) {\n const n = f.n\n const t = f.t\n if (!n || !t) continue\n const map = {\n text: { ts: 'string', db: 'text' },\n multiline: { ts: 'string', db: 'text' },\n integer: { ts: 'number', db: 'int' },\n float: { ts: 'number', db: 'float' },\n boolean: { ts: 'boolean', db: 'boolean' },\n date: { ts: 'Date', db: 'Date' },\n } as const\n const info = map[t as keyof typeof map]\n const fallback = { ts: 'string', db: 'text' }\n const resolved = info || fallback\n const propName = n.replace(/_([a-z])/g, (_, c) => c.toUpperCase())\n const columnName = n.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`)\n const dbType = resolved.db\n const tsType = resolved.ts\n const defaultValue =\n resolved.ts === 'boolean' ? ' = false' :\n resolved.ts === 'Date' ? ' = new Date()' :\n ''\n content += `\\n @Property({ name: '${columnName}', type: ${dbType === 'Date' ? 'Date' : `'${dbType}'`}${resolved.ts === 'boolean' ? ', default: false' : ''} })\\n ${propName}${tsType === 'number' ? '?: number | null' : tsType === 'boolean' ? ': boolean' : tsType === 'Date' ? ': Date' : '!: string'}${defaultValue}\\n`\n }\n content += `}\\n`\n fs.writeFileSync(file, content)\n console.log(`Updated ${path.relative(process.cwd(), file)}`)\n console.log('Generating and applying migrations...')\n execSync('yarn modules:prepare', { stdio: 'inherit' })\n execSync('yarn db:generate', { stdio: 'inherit' })\n execSync('yarn db:migrate', { stdio: 'inherit' })\n } finally {\n rl.close()\n }\n },\n },\n {\n command: 'crud',\n run: async (args: string[]) => {\n const fs = await import('node:fs')\n const path = await import('node:path')\n const { execSync } = await import('node:child_process')\n const mod = (args[0] || '').trim()\n const entity = (args[1] || '').trim()\n const routeSeg = (args[2] || '').trim() || `${entity.toLowerCase()}s`\n if (!mod || !entity) {\n console.error('Usage: mercato scaffold crud <moduleId> <EntityClass> [routeSegment]')\n return\n }\n const baseDir = path.resolve('src/modules', mod, 'api', routeSeg)\n fs.mkdirSync(baseDir, { recursive: true })\n const entitySnake = entity.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase()\n const tmpl = `import { z } from 'zod'\\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\\nimport { ${entity} } from '@open-mercato/shared/modules/${mod}/data/entities'\\nimport { E } from '#generated/entities.ids.generated'\\nimport ceEntities from '@open-mercato/shared/modules/${mod}/ce'\\nimport { buildCustomFieldSelectorsForEntity, extractCustomFieldsFromItem, buildCustomFieldFiltersFromQuery } from '@open-mercato/shared/lib/crud/custom-fields'\\nimport type { CustomFieldSet } from '@open-mercato/shared/modules/entities'\\n\\n// Field constants - update these based on your entity's actual fields\\nconst F = {\\n id: 'id',\\n tenant_id: 'tenant_id',\\n organization_id: 'organization_id',\\n created_at: 'created_at',\\n updated_at: 'updated_at',\\n deleted_at: 'deleted_at',\\n} as const\\n\\nconst querySchema = z.object({\\n id: z.string().uuid().optional(),\\n page: z.coerce.number().min(1).default(1),\\n pageSize: z.coerce.number().min(1).max(100).default(50),\\n sortField: z.string().optional().default('id'),\\n sortDir: z.enum(['asc','desc']).optional().default('asc'),\\n withDeleted: z.coerce.boolean().optional().default(false),\\n}).passthrough()\\n\\nconst createSchema = z.object({}).passthrough()\\nconst updateSchema = z.object({ id: z.string().uuid() }).passthrough()\\n\\ntype Query = z.infer<typeof querySchema>\\n\\nconst fieldSets: CustomFieldSet[] = []\\nconst ceEntity = Array.isArray(ceEntities) ? ceEntities.find((entity) => entity?.id === '${mod}:${entitySnake}') : undefined\\nif (ceEntity?.fields?.length) {\\n fieldSets.push({ entity: ceEntity.id, fields: ceEntity.fields, source: '${mod}' })\\n}\\n\\nconst cfSel = buildCustomFieldSelectorsForEntity(E.${mod}.${entitySnake}, fieldSets)\\nconst sortFieldMap: Record<string, unknown> = { id: F.id, created_at: F.created_at, ...Object.fromEntries(cfSel.keys.map(k => [\\`cf_\\${k}\\`, \\`cf:\\${k}\\`])) }\\n\\nexport const { metadata, GET, POST, PUT, DELETE } = makeCrudRoute({\\n metadata: { GET: { requireAuth: true }, POST: { requireAuth: true }, PUT: { requireAuth: true }, DELETE: { requireAuth: true } },\\n orm: { entity: ${entity}, idField: 'id', orgField: 'organizationId', tenantField: 'tenantId', softDeleteField: 'deletedAt' },\\n events: { module: '${mod}', entity: '${entitySnake}', persistent: true },\\n indexer: { entityType: E.${mod}.${entitySnake} },\\n list: {\\n schema: querySchema,\\n entityId: E.${mod}.${entitySnake},\\n fields: [F.id, F.created_at, ...cfSel.selectors],\\n sortFieldMap,\\n buildFilters: async (q: Query, ctx) => ({\\n ...(await buildCustomFieldFiltersFromQuery({\\n entityId: E.${mod}.${entitySnake},\\n query: q as any,\\n em: ctx.container.resolve('em'),\\n tenantId: ctx.auth!.tenantId,\\n })),\\n }),\\n transformItem: (item: any) => ({ id: item.id, created_at: item.created_at, ...extractCustomFieldsFromItem(item, cfSel.keys) }),\\n },\\n create: { schema: createSchema, mapToEntity: (input: any) => ({}), customFields: { enabled: true, entityId: E.${mod}.${entitySnake}, pickPrefixed: true } },\\n update: { schema: updateSchema, applyToEntity: (entity: ${entity}, input: any) => {}, customFields: { enabled: true, entityId: E.${mod}.${entitySnake}, pickPrefixed: true } },\\n del: { idFrom: 'query', softDelete: true },\\n})\\n`\n const file = path.join(baseDir, 'route.ts')\n fs.writeFileSync(file, tmpl, { flag: 'wx' })\n console.log(`Created CRUD route: ${path.relative(process.cwd(), file)}`)\n execSync('yarn modules:prepare', { stdio: 'inherit' })\n },\n },\n ],\n } as any)\n\n // Built-in CLI module: generate\n all.push({\n id: 'generate',\n cli: [\n {\n command: 'all',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { generateEntityIds, generateModuleRegistry, generateModuleRegistryCli, generateModuleEntities, generateModuleDi } = await import('./lib/generators')\n const resolver = createResolver()\n const quiet = args.includes('--quiet') || args.includes('-q')\n\n console.log('Running all generators...')\n await generateEntityIds({ resolver, quiet })\n await generateModuleRegistry({ resolver, quiet })\n await generateModuleRegistryCli({ resolver, quiet })\n await generateModuleEntities({ resolver, quiet })\n await generateModuleDi({ resolver, quiet })\n console.log('All generators completed.')\n },\n },\n {\n command: 'entity-ids',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { generateEntityIds } = await import('./lib/generators')\n const resolver = createResolver()\n await generateEntityIds({ resolver, quiet: args.includes('--quiet') })\n },\n },\n {\n command: 'registry',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { generateModuleRegistry } = await import('./lib/generators')\n const resolver = createResolver()\n await generateModuleRegistry({ resolver, quiet: args.includes('--quiet') })\n },\n },\n {\n command: 'entities',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { generateModuleEntities } = await import('./lib/generators')\n const resolver = createResolver()\n await generateModuleEntities({ resolver, quiet: args.includes('--quiet') })\n },\n },\n {\n command: 'di',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { generateModuleDi } = await import('./lib/generators')\n const resolver = createResolver()\n await generateModuleDi({ resolver, quiet: args.includes('--quiet') })\n },\n },\n ],\n } as any)\n\n // Built-in CLI module: db\n all.push({\n id: 'db',\n cli: [\n {\n command: 'generate',\n run: async () => {\n const { createResolver } = await import('./lib/resolver')\n const { dbGenerate } = await import('./lib/db')\n const resolver = createResolver()\n await dbGenerate(resolver)\n },\n },\n {\n command: 'migrate',\n run: async () => {\n const { createResolver } = await import('./lib/resolver')\n const { dbMigrate } = await import('./lib/db')\n const resolver = createResolver()\n await dbMigrate(resolver)\n },\n },\n {\n command: 'greenfield',\n run: async (args: string[]) => {\n const { createResolver } = await import('./lib/resolver')\n const { dbGreenfield } = await import('./lib/db')\n const resolver = createResolver()\n const yes = args.includes('--yes') || args.includes('-y')\n await dbGreenfield(resolver, { yes })\n },\n },\n ],\n } as any)\n\n // Built-in CLI module: server (runs Next.js + workers)\n all.push({\n id: 'server',\n cli: [\n {\n command: 'dev',\n run: async () => {\n const { spawn } = await import('child_process')\n const path = await import('path')\n const { createResolver } = await import('./lib/resolver')\n const resolver = createResolver()\n const appDir = resolver.getAppDir()\n\n // In monorepo, packages are hoisted to root; in standalone, they're in app's node_modules\n const nodeModulesBase = resolver.isMonorepo() ? resolver.getRootDir() : appDir\n\n const processes: ChildProcess[] = []\n const autoSpawnWorkers = process.env.AUTO_SPAWN_WORKERS !== 'false'\n\n function cleanup() {\n console.log('[server] Shutting down...')\n for (const proc of processes) {\n if (!proc.killed) {\n proc.kill('SIGTERM')\n }\n }\n }\n\n process.on('SIGTERM', cleanup)\n process.on('SIGINT', cleanup)\n\n console.log('[server] Starting Open Mercato in dev mode...')\n\n // Resolve paths relative to where node_modules are located\n const nextBin = path.join(nodeModulesBase, 'node_modules/next/dist/bin/next')\n const mercatoBin = path.join(nodeModulesBase, 'node_modules/@open-mercato/cli/bin/mercato')\n\n // Start Next.js dev\n const nextProcess = spawn('node', [nextBin, 'dev', '--turbopack'], {\n stdio: 'inherit',\n env: process.env,\n cwd: appDir,\n })\n processes.push(nextProcess)\n\n // Start workers if enabled\n if (autoSpawnWorkers) {\n console.log('[server] Starting workers for all queues...')\n const workerProcess = spawn('node', [mercatoBin, 'queue', 'worker', '--all'], {\n stdio: 'inherit',\n env: process.env,\n cwd: appDir,\n })\n processes.push(workerProcess)\n }\n\n // Wait for any process to exit\n await Promise.race(\n processes.map(\n (proc) =>\n new Promise<void>((resolve) => {\n proc.on('exit', () => resolve())\n })\n )\n )\n\n cleanup()\n },\n },\n {\n command: 'start',\n run: async () => {\n const { spawn } = await import('child_process')\n const path = await import('path')\n const { createResolver } = await import('./lib/resolver')\n const resolver = createResolver()\n const appDir = resolver.getAppDir()\n\n // In monorepo, packages are hoisted to root; in standalone, they're in app's node_modules\n const nodeModulesBase = resolver.isMonorepo() ? resolver.getRootDir() : appDir\n\n const processes: ChildProcess[] = []\n const autoSpawnWorkers = process.env.AUTO_SPAWN_WORKERS !== 'false'\n\n function cleanup() {\n console.log('[server] Shutting down...')\n for (const proc of processes) {\n if (!proc.killed) {\n proc.kill('SIGTERM')\n }\n }\n }\n\n process.on('SIGTERM', cleanup)\n process.on('SIGINT', cleanup)\n\n console.log('[server] Starting Open Mercato in production mode...')\n\n // Resolve paths relative to where node_modules are located\n const nextBin = path.join(nodeModulesBase, 'node_modules/next/dist/bin/next')\n const mercatoBin = path.join(nodeModulesBase, 'node_modules/@open-mercato/cli/bin/mercato')\n\n // Start Next.js production server\n const nextProcess = spawn('node', [nextBin, 'start'], {\n stdio: 'inherit',\n env: process.env,\n cwd: appDir,\n })\n processes.push(nextProcess)\n\n // Start workers if enabled\n if (autoSpawnWorkers) {\n console.log('[server] Starting workers for all queues...')\n const workerProcess = spawn('node', [mercatoBin, 'queue', 'worker', '--all'], {\n stdio: 'inherit',\n env: process.env,\n cwd: appDir,\n })\n processes.push(workerProcess)\n }\n\n // Wait for any process to exit\n await Promise.race(\n processes.map(\n (proc) =>\n new Promise<void>((resolve) => {\n proc.on('exit', () => resolve())\n })\n )\n )\n\n cleanup()\n },\n },\n ],\n } as any)\n\n if (appCli.length) all.push({ id: 'app', cli: appCli } as any)\n\n const quietBanner = process.env.OM_CLI_QUIET === '1'\n const banner = '\uD83E\uDDE9 Open Mercato CLI'\n if (!quietBanner) {\n const header = [\n '\u2554\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 `\u2551 ${banner.padEnd(21)}\u2551`,\n '\u255A\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 ].join('\\n')\n console.log(header)\n }\n const pad = (s: string) => ` ${s}`\n\n if (!modName || modName === 'help' || modName === '--help' || modName === '-h') {\n console.log(pad('Usage: \u2728 mercato <module> <command> [args]'))\n const list = all\n .filter((m) => m.cli && m.cli.length)\n .map((m) => `\u2022 ${m.id}: ${m.cli!.map((c) => `\"${c.command}\"`).join(', ')}`)\n if (list.length) {\n console.log('\\n' + pad('Available:'))\n console.log(list.map(pad).join('\\n'))\n } else {\n console.log(pad('\uD83C\uDF00 No CLI commands available'))\n }\n return 0\n }\n\n const mod = all.find((m) => m.id === modName)\n if (!mod) {\n console.error(`\u274C Module not found: \"${modName}\"`)\n return 1\n }\n if (!mod.cli || mod.cli.length === 0) {\n console.error(`\uD83D\uDEAB Module \"${modName}\" has no CLI commands`)\n return 1\n }\n if (!cmdName) {\n console.log(pad(`Commands for \"${modName}\": ${mod.cli.map((c) => c.command).join(', ')}`))\n return 1\n }\n const cmd = mod.cli.find((c) => c.command === cmdName)\n if (!cmd) {\n console.error(`\uD83E\uDD14 Unknown command \"${cmdName}\". Available: ${mod.cli.map((c) => c.command).join(', ')}`)\n return 1\n }\n\n console.log('')\n const started = Date.now()\n console.log(`\uD83D\uDE80 Running ${modName}:${cmdName} ${rest.join(' ')}`)\n try {\n await cmd.run(rest)\n const ms = Date.now() - started\n console.log(`\u23F1\uFE0F Done in ${ms}ms`)\n return 0\n } catch (e: any) {\n console.error(`\uD83D\uDCA5 Failed: ${e?.message || e}`)\n return 1\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["Client", "dbUrl", "mod", "createRequestContainer", "fs", "path"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/cli",
3
- "version": "0.4.2-canary-3f5eaf79f7",
3
+ "version": "0.4.2-canary-f4761534e7",
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-3f5eaf79f7",
58
+ "@open-mercato/shared": "0.4.2-canary-f4761534e7",
59
59
  "pg": "^8.16.3",
60
60
  "typescript": "^5.9.3"
61
61
  },
@@ -77,7 +77,8 @@ async function loadModuleEntities(entry: ModuleEntry, resolver: PackageResolver)
77
77
  path.join(roots.appBase, 'db'),
78
78
  path.join(roots.pkgBase, 'db'),
79
79
  ]
80
- const candidates = ['entities.ts', 'schema.ts']
80
+ // Check both .ts (src/monorepo) and .js (dist/production) extensions
81
+ const candidates = ['entities.ts', 'entities.js', 'schema.ts', 'schema.js']
81
82
 
82
83
  for (const base of bases) {
83
84
  for (const f of candidates) {
@@ -85,10 +86,12 @@ async function loadModuleEntities(entry: ModuleEntry, resolver: PackageResolver)
85
86
  if (fs.existsSync(p)) {
86
87
  const sub = path.basename(base)
87
88
  const fromApp = base.startsWith(roots.appBase)
89
+ const ext = path.extname(f)
90
+ const baseName = f.replace(ext, '')
88
91
  // For @app modules, use file:// URL since @/ alias doesn't work in Node.js runtime
89
92
  const importPath = (isAppModule && fromApp)
90
93
  ? `file://${p.replace(/\.ts$/, '.js')}`
91
- : `${fromApp ? imps.appBase : imps.pkgBase}/${sub}/${f.replace(/\.ts$/, '')}`
94
+ : `${fromApp ? imps.appBase : imps.pkgBase}/${sub}/${baseName}`
92
95
  try {
93
96
  const mod = await import(importPath)
94
97
  const entities = Object.values(mod).filter((v) => typeof v === 'function')
@@ -41,7 +41,7 @@ export async function generateModuleEntities(options: ModuleEntitiesOptions): Pr
41
41
  const appDb = path.join(roots.appBase, 'db')
42
42
  const pkgDb = path.join(roots.pkgBase, 'db')
43
43
  const bases = [appData, pkgData, appDb, pkgDb]
44
- const candidates = ['entities.override.ts', 'entities.ts', 'schema.ts']
44
+ const candidates = ['entities.override.ts', 'entities.override.js', 'entities.ts', 'entities.js', 'schema.ts', 'schema.js']
45
45
 
46
46
  let found: { base: string; file: string } | null = null
47
47
  for (const base of bases) {
@@ -63,12 +63,13 @@ export async function generateModuleEntities(options: ModuleEntitiesOptions): Pr
63
63
  // For @app modules, use relative path to ensure it works both in Next.js and Node.js CLI context
64
64
  // From .mercato/generated/, the relative path to src/modules/ is ../src/modules/
65
65
  let relImport: string
66
+ const fileBaseName = found.file.replace(/\.(ts|js)$/, '')
66
67
  if (isAppModule && fromApp) {
67
68
  // From .mercato/generated/, go up two levels (../..) to reach the app root, then into src/modules/
68
- relImport = `../../src/modules/${modId}/${sub}/${found.file.replace(/\.ts$/, '')}`
69
+ relImport = `../../src/modules/${modId}/${sub}/${fileBaseName}`
69
70
  } else {
70
71
  const baseImport = fromApp ? imp.appBase : imp.pkgBase
71
- relImport = `${baseImport}/${sub}/${found.file.replace(/\.ts$/, '')}`
72
+ relImport = `${baseImport}/${sub}/${fileBaseName}`
72
73
  }
73
74
  imports.push(`import * as ${importName} from '${relImport}'`)
74
75
  entitySources.push({ importName, moduleId: modId })
package/src/mercato.ts CHANGED
@@ -63,6 +63,25 @@ async function runModuleCommand(
63
63
  await cmd.run(args)
64
64
  }
65
65
 
66
+ // Helper to run a module command, skipping silently if module is not enabled
67
+ async function tryRunModuleCommand(
68
+ allModules: Module[],
69
+ moduleName: string,
70
+ commandName: string,
71
+ args: string[] = []
72
+ ): Promise<boolean> {
73
+ const mod = allModules.find((m) => m.id === moduleName)
74
+ if (!mod || !mod.cli || mod.cli.length === 0) {
75
+ return false
76
+ }
77
+ const cmd = mod.cli.find((c) => c.command === commandName)
78
+ if (!cmd) {
79
+ return false
80
+ }
81
+ await cmd.run(args)
82
+ return true
83
+ }
84
+
66
85
  // Build all CLI modules (registered + built-in)
67
86
  async function buildAllModules(): Promise<Module[]> {
68
87
  const modules = getCliModules()
@@ -300,13 +319,13 @@ export async function run(argv = process.argv) {
300
319
  await runModuleCommand(allModules, 'customers', 'seed-dictionaries', ['--tenant', tenantId, '--org', orgId])
301
320
  console.log('๐Ÿ“š โœ… Customer dictionaries seeded\n')
302
321
 
303
- console.log('๐Ÿ  Seeding staff address types...')
304
- await runModuleCommand(allModules, 'staff', 'seed-address-types', ['--tenant', tenantId, '--org', orgId])
305
- console.log('๐Ÿ  โœ… Staff address types seeded\n')
322
+ if (await tryRunModuleCommand(allModules, 'staff', 'seed-address-types', ['--tenant', tenantId, '--org', orgId])) {
323
+ console.log('๐Ÿ  โœ… Staff address types seeded\n')
324
+ }
306
325
 
307
- console.log('๐Ÿ  Seeding resources address types...')
308
- await runModuleCommand(allModules, 'resources', 'seed-address-types', ['--tenant', tenantId, '--org', orgId])
309
- console.log('๐Ÿ  โœ… Resources address types seeded\n')
326
+ if (await tryRunModuleCommand(allModules, 'resources', 'seed-address-types', ['--tenant', tenantId, '--org', orgId])) {
327
+ console.log('๐Ÿ  โœ… Resources address types seeded\n')
328
+ }
310
329
 
311
330
  console.log('๐Ÿ“š Seeding currencies...')
312
331
  await runModuleCommand(allModules, 'currencies', 'seed', ['--tenant', tenantId, '--org', orgId])
@@ -316,9 +335,9 @@ export async function run(argv = process.argv) {
316
335
  await runModuleCommand(allModules, 'catalog', 'seed-units', ['--tenant', tenantId, '--org', orgId])
317
336
  console.log('๐Ÿ“ โœ… Catalog units seeded\n')
318
337
 
319
- console.log('๐Ÿ—“๏ธ Seeding unavailability reasons...')
320
- await runModuleCommand(allModules, 'planner', 'seed-unavailability-reasons', ['--tenant', tenantId, '--org', orgId])
321
- console.log('๐Ÿ—“๏ธ โœ… Unavailability reasons seeded\n')
338
+ if (await tryRunModuleCommand(allModules, 'planner', 'seed-unavailability-reasons', ['--tenant', tenantId, '--org', orgId])) {
339
+ console.log('๐Ÿ—“๏ธ โœ… Unavailability reasons seeded\n')
340
+ }
322
341
 
323
342
  const parsedEncryption = parseBooleanToken(process.env.TENANT_DATA_ENCRYPTION ?? 'yes')
324
343
  const encryptionEnabled = parsedEncryption === null ? true : parsedEncryption
@@ -377,21 +396,21 @@ export async function run(argv = process.argv) {
377
396
  await runModuleCommand(allModules, 'sales', 'seed-examples', ['--tenant', tenantId, '--org', orgId])
378
397
  console.log('๐Ÿงพ โœ… Sales examples seeded\n')
379
398
 
380
- console.log('๐Ÿ‘ฅ Seeding staff examples...')
381
- await runModuleCommand(allModules, 'staff', 'seed-examples', ['--tenant', tenantId, '--org', orgId])
382
- console.log('๐Ÿ‘ฅ โœ… Staff examples seeded\n')
399
+ if (await tryRunModuleCommand(allModules, 'staff', 'seed-examples', ['--tenant', tenantId, '--org', orgId])) {
400
+ console.log('๐Ÿ‘ฅ โœ… Staff examples seeded\n')
401
+ }
383
402
 
384
- console.log('๐Ÿ“ฆ Seeding resource capacity units...')
385
- await runModuleCommand(allModules, 'resources', 'seed-capacity-units', ['--tenant', tenantId, '--org', orgId])
386
- console.log('๐Ÿ“ฆ โœ… Resource capacity units seeded\n')
403
+ if (await tryRunModuleCommand(allModules, 'resources', 'seed-capacity-units', ['--tenant', tenantId, '--org', orgId])) {
404
+ console.log('๐Ÿ“ฆ โœ… Resource capacity units seeded\n')
405
+ }
387
406
 
388
- console.log('๐Ÿงฐ Seeding resource examples...')
389
- await runModuleCommand(allModules, 'resources', 'seed-examples', ['--tenant', tenantId, '--org', orgId])
390
- console.log('๐Ÿงฐ โœ… Resource examples seeded\n')
407
+ if (await tryRunModuleCommand(allModules, 'resources', 'seed-examples', ['--tenant', tenantId, '--org', orgId])) {
408
+ console.log('๐Ÿงฐ โœ… Resource examples seeded\n')
409
+ }
391
410
 
392
- console.log('๐Ÿ—“๏ธ Seeding planner availability rulesets...')
393
- await runModuleCommand(allModules, 'planner', 'seed-availability-rulesets', ['--tenant', tenantId, '--org', orgId])
394
- console.log('๐Ÿ—“๏ธ โœ… Planner availability rulesets seeded\n')
411
+ if (await tryRunModuleCommand(allModules, 'planner', 'seed-availability-rulesets', ['--tenant', tenantId, '--org', orgId])) {
412
+ console.log('๐Ÿ—“๏ธ โœ… Planner availability rulesets seeded\n')
413
+ }
395
414
 
396
415
  // Optional: seed example todos if the example module is enabled
397
416
  const exampleModule = allModules.find((m) => m.id === 'example')