123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.generator = exports.BaseGenerator = exports.TsHelper = exports.createTsHelperInstance = exports.getDefaultGeneratorConfig = exports.defaultConfig = void 0;
- const tslib_1 = require("tslib");
- const assert_1 = tslib_1.__importDefault(require("assert"));
- const events_1 = require("events");
- const fs_1 = tslib_1.__importDefault(require("fs"));
- const crypto_1 = tslib_1.__importDefault(require("crypto"));
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
- const path_1 = tslib_1.__importDefault(require("path"));
- const generator = tslib_1.__importStar(require("./generator"));
- exports.generator = generator;
- const dot_prop_1 = require("dot-prop");
- const config_1 = require("./config");
- const watcher_1 = tslib_1.__importDefault(require("./watcher"));
- const base_1 = require("./generators/base");
- Object.defineProperty(exports, "BaseGenerator", { enumerable: true, get: function () { return base_1.BaseGenerator; } });
- const utils = tslib_1.__importStar(require("./utils"));
- const globby_1 = tslib_1.__importDefault(require("globby"));
- const isInUnitTest = process.env.NODE_ENV === 'test';
- exports.defaultConfig = {
- cwd: utils.convertString(process.env.ETS_CWD, process.cwd()),
- framework: utils.convertString(process.env.ETS_FRAMEWORK, 'egg'),
- typings: utils.convertString(process.env.ETS_TYPINGS, './typings'),
- caseStyle: utils.convertString(process.env.ETS_CASE_STYLE, 'lower'),
- autoRemoveJs: utils.convertString(process.env.ETS_AUTO_REMOVE_JS, true),
- throttle: utils.convertString(process.env.ETS_THROTTLE, 500),
- watch: utils.convertString(process.env.ETS_WATCH, false),
- watchOptions: undefined,
- execAtInit: utils.convertString(process.env.ETS_EXEC_AT_INIT, false),
- silent: utils.convertString(process.env.ETS_SILENT, isInUnitTest),
- generatorConfig: {},
- configFile: utils.convertString(process.env.ETS_CONFIG_FILE, '') || ['./tshelper', './tsHelper'],
- };
- // default watch dir
- function getDefaultGeneratorConfig(opt) {
- const baseConfig = {};
- // extend
- baseConfig.extend = {
- directory: 'app/extend',
- generator: 'extend',
- };
- // controller
- baseConfig.controller = {
- directory: 'app/controller',
- interface: config_1.declMapping.controller,
- generator: 'class',
- };
- // middleware
- baseConfig.middleware = {
- directory: 'app/middleware',
- interface: config_1.declMapping.middleware,
- generator: 'object',
- };
- // proxy
- baseConfig.proxy = {
- directory: 'app/proxy',
- interface: 'IProxy',
- generator: 'class',
- enabled: false,
- };
- // model
- baseConfig.model = {
- directory: 'app/model',
- generator: 'function',
- interface: 'IModel',
- caseStyle: 'upper',
- enabled: !(0, dot_prop_1.get)(opt === null || opt === void 0 ? void 0 : opt.eggInfo, 'config.customLoader.model'),
- };
- // config
- baseConfig.config = {
- directory: 'config',
- generator: 'config',
- trigger: ['add', 'unlink', 'change'],
- };
- // plugin
- baseConfig.plugin = {
- directory: 'config',
- generator: 'plugin',
- trigger: ['add', 'unlink', 'change'],
- };
- // service
- baseConfig.service = {
- directory: 'app/service',
- interface: config_1.declMapping.service,
- generator: 'auto',
- };
- // egg
- baseConfig.egg = {
- directory: 'app',
- generator: 'egg',
- watch: false,
- };
- // custom loader
- baseConfig.customLoader = {
- generator: 'custom',
- trigger: ['add', 'unlink', 'change'],
- };
- return baseConfig;
- }
- exports.getDefaultGeneratorConfig = getDefaultGeneratorConfig;
- class TsHelper extends events_1.EventEmitter {
- constructor(options) {
- super();
- this.watcherList = [];
- this.cacheDist = {};
- this.dtsFileList = [];
- // utils
- this.utils = utils;
- // configure ets
- this.configure(options);
- // init watcher
- this.initWatcher();
- }
- // build all watcher
- build() {
- // clean old files
- this.cleanFiles();
- this.watcherList.forEach(watcher => watcher.execute());
- return this;
- }
- // destroy
- destroy() {
- this.removeAllListeners();
- this.watcherList.forEach(item => item.destroy());
- this.watcherList.length = 0;
- }
- // log
- log(info, ignoreSilent) {
- if (!ignoreSilent && this.config.silent) {
- return;
- }
- utils.log(info);
- }
- warn(info) {
- this.log(chalk_1.default.yellow(info), !isInUnitTest);
- }
- // create oneForAll file
- createOneForAll(dist) {
- const config = this.config;
- const oneForAllDist = (typeof dist === 'string') ? dist : path_1.default.join(config.typings, './ets.d.ts');
- const oneForAllDistDir = path_1.default.dirname(oneForAllDist);
- // create d.ts includes all types.
- const distContent = config_1.dtsComment + this.dtsFileList
- .map(file => {
- const importUrl = path_1.default
- .relative(oneForAllDistDir, file.replace(/\.d\.ts$/, ''))
- .replace(/\/|\\/g, '/');
- return `import '${importUrl.startsWith('.') ? importUrl : `./${importUrl}`}';`;
- })
- .join('\n');
- this.emit('update', oneForAllDist);
- utils.writeFileSync(oneForAllDist, distContent);
- }
- // init watcher
- initWatcher() {
- Object.keys(this.config.generatorConfig).forEach(key => {
- this.registerWatcher(key, this.config.generatorConfig[key], false);
- });
- }
- // destroy watcher
- destroyWatcher(...refs) {
- this.watcherList = this.watcherList.filter(w => {
- if (refs.includes(w.ref)) {
- w.destroy();
- return false;
- }
- return true;
- });
- }
- // clean old files in startup
- cleanFiles() {
- const cwd = this.config.typings;
- globby_1.default.sync(['**/*.d.ts', '!**/node_modules'], { cwd })
- .forEach(file => {
- const fileUrl = path_1.default.resolve(cwd, file);
- const content = fs_1.default.readFileSync(fileUrl, 'utf-8');
- const isGeneratedByEts = content.match(config_1.dtsCommentRE);
- if (isGeneratedByEts)
- fs_1.default.unlinkSync(fileUrl);
- });
- }
- // register watcher
- registerWatcher(name, watchConfig, removeDuplicate = true) {
- if (removeDuplicate) {
- this.destroyWatcher(name);
- }
- if (watchConfig.hasOwnProperty('enabled') && !watchConfig.enabled) {
- return;
- }
- const directories = Array.isArray(watchConfig.directory)
- ? watchConfig.directory
- : [watchConfig.directory];
- // support array directory.
- return directories.map(dir => {
- const options = Object.assign({ name, ref: name, execAtInit: this.config.execAtInit }, watchConfig);
- if (dir) {
- options.directory = dir;
- }
- if (!this.config.watch) {
- options.watch = false;
- }
- const watcher = new watcher_1.default(this);
- watcher.on('update', this.generateTs.bind(this));
- watcher.init(options);
- this.watcherList.push(watcher);
- return watcher;
- });
- }
- loadWatcherConfig(config, options) {
- const configFile = options.configFile || config.configFile;
- const eggInfo = config.eggInfo;
- const getConfigFromPkg = pkg => (pkg.egg || {}).tsHelper;
- // read from enabled plugins
- if (eggInfo.plugins) {
- Object.keys(eggInfo.plugins)
- .forEach(k => {
- const pluginInfo = eggInfo.plugins[k];
- if (pluginInfo.enable && pluginInfo.path) {
- this.mergeConfig(config, getConfigFromPkg(utils.getPkgInfo(pluginInfo.path)));
- }
- });
- }
- // read from eggPaths
- if (eggInfo.eggPaths) {
- eggInfo.eggPaths.forEach(p => {
- this.mergeConfig(config, getConfigFromPkg(utils.getPkgInfo(p)));
- });
- }
- // read from package.json
- this.mergeConfig(config, getConfigFromPkg(utils.getPkgInfo(config.cwd)));
- // read from local file( default to tshelper | tsHelper )
- (Array.isArray(configFile) ? configFile : [configFile]).forEach(f => {
- this.mergeConfig(config, utils.requireFile(path_1.default.resolve(config.cwd, f)));
- });
- // merge local config and options to config
- this.mergeConfig(config, options);
- // create extra config
- config.tsConfig = utils.loadTsConfig(path_1.default.resolve(config.cwd, './tsconfig.json'));
- }
- // configure
- // options > configFile > package.json
- configure(options) {
- if (options.cwd) {
- options.cwd = path_1.default.resolve(exports.defaultConfig.cwd, options.cwd);
- }
- // base config
- const config = Object.assign({}, exports.defaultConfig);
- config.id = crypto_1.default.randomBytes(16).toString('base64');
- config.cwd = options.cwd || config.cwd;
- config.customLoader = config.customLoader || options.customLoader;
- // load egg info
- config.eggInfo = utils.getEggInfo({
- cwd: config.cwd,
- cacheIndex: config.id,
- customLoader: config.customLoader,
- });
- config.framework = options.framework || exports.defaultConfig.framework;
- config.generatorConfig = getDefaultGeneratorConfig(config);
- config.typings = path_1.default.resolve(config.cwd, config.typings);
- this.config = config;
- // load watcher config
- this.loadWatcherConfig(this.config, options);
- // deprecated framework
- if (this.config.framework && this.config.framework !== exports.defaultConfig.framework) {
- this.warn(`options.framework are deprecated, using default value(${exports.defaultConfig.framework}) instead`);
- }
- }
- generateTs(result, file, startTime) {
- const updateTs = (result, file) => {
- const config = this.config;
- const resultList = Array.isArray(result) ? result : [result];
- for (const item of resultList) {
- // check cache
- if (this.isCached(item.dist, item.content)) {
- return;
- }
- if (item.content) {
- // create file
- const dtsContent = `${config_1.dtsComment}\nimport '${config.framework}';\n${item.content}`;
- utils.writeFileSync(item.dist, dtsContent);
- this.emit('update', item.dist, file);
- this.log(`create ${path_1.default.relative(this.config.cwd, item.dist)} (${Date.now() - startTime}ms)`);
- this.updateDistFiles(item.dist);
- }
- else {
- if (!fs_1.default.existsSync(item.dist)) {
- return;
- }
- // remove file
- fs_1.default.unlinkSync(item.dist);
- delete this.cacheDist[item.dist];
- this.emit('remove', item.dist, file);
- this.log(`delete ${path_1.default.relative(this.config.cwd, item.dist)} (${Date.now() - startTime}ms)`);
- this.updateDistFiles(item.dist, true);
- }
- }
- };
- if (typeof result.then === 'function') {
- return result
- .then(r => updateTs(r, file))
- .catch(e => { this.log(e.message); });
- }
- updateTs(result, file);
- }
- updateDistFiles(fileUrl, isRemove) {
- const index = this.dtsFileList.indexOf(fileUrl);
- if (index >= 0) {
- if (isRemove) {
- this.dtsFileList.splice(index, 1);
- }
- }
- else {
- this.dtsFileList.push(fileUrl);
- }
- }
- isCached(fileUrl, content) {
- const cacheItem = this.cacheDist[fileUrl];
- if (content && cacheItem === content) {
- // no need to create file content is not changed.
- return true;
- }
- this.cacheDist[fileUrl] = content;
- return false;
- }
- // support dot prop config
- formatConfig(config) {
- const newConfig = {};
- Object.keys(config).forEach(key => (0, dot_prop_1.set)(newConfig, key, config[key]));
- return newConfig;
- }
- // merge ts helper options
- mergeConfig(base, ...args) {
- args.forEach(opt => {
- if (!opt)
- return;
- const config = this.formatConfig(opt);
- // compatitable for alias of generatorCofig
- if (config.watchDirs)
- config.generatorConfig = config.watchDirs;
- Object.keys(config).forEach(key => {
- if (key !== 'generatorConfig') {
- base[key] = config[key] === undefined ? base[key] : config[key];
- return;
- }
- const generatorConfig = config.generatorConfig || {};
- Object.keys(generatorConfig).forEach(k => {
- const item = generatorConfig[k];
- if (typeof item === 'boolean') {
- if (base.generatorConfig[k])
- base.generatorConfig[k].enabled = item;
- }
- else if (item) {
- // check private generator
- (0, assert_1.default)(!generator.isPrivateGenerator(item.generator), `${item.generator} is a private generator, can not configure in config file`);
- // compatible for deprecated fields
- [
- ['path', 'directory'],
- ].forEach(([oldValue, newValue]) => {
- if (item[oldValue]) {
- item[newValue] = item[oldValue];
- }
- });
- if (base.generatorConfig[k]) {
- Object.assign(base.generatorConfig[k], item);
- }
- else {
- base.generatorConfig[k] = item;
- }
- }
- });
- });
- });
- }
- }
- exports.default = TsHelper;
- exports.TsHelper = TsHelper;
- function createTsHelperInstance(options) {
- return new TsHelper(options);
- }
- exports.createTsHelperInstance = createTsHelperInstance;
|