UNPKG

@lenne.tech/cli

Version:

lenne.Tech CLI: lt

120 lines (119 loc) 5.14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.apiNeedsPortPatch = apiNeedsPortPatch; exports.appNeedsPortPatch = appNeedsPortPatch; exports.deriveDbName = deriveDbName; exports.deriveTestDbName = deriveTestDbName; exports.deriveTicketDbName = deriveTicketDbName; exports.resolveLayout = resolveLayout; const fs_1 = require("fs"); const path_1 = require("path"); const workspace_integration_1 = require("./workspace-integration"); /** * Detect whether the API project still has the legacy hardcoded `port: 3000`. * Returns the file path if a patch is needed, null otherwise. */ function apiNeedsPortPatch(apiDir) { const file = (0, path_1.join)(apiDir, 'src', 'config.env.ts'); if (!(0, fs_1.existsSync)(file)) return null; const content = (0, fs_1.readFileSync)(file, 'utf8'); return /port:\s*3000\s*,/.test(content) ? file : null; } /** * Detect whether the App project still has hardcoded `port: 3001` or a * hardcoded vite-proxy `target: 'http://localhost:3000'`. Returns an * array of file paths that need patching. */ function appNeedsPortPatch(appDir) { const candidates = [(0, path_1.join)(appDir, 'nuxt.config.ts'), (0, path_1.join)(appDir, 'playwright.config.ts')]; return candidates.filter((file) => { if (!(0, fs_1.existsSync)(file)) return false; const c = (0, fs_1.readFileSync)(file, 'utf8'); return (/port:\s*3001\s*,/.test(c) || /target:\s*'http:\/\/localhost:3000'/.test(c) || /baseURL:\s*'http:\/\/localhost:3001'/.test(c) || /url:\s*'http:\/\/localhost:3001'/.test(c) || /host:\s*'http:\/\/localhost:3001'/.test(c) || // Unguarded Playwright `webServer` (no LT_DEV_ACTIVE guard) — patch it so // `lt dev test`'s isolated stack is reused instead of a stray server. (/webServer:\s*[[{]/.test(c) && !/webServer:\s*process\.env\.LT_DEV_ACTIVE/.test(c))); }); } /** Read `dbName` from the API config (defaults to `<slug>-local`). */ function deriveDbName(apiDir, slug) { if (apiDir) { const cfg = (0, path_1.join)(apiDir, 'src', 'config.env.ts'); if ((0, fs_1.existsSync)(cfg)) { const content = (0, fs_1.readFileSync)(cfg, 'utf8'); const match = content.match(/dbName:\s*['"`]([^'"`]+)['"`]/); if (match) return match[1]; } } return `${slug}-local`; } /** * Derive the dedicated database name for the `lt dev test` stack from the * project's dev DB name. Distinct from both `<…>-local` (developer DB) and * the API unit-test DB (`<…>-e2e`), so Playwright E2E never touches developer * or API-test data. * * svl-sports-system-local → svl-sports-system-test * * Uses the `-test` suffix so it passes test-helper guards that only permit * local/test databases (name ending in `-local` | `-ci` | `-e2e` | `-test`). */ function deriveTestDbName(devDbName) { const base = devDbName.replace(/-(local|dev)$/i, ''); return `${base}-test`; } /** * Derive the per-TICKET database name from the project's dev DB name, so each * ticket worktree reads/writes its OWN database and tickets never collide. * * svl-sports-system-local + "2200" → svl-sports-system-2200 * * The ticket's isolated `lt dev test` stack then derives its test DB from this * via {@link deriveTestDbName} → `svl-sports-system-2200-test`. */ function deriveTicketDbName(devDbName, ticketId) { const base = devDbName.replace(/-(local|dev)$/i, ''); return `${base}-${ticketId}`; } /** * Resolve layout starting from `cwd`. Walks up to find a workspace if * cwd is inside `projects/api/` or `projects/app/`. */ function resolveLayout(cwd, filesystem) { const subContext = (0, workspace_integration_1.detectSubProjectContext)(cwd, filesystem); if (subContext) return monorepoLayout(subContext.workspaceRoot); const layout = (0, workspace_integration_1.detectWorkspaceLayout)(cwd, filesystem); if (layout.hasWorkspace) return monorepoLayout(layout.workspaceDir); const workspaceRoot = (0, workspace_integration_1.findWorkspaceRoot)(cwd, filesystem); if (workspaceRoot) return monorepoLayout(workspaceRoot); // Standalone project — figure out if it's API or App. const isApi = (0, fs_1.existsSync)((0, path_1.join)(cwd, 'src', 'config.env.ts')) || (0, fs_1.existsSync)((0, path_1.join)(cwd, 'nest-cli.json')); const isApp = (0, fs_1.existsSync)((0, path_1.join)(cwd, 'nuxt.config.ts')); return { apiDir: isApi ? cwd : null, appDir: isApp ? cwd : null, root: cwd, workspace: false, }; } /** Build the layout for an lt-monorepo workspace root. */ function monorepoLayout(workspaceRoot) { const apiDir = (0, path_1.join)(workspaceRoot, 'projects', 'api'); const appDir = (0, path_1.join)(workspaceRoot, 'projects', 'app'); return { apiDir: (0, fs_1.existsSync)(apiDir) ? apiDir : null, appDir: (0, fs_1.existsSync)(appDir) ? appDir : null, root: workspaceRoot, workspace: true, }; }