UNPKG

@serpent/common-cli

Version:

通用的 cli 相关的函数

147 lines (144 loc) 5.7 kB
import { createRequire } from 'module'; import path from 'path'; import assert from 'assert'; import { b as findupPackage, h as existsFile, p as toOSPath, k as existsDir, g as exists } from './context-96dcd180.mjs'; import { t as tryReadJsonFile } from './readJsonFile-255f65c0.mjs'; /** package.json 中的 name 的正则 */ var PROJECT_NAME_REGEXP = /(?:@([\w-]+)\/)?([\w-]+)/; /** package.json 中的 name 的正则(匹配字符串的开始和结束) */ var PROJECT_NAME_REGEXP_FULL = /^(?:@([\w-]+)\/)?([\w-]+)$/; /** package.json 中的 name 的正则(匹配字符串的开始) */ var PROJECT_NAME_REGEXP_START = /^(?:@([\w-]+)\/)?([\w-]+)/; /** package.json 中的 name 的正则(匹配字符串的结束) */ var PROJECT_NAME_REGEXP_END = /(?:@([\w-]+)\/)?([\w-]+)$/; /** * 获取项目的根目录 * * @param refAbsoluteFilePath 用于定位项目根目录的一个绝对路径,如果不传,默认使用 process.cwd */ function tryGetProjectRootDir(refAbsoluteFilePath) { var refPath = refAbsoluteFilePath || process.cwd(); try { // 移除后面 node_modules 目录 (会导致全局安装后执行 postinstall 时找不到根目录) // const pkg = findup.pkg(refPath.replace(/[\\\/]node_modules(\b|[\\\/].*)$/, '')) var pkg = findupPackage(refPath); return path.dirname(pkg); } catch (e) { return; } } /** * 判断指定的路径是否是一个项目(是否包含 package.json 文件)的根目录 */ function isProjectRootDir(absDir) { return existsFile(path.join(absDir, 'package.json')); } /** 确保指定的路径是项目根目录 */ function assertProjectRootDir(absDir, message) { assert.ok(isProjectRootDir(absDir), message || "path ".concat(absDir, " is not a valid project root directory")); } /** * 根据相对路径,获取其绝对路径(只能获取文件的,无法获取文件夹的) * * @param relativeProjectFilePath 相对于项目根目录的路径 * @param refAbsoluteFilePath 用于定位项目根目录的一个绝对路径,如果不传,默认使用 process.cwd * */ function tryGetProjectFile(relativeProjectFilePath, refAbsoluteFilePath) { return tryGetProjectPath(relativeProjectFilePath, refAbsoluteFilePath, existsFile); } /** * 根据相对路径,获取其绝对路径(只能获取文件夹的,无法获取文件的) * * @param relativeProjectFilePath 相对于项目根目录的路径 * @param refAbsoluteFilePath 用于定位项目根目录的一个绝对路径,如果不传,默认使用 process.cwd * */ function tryGetProjectDir(relativeProjectFilePath, refAbsoluteFilePath) { return tryGetProjectPath(relativeProjectFilePath, refAbsoluteFilePath, existsDir); } function tryGetProjectPath(relativeProjectFilePath, refAbsoluteFilePath, fn) { if (fn === void 0) { fn = exists; } var rootDir = tryGetProjectRootDir(refAbsoluteFilePath); if (rootDir) { var file = path.join(rootDir, toOSPath(relativeProjectFilePath)); if (fn(file)) return file; } return; } /** * 解析项目安装时可能会用的名称 * @param installName 项目名称,可以带有版本号,如:`vue`、`vue@^1`、`jquery@1.0.0`、`@serpent/foo@latest` * @returns * - `parseProjectInstallName("@serpent/foo@latest") => { scope: 'serpent', name: 'foo', tag: 'latest', range: '' }` * - `parseProjectInstallName("foo@^1") => { scope: '', name: 'foo', tag: '', range: '^1' }` * - `parseProjectInstallName("foo@*") => { scope: '', name: 'foo', tag: '', range: '' }` */ function parseProjectInstallName(installName) { var _a, _b, _c; var scope = ''; var range = ''; var tag = ''; var name = ''; var newName = installName; var error = function () { throw new Error("\"".concat(installName, "\" is not a valid project name")); }; if (newName[0] === '@') { _a = newName.substr(1).split('/'), scope = _a[0], newName = _a[1]; if (!scope || !newName) error(); } _b = newName.split('@'), name = _b[0], _c = _b[1], range = _c === void 0 ? '' : _c; if (!name || !PROJECT_NAME_REGEXP_FULL.test(name)) error(); // range 还要支持 "*" if (range && range !== '*' && /^[a-zA-Z][-\w]*$/.test(range)) { tag = range; range = ''; } return { scope: scope, range: range, tag: tag, name: name, }; } /** * 根据项目根目录,获取到 package.json 中指定的 bin 文件所在的绝对路径 */ function tryGetProjectBinFile(rootDir, binKey) { var bin = ''; var file = ''; try { var pkg = tryReadJsonFile(path.join(rootDir, 'package.json')); bin = pkg.bin; } catch (e) { } if (bin && typeof bin === 'string') { file = path.resolve(rootDir, bin); } else if (typeof bin === 'object') { if (binKey) { if (bin[binKey]) { file = path.resolve(rootDir, bin[binKey]); } } else { var binKeys = Object.keys(bin); if (binKeys.length === 1) { file = path.resolve(rootDir, bin[binKeys[0]]); } } } if (file) { try { return createRequire(import.meta.url).resolve(file); } catch (e) { } } return; } export { PROJECT_NAME_REGEXP as P, PROJECT_NAME_REGEXP_FULL as a, PROJECT_NAME_REGEXP_START as b, PROJECT_NAME_REGEXP_END as c, assertProjectRootDir as d, tryGetProjectFile as e, tryGetProjectDir as f, tryGetProjectBinFile as g, isProjectRootDir as i, parseProjectInstallName as p, tryGetProjectRootDir as t };