youzanyun-devtool-worker
Version:
565 lines (564 loc) • 21.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEPLOY_TYPE = void 0;
const tslib_1 = require("tslib");
const spring4js_nodejs_1 = require("spring4js-nodejs");
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
const path_1 = tslib_1.__importDefault(require("path"));
exports.DEPLOY_TYPE = {
SERVER: 'general',
CONFIG: 'ruleConfig',
MP_SELF: 'mp',
MP_TOOL: 'mp-tool',
};
const TIME = 4000;
let DeployPollService = class DeployPollService {
constructor() {
this._deploy = new spring4js_nodejs_1.Emitter();
this.onDeploy = this._deploy.registerEvent;
this._pollError = new spring4js_nodejs_1.Emitter();
this.onPollError = this._pollError.registerEvent;
this.isPolling = false;
this.isGeneralDeploy = false;
this.generalReleaseId = null;
this.isMpDeploy = false;
this.mpReleaseId = null;
this.isRuleConfigDeploy = false;
this.ruleConfigReleaseId = null;
this.clearRelease = (type) => {
if (type === 'mp') {
this.isMpDeploy = false;
this.mpReleaseId = null;
}
else if (type === 'general') {
this.isGeneralDeploy = false;
this.generalReleaseId = null;
}
else if (type === exports.DEPLOY_TYPE.CONFIG) {
this.isRuleConfigDeploy = false;
this.ruleConfigReleaseId = null;
}
};
}
get ecloudAuthHeader() {
return {
cookie: `app_env=dev; sid=${this.sid}; appid=${this.appDetail.appId}; apptype=${this.appDetail.appType}; user_name=${encodeURI(this.userName)}`,
};
}
async start() {
}
async initData(projectId) {
if (!projectId) {
return;
}
const { proName } = await this.projectService.getProjectById(projectId);
const { appDetail } = await this.applicationService.getAppDetail(proName);
const { userName } = await this.userService.getUserInfo();
this.sid = await this.userService.getSid();
this.appDetail = appDetail;
this.userName = userName;
}
async startLoop(projectId) {
await this.initData(projectId);
if (this.isPolling) {
return { success: false, message: '轮询中,请勿重复操作' };
}
this.isPolling = true;
this.isMpDeploy = false;
this.isGeneralDeploy = false;
this.isRuleConfigDeploy = false;
this.loop.call(this);
return { success: true };
}
async stopLoop() {
if (this.isPolling) {
this.isPolling = false;
this.isMpDeploy = false;
this.isGeneralDeploy = false;
this.isRuleConfigDeploy = false;
this.generalReleaseId = null;
this.mpReleaseId = null;
this.ruleConfigReleaseId = null;
return { success: true };
}
else {
return { success: false, message: '轮询未开始' };
}
}
async loop() {
if (!this.isPolling) {
return;
}
if (this.isGeneralDeploy && this.isMpDeploy && this.isRuleConfigDeploy) {
setTimeout(this.loop.bind(this), TIME);
return;
}
try {
const res = await this.requestService.get('https://diy.youzanyun.com/api/apps/deploy/get-deploy-records', {
params: {
region: this.appDetail.appRegion,
zone: 'dev',
appId: this.appDetail.appId,
pageSize: 30,
pageIndex: 1,
},
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
});
if (res.code !== 200) {
throw new Error(res.message);
}
const deployList = res.data.items || [];
const deployingList = deployList.filter((item) => item.releaseStatus === 'releasing');
const releaseingMp = deployingList.filter((item) => item.type === 'mp')[0];
const releaseingRuleConfig = deployingList.filter((item) => item.type === exports.DEPLOY_TYPE.CONFIG)[0];
const releaseingGeneral = deployingList.filter((item) => item.type === 'general')[0];
const recentMpReleaseId = (deployList.find((item) => item.type === 'mp' && item.releaseStatus === 'success') || {}).releaseId;
const localReleaseList = deployList.filter((item) => item.releaseStatus === 'success');
const recentSuccessGeneral = localReleaseList.find((item) => item.type === 'general');
const recentSuccessRuleConfig = localReleaseList.find((item) => item.type === exports.DEPLOY_TYPE.CONFIG);
const recentSuccessOrFailedMp = deployList.find((item) => item.type === 'mp' && item.releaseStatus !== 'releasing');
const fireData = {};
if (recentSuccessGeneral) {
fireData.isLocalSuccessGeneral = true;
fireData.recentSuccessGeneral = recentSuccessGeneral;
}
if (recentSuccessOrFailedMp) {
fireData.isLocalSuccessOrFailedMp = true;
fireData.recentSuccessOrFailedMp = recentSuccessOrFailedMp;
}
if (recentSuccessRuleConfig) {
fireData.isLocalSuccessRuleConfig = true;
fireData.recentSuccessRuleConfig = recentSuccessRuleConfig;
}
if (recentMpReleaseId) {
fireData.isRecentMpReleaseId = true;
fireData.recentMpReleaseId = recentMpReleaseId;
}
if (fireData.isRecentMpReleaseId ||
fireData.isLocalSuccessGeneral ||
fireData.isLocalSuccessMp ||
fireData.recentSuccessRuleConfig) {
this._deploy.fire({
type: 'merge-message',
code: 200,
data: fireData,
});
}
if (releaseingMp && !this.isMpDeploy) {
this.loopMp.call(this, releaseingMp);
}
if (releaseingGeneral && !this.isGeneralDeploy) {
this.loopGeneral.call(this, releaseingGeneral);
}
if (releaseingRuleConfig && !this.isRuleConfigDeploy) {
this.loopRuleConfig.call(this, releaseingRuleConfig);
}
}
catch (err) {
console.error(err);
this._pollError.fire({
message: err.message || err,
type: 'loop-catch-error',
data: err.message,
code: 500,
});
}
setTimeout(this.loop.bind(this), TIME);
}
async getMpLog(releaseId) {
return this.requestService.get('https://diy.youzanyun.com/api/apps/business/deploy-mp/log', {
params: {
releaseId,
},
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
});
}
async getGeneralLog(releaseId) {
return this.requestService.get('https://diy.youzanyun.com/api/apps/deploy/fetch-deploy-error-log', {
params: {
releaseId,
appId: this.appDetail.appId,
zone: 'dev',
},
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
});
}
loopMp(releaseingMp) {
if (releaseingMp) {
this.isMpDeploy = true;
this.mpReleaseId = releaseingMp.releaseId;
}
if (!this.mpReleaseId) {
return;
}
this.requestService
.get('https://diy.youzanyun.com/api/apps/deploy/get-deploy-status', {
params: {
zone: 'dev',
appId: this.appDetail.appId,
releaseId: this.mpReleaseId,
},
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
})
.then((res) => {
if (+res.code === 200) {
let fireData = {};
if (res.data === 'releasing') {
setTimeout(this.loopMp.bind(this, releaseingMp), TIME);
fireData = {
type: 'releaseing-mp',
data: { releaseingMp },
};
}
else {
this.clearRelease('mp');
}
if (res.data === 'success') {
fireData = {
type: 'success-mp',
data: { releaseingMp },
};
}
if (res.data === 'failed') {
fireData = {
type: 'failed-mp',
data: { releaseingMp },
};
}
this._deploy.fire(fireData);
}
else {
throw new Error(res.message);
}
})
.catch((err) => {
console.error(err);
this._pollError.fire({
type: 'loop-mp-error',
message: err.message || err,
data: err,
code: 500,
});
});
}
loopGeneral(releaseingGeneral) {
if (releaseingGeneral) {
this.isGeneralDeploy = true;
this.generalReleaseId = releaseingGeneral.releaseId;
}
if (!this.generalReleaseId) {
return;
}
this.requestService
.get('https://diy.youzanyun.com/api/apps/deploy/get-deploy-status', {
params: {
zone: 'dev',
appId: this.appDetail.appId,
releaseId: this.generalReleaseId,
},
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
})
.then((res) => {
if (+res.code === 200) {
let fireData = {};
if (res.data === 'releasing') {
setTimeout(this.loopGeneral.bind(this, releaseingGeneral), TIME);
fireData = {
type: 'releaseing-general',
data: { releaseingGeneral },
};
}
else {
this.clearRelease('general');
}
if (res.data === 'success') {
fireData = {
type: 'success-general',
data: { releaseingGeneral },
};
}
if (res.data === 'failed') {
fireData = {
type: 'failed-general',
data: { releaseingGeneral },
};
this.clearRelease('general');
}
this._deploy.fire(fireData);
}
else {
throw new Error(res.message);
}
})
.catch((err) => {
console.error(err);
this._pollError.fire({
message: err.message || err,
type: 'loop-general-error',
data: err,
code: 500,
});
});
}
loopRuleConfig(releaseingRuleConfig) {
if (releaseingRuleConfig) {
this.isRuleConfigDeploy = true;
this.ruleConfigReleaseId = releaseingRuleConfig.releaseId;
}
if (!this.ruleConfigReleaseId) {
return;
}
this.requestService
.get('https://diy.youzanyun.com/api/apps/deploy/get-deploy-status', {
params: {
zone: 'dev',
appId: this.appDetail.appId,
releaseId: this.ruleConfigReleaseId,
},
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
})
.then((res) => {
if (+res.code === 200) {
let fireData = {};
if (res.data === 'releasing') {
setTimeout(this.loopRuleConfig.bind(this, releaseingRuleConfig), TIME);
fireData = {
type: 'releaseing-ruleConfig',
data: { releaseingRuleConfig },
};
}
else {
this.clearRelease('ruleConfig');
}
if (res.data === 'success') {
fireData = {
type: 'success-ruleConfig',
data: { releaseingRuleConfig },
};
}
if (res.data === 'failed') {
fireData = {
type: 'failed-ruleConfig',
data: { releaseingRuleConfig },
};
this.clearRelease('ruleConfig');
}
this._deploy.fire(fireData);
}
else {
throw new Error(res.message);
}
})
.catch((err) => {
console.error(err);
this._pollError.fire({
message: err.message || err,
type: 'loop-ruleConfig-error',
data: err,
code: 500,
});
});
}
async openGeneralConfig(param) {
const { extPointId, uuid, branchTag } = param;
const result = await this.requestService.post('https://diy.youzanyun.com/api/apps/business/impl/router/add', {
appId: this.appDetail.appId,
extPointId,
env: 'dev',
customRuleMap: {},
isDefaultConfig: true,
ruleMap: {},
createBy: '',
uuid,
branchTag,
}, {
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
});
return result;
}
async closeGeneralConfig(param) {
const { uuid, branchTag } = param;
const result = await this.requestService.del(`https://diy.youzanyun.com/api/apps/business/impl/router/delete`, {
params: {
env: 'dev',
uuid,
branchTag,
},
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
});
return result;
}
async changeRuleConfigStatus(data) {
const result = await this.requestService.post(`https://diy.youzanyun.com/api/business/uiv3/configTemplate/enable`, data, { headers: this.ecloudAuthHeader }, {
projectName: this.appDetail.appName,
});
return result;
}
async getShopList(shopType) {
const params = {
appType: 0,
pageSize: 100,
page: 1,
authStatus: 1,
shopType,
env: 0,
};
const result = await this.requestService
.get('https://diy.youzanyun.com/api/apps/shop/multi', {
params,
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
})
.catch((err) => {
console.error('err', err);
});
return result;
}
async getShopListV2(projectId, shopType, env) {
const params = {
appType: 0,
pageSize: 100,
page: 1,
authStatus: 1,
shopType,
env,
};
const { proName } = await this.projectService.getProjectById(projectId);
const { appDetail } = await this.applicationService.getAppDetail(proName);
const { userName } = await this.userService.getUserInfo();
const sid = await this.userService.getSid();
const result = await this.requestService
.get('https://diy.youzanyun.com/api/apps/shop/multi', {
params,
headers: {
cookie: `app_env=dev; sid=${sid}; appid=${appDetail.appId}; apptype=${appDetail.appType}; user_name=${encodeURI(userName)}`,
},
}, {
projectName: appDetail.appName,
})
.catch((err) => {
console.error('err', err);
});
return result;
}
async saveMpConfig(config) {
let dataDir = this.configService.getDataDir();
let mpConfigFile = path_1.default.resolve(dataDir, `mp-deploy-config.${this.appDetail.appId}.json`);
await fs_extra_1.default.writeJson(mpConfigFile, config, { spaces: 2 });
return { code: 200 };
}
async getMpConfig() {
let dataDir = this.configService.getDataDir();
let mpConfigFIle = path_1.default.resolve(dataDir, `mp-deploy-config.${this.appDetail.appId}.json`);
let exists = await fs_extra_1.default.pathExists(mpConfigFIle);
if (exists) {
const config = await fs_extra_1.default.readJson(mpConfigFIle);
return { code: 200, data: config };
}
return { code: 404, message: '暂无配置' };
}
async deploy(type, branch, toolAppNameList) {
let context = null;
if (type === 'mp') {
const mpConfig = await this.getMpConfig();
if (mpConfig.code === 200) {
context = JSON.stringify(mpConfig.data);
}
else {
return mpConfig;
}
}
else if (type === 'general' || type === 'ruleConfig') {
context = '{}';
}
else {
return { code: 400, message: '未知的发布类型' };
}
const result = await this.requestService.post('https://diy.youzanyun.com/api/apps/deploy/deploy-new-app', Object.assign({ appId: this.appDetail.appId, comment: '开发者工具一键发布', region: this.appDetail.region, requestType: 'normal', isLocalPublish: 1, zone: 'dev', context,
type,
branch }, (type === 'mp' ? { toolAppNameList } : {})), {
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
});
return result;
}
async searchBranchList(params) {
const { projectId } = params, otherParams = tslib_1.__rest(params, ["projectId"]);
await this.initData(projectId);
const res = await this.requestService.get('https://diy.youzanyun.com/api/apps/branch/list', {
params: otherParams,
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
});
if (+res.code !== 200 && +res.code !== 0) {
throw new Error(res.message || res.msg);
}
return res.data;
}
async getCurrentBranch(projectId) {
await this.initData(projectId);
const res = await this.requestService.get('https://diy.youzanyun.com/api/apps/branch/current', {
headers: this.ecloudAuthHeader,
}, {
projectName: this.appDetail.appName,
});
if (+res.code !== 200 && +res.code !== 0) {
throw new Error(res.message || res.msg);
}
return res.data;
}
async checkConflict(param) {
const { projectId } = param, otherParams = tslib_1.__rest(param, ["projectId"]);
let res = await this.requestService.dubboCallWithAuth('com.youzan.mp.buildd.server.apiV2.DiyMpBuildService', 'checkConflict', [otherParams], { projectId, addPrivateData: ['appName'] });
if (+res.code !== 200 && +res.code !== 0) {
throw new Error(res.message);
}
return res.data;
}
async getVersions(param) {
const { projectId } = param, otherParams = tslib_1.__rest(param, ["projectId"]);
let res = await this.requestService.dubboCallWithAuth('com.youzan.mp.buildd.server.apiV2.check.MpTaskPublishCheckService', 'checkQrBasePackageVersion', [otherParams], { projectId, addPrivateData: ['appName'] });
if (+res.code !== 200 && +res.code !== 0) {
throw new Error(res.message || res.msg);
}
return res.data;
}
};
tslib_1.__decorate([
(0, spring4js_nodejs_1.Resource)()
], DeployPollService.prototype, "configService", void 0);
tslib_1.__decorate([
(0, spring4js_nodejs_1.Resource)()
], DeployPollService.prototype, "userService", void 0);
tslib_1.__decorate([
(0, spring4js_nodejs_1.Resource)()
], DeployPollService.prototype, "requestService", void 0);
tslib_1.__decorate([
(0, spring4js_nodejs_1.Resource)()
], DeployPollService.prototype, "projectService", void 0);
tslib_1.__decorate([
(0, spring4js_nodejs_1.Resource)()
], DeployPollService.prototype, "applicationService", void 0);
DeployPollService = tslib_1.__decorate([
(0, spring4js_nodejs_1.Service)()
], DeployPollService);
exports.default = DeployPollService;