39ee4b8873
* chore: skip sync localization-management plugin enable status * chore: unSyncPlugins array * chore: remove install at dev * chore: gateway and supervisor * chore: install command * chore: remove app manager * chore: share plugin * chore: wsserver * chore: websocket server * chore: websocket connection with app status * feat: socket server at gateway * chore: loading message * chore: ready status * chore: handle app error * feat: restart app at supervisor * feat: health check endpoint * chore: test * chore: test * chore: test * chore: test * chore: build * chore: test * chore: build * chore: application ready status * chore: error message * chore: handle application error * chore: handle error in load * chore: report error in websocket * chore: ws error * chore: ws error * chore: typo * chore: switch app ready status at install * chore: test * chore: test * chore: test * chore: test * feat: add WebSocket client * chore: start gateway * chore: start command in application * chore: code * chore: pm command * chore: run start after load sub app * feat: application fsm * refactor: server life cycle (#2402) * refactor: server life cycle * fix: test error * fix: test error * fix: test error * fix: app.start * fix: cronjob stop * fix: db.sync before upgrade * fix: pm.get * fix: test error * fix: test error * fix: test error * test: add test cases * fix: remove PluginType * chore: start application after install * chore: fsm * chore: working status * chore: working command * chore: remove swith app ready status * chore: switch status after working done * chore: ws status * chore: gateway error * chore: test * chore: stopping status * chore: test * chore: test * feat: app proxy * chore: application destory * chore: application message changed with status * chore: test * chore: test timeout * test: remove listener add by plugin * test: remove listener add by plugin * chore: test * feat: app maintaining * fix: add AppMaintainingDialog * feat: off * test: gateway http response * test: gateway with errors * chore: unkown error * chore: websocket message * chore: ws message * chore: code * chore: error format * chore: delay app load * feat: improve code * chore: application initializing status * chore: supervisor with app status * chore: command status response * chore: test * chore: ws message * chore: test * fix: command running message * feat: restart * chore: code * chore: status transition * chore: test * fix: improve code * fix: error * fix: restart * fix: command * chore: reset client app tag when app selector changed * chore: error report * fix: application status * fix: build * chore: disable help command dispatch * chore: test * test: multi apps test * fix: improve code * fix: test * fix: test * fix: multi apps single running * fix: improve code * fix: app status * chore: move plugin static file to gateway * feat: static file handler * chore: test * chore: enable plugins in share collection * chore: gateway serve upload files * fix: improve client * chore: ws nginx config * fix: gateway with naonoid * fix: db sync * fix: loading * fix: ping * fix: locale load * fix: yarn start --quickstart * fix: add debug log * chore: application started event * chore: running working message payload * chore: nginx log * chore: nginxconf * chore: working message log * feat: logs * feat: compression * fix: remove koa-send and koa-static * fix: remove -e * fix: remove nginx * fix: remove -e * fix: __appName * chore: delay install sub application * chore: sync plugin status * fix: boot sub app * fix: main app reload * fix: test * fix: app status * test: field.bind block event loop * feat: newrelic * feat: debug log * chore: upgrade * fix(file-manager): test error * fix: default app selector * fix: reload after maintained * chore: boot sub app * chore: application destroy command * chore: destroy command * chore: clean code * chore: package.json * chore: maintaining message * chore: test * fix: collection.sync * feat: add test cases * chore: application * fix: test error * feat: improve codes and add test cases * fix: test error * fix: pm enable and disable * fix: pm.disable * feat: update docs * chore: update dockerfile --------- Co-authored-by: chenos <chenlinxh@gmail.com>
210 lines
6.4 KiB
JavaScript
210 lines
6.4 KiB
JavaScript
const { existsSync } = require('fs');
|
|
const { resolve, sep } = require('path');
|
|
const packageJson = require('./package.json');
|
|
const fs = require('fs');
|
|
const glob = require('glob');
|
|
const path = require('path');
|
|
|
|
console.log('VERSION: ', packageJson.version);
|
|
|
|
function getUmiConfig() {
|
|
const { APP_PORT, API_BASE_URL } = process.env;
|
|
const API_BASE_PATH = process.env.API_BASE_PATH || '/api/';
|
|
const PROXY_TARGET_URL = process.env.PROXY_TARGET_URL || `http://127.0.0.1:${APP_PORT}`;
|
|
const LOCAL_STORAGE_BASE_URL = process.env.LOCAL_STORAGE_BASE_URL || '/storage/uploads/';
|
|
|
|
function getLocalStorageProxy() {
|
|
if (LOCAL_STORAGE_BASE_URL.startsWith('http')) {
|
|
return {};
|
|
}
|
|
|
|
return {
|
|
[LOCAL_STORAGE_BASE_URL]: {
|
|
target: PROXY_TARGET_URL,
|
|
changeOrigin: true,
|
|
},
|
|
};
|
|
}
|
|
|
|
return {
|
|
alias: getPackagePaths().reduce((memo, item) => {
|
|
memo[item[0]] = item[1];
|
|
return memo;
|
|
}, {}),
|
|
define: {
|
|
'process.env.API_BASE_URL': API_BASE_URL || API_BASE_PATH,
|
|
'process.env.APP_ENV': process.env.APP_ENV,
|
|
'process.env.VERSION': packageJson.version,
|
|
'process.env.WEBSOCKET_URL': process.env.WEBSOCKET_URL,
|
|
},
|
|
// only proxy when using `umi dev`
|
|
// if the assets are built, will not proxy
|
|
proxy: {
|
|
[API_BASE_PATH]: {
|
|
target: PROXY_TARGET_URL,
|
|
changeOrigin: true,
|
|
pathRewrite: { [`^${API_BASE_PATH}`]: API_BASE_PATH },
|
|
},
|
|
// for local storage
|
|
...getLocalStorageProxy(),
|
|
},
|
|
};
|
|
}
|
|
|
|
function getNamespace() {
|
|
const content = fs.readFileSync(resolve(process.cwd(), 'package.json'), 'utf-8');
|
|
const json = JSON.parse(content);
|
|
return json.name;
|
|
}
|
|
|
|
function getTsconfigPaths() {
|
|
const content = fs.readFileSync(resolve(process.cwd(), 'tsconfig.json'), 'utf-8');
|
|
const json = JSON.parse(content);
|
|
return json.compilerOptions.paths;
|
|
}
|
|
|
|
function getPackagePaths() {
|
|
const paths = getTsconfigPaths();
|
|
const pkgs = [];
|
|
for (const key in paths) {
|
|
if (Object.hasOwnProperty.call(paths, key)) {
|
|
const dir = paths[key][0];
|
|
if (dir.includes('*')) {
|
|
const files = glob.sync(dir);
|
|
for (const file of files) {
|
|
const dirname = resolve(process.cwd(), file);
|
|
if (existsSync(dirname)) {
|
|
const re = new RegExp(dir.replace('*', '(.+)'));
|
|
const p = dirname
|
|
.substring(process.cwd().length + 1)
|
|
.split(sep)
|
|
.join('/');
|
|
const match = re.exec(p);
|
|
pkgs.push([key.replace('*', match?.[1]), dirname]);
|
|
}
|
|
}
|
|
} else {
|
|
const dirname = resolve(process.cwd(), dir);
|
|
pkgs.push([key, dirname]);
|
|
}
|
|
}
|
|
}
|
|
return pkgs;
|
|
}
|
|
|
|
function resolveNocobasePackagesAlias(config) {
|
|
const pkgs = getPackagePaths();
|
|
for (const [pkg, dir] of pkgs) {
|
|
config.module.rules.get('ts-in-node_modules').include.add(dir);
|
|
config.resolve.alias.set(pkg, dir);
|
|
}
|
|
}
|
|
|
|
class IndexGenerator {
|
|
constructor(outputPath, pluginsPath) {
|
|
this.outputPath = outputPath;
|
|
this.pluginsPath = pluginsPath;
|
|
}
|
|
|
|
get indexPath() {
|
|
return path.join(this.outputPath, 'index.ts');
|
|
}
|
|
|
|
get packageMapPath() {
|
|
return path.join(this.outputPath, 'packageMap.json');
|
|
}
|
|
|
|
get packagesPath() {
|
|
return path.join(this.outputPath, 'packages');
|
|
}
|
|
|
|
generate() {
|
|
this.generatePluginContent();
|
|
if (process.env.NODE_ENV === 'production') return;
|
|
this.pluginsPath.forEach((pluginPath) => {
|
|
if (!fs.existsSync(pluginPath)) {
|
|
return;
|
|
}
|
|
fs.watch(pluginPath, { recursive: false }, () => {
|
|
this.generatePluginContent();
|
|
});
|
|
});
|
|
}
|
|
|
|
get indexContent() {
|
|
return `// @ts-nocheck
|
|
import packageMap from './packageMap.json';
|
|
|
|
function devDynamicImport(packageName: string): Promise<any> {
|
|
const fileName = packageMap[packageName];
|
|
if (!fileName) {
|
|
return Promise.resolve(null);
|
|
}
|
|
return import(\`./packages/\${fileName}\`)
|
|
}
|
|
export default devDynamicImport;`;
|
|
}
|
|
|
|
get emptyIndexContent() {
|
|
return `
|
|
export default function devDynamicImport(packageName: string): Promise<any> {
|
|
return Promise.resolve(null);
|
|
}`;
|
|
}
|
|
|
|
generatePluginContent() {
|
|
if (fs.existsSync(this.outputPath)) {
|
|
fs.rmdirSync(this.outputPath, { recursive: true, force: true });
|
|
}
|
|
fs.mkdirSync(this.outputPath);
|
|
const validPluginPaths = this.pluginsPath.filter((pluginPath) => fs.existsSync(pluginPath));
|
|
if (!validPluginPaths.length || process.env.NODE_ENV === 'production') {
|
|
fs.writeFileSync(this.indexPath, this.emptyIndexContent);
|
|
return;
|
|
}
|
|
|
|
const pluginInfos = validPluginPaths.map((pluginPath) => this.getContent(pluginPath)).flat();
|
|
|
|
// index.ts
|
|
fs.writeFileSync(this.indexPath, this.indexContent);
|
|
// packageMap.json
|
|
const packageMapContent = pluginInfos.reduce((memo, item) => {
|
|
memo[item.packageJsonName] = item.pluginFileName + '.ts';
|
|
return memo;
|
|
}, {});
|
|
fs.writeFileSync(this.packageMapPath, JSON.stringify(packageMapContent, null, 2));
|
|
// packages
|
|
fs.mkdirSync(this.packagesPath, { recursive: true });
|
|
pluginInfos.forEach((item) => {
|
|
const pluginPackagePath = path.join(this.packagesPath, item.pluginFileName + '.ts');
|
|
fs.writeFileSync(pluginPackagePath, item.exportStatement);
|
|
});
|
|
}
|
|
|
|
getContent(pluginPath) {
|
|
const pluginFolders = fs.readdirSync(pluginPath);
|
|
const pluginInfos = pluginFolders
|
|
.filter((folder) => {
|
|
const pluginPackageJsonPath = path.join(pluginPath, folder, 'package.json');
|
|
const pluginSrcClientPath = path.join(pluginPath, folder, 'src', 'client');
|
|
return fs.existsSync(pluginPackageJsonPath) && fs.existsSync(pluginSrcClientPath);
|
|
})
|
|
.map((folder) => {
|
|
const pluginPackageJsonPath = path.join(pluginPath, folder, 'package.json');
|
|
const pluginPackageJson = require(pluginPackageJsonPath);
|
|
const pluginSrcClientPath = path
|
|
.relative(this.packagesPath, path.join(pluginPath, folder, 'src', 'client'))
|
|
.replaceAll('\\', '/');
|
|
const pluginFileName = `${path.basename(pluginPath)}_${folder.replaceAll('-', '_')}`;
|
|
const exportStatement = `export { default } from '${pluginSrcClientPath}';`;
|
|
return { exportStatement, pluginFileName, packageJsonName: pluginPackageJson.name };
|
|
});
|
|
|
|
return pluginInfos;
|
|
}
|
|
}
|
|
|
|
exports.getUmiConfig = getUmiConfig;
|
|
exports.resolveNocobasePackagesAlias = resolveNocobasePackagesAlias;
|
|
exports.IndexGenerator = IndexGenerator;
|