@winner-fed/deploy-cli
Version:
CLI tool for deploy.
650 lines (633 loc) • 20 kB
JavaScript
/*
* @winner-fed/deploy-cli
* @Author: whaleFE
* @Version: 1.0.0
* @Description: CLI tool for deploy.
* @Date: Build time 2025/7/11 13:19:21
*/
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// package.json
var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "@winner-fed/deploy-cli",
version: "1.0.0",
description: "CLI tool for deploy.",
main: "dist/index.js",
types: "dist/index.d.ts",
bin: {
"deploy-cli": "bin/deploy.js"
},
files: [
"dist",
"bin"
],
keywords: [
"depoly",
"deploy-cli",
"ftp",
"see"
],
scripts: {
prepublishOnly: "npm run build",
dev: "tsup --watch",
build: "tsup",
typecheck: "tsc --noEmit"
},
dependencies: {
"@winner-fed/winner-deploy": "workspace:^",
"@winner-fed/ftp-deploy": "workspace:^",
cac: "^6.7.12",
colorette: "^2.0.19",
chokidar: "^3.5.3",
"fs-extra": "^10.1.0",
"strip-json-comments": "3.1.1",
jiti: "^1.21.0",
joycon: "^3.0.1",
deepmerge: "^4.2.2"
},
devDependencies: {
"@types/fs-extra": "^9.0.13",
tslib: "^2.4.0",
tsup: "^8.5.0"
},
engines: {
node: ">=14"
},
license: "ISC"
};
}
});
// src/index.ts
var index_exports = {};
__export(index_exports, {
cli: () => cli,
copyDistToDocker: () => copyDistToDocker,
defineConfig: () => defineConfig,
formatDate: () => formatDate,
generateGUID: () => generateGUID,
generateSeePackageInfo: () => generateSeePackageInfo,
getGitHash: () => getGitHash,
isGitSync: () => isGitSync,
transformTime: () => transformTime
});
module.exports = __toCommonJS(index_exports);
// src/cli.ts
var import_cac = require("cac");
// src/command.ts
var import_deepmerge = __toESM(require("deepmerge"));
// src/load.ts
var import_fs = __toESM(require("fs"));
var import_joycon = __toESM(require("joycon"));
var import_path = __toESM(require("path"));
var import_jiti = __toESM(require("jiti"));
// src/jsoncParse.ts
var import_strip_json_comments = __toESM(require("strip-json-comments"));
function jsoncParse(data) {
try {
return new Function("return " + (0, import_strip_json_comments.default)(data).trim())();
} catch (e) {
return {};
}
}
// src/load.ts
var joycon = new import_joycon.default();
var loadJson = (filepath) => __async(null, null, function* () {
try {
return jsoncParse(yield import_fs.default.promises.readFile(filepath, "utf8"));
} catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to parse ${import_path.default.relative(process.cwd(), filepath)}: ${error.message}`);
} else {
throw error;
}
}
});
var jsonLoader = {
test: /\.json$/,
load(filepath) {
return loadJson(filepath);
}
};
joycon.addLoader(jsonLoader);
function loadUserConfig(cwd, configFile) {
return __async(this, null, function* () {
const configJoycon = new import_joycon.default();
const configPath = yield configJoycon.resolve({
files: configFile ? [configFile] : [
`deploy.config.ts`,
`deploy.config.js`,
`deploy.config.cjs`,
`deploy.config.mjs`,
`deploy.config.json`,
"package.json"
],
cwd,
stopDir: import_path.default.parse(cwd).root,
packageKey: `deploy`
});
if (configPath) {
if (configPath.endsWith(".json")) {
let data = yield loadJson(configPath);
if (configPath.endsWith("package.json")) {
data = data.deploy;
}
if (data) {
return { path: configPath, data };
}
return {};
}
const jiti = (0, import_jiti.default)(configPath, {
cache: true,
debug: process.env.NODE_ENV === "development"
});
try {
const configModule = jiti(configPath);
return {
path: configPath,
data: configModule.deploy || configModule.default || configModule
};
} catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to load config from ${import_path.default.relative(process.cwd(), configPath)}: ${error.message}`);
} else {
throw error;
}
}
}
return {};
});
}
function loadPkg(cwd) {
return __async(this, null, function* () {
const { data } = yield joycon.load(["package.json"], cwd, import_path.default.dirname(cwd));
return data || {};
});
}
// src/command.ts
var mergeDeployConfig = (defaultAppConfig) => __async(null, null, function* () {
var _a;
const userConfig = (_a = yield loadUserConfig(defaultAppConfig.source, defaultAppConfig.config)) == null ? void 0 : _a.data;
return (0, import_deepmerge.default)(defaultAppConfig, userConfig);
});
// src/see.ts
var import_fs_extra2 = __toESM(require("fs-extra"));
var import_path3 = __toESM(require("path"));
// src/util.ts
var import_path2 = __toESM(require("path"));
var import_fs_extra = __toESM(require("fs-extra"));
// src/log.ts
var colors = __toESM(require("colorette"));
var colorize = (type, data, onlyImportant = false) => {
if (onlyImportant && (type === "info" || type === "success")) return data;
const color = type === "info" ? "blue" : type === "error" ? "red" : type === "warn" ? "yellow" : "green";
return colors[color](data);
};
var makeLabel = (name, input, type) => {
return [name && `${colors.dim("[")}${name.toUpperCase()}${colors.dim("]")}`, colorize(type, input)].filter(Boolean).join(" ");
};
var silent = false;
var createLogger = (name) => {
return {
setName(_name) {
name = _name;
},
success(label, ...args) {
return this.log(label, "success", ...args);
},
info(label, ...args) {
return this.log(label, "info", ...args);
},
error(label, ...args) {
return this.log(label, "error", ...args);
},
warn(label, ...args) {
return this.log(label, "warn", ...args);
},
log(label, type, ...data) {
switch (type) {
case "error": {
return console.error(makeLabel(name, label, type), ...data.map((item) => colorize(type, item, true)));
}
default:
if (silent) return;
console.log(makeLabel(name, label, type), ...data.map((item) => colorize(type, item, true)));
}
}
};
};
// src/util.ts
var logger = createLogger();
function generateGUID() {
var d = Date.now();
var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === "x" ? r : r & 7 | 8).toString(16);
});
return uuid;
}
function formatDate(date, fmt) {
if (date === void 0) date = /* @__PURE__ */ new Date();
if (fmt === void 0) fmt = "yyyy-MM-dd HH:mm:ss";
if (typeof date === "string" || typeof date === "number") {
date = new Date(date);
}
const o = {
"M+": date.getMonth() + 1,
// 月份
"d+": date.getDate(),
// 日
"h+": date.getHours() % 12 === 0 ? 12 : date.getHours() % 12,
// 小时
"H+": date.getHours(),
// 小时
"m+": date.getMinutes(),
// 分
"s+": date.getSeconds(),
// 秒
"q+": Math.floor((date.getMonth() + 3) / 3),
// 季度
S: date.getMilliseconds()
// 毫秒
};
const week = {
"0": "\u65E5",
"1": "\u4E00",
"2": "\u4E8C",
"3": "\u4E09",
"4": "\u56DB",
"5": "\u4E94",
"6": "\u516D"
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
}
if (/(E+)/.test(fmt)) {
const dayKey = date.getDay().toString();
fmt = fmt.replace(
RegExp.$1,
(RegExp.$1.length > 1 ? RegExp.$1.length > 2 ? "\u661F\u671F" : "\u5468" : "") + (week[dayKey] || "")
);
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
const value = o[k];
fmt = fmt.replace(
RegExp.$1,
RegExp.$1.length === 1 ? value.toString() : ("00" + value).substr(("" + value).length)
);
}
}
return fmt;
}
var isGitSync = function isGitSync2(dir) {
let currentDir = import_path2.default.resolve(dir);
let gitRoot;
while (currentDir !== import_path2.default.dirname(currentDir)) {
const gitPath = import_path2.default.join(currentDir, ".git");
if (import_fs_extra.default.existsSync(gitPath)) {
gitRoot = currentDir;
break;
}
currentDir = import_path2.default.dirname(currentDir);
}
return {
isGit: !!gitRoot,
gitRoot
};
};
var getGitHash = function getGitHash2(gitRoot) {
let rev;
try {
const gitHeadPath = gitRoot ? import_path2.default.join(gitRoot, ".git/HEAD") : ".git/HEAD";
rev = import_fs_extra.default.readFileSync(gitHeadPath).toString().trim().split(/.*[: ]/).slice(-1)[0];
} catch (error) {
rev = generateGUID().slice(0, 8);
}
if (rev.indexOf("/") === -1) {
return rev;
} else {
try {
const gitRefPath = gitRoot ? import_path2.default.join(gitRoot, ".git", rev) : `.git/${rev}`;
return import_fs_extra.default.readFileSync(gitRefPath).toString().trim();
} catch (error) {
logger.error(".git/refs/heads/master \u8BBF\u95EE\u5931\u8D25\uFF0C\u8FD8\u6CA1\u6709\u8FDB\u884C\u8FC7\u7B2C\u4E00\u6B21\u63D0\u4EA4\u3002\u9ED8\u8BA4\u53D6\u503C\u4E3A guid\u3002");
return generateGUID().slice(0, 8);
}
}
};
var transformTime = function transformTime2(cwd) {
const gitResult = isGitSync(cwd);
if (gitResult.isGit) {
return `${formatDate(Date.now(), "yyyyMMddHHmmss")}.${getGitHash(gitResult.gitRoot).substring(0, 8)}`;
} else {
return `${formatDate(Date.now(), "yyyyMMddHHmmss")}.${generateGUID().slice(0, 8)}`;
}
};
function generateSeePackageInfo(source, {
system,
type,
version,
name,
description,
outputName,
configName,
isDocker,
buildVersion,
isProduction,
variables,
configTemplate
}) {
let seePackageName = `${system}-${name}-web`;
const templateFunc = () => {
if (configTemplate) return configTemplate;
if (type === "bizframe") {
return `./${outputName}/${configName}.js`;
}
return `./${outputName}/${name}/sysconfig.js`;
};
const variablesFunc = () => {
try {
return variables || [];
} catch (error) {
console.error(error);
return [];
}
};
const seePackageOptions = {
system,
type,
name,
version,
templateFunc,
variablesFunc,
description,
seePackageType: "web"
};
if (isDocker) {
seePackageName += "-docker";
seePackageOptions.seePackageType = "docker";
}
function generateSeePackageNameAndVersion() {
let appVersion2 = version.replace("-patch", ".") || `1.0.0`;
const appVersionArray = appVersion2.split(".");
appVersion2 = appVersionArray.length === 3 ? appVersion2 + ".0" : appVersion2;
const cloneBuildVersion = buildVersion || appVersion2;
seePackageName += `-${cloneBuildVersion}`;
if (!isProduction) {
appVersion2 = `${appVersion2}-${transformTime(source)}`;
seePackageName += `-${transformTime(source)}`;
}
return {
appVersion: appVersion2
};
}
const { appVersion } = generateSeePackageNameAndVersion();
seePackageOptions.version = appVersion || version;
return {
seePackageOptions,
defaultSeePackageName: seePackageName
};
}
function copyDistToDocker(cwd, outputName = "dist") {
const dockerHtmlPath = import_path2.default.resolve(cwd, "docker/html");
import_fs_extra.default.remove(dockerHtmlPath, (err) => {
if (err) return;
import_fs_extra.default.copy(import_path2.default.resolve(cwd, outputName), dockerHtmlPath, (err2) => {
if (err2) {
logger.error("\u62F7\u8D1D dist \u81F3 docker/html \u5931\u8D25\uFF01\uFF01\uFF01");
}
});
});
}
// src/see.ts
var import_winner_deploy = require("@winner-fed/winner-deploy");
function seeBuild(source, seeConfig) {
return __async(this, null, function* () {
const projectPkg = yield loadPkg(source);
let _a = seeConfig, {
name = projectPkg.name,
version = projectPkg.version,
description = projectPkg.description,
system,
type,
appType = projectPkg.name,
configName,
buildVersion = projectPkg.buildVersion,
outputName,
isDocker,
variables,
isProduction,
seePackageName,
dockerImage,
configTemplate,
seePackagePath,
cb
} = _a, restArgs = __objRest(_a, [
"name",
"version",
"description",
"system",
"type",
"appType",
"configName",
"buildVersion",
"outputName",
"isDocker",
"variables",
"isProduction",
"seePackageName",
"dockerImage",
"configTemplate",
"seePackagePath",
"cb"
]);
seePackagePath = seePackagePath || "package";
if (!system) {
throw new Error("system \u4E0D\u80FD\u4E3A\u7A7A\uFF01\u6839\u636E\u5B9E\u9645\u9879\u76EE\u9700\u6C42\u8FDB\u884C\u547D\u540D\uFF01");
}
const { defaultSeePackageName, seePackageOptions } = generateSeePackageInfo(source, {
system,
type,
version,
name,
description,
outputName,
configName,
isDocker,
buildVersion,
isProduction,
variables,
configTemplate
});
if (!seePackageName) {
seePackageName = defaultSeePackageName;
}
if (seePackagePath && seePackagePath !== "/") {
import_fs_extra2.default.removeSync(import_path3.default.join(source, seePackagePath));
}
if (seePackageOptions.seePackageType === "docker") {
(0, import_winner_deploy.generateSeePackageZip)(
__spreadValues(__spreadProps(__spreadValues({}, seePackageOptions), {
appType,
configName,
outputName,
seePackageName,
dockerImage,
seePackagePath
}), restArgs),
function() {
copyDistToDocker(source, outputName);
(0, import_winner_deploy.generateSeePackageZip)(
__spreadValues(__spreadProps(__spreadValues({}, seePackageOptions), {
appType,
seePackageType: "web",
configName,
outputName,
seePackageName: seePackageName == null ? void 0 : seePackageName.replace("-docker", ""),
scriptsType: "bash",
seePackagePath
}), restArgs),
() => {
typeof cb === "function" && cb();
}
);
}
);
return;
}
(0, import_winner_deploy.generateSeePackageZip)(
__spreadValues(__spreadProps(__spreadValues({}, seePackageOptions), {
appType,
configName,
outputName,
seePackageName,
scriptsType: "bash",
seePackagePath
}), restArgs),
() => {
typeof cb === "function" && cb();
}
);
});
}
// src/ftp.ts
var import_ftp_deploy = require("@winner-fed/ftp-deploy");
var logger2 = createLogger();
function ftpBuild(source, ftpConfig) {
const ftpDeploy = new import_ftp_deploy.FtpDeployer();
logger2.info("Start uploading...");
ftpDeploy.deploy(ftpConfig).then((res) => logger2.info("upload finished:", res)).catch((err) => logger2.error(err));
}
// src/cli.ts
var cli = (defaultAppConfig) => {
const program = (0, import_cac.cac)("@winner-fed/deploy-cli");
const versionCli = require_package().version;
program.version(`@winner-fed/cli@${versionCli}`);
program.help();
program.command("see [project]", "Build see package").option("--config <filename>", "Use a custom config file").action((filename, options) => __async(null, null, function* () {
Object.assign(defaultAppConfig, __spreadValues({}, options));
const { source, seeConfig } = yield mergeDeployConfig(defaultAppConfig);
yield seeBuild(source, seeConfig);
}));
program.command("ftp [project]", "FTP uploads local files to the target server").option("--config <filename>", "Use a custom config file").action((filename, options) => __async(null, null, function* () {
Object.assign(defaultAppConfig, __spreadValues({}, options));
const { source, ftpConfig } = yield mergeDeployConfig(defaultAppConfig);
yield ftpBuild(source, ftpConfig);
}));
program.parse(process.argv);
};
// src/defineConfig.ts
var defineConfig = (config) => config;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
cli,
copyDistToDocker,
defineConfig,
formatDate,
generateGUID,
generateSeePackageInfo,
getGitHash,
isGitSync,
transformTime
});