You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1423 lines
43 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _react() {
const data = _interopRequireDefault(require("react"));
_react = function _react() {
return data;
};
return data;
}
require("regenerator-runtime/runtime");
function _assert() {
const data = _interopRequireDefault(require("assert"));
_assert = function _assert() {
return data;
};
return data;
}
function _emptyDir() {
const data = _interopRequireDefault(require("empty-dir"));
_emptyDir = function _emptyDir() {
return data;
};
return data;
}
function _express() {
const data = _interopRequireDefault(require("express"));
_express = function _express() {
return data;
};
return data;
}
function _compression() {
const data = _interopRequireDefault(require("compression"));
_compression = function _compression() {
return data;
};
return data;
}
function _clearModule() {
const data = _interopRequireDefault(require("clear-module"));
_clearModule = function _clearModule() {
return data;
};
return data;
}
function _sockjs() {
const data = _interopRequireDefault(require("sockjs"));
_sockjs = function _sockjs() {
return data;
};
return data;
}
function _path() {
const data = require("path");
_path = function _path() {
return data;
};
return data;
}
function _launchEditor() {
const data = _interopRequireDefault(require("@umijs/launch-editor"));
_launchEditor = function _launchEditor() {
return data;
};
return data;
}
function _openBrowser() {
const data = _interopRequireDefault(require("react-dev-utils/openBrowser"));
_openBrowser = function _openBrowser() {
return data;
};
return data;
}
function _fs() {
const data = require("fs");
_fs = function _fs() {
return data;
};
return data;
}
function _child_process() {
const data = require("child_process");
_child_process = function _child_process() {
return data;
};
return data;
}
function _umi() {
const data = require("umi");
_umi = function _umi() {
return data;
};
return data;
}
function _resolveFrom() {
const data = _interopRequireDefault(require("resolve-from"));
_resolveFrom = function _resolveFrom() {
return data;
};
return data;
}
var _index = _interopRequireDefault(require("./routes/index"));
var _common = _interopRequireDefault(require("./routes/common"));
var _resize = _interopRequireDefault(require("./routes/resize"));
var _Config = _interopRequireDefault(require("./Config"));
var _getClientScript = _interopRequireWildcard(require("./getClientScript"));
var _listDirectory = _interopRequireDefault(require("./listDirectory"));
var _installCreator = _interopRequireDefault(require("./installCreator"));
var _npmClient = require("./npmClient");
var _ActiveProjectError = _interopRequireDefault(require("./ActiveProjectError"));
var _Actions = require("./Actions");
var _checkProject = require("./checkProject");
var _isDepFileExists = _interopRequireDefault(require("./utils/isDepFileExists"));
var _terminal = _interopRequireDefault(require("./terminal"));
var _detectLanguage = _interopRequireDefault(require("./detectLanguage"));
var _detectNpmClients = _interopRequireDefault(require("./detectNpmClients"));
var _debug = _interopRequireWildcard(require("./debug"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
const winPath = _umi().utils.winPath,
lodash = _umi().utils.lodash,
semver = _umi().utils.semver,
portfinder = _umi().utils.portfinder,
rimraf = _umi().utils.rimraf,
chalk = _umi().utils.chalk;
const pick = lodash.pick,
uniq = lodash.uniq;
class UmiUI {
constructor() {
this.cwd = void 0;
this.servicesByKey = void 0;
this.ctx = void 0;
this.server = void 0;
this.socketServer = void 0;
this.logs = void 0;
this.config = void 0;
this.send = void 0;
this.developMode = false;
this.npmClients = [];
this.basicUIPath = void 0;
this.basicConfigPath = void 0;
this.getService = cwd => {
const serviceModule = process.env.BIGFISH_COMPAT ? '@alipay/bigfish/_Service.js' : 'umi/_Service.js';
const servicePath = process.env.LOCAL_DEBUG ? 'umi/lib/cjs' : _resolveFrom().default.silent(cwd, serviceModule) || 'umi/lib/cjs';
(0, _debug.default)(`Service path: ${servicePath}`); // eslint-disable-next-line import/no-dynamic-require
const _require = require(servicePath),
UmiService = _require.Service;
const service = new UmiService({
cwd
});
return service;
};
this.cwd = process.cwd(); // 兼容旧版 Bigfish
this.basicUIPath = process.env.BASIC_UI_PATH || ''; // export default { serices, ... }
this.basicConfigPath = process.env.BASIC_CONFIG_PATH || '';
this.servicesByKey = {};
this.server = null;
this.socketServer = null;
this.config = new _Config.default({
onSave: data => {
if (this.send) {
this.send({
type: '@@project/list/progress',
payload: data
});
}
}
});
this.npmClients = [];
this.logs = [];
this.ctx = {
cwd: process.cwd(),
developMode: !!process.env.DEVELOP_MODE,
config: this.config,
basicUIPath: this.basicUIPath,
servicesByKey: this.servicesByKey,
npmClients: this.npmClients,
logs: this.logs
};
this.developMode = !!process.env.DEVELOP_MODE;
if (process.env.CURRENT_PROJECT) {
const key = this.config.addProjectWithPath((0, _path().join)(process.cwd(), process.env.CURRENT_PROJECT));
this.config.setCurrentProject(key);
}
process.nextTick(() => {
this.initNpmClients();
});
}
openProject(key, service, opts) {
var _this = this;
return _asyncToGenerator(function* () {
const _ref = opts || {},
lang = _ref.lang;
const project = _this.config.data.projectsByKey[key];
(0, _assert().default)(project, `project of key ${key} not exists`); // Check exists.
if (!(0, _fs().existsSync)(project.path)) {
throw new _ActiveProjectError.default({
title: {
'zh-CN': `项目 ${project.path} 路径不存在。`,
'en-US': `Project ${project.path} not exists.`
},
lang,
actions: [_Actions.BackToHomeAction]
});
} // Check umi valid.
if (!(0, _checkProject.isUmiProject)(project.path)) {
throw new _ActiveProjectError.default({
title: {
'zh-CN': `项目 ${project.path} 不是 Umi 项目。`,
'en-US': `Project ${project.path} is not a valid Umi project.`
},
lang,
actions: [_Actions.BackToHomeAction]
});
}
if (process.env.BIGFISH_COMPAT && (0, _checkProject.isUsingUmi)(project.path)) {
throw new _ActiveProjectError.default({
title: {
'zh-CN': `项目 ${project.path} 是 Umi 项目,不能使用 Bigfish 打开。`,
'en-US': `Project ${project.path} is Umi Project, don't open it with Bigfish.`
},
lang,
actions: [_Actions.BackToHomeAction]
});
}
if (!process.env.BIGFISH_COMPAT && (0, _checkProject.isUsingBigfish)(project.path)) {
throw new _ActiveProjectError.default({
title: {
'zh-CN': `项目 ${project.path} 是 Bigfish 项目,不能使用 Umi 打开。`,
'en-US': `Project ${project.path} is Bigfish Project, don't open it with Umi.`
},
lang,
actions: [_Actions.BackToHomeAction]
});
}
if (!_this.developMode && service) {
_this.servicesByKey[key] = service;
} else if (!_this.servicesByKey[key]) {
// Attach Service
(0, _debug.default)(`Attach service for ${key}`); // Use local service and detect version compatibility
const binModule = process.env.BIGFISH_COMPAT ? '@alipay/bigfish/bin/bigfish.js' : 'umi/bin/umi.js';
const pkgModule = process.env.BIGFISH_COMPAT ? '@alipay/bigfish/package.json' : 'umi/package.json';
const cwd = project.path;
const localBin = (0, _isDepFileExists.default)(cwd, binModule);
if (process.env.UI_CHECK_LOCAL !== 'none' && localBin) {
const _JSON$parse = JSON.parse((0, _fs().readFileSync)((0, _path().join)(cwd, 'node_modules', pkgModule), 'utf-8')),
version = _JSON$parse.version;
if (!semver.gt(version, process.env.BIGFISH_COMPAT ? '3.0.0' : '3.0.0')) {
throw new _ActiveProjectError.default({
title: process.env.BIGFISH_COMPAT ? `本地项目的 Bigfish 版本(${version})过低,请升级到 @alipay/bigfish@3.0 或以上,<a target="_blank" href="https://yuque.antfin-inc.com/bigfish/doc/uzfwoc#ff1deb63">查看详情</a>。` : {
'zh-CN': `本地项目的 Umi 版本(${version})过低,请升级到 umi@3.0 或以上,<a target="_blank" href="https://umijs.org/zh/guide/faq.html#umi-%E7%89%88%E6%9C%AC%E8%BF%87%E4%BD%8E%EF%BC%8C%E8%AF%B7%E5%8D%87%E7%BA%A7%E5%88%B0%E6%9C%80%E6%96%B0">查看详情</a>。`,
'en-US': `Umi version (${version}) of the project is too low, please upgrade to umi@2.12 or above, <a target="_blank" href="https://umijs.org/guide/faq.html#umi-version-is-too-low-please-upgrade-to-umi-2-9-or-above">view details</a>.`
},
lang,
actions: [_Actions.ReInstallDependencyAction, _Actions.OpenProjectAction, _Actions.BackToHomeAction]
});
}
}
try {
const currentService = _this.getService(cwd);
(0, _debug.default)(`Attach service for ${key} after new and before init()`);
yield currentService.init();
(0, _debug.default)(`Attach service for ${key} ${chalk.green('SUCCESS')}`);
_this.servicesByKey[key] = currentService;
} catch (e) {
if ((0, _checkProject.isDepLost)(e) || (0, _checkProject.isPluginLost)(e)) {
throw new _ActiveProjectError.default({
title: {
'zh-CN': `依赖文件没找到。`,
'en-US': 'Dependency file not found.'
},
message: e.message,
stack: e.stack,
lang,
actions: [_Actions.ReInstallDependencyAction, _Actions.BackToHomeAction]
});
} else {
throw new _ActiveProjectError.default({
title: {
'zh-CN': '其他错误',
'en-US': 'Other Errors'
},
message: e.message,
stack: e.stack,
lang,
// exception tag
exception: true,
actions: [_Actions.BackToHomeAction]
});
}
}
}
_this.config.editProject(key, {
opened_at: +new Date()
});
})();
}
openProjectInEditor(key, callback = {}, lang = 'zh-CN') {
var _this2 = this;
return _asyncToGenerator(function* () {
let launchPath = key;
if (!(key.startsWith('/') && (0, _fs().existsSync)(key))) {
const project = _this2.config.data.projectsByKey[key];
(0, _assert().default)(project, `project of key ${key} not exists`);
launchPath = project.path;
}
if (!(0, _fs().existsSync)(launchPath)) {
if (callback.failure) {
const msg = {
'zh-CN': `打开编辑器失败 ${launchPath},项目不存在`,
'en-US': `Open Editor Failure, ${launchPath}, project does not exist`
};
console.error(chalk.red(msg[lang]));
callback.failure({
message: msg[lang]
});
}
if (callback.success) {
callback.success();
}
} else {
try {
const res = yield (0, _launchEditor().default)(launchPath);
if (res && res.success) {
callback.success(res);
} else {
callback.failure(res);
}
} catch (e) {
callback.failure(e);
}
}
})();
}
openConfigFileInEditor(projectPath, {
success,
failure,
lang
}) {
return _asyncToGenerator(function* () {
let configFile;
const configFiles = ['.umirc.js', '.umirc.ts', 'config/config.js', 'config/config.ts'];
for (var _i = 0, _configFiles = configFiles; _i < _configFiles.length; _i++) {
const file = _configFiles[_i];
if ((0, _fs().existsSync)((0, _path().join)(projectPath, file))) {
configFile = (0, _path().join)(projectPath, file);
break;
}
}
try {
(0, _assert().default)(configFile, lang === 'zh-CN' ? '在编辑器中打开失败,因为配置文件不存在。' : `Open failed with editor, since configFile not exists.`);
const res = yield (0, _launchEditor().default)(configFile);
if (res && res.success) {
success(res);
} else {
failure(res);
}
} catch (e) {
console.error(e);
failure({
message: e.message
});
}
})();
}
getExtraAssets({
key,
success
}) {
var _this3 = this;
return _asyncToGenerator(function* () {
const service = _this3.servicesByKey[key];
const uiPlugins = yield service.applyPlugins({
key: 'addUIPlugin',
type: service.ApplyPluginsType.add,
initialValue: []
});
(0, _debug.default)('uiPlugins', uiPlugins);
const script = (0, _getClientScript.default)(uiPlugins);
success({
script
});
})();
}
getBasicAssets() {
const script = this.basicUIPath ? (0, _getClientScript.getBasicScriptContent)(this.basicUIPath) : '';
return {
script
};
}
installDeps(npmClient, projectPath, {
onProgress,
onSuccess,
taobaoSpeedUp
}) {
return _asyncToGenerator(function* () {
yield (0, _npmClient.installDeps)(npmClient, projectPath, {
taobaoSpeedUp,
onData(data) {
onProgress({
install: data
});
}
});
onSuccess();
})();
}
createProject(opts = {}, {
onSuccess,
onFailure,
onProgress,
lang
}) {
var _this4 = this;
return _asyncToGenerator(function* () {
let key = opts.key;
let retryFrom = opts.retryFrom;
let createOpts = opts;
if (key) {
(0, _assert().default)('retryFrom' in opts, `key 和 retryFrom 必须同时提供。`); // eslint-disable-next-line prefer-destructuring
createOpts = _this4.config.data.projectsByKey[key].createOpts;
}
const setProgress = args => {
(0, _assert().default)(key, `key is not initialized.`);
_this4.config.setCreatingProgress(key, args);
};
const sigintHandler = () => {
if (key) {
_this4.config.setCreatingProgress(key, {
stepStatus: 3,
failure: {
message: 'exit UmiUi server'
}
});
}
process.exit();
};
try {
(0, _assert().default)(createOpts.baseDir, `baseDir must be supplied`);
(0, _assert().default)(createOpts.name, `name must be supplied`);
(0, _assert().default)(createOpts.type, `type must be supplied`);
const targetDir = (0, _path().join)(createOpts.baseDir, createOpts.name);
if (!retryFrom) {
// 步骤:
//
// 1. 校验
// a) 比如检查目标目录是否为空或不存在
// 2. 添加项目状态到本地存储,后面每一步都更新状态到存储
// 3. 安装 create-umi 或更新他
// 4. create-umi 创建
// 如果是 ant-design-pro还需要拆几步出来比如 git clone
// 5. 安装依赖
//
// 项目步骤:
// 1. 校验参数
// 2. 安装/更新 create-umi
// 3. 使用 create-umi 初始化项目
// 4. 安装依赖
//
// 结束后打开项目。
// 0
(0, _assert().default)(!(0, _fs().existsSync)(targetDir) || _emptyDir().default.sync(targetDir), `target dir ${targetDir} exists and not empty`); // 1
key = _this4.config.addProject({
path: targetDir,
name: createOpts.name,
npmClient: createOpts.npmClient,
createOpts
}); // get create key
onSuccess({
key
});
setProgress({
// 表示第几个 step从 0 开始
step: 1,
// 0: 未开始
// 1: 执行中
// 2: 执行完成
// 3: 执行失败
stepStatus: 0,
steps: {
'zh-CN': ['校验参数', '安装或更新 create-umi', '初始化项目', '安装依赖'],
'en-US': ['Validate Params', 'Install or Update create-umi', 'Initialize Project', 'Install Dependency']
}
});
} // catch exit
process.on('SIGINT', sigintHandler); // 1
let creatorPath; // step 2 依赖 step 1
if (retryFrom === 2) {
retryFrom = 1;
}
if (!retryFrom || retryFrom <= 1) {
setProgress({
step: 1,
stepStatus: 1
});
creatorPath = yield (0, _installCreator.default)({
// npmClient: createOpts.npmClient,
onData(data) {
onProgress({
install: data
});
}
});
setProgress({
stepStatus: 2
});
} // 2
if (!retryFrom || retryFrom <= 2) {
setProgress({
step: 2,
stepStatus: 1
});
(0, _clearModule().default)(creatorPath);
yield require(creatorPath).run({
cwd: targetDir,
type: createOpts.type || {},
args: createOpts.args || {}
});
setProgress({
stepStatus: 2
});
} // 3
if (!retryFrom || retryFrom <= 3) {
setProgress({
step: 3,
stepStatus: 1
}); // 重装 node_modules 时先清空,否则可能会失败
if (retryFrom === 3) {
rimraf.sync((0, _path().join)(targetDir, 'node_modules'));
}
yield (0, _npmClient.installDeps)(createOpts.npmClient, targetDir, {
taobaoSpeedUp: _this4.hasTaobaoSpeedUp(),
onData(data) {
onProgress({
install: data
});
}
});
setProgress({
stepStatus: 2
});
setProgress({
success: true
});
}
} catch (e) {
if (key) {
_this4.config.setCreatingProgress(key, {
stepStatus: 3,
failure: e
});
}
onFailure(e);
} finally {
process.removeListener('SIGINT', sigintHandler);
}
})();
}
checkDirValid({
dir
}, {
onSuccess,
onFailure
}) {
try {
// 入参校验
(0, _assert().default)(dir, `payload.dir must be supplied`);
if (!(0, _fs().existsSync)(dir)) {
return onSuccess();
} // 非目录判断和权限校验
const stat = (0, _fs().statSync)(dir);
(0, _assert().default)(stat.isDirectory(), `target directory must be a directory`); // 费空目录判断
(0, _assert().default)(_emptyDir().default.sync(dir), `target directory must be empty`);
} catch (e) {
onFailure(e);
}
}
initNpmClients() {
const ret = ['tnpm', 'cnpm', 'npm', 'ayarn', 'tyarn', 'yarn'].filter(npmClient => {
try {
(0, _child_process().execSync)(`${npmClient} --version`, {
stdio: 'ignore'
});
return true;
} catch (e) {}
return false;
});
(0, _debug.default)('ret', ret);
this.npmClients = ret;
}
getNpmClients() {
return this.npmClients;
}
getRouteComponents({
service
}) {
var _this5 = this;
return _asyncToGenerator(function* () {
const routes = yield service.getRoutes();
const getComponents = routes => routes.reduce((memo, route) => {
if (route.component && !route.component.startsWith('()')) {
const component = (0, _path().isAbsolute)(route.component) ? route.component : require.resolve((0, _path().join)(_this5.cwd, route.component));
memo.push(winPath(component));
}
if (route.routes) {
memo = memo.concat(getComponents(route.routes));
}
return memo;
}, []);
return uniq(getComponents(routes));
})();
}
detectLanguage({
success,
failure,
key
}) {
var _this6 = this;
return _asyncToGenerator(function* () {
const service = _this6.servicesByKey[key];
try {
const routeComponents = yield _this6.getRouteComponents({
service
});
const language = (0, _detectLanguage.default)(service.cwd, {
routeComponents
});
success({
language
});
} catch (e) {
failure(e);
}
})();
} // reloadProject(key: string) {}
handleCoreData({
type,
payload,
lang,
key
}, {
log,
send,
success,
failure,
progress
}) {
var _this7 = this;
return _asyncToGenerator(function* () {
switch (type) {
case '@@project/getBasicAssets':
success(_this7.getBasicAssets());
break;
case '@@project/getExtraAssets':
_this7.getExtraAssets({
key,
success
});
break;
case '@@project/list':
_this7.config.checkValid();
_this7.config.load();
success({
data: _this7.config.data
});
break;
case '@@project/detail':
success({
data: _this7.config.data.projectsByKey[payload.key]
});
break;
case '@@project/add':
// TODO: 检验是否 umi 项目,不是则抛错给客户端
try {
(0, _assert().default)((0, _fs().existsSync)(payload.path), `Add project failed, since path ${payload.path} don't exists.`);
log('info', `Add project ${payload.path} with name ${payload.name}`);
_this7.config.addProject({
path: payload.path,
name: payload.name
});
success();
} catch (e) {
console.error(chalk.red(`Error: Add project FAILED`));
console.error(e);
failure({
message: e.message
});
}
break;
case '@@project/delete':
if (_this7.config.data.projectsByKey[payload.key]) {
log('info', `Delete project: ${_this7.getProjectName(payload.key)}`);
_this7.config.deleteProject(payload.key);
success();
}
break;
case '@@project/getKeyOrAddWithPath':
success({
key: _this7.config.getKeyOrAddWithPath(payload.path)
});
break;
case '@@project/open':
{
log('info', `Open project: ${_this7.getProjectName(payload.key)}`);
try {
yield _this7.openProject(payload.key, null, {
lang
});
success();
} catch (e) {
failure(pick(e, ['title', 'message', 'stack', 'actions', 'exception']));
console.error(chalk.red(`Error: Attach Project of key ${payload.key} FAILED`));
}
break;
}
case '@@project/openInEditor':
log('info', `Open in editor: ${_this7.getProjectName(payload.key)}`);
_this7.openProjectInEditor(payload.key, {
success,
failure
}, lang);
break;
case '@@project/edit':
log('info', `Edit project: ${_this7.getProjectName(payload.key)}`);
_this7.config.editProject(payload.key, {
name: payload.name,
cloudUrl: payload.cloudUrl
});
success();
break;
case '@@project/setCurrentProject':
_this7.config.load(); // 重新 load
_this7.config.setCurrentProject(payload.key);
success();
break;
case '@@project/clearCurrentProject':
_this7.config.clearCurrentProject();
success();
break;
case '@@project/create':
log('info', `Create project: ${_this7.getProjectName(payload.key)}`);
_this7.createProject(payload, {
onSuccess: success,
onFailure(e) {
failure({
message: e.message
});
},
onProgress: progress,
lang
});
break;
case '@@project/checkDirValid':
_this7.checkDirValid(payload, {
onSuccess: success,
onFailure(e) {
failure({
message: e.message
});
}
});
break;
case '@@project/createTemplateList':
success({
data: [{
title: 'Ant Design Pro',
description: 'A layout-only ant-design-pro boilerplate, use together with umi block',
url: 'https://preview.pro.ant.design/'
}, {
title: 'Basic Template',
description: 'A simple boilerplate, support typescript.'
}]
});
break;
case '@@project/getNpmClients':
success({
data: _this7.getNpmClients()
});
break;
case '@@project/getSharedDataDir':
success({
tmpDir: (0, _path().join)((0, _path().dirname)(_this7.config.dbPath), 'shared-data', key)
});
break;
case '@@project/detectLanguage':
try {
(0, _assert().default)(key && _this7.servicesByKey[key], `Detect language failed, key must be supplied.`);
_this7.detectLanguage({
key,
success,
failure
});
} catch (e) {
console.error(e);
failure({
message: e.message
});
}
break;
case '@@project/detectNpmClients':
try {
(0, _assert().default)(key && _this7.servicesByKey[key], `Detect language failed, key must be supplied.`);
const service = _this7.servicesByKey[key];
success({
npmClients: (0, _detectNpmClients.default)(service.cwd)
});
} catch (e) {
console.error(e);
failure({
message: e.message
});
}
break;
case '@@fs/getCwd':
success({
cwd: _this7.cwd
});
break;
case '@@fs/listDirectory':
{
try {
const data = (0, _listDirectory.default)(payload.dirPath, {
directoryOnly: true
});
success({
data
});
} catch (e) {
failure({
message: e.message
});
}
break;
}
case '@@log/getHistory':
success({
data: _this7.logs
});
break;
case '@@log/clear':
_this7.logs = [];
success();
break;
case '@@actions/installDependencies':
_this7.config.setProjectNpmClient({
key: payload.key,
npmClient: payload.npmClient
});
_this7.installDeps(payload.npmClient, payload.projectPath, {
taobaoSpeedUp: _this7.hasTaobaoSpeedUp(),
onProgress: progress,
onSuccess: success
});
break;
case '@@actions/reInstallDependencies':
_this7.config.setProjectNpmClient({
key: payload.key,
npmClient: payload.npmClient
});
rimraf.sync((0, _path().join)(payload.projectPath, 'node_modules'));
_this7.installDeps(payload.npmClient, payload.projectPath, {
taobaoSpeedUp: _this7.hasTaobaoSpeedUp(),
onProgress: progress,
onSuccess: success
});
break;
case '@@actions/openConfigFile':
_this7.openConfigFileInEditor(payload.projectPath, {
success,
failure,
lang
});
break;
case '@@actions/openProjectInEditor':
_this7.openProjectInEditor(payload.projectPath, {
success,
failure
}, lang);
break;
case '@@app/notify':
try {
const notifier = require('node-notifier');
const buildInImages = {
error: winPath((0, _path().resolve)(__dirname, 'assets', 'error.png')),
info: winPath((0, _path().resolve)(__dirname, 'assets', 'info.png')),
success: winPath((0, _path().resolve)(__dirname, 'assets', 'success.png')),
warning: winPath((0, _path().resolve)(__dirname, 'assets', 'warning.png'))
};
const type = payload.type,
restPayload = _objectWithoutProperties(payload, ["type"]);
const noticeConfig = _objectSpread(_objectSpread({}, restPayload), {}, {
contentImage: buildInImages[type] || buildInImages.info,
icon: winPath((0, _path().resolve)(__dirname, 'assets', 'umi.png')),
sound: true
});
notifier.notify(noticeConfig);
success();
} catch (e) {
console.error(chalk.red(`Error: Notify for ${e.message} FAILED`));
failure(e);
}
break;
default:
// log('error', chalk.red(`Unhandled message type ${type}`));
// failure();
break;
}
})();
}
start(opts) {
var _this8 = this;
return _asyncToGenerator(function* () {
const _ref2 = opts || {},
browser = _ref2.browser,
_ref2$full = _ref2.full,
full = _ref2$full === void 0 ? false : _ref2$full;
_this8.ctx.full = full;
_this8.ctx.browser = browser;
return new Promise( /*#__PURE__*/function () {
var _ref3 = _asyncToGenerator(function* (resolve, reject) {
console.log(`🚀 Starting Umi UI using umi@${process.env.UMI_VERSION}...`);
const app = (0, _express().default)();
app.use((0, _compression().default)()); // Serve Static (Production Only)
if (!process.env.LOCAL_DEBUG) {
app.use(_express().default.static((0, _path().join)(__dirname, '..', 'web/dist'), {
index: false
}));
}
/**
* Terminal shell resize server
*/
app.get('/terminal/resize', (0, _resize.default)(_this8.ctx)); // 访问域名打开
app.get('/', (0, _index.default)(_this8.ctx));
app.use('/*', (0, _common.default)(_this8.ctx));
const ss = _sockjs().default.createServer();
const conns = {};
function send(action) {
const message = JSON.stringify(action);
(0, _debug.debugSocket)(chalk.green.bold('>>>>'), formatLogMessage(message));
Object.keys(conns).forEach(id => {
conns[id].write(message);
});
}
function formatLogMessage(message) {
let ret = message.length > 500 ? `${message.slice(0, 500)} ${chalk.gray('...')}` : message;
ret = ret.replace(/{"type":"(.+?)"/, `{"type":"${chalk.magenta.bold('$1')}"`);
return ret;
}
ss.on('connection', conn => {
if (!conn) {
return;
}
conns[conn.id] = conn;
(0, _debug.debugSocket)(`🔗 ${chalk.green('Connected to')}: ${conn.id}`);
function success(type, payload) {
send({
type: `${type}/success`,
payload
});
}
function failure(type, payload) {
send({
type: `${type}/failure`,
payload
});
}
function progress(type, payload) {
send({
type: `${type}/progress`,
payload
});
}
_this8.send = send; // 给 packages/umi/src/scripts/dev.js 用
global.g_send = send;
const log = (type, message) => {
const payload = {
date: +new Date(),
type,
message
};
const msg = `${chalk.gray(`[${type}]`)} ${message}`;
const logFunc = type === 'error' ? console.error : _debug.debugSocket;
logFunc(msg);
_this8.logs.push(payload);
send({
type: '@@log/message',
payload
});
};
conn.on('close', () => {
(0, _debug.debugSocket)(`😿 ${chalk.red('Disconnected to')}: ${conn.id}`);
delete conns[conn.id];
});
conn.on('data', /*#__PURE__*/function () {
var _ref4 = _asyncToGenerator(function* (message) {
try {
const _JSON$parse2 = JSON.parse(message),
type = _JSON$parse2.type,
payload = _JSON$parse2.payload,
lang = _JSON$parse2.$lang,
key = _JSON$parse2.$key;
(0, _debug.debugSocket)(chalk.blue.bold('<<<<'), formatLogMessage(message));
const serviceArgs = {
action: {
type,
payload,
lang
},
log,
send,
success: success.bind(_this8, type),
failure: failure.bind(_this8, type),
progress: progress.bind(_this8, type)
}; // Bigfish extend service
if (_this8.basicConfigPath) {
const _ref5 = // eslint-disable-next-line import/no-dynamic-require
require(_this8.basicConfigPath).default || require(_this8.basicConfigPath) || [],
services = _ref5.services;
if ((services === null || services === void 0 ? void 0 : services.length) > 0) {
// register framework services
services.forEach(baseUIService => {
baseUIService(serviceArgs);
});
}
}
if (type.startsWith('@@')) {
yield _this8.handleCoreData({
type,
payload,
lang,
key
}, {
log,
send,
success: success.bind(_this8, type),
failure: failure.bind(_this8, type),
progress: progress.bind(_this8, type)
});
} else {
(0, _assert().default)(_this8.servicesByKey[key], `service of key ${key} not exists.`);
const service = _this8.servicesByKey[key];
yield service.applyPlugins({
key: 'onUISocket',
type: service.ApplyPluginsType.event,
args: serviceArgs
});
} // eslint-disable-next-line no-empty
} catch (e) {
console.error(chalk.red(e.stack));
}
});
return function (_x3) {
return _ref4.apply(this, arguments);
};
}());
});
const port = yield portfinder.getPortPromise({
port: process.env.UMI_UI_PORT || process.env.UMI_PORT || 3000
});
const server = app.listen(port, process.env.HOST || '127.0.0.1', err => {
if (err) {
reject(err);
} else {
const _process$argv$slice = process.argv.slice(2),
_process$argv$slice2 = _slicedToArray(_process$argv$slice, 1),
command = _process$argv$slice2[0];
const url = `http://localhost:${port}/`;
console.log(command === 'dev' ? `🌈 Umi UI mini Ready on port 3000.` : `⛽️ Ready on ${url}.`);
if (browser) {
(0, _openBrowser().default)(url);
}
resolve({
port,
server: _this8.server
}); // just TEST or ALL ?
if (process.send) {
const message = {
type: 'UI_SERVER_DONE',
data: {
port,
url
}
};
(0, _debug.default)(`send ${JSON.stringify(message)}`);
process.send(message);
}
}
});
ss.installHandlers(server, {
prefix: '/umiui',
log: () => {}
});
_terminal.default.call(_this8, server);
_this8.socketServer = ss;
_this8.server = server;
});
return function (_x, _x2) {
return _ref3.apply(this, arguments);
};
}());
})();
}
/**
* 返回 projcet name如果 project 不存在,则返回 key
* @param key project key
*/
getProjectName(key) {
if (!key) {
return '';
}
const project = this.config.data.projectsByKey[key];
if (!project) {
return key;
}
return project.name;
}
/**
* 是否使用淘宝加速
* @param key project key
*/
hasTaobaoSpeedUp() {
// 一期默认开启,二期走全局配置。
return true;
}
}
exports.default = UmiUI;