@serpent/common-cli
Version:
通用的 cli 相关的函数
147 lines (144 loc) • 5.7 kB
JavaScript
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 };