@szzbmy/lowcode-cli
Version:
🐇 lowcode-cli is an efficient cli tool for Rabbitpre plugin component secondary development. ❤️
269 lines (268 loc) • 10.1 kB
JavaScript
"use strict";
/**
* @describe 文件压缩打包上传
* @author Richlee
* @since 20210706
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const react_1 = __importStar(require("react"));
const ink_1 = require("ink");
const form_data_1 = __importDefault(require("form-data"));
const archiver_1 = __importDefault(require("archiver"));
const fs_2 = require("../../config/fs");
const components_1 = require("../../components");
const logger_1 = __importDefault(require("../../utils/logger"));
const shell_1 = require("../../utils/shell");
const deploy_code_1 = require("../../apis/deploy-code");
const config_1 = __importDefault(require("../../config"));
const interactive_1 = require("../../components/interactive");
// 发布执行状态
var DEPLOY_STEP;
(function (DEPLOY_STEP) {
DEPLOY_STEP[DEPLOY_STEP["INIT"] = 0] = "INIT";
DEPLOY_STEP[DEPLOY_STEP["CHECH_CONFIG"] = 1] = "CHECH_CONFIG";
DEPLOY_STEP[DEPLOY_STEP["BUILDING"] = 2] = "BUILDING";
DEPLOY_STEP[DEPLOY_STEP["COMPRESSING"] = 3] = "COMPRESSING";
DEPLOY_STEP[DEPLOY_STEP["RELEASE"] = 4] = "RELEASE";
DEPLOY_STEP[DEPLOY_STEP["FINISHED"] = 5] = "FINISHED";
DEPLOY_STEP[DEPLOY_STEP["INFO"] = 6] = "INFO";
DEPLOY_STEP[DEPLOY_STEP["MESSAGE"] = 7] = "MESSAGE";
DEPLOY_STEP[DEPLOY_STEP["INTERACTION"] = 8] = "INTERACTION";
})(DEPLOY_STEP || (DEPLOY_STEP = {}));
/**
* 压缩方法
* @returns void
*/
const compress = () => new Promise((resolve, reject) => {
const { paths: { distPath, zipPath }, } = config_1.default;
const output = fs_1.default.createWriteStream(zipPath);
const archive = (0, archiver_1.default)('zip', {
zlib: { level: 9 },
});
// 直接压缩整个 dist 文件夹
archive.directory(distPath, false);
output.on('close', () => {
logger_1.default.info(`模块压缩完成,压缩大小:${archive.pointer()}bytes`);
resolve(archive.pointer());
});
// 监听结束
output.on('end', () => {
logger_1.default.info('模块压缩结束');
});
// 监听错误
archive.on('error', err => {
reject(err);
});
archive.pipe(output);
archive.finalize();
});
/**
* 部署方法
*/
const deploy = async () => {
const { paths: { zipPath }, debugConfig: { schemaType, debugComponentList: [firstDebugComponent], }, } = config_1.default;
if (!fs_1.default.existsSync(zipPath)) {
logger_1.default.error('代码包[deploy.zip]不存在');
return;
}
const form = new form_data_1.default();
form.append('file', fs_1.default.createReadStream(zipPath), {
filename: 'deploy.zip',
contentType: 'application/zip',
});
// 组件(库)上传
if (schemaType === 'cmplib') {
const jsoncConfig = (0, fs_2.getComponentConfig)();
const libJsonStr = JSON.stringify(jsoncConfig);
form.append('libJsonStr', libJsonStr);
await (0, deploy_code_1.uploadLibs)(form);
logger_1.default.info('部署组件库代码包成功');
}
else {
// 组件上传
const name = firstDebugComponent?.name || '';
form.append('name', name);
logger_1.default.debug(`上传的数据: ${JSON.stringify({ name, filename: 'deploy.zip' })}`);
const version = await (0, deploy_code_1.uploadCode)(form);
logger_1.default.info(`部署代码包成功, 当前研发版本为: ${version}`);
}
};
var MESSAGE_COLOR;
(function (MESSAGE_COLOR) {
MESSAGE_COLOR["info"] = "white";
MESSAGE_COLOR["success"] = "green";
MESSAGE_COLOR["error"] = "#cb3837";
})(MESSAGE_COLOR || (MESSAGE_COLOR = {}));
function Deploy() {
const [stepState, setStepStateOriginal] = (0, react_1.useState)({
step: DEPLOY_STEP.INIT,
options: {
msg: '开始构建代码',
},
});
const setStepState = (0, react_1.useCallback)((step, options) => {
setStepStateOriginal({ step, options });
}, []);
const init = (0, react_1.useCallback)(async () => {
setStepState(DEPLOY_STEP.CHECH_CONFIG);
}, [setStepState]);
// 检查项目配置是否有效
const checkConfig = (0, react_1.useCallback)(() => {
const { debugConfig: { isValid, validateErrorMessage }, } = config_1.default;
if (isValid) {
setStepState(DEPLOY_STEP.BUILDING);
}
else {
logger_1.default.error(validateErrorMessage);
process.exit(1);
}
}, [setStepState]);
// 构建
const building = (0, react_1.useCallback)(async () => {
setStepState(DEPLOY_STEP.MESSAGE, {
msg: '开始构建代码',
});
const code = await (0, shell_1.execCommandPromise)({
cmd: 'npm run build',
silent: false,
});
if (code !== 0) {
logger_1.default.error('构建代码失败');
process.exit(code);
}
setStepState(DEPLOY_STEP.COMPRESSING, {
msg: '构建代码成功',
});
}, [setStepState]);
// 压缩
const compressing = (0, react_1.useCallback)(async () => {
setStepState(DEPLOY_STEP.MESSAGE, {
loading: true,
msg: '开始压缩代码',
});
await compress();
setStepState(DEPLOY_STEP.RELEASE);
}, [setStepState]);
// 上传代码
const uploadCode = (0, react_1.useCallback)(async (isRelease) => {
if (!isRelease) {
setStepState(DEPLOY_STEP.FINISHED);
}
setStepState(DEPLOY_STEP.MESSAGE, {
loading: true,
msg: '项目开始上传',
});
await deploy();
setStepState(DEPLOY_STEP.FINISHED, {
msg: '项目部署完成',
});
}, [setStepState]);
// 发布
const release = (0, react_1.useCallback)(async () => {
try {
if (config_1.default.debugConfig.schemaType === 'cmplib') {
uploadCode(true);
}
else {
// 校验是否存在开发中版本
const { name = '' } = config_1.default.debugConfig.debugComponentList[0];
const hasExiseDevVersion = await (0, deploy_code_1.existDevVersions)(name);
// 询问是否覆盖开发中版本
if (hasExiseDevVersion) {
setStepState(DEPLOY_STEP.INTERACTION, {
type: 'confirm',
quetion: '当前组件存在开发中版本, 是否进行覆盖? ',
});
}
else {
uploadCode(true);
}
}
}
catch (err) {
setStepState(DEPLOY_STEP.MESSAGE, {
type: MESSAGE_COLOR.error,
msg: `发布失败: ${err.message || '版本校验错误'}`,
});
}
}, [setStepState, uploadCode]);
// 结束进程
const finished = (0, react_1.useCallback)(() => {
const code = stepState.options?.code;
const _code = typeof code === 'undefined' ? 0 : 1;
process.exit(_code);
}, [stepState]);
// info, success, error 信息打印
const message = (0, react_1.useCallback)(() => {
if (stepState.options?.type === 'error') {
setStepState(DEPLOY_STEP.FINISHED, { code: 1 });
}
}, [stepState, setStepState]);
(0, react_1.useEffect)(() => {
const func = {
[DEPLOY_STEP.INIT]: init,
[DEPLOY_STEP.CHECH_CONFIG]: checkConfig,
[DEPLOY_STEP.BUILDING]: building,
[DEPLOY_STEP.COMPRESSING]: compressing,
[DEPLOY_STEP.RELEASE]: release,
[DEPLOY_STEP.FINISHED]: finished,
[DEPLOY_STEP.MESSAGE]: message,
}[stepState.step];
func && func();
}, [
stepState.step,
init,
checkConfig,
building,
compressing,
release,
finished,
message,
]);
let renderer = null;
// @ts-ignore
const color = MESSAGE_COLOR[stepState.options?.type];
switch (stepState.step) {
case DEPLOY_STEP.MESSAGE:
renderer = (react_1.default.createElement(react_1.default.Fragment, null,
stepState.options?.loading ? (react_1.default.createElement(ink_1.Text, { color: "green" },
react_1.default.createElement(components_1.Spinner, { type: "dots" }))) : null,
react_1.default.createElement(ink_1.Text, { color: color }, stepState.options?.msg)));
break;
case DEPLOY_STEP.INTERACTION:
renderer = (react_1.default.createElement(interactive_1.InteractiveGenerator, { type: interactive_1.GENERATOR_TYPE.CONFIRM, options: {
quetion: '当前组件存在开发中版本, 是否进行覆盖 ?',
props: {
onSubmit: uploadCode,
},
} }));
break;
default:
renderer = null;
}
return renderer;
}
exports.default = Deploy;