import { program, Command } from '@/program.ts'; import { chalk } from '../module/chalk.ts'; import path from 'path'; import { spawn } from 'child_process'; import { fileIsExist } from '@/uitls/file.ts'; import { getConfig } from '@/module/get-config.ts'; import fs from 'fs'; import { select, confirm } from '@inquirer/prompts'; import { checkPnpm } from '@/uitls/npm.ts'; const parseIfJson = (str: string) => { try { return JSON.parse(str); } catch (e) { return {}; } }; const publishRegistry = (options: { execPath: string, registry: string, tag?: string, config: any, env: any }) => { const packageJson = path.resolve(options.execPath, 'package.json'); let cmd = ''; const config = options.config || {}; const execPath = options.execPath; const registry = options.registry; const setEnv = options.env || {}; switch (registry) { case 'npm': cmd = 'npm publish -s --registry https://registry.npmjs.org'; break; case 'cnb': cmd = 'npm publish -s --registry https://npm.cnb.cool/kevisual/registry/-/packages/'; break; default: cmd = 'npm publish -s --registry https://registry.npmjs.org'; break; } if (fileIsExist(packageJson)) { const keys = Object.keys(config).filter((key) => key.includes('NPM_TOKEN')); const tokenEnv = keys.reduce((prev, key) => { return { ...prev, [key]: config[key], }; }, {}); const pkg = fs.readFileSync(packageJson, 'utf-8'); const pkgJson = parseIfJson(pkg); const version = pkgJson?.version as string; if (version && options?.tag) { let tag = String(version).split('-')[1] || ''; if (tag) { if (tag.includes('.')) { tag = tag.split('.')[0]; } cmd = `${cmd} --tag ${tag}`; } } console.log(chalk.green(cmd)); const child = spawn(cmd, { shell: true, cwd: execPath, env: { ...process.env, // 保留当前环境变量 ...tokenEnv, ...setEnv, }, }); child.stdout.on('data', (data) => { console.log(chalk.green(`${data}`)); }); child.stderr.on('data', (data) => { // 过滤掉 'npm notice' 或者其他信息 if (data.toString().includes('npm notice')) { console.log(chalk.yellow(`notice: ${data}`)); } else { console.error(`stderr: ${data}`); } }); child.on('close', (code) => { // console.log(`child process exited with code ${code}`); }); } else { console.error(chalk.red('package.json not found')); } } const command = new Command('npm').description('npm command show publish and set .npmrc').action(async (options) => { }); const publish = new Command('publish') .argument('[registry]') .option('-p --proxy', 'proxy') .option('-t, --tag', 'tag') .option('-u, --update', 'update new version') .description('publish npm') .action(async (registry, options) => { if (!registry) { registry = await select({ message: 'Select the registry to publish', choices: [ { name: 'all', value: 'all', }, { name: 'npm', value: 'npm', }, { name: 'cnb', value: 'cnb' } ], }); } const config = getConfig(); const execPath = process.cwd(); let setEnv = {}; const proxyEnv = { https_proxy: 'http://127.0.0.1:7890', http_proxy: 'http://127.0.0.1:7890', all_proxy: 'socks5://127.0.0.1:7890', ...config?.proxy, }; if (options?.proxy) { setEnv = { ...proxyEnv, }; } if (options?.update) { patchFunc({ directory: execPath }); } if (registry === 'all') { publishRegistry({ execPath, registry: 'npm', config, env: setEnv }); publishRegistry({ execPath, registry: 'cnb', config, env: setEnv }); } else { publishRegistry({ execPath, registry, tag: options?.tag, config, env: setEnv }); } }); command.addCommand(publish); const getnpmrc = new Command('get').action(async () => { const execPath = process.cwd(); const npmrcPath = path.resolve(execPath, '.npmrc'); if (fileIsExist(npmrcPath)) { const npmrcContent = fs.readFileSync(npmrcPath, 'utf-8'); // console.log(chalk.green('get .npmrc success')); console.log(npmrcContent); } }); command.addCommand(getnpmrc); const npmrc = new Command('set') .description('set .npmrc') .option('-f ') .action(async (options) => { const config = getConfig(); const npmrcContent = config?.npmrc || `/npm.cnb.cool/kevisual/registry/-/packages/:_authToken=\${CNB_API_KEY} //registry.npmjs.org/:_authToken=\${NPM_TOKEN} `; const execPath = process.cwd(); const npmrcPath = path.resolve(execPath, '.npmrc'); let writeFlag = false; if (fileIsExist(npmrcPath)) { if (options.force) { writeFlag = true; } else { const confirmed = await confirm({ message: `Are you sure you want to overwrite the .npmrc file?`, default: false, }); if (confirmed) { writeFlag = true; } } } else { writeFlag = true; } if (writeFlag) { fs.writeFileSync(npmrcPath, npmrcContent); console.log(chalk.green('write .npmrc success')); } }); command.addCommand(npmrc); const remove = new Command('remove').description('remove .npmrc').action(async () => { const execPath = process.cwd(); const npmrcPath = path.resolve(execPath, '.npmrc'); if (fileIsExist(npmrcPath)) { fs.unlinkSync(npmrcPath); console.log(chalk.green('remove .npmrc success')); } else { console.log(chalk.green('.npmrc success')); } }); command.addCommand(remove); const install = new Command('install') .option('-n, --noproxy', 'no proxy') .description('npm install 使用 proxy代理去下载') .action(async (options) => { const cwd = process.cwd(); const config = getConfig(); let setEnv = {}; const proxyEnv = { https_proxy: 'http://127.0.0.1:7890', http_proxy: 'http://127.0.0.1:7890', all_proxy: 'socks5://127.0.0.1:7890', ...config?.proxy, }; setEnv = { ...proxyEnv, }; if (options?.noproxy) { setEnv = {}; } if (checkPnpm()) { spawn('pnpm', ['i'], { stdio: 'inherit', cwd: cwd, env: { ...process.env, ...setEnv } }); } else { spawn('npm', ['i'], { stdio: 'inherit', cwd: cwd, env: { ...process.env, ...setEnv } }); } }); command.addCommand(install); const patchFunc = (opts?: { directory?: string }) => { const cwd = opts?.directory || process.cwd(); const packageJson = path.resolve(cwd, 'package.json'); if (fileIsExist(packageJson)) { const pkg = fs.readFileSync(packageJson, 'utf-8'); const pkgJson = parseIfJson(pkg); const version = pkgJson?.version as string; if (version) { const versionArr = String(version).split('.'); if (versionArr.length === 3) { const patchVersion = Number(versionArr[2]) + 1; const newVersion = `${versionArr[0]}.${versionArr[1]}.${patchVersion}`; pkgJson.version = newVersion; fs.writeFileSync(packageJson, JSON.stringify(pkgJson, null, 2)); console.log(chalk.green(`${pkgJson?.name} 更新到版本: ${newVersion}`)); } } } } // npm patch const patch = new Command('patch').description('npm patch 发布补丁版本').action(async () => { patchFunc(); }); command.addCommand(patch); // program 添加npm 的命令 program.addCommand(command);