youzanyun-devtool-worker
Version:
- web - ws - proxy
458 lines (457 loc) • 21.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const path_1 = tslib_1.__importDefault(require("path"));
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
const download_1 = tslib_1.__importDefault(require("download"));
const fast_glob_1 = tslib_1.__importDefault(require("fast-glob"));
const merge_1 = tslib_1.__importDefault(require("lodash/merge"));
const spring4js_nodejs_1 = require("spring4js-nodejs");
const PageHandler_1 = tslib_1.__importDefault(require("./PageHandler"));
let H5ExtensionService = class H5ExtensionService {
constructor() {
this.previewCompsMap = {};
this._broadcastPreviewComps = new spring4js_nodejs_1.Emitter();
this.onBroadcastPreviewComps = this._broadcastPreviewComps.registerEvent;
this.remoteTemplateVersion = {};
this.pageHandlerCache = {};
this.versionFileName = 'ecloud-tpl-version.json';
}
async start() {
this.workDir = this.configService.getWorkerDir();
const h5DemoDir = this.configService.getH5DemoDir();
await fs_extra_1.default.ensureDir(h5DemoDir);
this.h5CompDemoDir = path_1.default.resolve(h5DemoDir, 'h5-extension');
this.h5ReplaceDemoDir = path_1.default.resolve(h5DemoDir, 'h5-script-replace');
const remoteToolConfig = await this.customApiService.getRemoteToolConfig();
if (remoteToolConfig.templateVersion) {
this.remoteTemplateVersion = JSON.parse(remoteToolConfig.templateVersion);
}
}
async getMenu(workbenchId, projectId) {
let menuData = [{
key: 'home',
title: '首页',
param: {
contentType: 'webview',
url: `/html/h5-extension/?projectId=${projectId}&workbenchId=${workbenchId}#/home`,
docKey: 'h5-home',
}
}];
const nodeData = await this.customApiService.getH5NodeList();
if (nodeData && nodeData.length > 0) {
const nodeList = nodeData.filter((item) => {
const { bizNodeCode, bizNodeElement } = item;
return (bizNodeElement.indexOf(1) > -1) && bizNodeCode;
}).map((item) => {
let { bizNodeName, bizNodeCode, bizNodeId } = item;
let url = `/html/h5-extension?projectId=${projectId}&workbenchId=${workbenchId}&selectedKey=${bizNodeId}`
+ `&nodeName=${bizNodeName}&nodeCode=${bizNodeCode}#/list`;
return {
key: item.bizNodeId,
title: item.bizNodeName,
param: {
contentType: 'webview',
url,
docKey: 'h5-custom',
}
};
});
nodeList.push({
key: 0,
title: '全局页面定制',
param: {
contentType: 'webview',
url: `/html/h5-extension?projectId=${projectId}&workbenchId=${workbenchId}&selectedKey=0`
+ `&nodeName=全局页面定制&nodeCode=_global#/list`,
docKey: 'h5-custom',
}
});
menuData.push({
key: 'pageCustom',
title: '页面配置',
children: nodeList,
});
}
menuData.push({
key: 'upload',
title: '打包上传',
param: {
contentType: 'webview',
url: `/html/h5-extension/?projectId=${projectId}&workbenchId=${workbenchId}#/upload`,
docKey: 'h5-deploy',
}
});
return menuData;
}
async initPageDemo(projectId) {
const project = await this.projectService.getProjectById(projectId);
let versionInfo = {};
const customTypes = ['h5-extension', 'h5-script-replace'];
for (let i = 0; i < customTypes.length; i++) {
const customType = customTypes[i];
const demoDir = customType === 'h5-script-replace' ? this.h5ReplaceDemoDir : this.h5CompDemoDir;
let remoteConfig = {};
remoteConfig.version = customType === 'h5-script-replace'
? this.remoteTemplateVersion.h5ReplaceFrameworkVersion
: this.remoteTemplateVersion.h5CompFrameworkVersion;
remoteConfig.demoUrl = customType === 'h5-script-replace'
? this.remoteTemplateVersion.h5ReplaceUrl
: this.remoteTemplateVersion.h5CompUrl;
if (remoteConfig.demoUrl) {
await this.checkAndDownloadTpl(remoteConfig, demoDir);
const workDir = path_1.default.resolve(project.proPath, `${project.proName}-ui/${customType}`);
const versionPath = path_1.default.resolve(workDir, this.versionFileName);
let isVersionExist = await fs_extra_1.default.pathExists(versionPath);
if (!isVersionExist) {
versionInfo[customType] = {
latestVersion: remoteConfig.version,
currentVersion: null,
};
}
else {
const currentVersionInfo = await fs_extra_1.default.readJSON(versionPath);
versionInfo[customType] = {
latestVersion: remoteConfig.version,
currentVersion: currentVersionInfo.frameworkVersion
};
}
}
}
return versionInfo;
}
async updateH5Project(projectId) {
const project = await this.projectService.getProjectById(projectId);
const h5CompDir = path_1.default.resolve(project.proPath, `${project.proName}-ui/h5-extension`);
await fs_extra_1.default.ensureDir(path_1.default.resolve(h5CompDir, 'src'));
await fs_extra_1.default.remove(path_1.default.resolve(h5CompDir, 'ecloud-tpl-version.json'));
await fs_extra_1.default.copy(path_1.default.resolve(this.h5CompDemoDir, 'ecloud-tpl-version.json'), path_1.default.resolve(h5CompDir, 'ecloud-tpl-version.json'));
await fs_extra_1.default.remove(path_1.default.resolve(h5CompDir, 'webpack'));
await fs_extra_1.default.copy(path_1.default.resolve(this.h5CompDemoDir, 'webpack'), path_1.default.resolve(h5CompDir, 'webpack'));
await fs_extra_1.default.remove(path_1.default.resolve(h5CompDir, 'package-lock.json'));
await fs_extra_1.default.remove(path_1.default.resolve(h5CompDir, 'yarn.lock'));
const compPckExist = await fs_extra_1.default.pathExists(path_1.default.resolve(h5CompDir, 'package.json'));
if (compPckExist) {
const currentCompPackage = await fs_extra_1.default.readJSON(path_1.default.resolve(h5CompDir, 'package.json'));
const demoCompPackage = await fs_extra_1.default.readJSON(path_1.default.resolve(this.h5CompDemoDir, 'package.json'));
await fs_extra_1.default.writeJSON(path_1.default.resolve(h5CompDir, 'package.json'), merge_1.default({}, currentCompPackage, demoCompPackage), { spaces: 2 });
}
else {
await fs_extra_1.default.copy(path_1.default.resolve(this.h5CompDemoDir, 'package.json'), path_1.default.resolve(h5CompDir, 'package.json'));
}
await fs_extra_1.default.remove(path_1.default.resolve(h5CompDir, 'README.md'));
await fs_extra_1.default.copy(path_1.default.resolve(this.h5CompDemoDir, 'README.md'), path_1.default.resolve(h5CompDir, 'README.md'));
const h5ReplaceDir = path_1.default.resolve(project.proPath, `${project.proName}-ui/h5-script-replace`);
await fs_extra_1.default.ensureDir(path_1.default.resolve(h5ReplaceDir, 'src'));
await fs_extra_1.default.remove(path_1.default.resolve(h5ReplaceDir, 'ecloud-tpl-version.json'));
await fs_extra_1.default.copy(path_1.default.resolve(this.h5ReplaceDemoDir, 'ecloud-tpl-version.json'), path_1.default.resolve(h5ReplaceDir, 'ecloud-tpl-version.json'));
await fs_extra_1.default.remove(path_1.default.resolve(h5ReplaceDir, 'webpack'));
await fs_extra_1.default.copy(path_1.default.resolve(this.h5ReplaceDemoDir, 'webpack'), path_1.default.resolve(h5ReplaceDir, 'webpack'));
await fs_extra_1.default.remove(path_1.default.resolve(h5ReplaceDir, 'package-lock.json'));
await fs_extra_1.default.remove(path_1.default.resolve(h5ReplaceDir, 'yarn.lock'));
const replacePckExist = await fs_extra_1.default.pathExists(path_1.default.resolve(h5ReplaceDir, 'package.json'));
if (replacePckExist) {
const currentReplacePackage = await fs_extra_1.default.readJSON(path_1.default.resolve(h5ReplaceDir, 'package.json'));
const demoReplacePackage = await fs_extra_1.default.readJSON(path_1.default.resolve(this.h5ReplaceDemoDir, 'package.json'));
await fs_extra_1.default.writeJSON(path_1.default.resolve(h5ReplaceDir, 'package.json'), merge_1.default({}, currentReplacePackage, demoReplacePackage), { spaces: 2 });
}
else {
await fs_extra_1.default.copy(path_1.default.resolve(this.h5ReplaceDemoDir, 'package.json'), path_1.default.resolve(h5ReplaceDir, 'package.json'));
}
}
async getPageCustomList(params) {
const { projectId } = params;
const result = [];
const nodeData = await this.customApiService.getH5NodeList();
if (!nodeData && nodeData.length === 0) {
return result;
}
const feNodeData = nodeData.filter((item) => {
const { bizNodeCode, bizNodeElement } = item;
return (bizNodeElement.indexOf(1) > -1) && bizNodeCode;
});
feNodeData.push({
bizNodeCode: "_global",
bizNodeId: 0,
bizNodeName: "全局页面定制",
id: 0,
});
for (let i = 0; i < feNodeData.length; i++) {
const { bizNodeCode, bizNodeId } = feNodeData[i];
const pageInfo = await this.getPageCustomListByNodeId({
projectId,
nodeCode: bizNodeCode,
pageIndex: 0,
pageSize: 1000,
relType: 2,
status: 1,
bizNodeElementId: 1,
bizNodeId,
});
const customInfo = pageInfo.filter((item) => item.isCustomed);
if (customInfo.length > 0) {
result.push(Object.assign(Object.assign({}, feNodeData[i]), { children: customInfo }));
}
}
return result;
}
async getPageCustomListByNodeId(params) {
const { projectId, nodeCode } = params, yzyParams = tslib_1.__rest(params, ["projectId", "nodeCode"]);
let result = [];
if (nodeCode === '_global') {
result = [{
description: "[特殊] 全局组件定制",
id: 0,
implType: "components",
name: "_global",
pageId: 0,
pageType: 0,
status: 1,
}];
}
else {
const res = await this.customApiService.getH5TemplatesByNodeId(yzyParams);
result = res.items || [];
result.push({
description: "[特殊] 节点组件定制",
id: 0,
implType: "components",
name: "_common",
pageId: 0,
pageType: 0,
status: 1,
});
}
if (result && result.length > 0) {
const project = await this.projectService.getProjectById(projectId);
for (let i = 0; i < result.length; i++) {
const { isCustomed, expandedList } = await this.checkCustomed(project, nodeCode, result[i]);
result[i].isCustomed = isCustomed;
result[i].expandedList = expandedList;
}
}
return result;
}
async checkCustomed(project, nodeCode, item) {
if (!project.proPath) {
return { isCustomed: false, expandedList: [] };
}
const { name, implType } = item;
const customType = implType === 'scriptReplace' ? 'h5-script-replace' : 'h5-extension';
const pageHandler = await this.getPageHandler({
customType,
projectId: project.id,
nodeCode,
pageName: name
});
if (implType === 'scriptReplace') {
const customInfo = await pageHandler.isPageReplaceCustom();
return customInfo;
}
else {
const isExist = await pageHandler.isPageCompCustom();
let comps = [];
if (isExist) {
comps = await pageHandler.getComponents();
}
return {
isCustomed: isExist,
expandedList: comps
};
}
}
async getPageHandler({ customType, projectId, nodeCode, pageName }) {
let cacheKey = `${projectId}-${customType}-${nodeCode}-${pageName}`;
let pageHandler = this.pageHandlerCache[cacheKey];
if (pageHandler) {
return pageHandler;
}
const project = await this.projectService.getProjectById(projectId);
pageHandler = new PageHandler_1.default({
h5CompDemoDir: this.h5CompDemoDir,
h5ReplaceDemoDir: this.h5ReplaceDemoDir,
workDir: this.workDir,
customType: customType,
projectRootDir: project.proPath,
projectName: project.proName,
nodeCode,
pageName,
});
await pageHandler.start();
this.pageHandlerCache[cacheKey] = pageHandler;
return pageHandler;
}
async checkAndDownloadTpl(remoteConfig, demoDir) {
let needDownload = false;
let cacheVersionInfo = {};
try {
cacheVersionInfo = await fs_extra_1.default.readJson(path_1.default.resolve(demoDir, this.versionFileName));
if (remoteConfig.version != cacheVersionInfo.frameworkVersion) {
needDownload = true;
}
}
catch (e) {
needDownload = true;
}
if (needDownload) {
await fs_extra_1.default.remove(demoDir);
await download_1.default(remoteConfig.demoUrl, demoDir, {
extract: true,
strip: 1,
});
}
}
async getTouchJsPath() {
const touchJsPath = path_1.default.resolve(this.configService.getWorkerDir(), 'assets/utils/touch-emulator.js');
return touchJsPath;
}
async broadcastPreviewComps(projectId, workbenchId, previewComps) {
this._broadcastPreviewComps.fire(previewComps);
}
async updatePreviewComps(projectId, url, previewComps) {
const key = projectId + '_' + url;
this.previewCompsMap[key] = previewComps;
return true;
}
async getPreviewComps(projectId, url) {
const key = projectId + '_' + url;
return this.previewCompsMap[key] || [];
}
async uploadInfo(params) {
const { projectId } = params;
const project = await this.projectService.getProjectById(projectId);
const isClean = await this.projectService.checkProjectStatus(project.proPath);
if (!isClean) {
throw new Error('请先提交本地代码');
}
const userInfo = await this.userService.getUserInfo();
await this.uploadH5CompsInfo(project, userInfo);
await this.uploadH5ReplaceInfo(project, userInfo);
return true;
}
async uploadH5CompsInfo(project, userInfo) {
const prodBuildDir = path_1.default.resolve(project.proPath, `${project.proName}-ui/h5-extension/dist`);
const builds = await fs_extra_1.default.readdir(prodBuildDir);
const buildFileNameList = builds.filter(item => {
return item !== 'info.json' && !item.endsWith('.map');
});
const fileList = buildFileNameList.map(fileShorr => {
return path_1.default.resolve(prodBuildDir, fileShorr);
});
const pageNames = buildFileNameList.map(fileShorr => {
return fileShorr.split('.')[0];
});
const uploadCompFileList = await this.cdnService.uploadFileToCdn({
projectName: project.proName,
pageName: 'h5-comps',
fileList,
addHash: false,
});
const uploadUrls = uploadCompFileList.map(item => item.url);
const infoPath = path_1.default.resolve(project.proPath, `${project.proName}-ui/h5-extension/dist/info.json`);
const pages = await this.getInfo(uploadUrls, infoPath, pageNames);
const customInfo = {
type: 'h5',
appName: project.proName,
commitUser: userInfo.userName || userInfo.mobile || 'youzanyun-developer-tool',
commitHash: 'unknown',
pages,
};
const saveRes = await this.customApiService.saveCustomContent(customInfo);
return saveRes;
}
async uploadH5ReplaceInfo(project, userInfo) {
const workDir = path_1.default.resolve(project.proPath, `${project.proName}-ui/h5-script-replace/src`);
const distDir = path_1.default.resolve(project.proPath, `${project.proName}-ui/h5-script-replace/dist`);
const temp = await fast_glob_1.default('**/main.js', {
cwd: workDir
});
const result = [];
for (let i = 0, len = temp.length; i < len; i++) {
const item = temp[i];
const relative = path_1.default.dirname(item);
const pageDir = path_1.default.resolve(workDir, relative);
const config = await fs_extra_1.default.readJson(pageDir + "/config.json");
if (config.pageName && config.planName) {
let pageInfo = {
pageName: config.pageName,
planName: config.planName,
js: [],
css: [],
};
const distPageDir = path_1.default.resolve(distDir, relative);
const buildFileNameList = await fs_extra_1.default.readdir(distPageDir);
const jsArr = [];
const cssArr = [];
for (let j = 0; j < buildFileNameList.length; j++) {
const pageFile = path_1.default.join(distPageDir, buildFileNameList[j]);
const info = fs_extra_1.default.statSync(pageFile);
if (!info.isDirectory()) {
if (path_1.default.extname(pageFile) === '.css') {
cssArr.push(pageFile);
}
else if (path_1.default.extname(pageFile) === '.js') {
jsArr.push(pageFile);
}
}
}
const uploadJs = await this.cdnService.uploadFileToCdn({
projectName: project.proName,
pageName: config.pageName,
fileList: jsArr,
addHash: false,
});
pageInfo.js = uploadJs.map(item => item.url);
const uploadCss = await this.cdnService.uploadFileToCdn({
projectName: project.proName,
pageName: config.pageName,
fileList: cssArr,
addHash: false,
});
pageInfo.css = uploadCss.map(item => item.url);
result.push(pageInfo);
}
}
if (result.length === 0) {
return;
}
const customInfo = {
type: 'scriptReplace',
appName: project.proName,
commitUser: userInfo.userName || userInfo.mobile || 'youzanyun-developer-tool',
commitHash: 'unknown',
pages: result,
};
const saveRes = await this.customApiService.saveCustomContent(customInfo);
return saveRes;
}
async getInfo(urls, infoPath, fileNameList) {
const pagesInfo = await fs_extra_1.default.readJSON(infoPath);
const result = [];
fileNameList.map((pageName, i) => {
result.push(Object.assign({ pageName, url: urls[i], methods: [], components: [] }, pagesInfo[pageName]));
});
return result;
}
;
};
tslib_1.__decorate([
spring4js_nodejs_1.Resource()
], H5ExtensionService.prototype, "projectService", void 0);
tslib_1.__decorate([
spring4js_nodejs_1.Resource()
], H5ExtensionService.prototype, "configService", void 0);
tslib_1.__decorate([
spring4js_nodejs_1.Resource()
], H5ExtensionService.prototype, "customApiService", void 0);
tslib_1.__decorate([
spring4js_nodejs_1.Resource()
], H5ExtensionService.prototype, "cdnService", void 0);
tslib_1.__decorate([
spring4js_nodejs_1.Resource()
], H5ExtensionService.prototype, "userService", void 0);
H5ExtensionService = tslib_1.__decorate([
spring4js_nodejs_1.Service()
], H5ExtensionService);
exports.default = H5ExtensionService;
;