@sanpjs/generator
Version:
@sanpjs/generator
268 lines • 10.1 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_extra_1 = __importDefault(require("fs-extra"));
// @ts-ignore
const map_stream_1 = __importDefault(require("map-stream"));
const vinyl_fs_1 = __importDefault(require("vinyl-fs"));
const lodash_merge_1 = __importDefault(require("lodash.merge"));
const glob_1 = __importDefault(require("glob"));
const getGlobPatterns_1 = __importDefault(require("./utils/getGlobPatterns"));
const validate_1 = __importDefault(require("./utils/validate"));
const utils_1 = require("@sanpjs/utils");
const ACTION_TYPE = {
add: 'add',
modify: 'modify',
move: 'move',
remove: 'remove'
};
class Generator {
actions;
config;
running;
constructor(config) {
this.running = false;
this.actions = [];
this.config = config;
this.normalize();
}
normalize() {
// 未关闭config文件读取
if (this.config.configFile !== false) {
const configFile = typeof this.config.configFile === 'string'
? this.config.configFile
: `${this.config.templateDir}/generator.config.js`;
if (fs_extra_1.default.pathExistsSync(configFile)) {
const config = require(configFile);
this.config = Object.assign(config, this.config);
}
}
// 验证 options schema
(0, validate_1.default)(this.config);
this.addAction(this.config.actions);
}
addAction(actions) {
if (actions) {
this.actions = this.actions.concat(actions);
}
}
getActionData(action) {
const templateDir = action.templateDir || this.config.templateDir;
const outputDir = action.outputDir || this.config.outputDir;
const templateVars = (0, lodash_merge_1.default)({}, this.config.templateVars, action.templateVars);
return { templateDir, outputDir, templateVars };
}
/**
* 添加项目文件的Action
*/
async runAddAction(action) {
if (!action.files || typeof action.files !== 'string') {
utils_1.logger.error(` No file to add on action(${action.type})`);
return;
}
const { templateDir, outputDir, templateVars } = this.getActionData(action);
const rootSrc = ['!**/node_modules/**'].concat(action.files);
if (action.filters) {
const excludedPatterns = (0, getGlobPatterns_1.default)(action.filters, templateVars);
if (excludedPatterns.length > 0) {
for (const glob of excludedPatterns) {
rootSrc.push(`!${glob}`);
}
}
}
return new Promise((resolve, reject) => {
vinyl_fs_1.default.src(rootSrc, {
cwd: templateDir,
cwdbase: action.cwdbase,
dot: true
})
.pipe((0, map_stream_1.default)(async (file, cb) => {
if (file.contents) {
let contents = file.contents.toString();
if ((0, utils_1.isLodashTpl)(contents)) {
contents = (0, utils_1.template)(contents, this.config.lodashTemplateSettings || {})(templateVars);
}
if (typeof action.handler === 'function') {
const changeContents = await action.handler(contents, file.path);
// 保证有返回才行
if (changeContents !== undefined) {
contents = changeContents;
}
}
file.contents = Buffer.from(contents);
}
cb(null, file);
}))
.pipe(vinyl_fs_1.default.dest(outputDir))
.on('end', () => {
utils_1.logger.debug(`Add files successfully...${rootSrc.join()}`);
resolve(true);
})
.on('error', (err) => {
utils_1.logger.error(err);
reject();
})
.resume();
});
}
/**
* 修改项目文件的Action
*/
async runModifyAction(action) {
if (!action.files || typeof action.files !== 'string') {
utils_1.logger.error(` No file to add on action(${action.type})`);
return;
}
const rootSrc = action.files;
const { outputDir, templateVars } = this.getActionData(action);
return new Promise((resolve, reject) => {
return vinyl_fs_1.default
.src(rootSrc, {
cwd: outputDir,
cwdbase: true,
dot: true,
allowEmpty: true
})
.pipe((0, map_stream_1.default)(async (file, cb) => {
if (file.contents) {
const isJson = file.path.endsWith('.json');
let contents = file.contents.toString();
contents = (0, utils_1.template)(contents, this.config.lodashTemplateSettings)(templateVars);
if (isJson) {
contents = JSON.parse(contents);
}
let result = contents;
if (typeof action.handler === 'function') {
const r = await action.handler(contents, file.path);
if (r !== undefined) {
result = r;
}
}
if (isJson) {
result = JSON.stringify(result, null, 2);
}
file.contents = result;
file.contents = Buffer.from(file.contents);
}
cb(null, file);
}))
.pipe(vinyl_fs_1.default.dest(outputDir))
.on('end', () => {
utils_1.logger.debug('run runModifyAction successfully');
resolve(true);
})
.on('error', (err) => {
utils_1.logger.error(err);
reject();
})
.resume();
});
}
/**
* 移动项目文件的Action
*/
async runMoveAction(action) {
const { outputDir, templateVars } = this.getActionData(action);
if (!action.patterns) {
return;
}
await Promise.all(Object.keys(action.patterns).map(async (pattern) => {
const files = glob_1.default.sync(pattern, {
cwd: outputDir,
absolute: true
});
files.forEach(from => {
if (action.patterns) {
let to = action.patterns[pattern];
if (typeof action.patterns[pattern] === 'function') {
to = action.patterns[pattern](from, templateVars);
}
if (from !== to) {
fs_extra_1.default.moveSync(from, to, {
overwrite: true
});
utils_1.logger.debug(`Move file from '${from}' to '${to}'`);
}
}
});
}));
}
/**
* 删除项目文件的Action
*/
async runRemoveAction(action) {
// 单个 action 的事件
const { outputDir, templateVars } = this.getActionData(action);
let patterns = [];
if (typeof action.files === 'function') {
action.files = action.files(templateVars);
}
if (typeof action.files === 'string' || Array.isArray(action.files)) {
patterns = patterns.concat(action.files);
}
else if (typeof action.files === 'object') {
patterns = (0, getGlobPatterns_1.default)(action.files, templateVars);
}
let files = [];
patterns.forEach((pattern) => {
files = files.concat(glob_1.default.sync(pattern, {
cwd: outputDir,
absolute: true
}));
});
await Promise.all(files.map((file) => {
utils_1.logger.debug('Remove file:' + file);
return fs_extra_1.default.removeSync(file);
}));
}
/**
* 批量运行任务
*/
async run() {
this.running = true;
let startTime = Date.now();
if (!this.actions) {
utils_1.logger.error('No actions are provided');
return;
}
if (this.config.before) {
await this.config.before.call(this, this.config, { logger: utils_1.logger, color: utils_1.color });
}
for (const action of this.actions) {
switch (action.type) {
case ACTION_TYPE.add:
await this.runAddAction(action);
break;
case ACTION_TYPE.modify:
await this.runModifyAction(action);
break;
case ACTION_TYPE.move:
await this.runMoveAction(action);
break;
case ACTION_TYPE.remove:
await this.runRemoveAction(action);
break;
}
}
if (this.config.after) {
await this.config.after.call(this, this.config, { logger: utils_1.logger, color: utils_1.color });
}
else {
utils_1.logger.info(`Generator run completed in ${Date.now() - startTime}ms.`);
}
}
watch() { }
// pagedir -> list -> router.js
// async run(args) {
// switch(type){
// case 'page':
// const data = ;
// this.createAppFile(data);
// }
// }
close() { }
}
exports.default = Generator;
//# sourceMappingURL=index.js.map