UNPKG

@shuyun-ep-team/scripts

Version:

为项目提供相应的脚本,使其减少繁琐的配置。

258 lines 11.3 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const fs_extra_1 = __importDefault(require("fs-extra")); const semver_1 = __importDefault(require("semver")); const inquirer_1 = __importDefault(require("inquirer")); const cross_spawn_1 = __importDefault(require("cross-spawn")); const chalk_1 = __importDefault(require("../../tools/chalk")); const sync_tnpm_1 = __importDefault(require("../sync-tnpm")); const npm_1 = require("../utils/npm"); function genPackageVersion(distTags) { return __awaiter(this, void 0, void 0, function* () { const { latest, beta, alpha } = distTags; const betaVersion = semver_1.default.gte(latest, beta) ? latest : beta; const alphaVersion = semver_1.default.gte(latest, alpha) ? latest : alpha; const prePublishTags = { major: semver_1.default.inc(latest, 'major'), minor: semver_1.default.inc(latest, 'minor'), patch: semver_1.default.inc(latest, 'patch'), beta: semver_1.default.inc(betaVersion, 'prerelease', 'beta'), alpha: semver_1.default.inc(alphaVersion, 'prerelease', 'alpha'), custom: '' }; const { publishType } = yield inquirer_1.default.prompt([ { type: 'list', name: 'publishType', message: '请选择发布版本类型: ', default: 'patch', choices: [ { name: `做不兼容的 API 修改(${chalk_1.default.gray(`v${prePublishTags.major}`)})`, value: 'major' }, { name: `做了向下兼容的功能性新增(${chalk_1.default.gray(`v${prePublishTags.minor})`)}`, value: 'minor' }, { name: `做了向下兼容的问题修正(${chalk_1.default.gray(`v${prePublishTags.patch})`)}`, value: 'patch' }, { name: `测试版 Beta(${chalk_1.default.gray(`v${prePublishTags.beta}`)})`, value: 'beta' }, { name: `先行版 Alpha(${chalk_1.default.gray(`v${prePublishTags.alpha}`)})`, value: 'alpha' }, { name: '自定义版本', value: 'custom' } ] } ]); if (publishType === 'custom') { const { version } = yield inquirer_1.default.prompt([ { type: 'input', name: 'version', message: '请输入自定义版本' } ]); if (semver_1.default.valid(version) === null) { console.error(chalk_1.default.red(`输入自定义版本 ${version} 无效!`)); process.exit(1); } prePublishTags.custom = version; } return prePublishTags[publishType]; }); } function getPackageDistTags(packageName) { return __awaiter(this, void 0, void 0, function* () { try { const { stdout = '', stderr = '' } = cross_spawn_1.default.sync('npm', ['dist-tags', 'ls', packageName], { encoding: 'utf-8' }); const initTags = { latest: '0.0.0', beta: '0.0.0', alpha: '0.0.0' }; if (stderr) { if (/npm ERR! code E404/g.test(stderr)) { const { first } = yield inquirer_1.default.prompt([ { type: 'confirm', name: 'first', message: '是否为第一次发版 ?' } ]); if (first) { return initTags; } process.exit(1); } else { throw new Error(stderr); } } const matchArray = stdout.match(/(.+?):\s*(.*)/gu); if (matchArray) { return matchArray .map(str => { const [type, v] = str.split(':'); return { [type.trim()]: v.trim() }; }) .reduce((a, b) => Object.assign(a, b), initTags); } return initTags; } catch (error) { throw new Error(error); } }); } function publishToNpm(version, dir = '.') { return __awaiter(this, void 0, void 0, function* () { const prerelease = semver_1.default.prerelease(version); const publishArgs = ['publish', dir, '--access', 'public']; const versionArgs = ['version']; if (prerelease !== null) { versionArgs.push('prerelease', `--preid=${prerelease.join('.')}`); publishArgs.push('--tag', prerelease[0]); } else { versionArgs.push(version); } cross_spawn_1.default.sync('npm', versionArgs, { stdio: 'inherit', encoding: 'utf-8' }); cross_spawn_1.default.sync('npm', publishArgs, { stdio: 'inherit', encoding: 'utf-8' }); }); } function updatePackageVersion(version) { return __awaiter(this, void 0, void 0, function* () { const pkg = require(`${process.cwd()}/package.json`); pkg.version = version; fs_extra_1.default.writeFileSync(`${process.cwd()}/package.json`, JSON.stringify(pkg, null, 2), { encoding: 'utf-8' }); }); } function checkPublishAssets(dist) { const pkgPath = path_1.default.join(process.cwd(), dist, 'package.json'); return fs_extra_1.default.existsSync(pkgPath); } function removePackageRedundantConfig(dist) { const pkgPath = path_1.default.join(process.cwd(), dist, 'package.json'); const pkg = require(pkgPath); Reflect.set(pkg, 'scripts', {}); fs_extra_1.default.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`, { encoding: 'utf-8' }); } function chainApply(items, defaultParams = []) { return Promise.resolve(items.reduce((chain, current) => chain .then((chainResult) => __awaiter(this, void 0, void 0, function* () { chainResult.push(yield current(chainResult)); return Promise.resolve(chainResult); })) .catch(err => { throw new Error(err); }), Promise.resolve(defaultParams))); } exports.default = (config) => __awaiter(void 0, void 0, void 0, function* () { try { const { name, pre = [], post = [], autoProcessPackageJson = true, isPrerelease, dist = '.' } = config; const context = process.cwd(); const release = !isPrerelease; const result = npm_1.checkPackageName(name); if (result.validForNewPackages === false && result.validForOldPackages === false) { throw new Error(`npm package name ${chalk_1.default.green(name)} invalid`); } if (release === false) { checkPublishEnv(name); } console.log(`正在执行 ${chalk_1.default.bgBlack.green(name)} 发布...`); console.log(`进入执行目录:${chalk_1.default.green(context)}`); console.log('获取当前项目版本信息:'); const distTags = yield getPackageDistTags(name); const infoLog = Object.entries(distTags) .map(([key, v]) => `${chalk_1.default.green(key)}: ${v}`) .join('\n '); console.log(` version: ${infoLog} `); console.log('设置发布版本'); const version = (yield genPackageVersion(distTags)); console.log(`将发布版本号为:${chalk_1.default.green(`v${version}`)}`); console.log('执行设定前置任务...'); yield chainApply(pre, [version]); console.log('发布目录资源监测'); if (!checkPublishAssets(dist)) { if (autoProcessPackageJson) { fs_extra_1.default.ensureDirSync(path_1.default.join(context, dist)); fs_extra_1.default.copySync(path_1.default.join(context, 'package.json'), path_1.default.join(context, dist, 'package.json')); } else { throw new Error(`发布目录 ${chalk_1.default.green(dist)} 中缺少 package.json 文件`); } } removePackageRedundantConfig(dist); if (!isPrerelease) { console.log('执行发布...'); yield publishToNpm(version, dist); console.log('同步至淘宝镜像'); yield sync_tnpm_1.default(name); } if (autoProcessPackageJson) { updatePackageVersion(version); } console.log('执行设定后置任务...'); yield chainApply(post, [version]); console.log(`✨ ${chalk_1.default.green(`${isPrerelease ? '预' : ''}发布完成!`)}`); } catch (error) { console.error(error.message); } }); function checkPublishEnv(name) { return __awaiter(this, void 0, void 0, function* () { const registry = yield npm_1.getRegistry(); const isNpmRegistry = npm_1.checkNpmRegistry(registry); console.log('检测当前发布环境:'); console.log(`${chalk_1.default.green('NPM 源地址:')}${registry}`); if (isNpmRegistry) { const username = getNPMLoginUsername(); console.log(chalk_1.default.green('NPM 账户:'), username); const maintainers = npm_1.getPackageMaintainers(name); if (maintainers.findIndex(item => (item === null || item === void 0 ? void 0 : item.user) === username) < 0) { throw new Error('当前登陆账户不在本仓库维护人名列表中!!!'); } return; } throw new Error(`${chalk_1.default.red('请切换 NPM 安装源为:')}${npm_1.NPMRegistry} for example: $ ${chalk_1.default.green('npm')} config set registry ${npm_1.NPMRegistry} `); }); } function getNPMLoginUsername() { const username = npm_1.getUsername(); if (username === null) { console.log('请登录NPM账户...'); npm_1.npmLogin(); getNPMLoginUsername(); } return username; } //# sourceMappingURL=index.js.map