UNPKG

@lenne.tech/cli

Version:

lenne.Tech CLI: lt

200 lines (199 loc) 9.08 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.help = void 0; const framework_detection_1 = require("../../lib/framework-detection"); /** * Convert an existing API project between npm mode and vendor mode. * * Usage: * lt server convert-mode --to vendor [--upstream-branch 11.24.2] * lt server convert-mode --to npm [--version 11.24.2] */ exports.help = { description: 'Convert API project between npm and vendor framework modes', name: 'convert-mode', options: [ { description: 'Target mode', flag: '--to', required: true, type: 'string', values: ['vendor', 'npm'], }, { description: 'Upstream branch/tag to vendor from (only with --to vendor)', flag: '--upstream-branch', required: false, type: 'string', }, { description: 'nest-server version to install (only with --to npm, default: from VENDOR.md baseline)', flag: '--version', required: false, type: 'string', }, { default: false, description: 'Skip confirmation prompt', flag: '--noConfirm', required: false, type: 'boolean', }, { default: false, description: 'Show the resolved plan without making any changes', flag: '--dry-run', required: false, type: 'boolean', }, ], }; const ConvertModeCommand = { description: 'Convert API project between npm and vendor framework modes', hidden: false, name: 'convert-mode', run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () { const { filesystem, parameters, print: { error, info, spin, success, warning }, prompt: { confirm }, server, } = toolbox; // Handle --help-json flag if (toolbox.tools.helpJson(exports.help)) { return; } const targetMode = parameters.options.to; if (!targetMode || !['npm', 'vendor'].includes(targetMode)) { error('Missing or invalid --to flag. Use: --to vendor or --to npm'); return; } // Find the API project root const cwd = filesystem.cwd(); const projectDir = (0, framework_detection_1.findProjectDir)(cwd); if (!projectDir) { error('Could not find a package.json in the current directory or any parent. Are you inside an API project?'); return; } // Detect current mode const currentMode = (0, framework_detection_1.detectFrameworkMode)(projectDir); info(`Detected current mode: ${currentMode}`); if (currentMode === targetMode) { warning(`Project is already in ${targetMode} mode. Nothing to do.`); return; } // Dry-run: print the resolved plan and exit without any disk changes. const dryRun = parameters.options['dry-run'] === true || parameters.options['dry-run'] === 'true'; if (dryRun) { info(''); info('Dry-run plan:'); info(` projectDir: ${projectDir}`); info(` currentMode: ${currentMode}`); info(` targetMode: ${targetMode}`); if (targetMode === 'vendor') { const upstreamBranch = parameters.options['upstream-branch']; info(` upstreamBranch: ${upstreamBranch || '(auto-detect from package.json)'}`); info(''); info('Would execute:'); info(' 1. Clone @lenne.tech/nest-server → /tmp/lt-vendor-nest-server-*'); info(' 2. Copy src/core/, src/index.ts, src/core.module.ts, test/, templates/, types/ → src/core/'); info(' 3. Apply flatten-fix (index.ts, core.module.ts, test.helper.ts)'); info(' 4. Rewrite consumer imports: @lenne.tech/nest-server → relative paths'); info(' 5. Merge upstream deps dynamically into package.json'); info(' 6. Rewrite migrate scripts to use local bin/migrate.js'); info(' 7. Add check:vendor-freshness script'); info(' 8. Create src/core/VENDOR.md with baseline metadata'); info(' 9. Prepend vendor-mode notice to CLAUDE.md'); } else { const targetVersion = parameters.options.version; info(` targetVersion: ${targetVersion || '(from VENDOR.md baseline)'}`); info(''); info('Would execute:'); info(' 1. Read baseline version from src/core/VENDOR.md'); info(' 2. Warn if local patches exist in VENDOR.md'); info(' 3. Rewrite consumer imports: relative → @lenne.tech/nest-server'); info(' 4. Delete src/core/'); info(' 5. Restore @lenne.tech/nest-server in package.json'); info(' 6. Restore migrate scripts to node_modules paths'); info(' 7. Remove vendor artifacts and CLAUDE.md marker'); } info(''); return `server convert-mode dry-run (${currentMode}${targetMode})`; } // Confirm const noConfirm = parameters.options.noConfirm; if (!noConfirm) { const proceed = yield confirm(`Convert project from ${currentMode} mode to ${targetMode} mode?\n` + ` Project: ${projectDir}\n` + ` This will modify package.json, imports, tsconfig, and CLAUDE.md.`); if (!proceed) { info('Aborted.'); return; } } // Execute conversion if (targetMode === 'vendor') { // npm → vendor const upstreamBranch = parameters.options['upstream-branch']; // Auto-detect version from current @lenne.tech/nest-server dep let branch = upstreamBranch; if (!branch) { try { const pkg = filesystem.read(`${projectDir}/package.json`, 'json'); const deps = Object.assign(Object.assign({}, ((pkg === null || pkg === void 0 ? void 0 : pkg.dependencies) || {})), ((pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies) || {})); const version = deps['@lenne.tech/nest-server']; if (version) { // Strip semver range chars (^, ~, >=, etc.) to get the bare version branch = version.replace(/^[^0-9]*/, ''); info(`Auto-detected @lenne.tech/nest-server version: ${branch}`); } } catch (_a) { // Will prompt or use HEAD } } const spinner = spin('Converting to vendor mode...'); try { yield server.convertToVendorMode({ dest: projectDir, upstreamBranch: branch, }); spinner.succeed('Converted to vendor mode successfully.'); success('\nNext steps:'); info(' 1. Run: pnpm install'); info(' 2. Run: pnpm exec tsc --noEmit'); info(' 3. Run: pnpm test'); info(' 4. Commit the changes'); } catch (err) { spinner.fail(`Conversion failed: ${err.message}`); } } else { // vendor → npm const targetVersion = parameters.options.version; const spinner = spin('Converting to npm mode...'); try { yield server.convertToNpmMode({ dest: projectDir, targetVersion, }); spinner.succeed('Converted to npm mode successfully.'); success('\nNext steps:'); info(' 1. Run: pnpm install'); info(' 2. Run: pnpm exec tsc --noEmit'); info(' 3. Run: pnpm test'); info(' 4. Commit the changes'); } catch (err) { spinner.fail(`Conversion failed: ${err.message}`); } } }), }; exports.default = ConvertModeCommand;