@mainset/cli 0.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -0
- package/dist/esm/@types/process.env.js +1 -0
- package/dist/esm/commands/index.mjs +3 -0
- package/dist/esm/commands/node-package.mjs +64 -0
- package/dist/esm/commands/process-runner-chunks/index.mjs +3 -0
- package/dist/esm/commands/process-runner-chunks/rslib.chunk.mjs +15 -0
- package/dist/esm/commands/process-runner-chunks/system.chunk.mjs +8 -0
- package/dist/esm/commands/process-runner-chunks/typescript.chunk.mjs +48 -0
- package/dist/esm/commands/source-code.mjs +56 -0
- package/dist/esm/commands/web-app.mjs +136 -0
- package/dist/esm/mainset-cli.mjs +15 -0
- package/dist/esm/runtime/constants.mjs +5 -0
- package/dist/esm/runtime/index.mjs +3 -0
- package/dist/esm/runtime/path.mjs +13 -0
- package/dist/esm/runtime/resolve-host-package.mjs +20 -0
- package/dist/esm/services/express-base-app/express-base-app.config.json +9 -0
- package/dist/esm/services/express-base-app/express-base-app.mjs +38 -0
- package/dist/esm/services/express-base-app/index.mjs +2 -0
- package/dist/esm/services/serve-static/serve-static-config-loader.mjs +14 -0
- package/dist/esm/services/serve-static/serve-static.mjs +4 -0
- package/dist/esm/services/ssr-server/global.mjs +8 -0
- package/dist/esm/services/ssr-server/index.mjs +1 -0
- package/dist/esm/services/ssr-server/ssr-server-config-loader.mjs +12 -0
- package/dist/esm/services/ssr-server/ssr-server.mjs +43 -0
- package/dist/esm/utils/console-colorize.mjs +25 -0
- package/dist/esm/utils/index.mjs +3 -0
- package/dist/esm/utils/process-runner/index.mjs +1 -0
- package/dist/esm/utils/process-runner/process-manager.mjs +44 -0
- package/dist/esm/utils/process-runner/process-runner.mjs +56 -0
- package/dist/esm/utils/verify-or-set-node-env.mjs +13 -0
- package/dist/types/@types/process.env.d.ts +11 -0
- package/dist/types/commands/index.d.mts +3 -0
- package/dist/types/commands/node-package.d.mts +3 -0
- package/dist/types/commands/process-runner-chunks/index.d.mts +3 -0
- package/dist/types/commands/process-runner-chunks/rslib.chunk.d.mts +3 -0
- package/dist/types/commands/process-runner-chunks/system.chunk.d.mts +2 -0
- package/dist/types/commands/process-runner-chunks/typescript.chunk.d.mts +9 -0
- package/dist/types/commands/source-code.d.mts +3 -0
- package/dist/types/commands/web-app.d.mts +3 -0
- package/dist/types/mainset-cli.d.mts +2 -0
- package/dist/types/runtime/constants.d.mts +7 -0
- package/dist/types/runtime/index.d.mts +4 -0
- package/dist/types/runtime/path.d.mts +7 -0
- package/dist/types/runtime/resolve-host-package.d.mts +3 -0
- package/dist/types/services/express-base-app/express-base-app.d.mts +18 -0
- package/dist/types/services/express-base-app/index.d.mts +2 -0
- package/dist/types/services/serve-static/serve-static-config-loader.d.mts +3 -0
- package/dist/types/services/serve-static/serve-static.d.mts +1 -0
- package/dist/types/services/ssr-server/global.d.mts +6 -0
- package/dist/types/services/ssr-server/index.d.mts +1 -0
- package/dist/types/services/ssr-server/ssr-server-config-loader.d.mts +11 -0
- package/dist/types/services/ssr-server/ssr-server.d.mts +1 -0
- package/dist/types/utils/console-colorize.d.mts +12 -0
- package/dist/types/utils/index.d.mts +3 -0
- package/dist/types/utils/process-runner/index.d.mts +1 -0
- package/dist/types/utils/process-runner/process-manager.d.mts +13 -0
- package/dist/types/utils/process-runner/process-runner.d.mts +16 -0
- package/dist/types/utils/verify-or-set-node-env.d.mts +2 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { runtimePathById } from '../runtime/index.mjs';
|
|
4
|
+
import { consoleColorize, initProcessCatchErrorLogger, } from '../utils/index.mjs';
|
|
5
|
+
import { execPurgeDist, execRslibCLICommand, execTypeScriptCompileTypeOnly, runRslibCLICommand, runTypeScriptCompileTypeOnly, } from './process-runner-chunks/index.mjs';
|
|
6
|
+
function registerNodePackageCommand(program) {
|
|
7
|
+
program
|
|
8
|
+
.command('node-package')
|
|
9
|
+
.description('Run node package build or watch using Rslib')
|
|
10
|
+
.requiredOption('-e, --exec <type>', 'Execution mode: build or watch')
|
|
11
|
+
// .option('-b, --builder <builder>', 'Builder tool (default: rslib)', 'rslib')
|
|
12
|
+
.option('-c, --config <path>', 'Path to config file', './rslib.config.mts')
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
// Step 0: determinate command params
|
|
15
|
+
const customRslibConfigPath = path.resolve(runtimePathById.root, options.config);
|
|
16
|
+
const rslibConfigPath = fs.existsSync(customRslibConfigPath)
|
|
17
|
+
? customRslibConfigPath
|
|
18
|
+
: path.resolve(runtimePathById.root,
|
|
19
|
+
// NOTE: possibility to check if package is installed, otherwise throw error
|
|
20
|
+
'node_modules', '@mainset/builder-rslib/dist/esm/rslib.node-package.config.mjs');
|
|
21
|
+
if (options.exec === 'build') {
|
|
22
|
+
// ========== Build mode ==========
|
|
23
|
+
console.log('\n🏗️ [mainset cli] node-package: build');
|
|
24
|
+
try {
|
|
25
|
+
// Step 1: purge dist folder
|
|
26
|
+
execPurgeDist();
|
|
27
|
+
// Step 2: build source code
|
|
28
|
+
console.log('\n📦 Compiling Source Code with Rslib ...');
|
|
29
|
+
await execRslibCLICommand(`build --config ${rslibConfigPath}`);
|
|
30
|
+
// Step 3: build type only
|
|
31
|
+
await execTypeScriptCompileTypeOnly();
|
|
32
|
+
console.log('\n✅ Build completed successfully\n');
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
initProcessCatchErrorLogger('node-package', error, 'build');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (options.exec === 'watch') {
|
|
39
|
+
// ========== Watch mode ==========
|
|
40
|
+
console.log('\n🏗️ [mainset cli] node-package: watch');
|
|
41
|
+
try {
|
|
42
|
+
// Step 1: purge dist folder
|
|
43
|
+
execPurgeDist();
|
|
44
|
+
// Step 2: watch source code
|
|
45
|
+
await runRslibCLICommand([
|
|
46
|
+
'build',
|
|
47
|
+
'--config',
|
|
48
|
+
rslibConfigPath,
|
|
49
|
+
'--watch',
|
|
50
|
+
]);
|
|
51
|
+
// Step 3: watch type only
|
|
52
|
+
await runTypeScriptCompileTypeOnly();
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
initProcessCatchErrorLogger('node-package', error, 'watch');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
console.error(consoleColorize('BRIGHT_YELLOW', `[mainset cli][node-package] Unknown exec mode: "${options.exec}"`));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export { registerNodePackageCommand };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { resolveHostPackageBinForCLICommandPath } from '../../runtime/index.mjs';
|
|
2
|
+
import { execImmediateCommand, runStreamingCommand, } from '../../utils/index.mjs';
|
|
3
|
+
async function getRslibCLICommandPath() {
|
|
4
|
+
const rslibCLICommandPath = await resolveHostPackageBinForCLICommandPath('@mainset/builder-rslib', '@rslib/core', 'rslib');
|
|
5
|
+
return rslibCLICommandPath;
|
|
6
|
+
}
|
|
7
|
+
async function execRslibCLICommand(command) {
|
|
8
|
+
const rslibCLICommandPath = await getRslibCLICommandPath();
|
|
9
|
+
return execImmediateCommand(`node ${rslibCLICommandPath} ${command}`);
|
|
10
|
+
}
|
|
11
|
+
async function runRslibCLICommand(commandParams) {
|
|
12
|
+
const rslibCLICommandPath = await getRslibCLICommandPath();
|
|
13
|
+
return runStreamingCommand('node', [rslibCLICommandPath, ...commandParams]);
|
|
14
|
+
}
|
|
15
|
+
export { execRslibCLICommand, runRslibCLICommand };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { runtimePathById } from '../../runtime/index.mjs';
|
|
2
|
+
import { execImmediateCommand } from '../../utils/index.mjs';
|
|
3
|
+
// Cleanup
|
|
4
|
+
function execPurgeDist() {
|
|
5
|
+
console.log('🧹 Cleaning dist folder ...');
|
|
6
|
+
execImmediateCommand(`rm -rf ${runtimePathById.dist}`);
|
|
7
|
+
}
|
|
8
|
+
export { execPurgeDist };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { resolveHostPackageBinForCLICommandPath, runtimePathById, } from '../../runtime/index.mjs';
|
|
3
|
+
import { execImmediateCommand, runStreamingCommand, } from '../../utils/index.mjs';
|
|
4
|
+
async function getTscCLICommandPath() {
|
|
5
|
+
const tscCLICommandPath = await resolveHostPackageBinForCLICommandPath('@mainset/dev-stack-fe', 'typescript', 'tsc');
|
|
6
|
+
return tscCLICommandPath;
|
|
7
|
+
}
|
|
8
|
+
// Source code
|
|
9
|
+
async function execTypeScriptCompileSourceCode({ configPath, }) {
|
|
10
|
+
const tscCLICommandPath = await getTscCLICommandPath();
|
|
11
|
+
console.log('\n📦 Compiling Source Code with TypeScript ...');
|
|
12
|
+
execImmediateCommand(`node ${tscCLICommandPath} --project ${configPath}`);
|
|
13
|
+
}
|
|
14
|
+
async function runTypeScriptCompileSourceCode({ configPath, }) {
|
|
15
|
+
const tscCLICommandPath = await getTscCLICommandPath();
|
|
16
|
+
console.log('\n📝 Compiling .d.ts Types in watch mode ...');
|
|
17
|
+
runStreamingCommand('node', [
|
|
18
|
+
tscCLICommandPath,
|
|
19
|
+
'--project',
|
|
20
|
+
configPath,
|
|
21
|
+
'--watch',
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
// Type only
|
|
25
|
+
function getTypeScriptTypeOnlyConfigPath() {
|
|
26
|
+
const customTypeScriptTypeOnlyConfigPath = path.join(runtimePathById.root, './tsconfig.build-type.json');
|
|
27
|
+
return {
|
|
28
|
+
configPath: customTypeScriptTypeOnlyConfigPath,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async function execTypeScriptCompileTypeOnly() {
|
|
32
|
+
const { configPath } = getTypeScriptTypeOnlyConfigPath();
|
|
33
|
+
const tscCLICommandPath = await getTscCLICommandPath();
|
|
34
|
+
console.log('\n📝 Compiling .d.ts Types in build mode ...');
|
|
35
|
+
execImmediateCommand(`node ${tscCLICommandPath} --project ${configPath}`);
|
|
36
|
+
}
|
|
37
|
+
async function runTypeScriptCompileTypeOnly() {
|
|
38
|
+
const { configPath } = getTypeScriptTypeOnlyConfigPath();
|
|
39
|
+
const tscCLICommandPath = await getTscCLICommandPath();
|
|
40
|
+
console.log('\n📝 Compiling .d.ts Types in watch mode ...');
|
|
41
|
+
runStreamingCommand('node', [
|
|
42
|
+
tscCLICommandPath,
|
|
43
|
+
'--project',
|
|
44
|
+
configPath,
|
|
45
|
+
'--watch',
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
export { execTypeScriptCompileSourceCode, execTypeScriptCompileTypeOnly, runTypeScriptCompileSourceCode, runTypeScriptCompileTypeOnly, };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { runtimePathById } from '../runtime/index.mjs';
|
|
3
|
+
import { consoleColorize, initProcessCatchErrorLogger, } from '../utils/index.mjs';
|
|
4
|
+
import { execPurgeDist, execTypeScriptCompileSourceCode, execTypeScriptCompileTypeOnly, runTypeScriptCompileSourceCode, runTypeScriptCompileTypeOnly, } from './process-runner-chunks/index.mjs';
|
|
5
|
+
function registerSourceCodeCommand(program) {
|
|
6
|
+
program
|
|
7
|
+
.command('source-code')
|
|
8
|
+
.description('Run source code compile or watch using TypeScript')
|
|
9
|
+
.requiredOption('-e, --exec <type>', 'Execution mode: compile or watch')
|
|
10
|
+
// .option('-b, --builder <builder>', 'Compiler tool (default: tsc)', 'tsc')
|
|
11
|
+
.option('-c, --config <path>', 'Path to config file', './tsconfig.json')
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
// Step 0: determinate command params
|
|
14
|
+
const typeScriptSourceCodeConfigPath = path.join(runtimePathById.root, options.config);
|
|
15
|
+
if (options.exec === 'compile') {
|
|
16
|
+
// ========== Compile mode ==========
|
|
17
|
+
console.log('\n🏗️ [mainset cli] source-code: compile');
|
|
18
|
+
try {
|
|
19
|
+
// Step 1: purge dist folder
|
|
20
|
+
execPurgeDist();
|
|
21
|
+
// Step 2: compile source code
|
|
22
|
+
await execTypeScriptCompileSourceCode({
|
|
23
|
+
configPath: typeScriptSourceCodeConfigPath,
|
|
24
|
+
});
|
|
25
|
+
// Step 3: compile type only
|
|
26
|
+
await execTypeScriptCompileTypeOnly();
|
|
27
|
+
console.log('\n✅ Build completed successfully\n');
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
initProcessCatchErrorLogger('source-code', error, 'compile');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else if (options.exec === 'watch') {
|
|
34
|
+
// ========== Watch mode ==========
|
|
35
|
+
console.log('\n🏗️ [mainset cli] source-code: watch');
|
|
36
|
+
try {
|
|
37
|
+
// Step 1: purge dist folder
|
|
38
|
+
execPurgeDist();
|
|
39
|
+
// Step 2: watch source code
|
|
40
|
+
await runTypeScriptCompileSourceCode({
|
|
41
|
+
configPath: typeScriptSourceCodeConfigPath,
|
|
42
|
+
});
|
|
43
|
+
// Step 3: watch type only
|
|
44
|
+
await runTypeScriptCompileTypeOnly();
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
initProcessCatchErrorLogger('source-code', error, 'watch');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
console.error(consoleColorize('BRIGHT_YELLOW', `[mainset cli][source-code] Unknown exec mode: "${options.exec}"`));
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
export { registerSourceCodeCommand };
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { resolveHostPackageBinForCLICommandPath, runtimePathById, } from '../runtime/index.mjs';
|
|
4
|
+
import { consoleColorize, execImmediateCommand, initProcessCatchErrorLogger, runStreamingCommand, } from '../utils/index.mjs';
|
|
5
|
+
import { execPurgeDist, execRslibCLICommand, runRslibCLICommand, } from './process-runner-chunks/index.mjs';
|
|
6
|
+
function registerWebAppCommand(program) {
|
|
7
|
+
program
|
|
8
|
+
.command('web-app')
|
|
9
|
+
.description('Run web app build or serve using bundler')
|
|
10
|
+
.requiredOption('-e, --exec <type>', 'Execution mode: build, serve, serve-static')
|
|
11
|
+
// .option(
|
|
12
|
+
// '-b, --bundler <bundler>',
|
|
13
|
+
// 'Bundler tool: webpack or rslib (default: webpack)',
|
|
14
|
+
// 'webpack'
|
|
15
|
+
// )
|
|
16
|
+
.option('-c, --config <path>', 'Path to config file')
|
|
17
|
+
.option('--serveMode <mode>', 'Serve mode: ssr or csr (default: ssr)', 'ssr')
|
|
18
|
+
.action(async (options) => {
|
|
19
|
+
// Step 0: determinate command params
|
|
20
|
+
const customWebpackConfigPath = path.resolve(runtimePathById.root, options.config || './config/webpack.config.mjs');
|
|
21
|
+
// Webpack paths
|
|
22
|
+
const webpackCLICommandPath = await resolveHostPackageBinForCLICommandPath('@mainset/bundler-webpack', 'webpack', 'webpack');
|
|
23
|
+
const webpackSSRConfigPath = fs.existsSync(customWebpackConfigPath)
|
|
24
|
+
? customWebpackConfigPath
|
|
25
|
+
: path.resolve(runtimePathById.root, 'node_modules', '@mainset/bundler-webpack/dist/esm/webpack-config/webapp.ssr.config.mjs');
|
|
26
|
+
const rslibSSRConfigPath = path.resolve(runtimePathById.root, 'node_modules', '@mainset/builder-rslib/dist/esm/rslib.ssr-server.config.mjs');
|
|
27
|
+
if (options.exec === 'build') {
|
|
28
|
+
// ========== Build mode ==========
|
|
29
|
+
console.log('\n🏗️ [mainset cli] web-app: build');
|
|
30
|
+
try {
|
|
31
|
+
if (options.serveMode === 'ssr') {
|
|
32
|
+
// ========== [Build] SSR mode ==========
|
|
33
|
+
// Step 1: purge dist folder
|
|
34
|
+
execPurgeDist();
|
|
35
|
+
// Step 2: build:ssr-webapp source code
|
|
36
|
+
console.log('\n📦 Compiling SSR WebApp with Webpack ...');
|
|
37
|
+
execImmediateCommand(`node ${webpackCLICommandPath} --config ${webpackSSRConfigPath}`);
|
|
38
|
+
// Step 3: build:ssr-server source code
|
|
39
|
+
console.log('\n📦 Compiling SSR Server with Rslib ...');
|
|
40
|
+
await execRslibCLICommand(`build --config ${rslibSSRConfigPath}`);
|
|
41
|
+
console.log('\n✅ SSR Build completed successfully\n');
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// ========== [Build] CSR mode ==========
|
|
45
|
+
const webpackCSRConfigPath = fs.existsSync(customWebpackConfigPath)
|
|
46
|
+
? customWebpackConfigPath
|
|
47
|
+
: path.resolve(runtimePathById.root, 'node_modules', '@mainset/bundler-webpack/dist/esm/webpack-config/webapp.csr.config.mjs');
|
|
48
|
+
// Step 1: purge dist folder
|
|
49
|
+
execPurgeDist();
|
|
50
|
+
// Step 2: build:csr-webapp source code
|
|
51
|
+
console.log('\n📦 Compiling CSR WebApp with Webpack ...');
|
|
52
|
+
execImmediateCommand(`node ${webpackCLICommandPath} --config ${webpackCSRConfigPath}`);
|
|
53
|
+
console.log('\n✅ CSR Build completed successfully\n');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
initProcessCatchErrorLogger('web-app', error, 'build');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (options.exec === 'serve') {
|
|
61
|
+
// ========== Serve mode ==========
|
|
62
|
+
console.log('\n🏗️ [mainset cli] web-app: serve');
|
|
63
|
+
try {
|
|
64
|
+
if (options.serveMode === 'ssr') {
|
|
65
|
+
// ========== [Serve] SSR mode ==========
|
|
66
|
+
const ssrServerEntryPath = path.resolve(runtimePathById.msCLISrc, '../services/ssr-server/ssr-server.mjs');
|
|
67
|
+
const ssrServerConfigCompiledPath = path.resolve(runtimePathById.dist, './private/ssr-server.config.mjs');
|
|
68
|
+
// Step 1: watch:ssr-server start ssr server
|
|
69
|
+
await runRslibCLICommand([
|
|
70
|
+
'build',
|
|
71
|
+
'--config',
|
|
72
|
+
rslibSSRConfigPath,
|
|
73
|
+
'--watch',
|
|
74
|
+
]);
|
|
75
|
+
// Step 2: watch:ssr-webapp source code of web app
|
|
76
|
+
runStreamingCommand('node', [
|
|
77
|
+
webpackCLICommandPath,
|
|
78
|
+
'--config',
|
|
79
|
+
webpackSSRConfigPath,
|
|
80
|
+
'--watch',
|
|
81
|
+
]);
|
|
82
|
+
// Step 3: start:ssr-server which is compiled web app and ssr-server code
|
|
83
|
+
runStreamingCommand('node', [
|
|
84
|
+
'--watch', // Enable watch mode for {node}
|
|
85
|
+
ssrServerEntryPath,
|
|
86
|
+
'--ssrServerConfig',
|
|
87
|
+
ssrServerConfigCompiledPath,
|
|
88
|
+
]);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// ========== [Serve] CSR mode ==========
|
|
92
|
+
const webpackDevServerCLICommandPath = await resolveHostPackageBinForCLICommandPath('@mainset/bundler-webpack', 'webpack-dev-server');
|
|
93
|
+
const webpackDevServerConfigPath = fs.existsSync(customWebpackConfigPath)
|
|
94
|
+
? customWebpackConfigPath
|
|
95
|
+
: path.resolve(runtimePathById.root, 'node_modules', '@mainset/bundler-webpack/dist/esm/webpack-config/dev-server.csr.config.mjs');
|
|
96
|
+
// Step 1: watch:csr-server / start:csr-server source code
|
|
97
|
+
runStreamingCommand('node', [
|
|
98
|
+
webpackDevServerCLICommandPath,
|
|
99
|
+
'--config',
|
|
100
|
+
webpackDevServerConfigPath,
|
|
101
|
+
'--open',
|
|
102
|
+
]);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
initProcessCatchErrorLogger('web-app', error, 'watch');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (options.exec === 'serve-static') {
|
|
110
|
+
// ========== Serve static mode ==========
|
|
111
|
+
console.log('\n🏗️ [mainset cli] web-app: serve-static');
|
|
112
|
+
try {
|
|
113
|
+
// Step 1: determinate command params
|
|
114
|
+
const serverEntryPath = path.resolve(runtimePathById.msCLISrc, '../services/serve-static/serve-static.mjs');
|
|
115
|
+
const customServeStaticConfigPath = path.resolve(runtimePathById.root, options.config || './config/serve-static.config.json');
|
|
116
|
+
const serveStaticConfigPath = fs.existsSync(customServeStaticConfigPath)
|
|
117
|
+
? customServeStaticConfigPath
|
|
118
|
+
: path.resolve(runtimePathById.msCLISrc, '../services/express-base-app/express-base-app.config.json');
|
|
119
|
+
// Step 2: serve static compiled files
|
|
120
|
+
runStreamingCommand('node', [
|
|
121
|
+
serverEntryPath,
|
|
122
|
+
'--serveStaticConfig',
|
|
123
|
+
serveStaticConfigPath,
|
|
124
|
+
]);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
initProcessCatchErrorLogger('web-app', error, 'serve-static');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
console.error(consoleColorize('BRIGHT_YELLOW', `[mainset cli][web-app] Unknown exec mode: "${options.exec}"`));
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
export { registerWebAppCommand };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { registerNodePackageCommand, registerSourceCodeCommand, registerWebAppCommand, } from './commands/index.mjs';
|
|
4
|
+
import { verifyOrSetNodeEnv } from './utils/index.mjs';
|
|
5
|
+
// !IMPORTANT: Set NODE_ENV is case it is not passed
|
|
6
|
+
verifyOrSetNodeEnv();
|
|
7
|
+
const program = new Command();
|
|
8
|
+
program
|
|
9
|
+
.name('ms-cli')
|
|
10
|
+
.description('CLI to manage frontend tooling and infrastructure')
|
|
11
|
+
.version('0.1.0');
|
|
12
|
+
registerSourceCodeCommand(program);
|
|
13
|
+
registerNodePackageCommand(program);
|
|
14
|
+
registerWebAppCommand(program);
|
|
15
|
+
program.parse(process.argv);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
4
|
+
const root = process.cwd();
|
|
5
|
+
const runtimePathById = {
|
|
6
|
+
// Relative to executable project
|
|
7
|
+
root,
|
|
8
|
+
dist: path.join(root, 'dist'),
|
|
9
|
+
src: path.join(root, 'src'),
|
|
10
|
+
// Relative to file being executed
|
|
11
|
+
msCLISrc: __dirname,
|
|
12
|
+
};
|
|
13
|
+
export { runtimePathById };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { runtimePathById } from './path.mjs';
|
|
4
|
+
function resolveHostPackageNodeModulesPath(hostPackageName, dependencyPackageName) {
|
|
5
|
+
const hostPackageNodeModulesPath = path.resolve(runtimePathById.root, `node_modules/${hostPackageName}/node_modules`);
|
|
6
|
+
const isNodeModulesDeepNested = fs.existsSync(hostPackageNodeModulesPath);
|
|
7
|
+
return isNodeModulesDeepNested // Pnpm uses such a structure
|
|
8
|
+
? path.join(hostPackageNodeModulesPath, dependencyPackageName)
|
|
9
|
+
: path.join(runtimePathById.root, 'node_modules', dependencyPackageName);
|
|
10
|
+
}
|
|
11
|
+
async function resolveHostPackageBinForCLICommandPath(hostPackageName, dependencyPackageName, cliCommandName) {
|
|
12
|
+
// Pnpm node_modules structure
|
|
13
|
+
const dependencyPackageNodeModulesPath = resolveHostPackageNodeModulesPath(hostPackageName, dependencyPackageName);
|
|
14
|
+
const packageJson = await import(path.join(dependencyPackageNodeModulesPath, 'package.json'), { with: { type: 'json' } });
|
|
15
|
+
const binPath = cliCommandName
|
|
16
|
+
? packageJson.default.bin[cliCommandName]
|
|
17
|
+
: packageJson.default.bin;
|
|
18
|
+
return path.join(dependencyPackageNodeModulesPath, binPath);
|
|
19
|
+
}
|
|
20
|
+
export { resolveHostPackageBinForCLICommandPath, resolveHostPackageNodeModulesPath, };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
// Import type { Options } from 'http-proxy-middleware';
|
|
4
|
+
import { runtimePathById } from '../../runtime/index.mjs';
|
|
5
|
+
import defaultExpressConfig from './express-base-app.config.json' with { type: 'json' };
|
|
6
|
+
class ExpressBaseApp {
|
|
7
|
+
// ========== Constructor ==========
|
|
8
|
+
constructor(customExpressConfig = {}) {
|
|
9
|
+
const { listenPort = defaultExpressConfig.listenPort, serveStatics } = customExpressConfig;
|
|
10
|
+
this.listenPort = listenPort;
|
|
11
|
+
this.app = express();
|
|
12
|
+
this.appUseStatic({
|
|
13
|
+
serveStatics,
|
|
14
|
+
});
|
|
15
|
+
this.startListening = this.startListening.bind(this);
|
|
16
|
+
}
|
|
17
|
+
// ========== Private ==========
|
|
18
|
+
appUseStatic({ serveStatics, }) {
|
|
19
|
+
serveStatics === null || serveStatics === void 0 ? void 0 : serveStatics.forEach((customServeStaticConfig) => {
|
|
20
|
+
const serveStaticConfig = Object.assign(Object.assign({}, defaultExpressConfig.serveStatics[0]), customServeStaticConfig);
|
|
21
|
+
this.app.use(serveStaticConfig.publicPath, express.static(serveStaticConfig.rootPath));
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
// Private appUseProxy() {
|
|
25
|
+
// app.use('/api', createProxyMiddleware(proxyConfig['/api/']));
|
|
26
|
+
// app.use('/api-local', createProxyMiddleware(proxyConfig['/api-local/']));
|
|
27
|
+
// app.use('/api-boilerplate', createProxyMiddleware(proxyConfig['/api-boilerplate/']));
|
|
28
|
+
// }
|
|
29
|
+
// ========== Public ==========
|
|
30
|
+
async startListening() {
|
|
31
|
+
this.app.listen(this.listenPort, async () => {
|
|
32
|
+
var _a;
|
|
33
|
+
const packageJson = await import(path.resolve(runtimePathById.root, 'package.json'), { with: { type: 'json' } });
|
|
34
|
+
console.log(`${((_a = packageJson === null || packageJson === void 0 ? void 0 : packageJson.default) === null || _a === void 0 ? void 0 : _a.name) || 'Web App'} listening at http://localhost:${this.listenPort}`);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export { ExpressBaseApp };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
// Step-1: parse CLI arguments
|
|
4
|
+
const options = new Command()
|
|
5
|
+
.option('--serveStaticConfig <path>', 'Path to ./config/serve-static.config.json config file')
|
|
6
|
+
.allowUnknownOption() // Bypass {error: unknown option '--config'}
|
|
7
|
+
.allowExcessArguments() // Bypass {error: too many arguments. Expected 0 arguments but got 2.}
|
|
8
|
+
.parse(process.argv)
|
|
9
|
+
.opts();
|
|
10
|
+
// Step-2: load Serve Static config from JSON file
|
|
11
|
+
const serveStaticConfig = options.serveStaticConfig
|
|
12
|
+
? JSON.parse(fs.readFileSync(options.serveStaticConfig, 'utf-8'))
|
|
13
|
+
: {};
|
|
14
|
+
export { serveStaticConfig };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
// Step-1: parse CLI arguments
|
|
3
|
+
const options = new Command()
|
|
4
|
+
.option('--ssrServerConfig <path>', 'Path to ./config/ssr-server.config.mts config file')
|
|
5
|
+
.allowUnknownOption() // Bypass {error: unknown option '--config'}
|
|
6
|
+
.allowExcessArguments() // Bypass {error: too many arguments. Expected 0 arguments but got 2.}
|
|
7
|
+
.parse(process.argv)
|
|
8
|
+
.opts();
|
|
9
|
+
// Step-2: load SSR server config from JSON file
|
|
10
|
+
const ssrServerConfig = (await import(options.ssrServerConfig))
|
|
11
|
+
.default;
|
|
12
|
+
export { ssrServerConfig };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import cors from 'cors';
|
|
13
|
+
import { ExpressBaseApp } from '../express-base-app/index.mjs';
|
|
14
|
+
import global from './global.mjs';
|
|
15
|
+
import { ssrServerConfig } from './ssr-server-config-loader.mjs';
|
|
16
|
+
const { renderSSRContentByPath } = ssrServerConfig, customExpressConfig = __rest(ssrServerConfig, ["renderSSRContentByPath"]);
|
|
17
|
+
global.init();
|
|
18
|
+
const { app, startListening } = new ExpressBaseApp(customExpressConfig);
|
|
19
|
+
app.use(cors());
|
|
20
|
+
// Get all path which is not starts from api
|
|
21
|
+
Object.keys(renderSSRContentByPath).forEach((renderSSRContentPath) => {
|
|
22
|
+
app.get(renderSSRContentPath, async (req, res) => {
|
|
23
|
+
try {
|
|
24
|
+
// Construct the full URL for the incoming request
|
|
25
|
+
const fullUrl = `${req.protocol}://${req.get('host')}${req.url}`;
|
|
26
|
+
const renderSSRContent = renderSSRContentByPath[renderSSRContentPath];
|
|
27
|
+
const htmlContent = await renderSSRContent({
|
|
28
|
+
reqUrl: req.url,
|
|
29
|
+
fullUrl,
|
|
30
|
+
});
|
|
31
|
+
res.send(htmlContent);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
if (error instanceof Response && error.status === 302) {
|
|
35
|
+
// Handle redirects
|
|
36
|
+
res.redirect(error.headers.get('Location') || '/');
|
|
37
|
+
}
|
|
38
|
+
console.error(error);
|
|
39
|
+
res.status(500).send('Internal Server Error');
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
startListening();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const TERMINAL_COLOR__BY_KEY = {
|
|
2
|
+
RESET: '\x1b[0m',
|
|
3
|
+
// Regular colors
|
|
4
|
+
RED: '\x1b[31m',
|
|
5
|
+
GREEN: '\x1b[32m',
|
|
6
|
+
YELLOW: '\x1b[33m',
|
|
7
|
+
BLUE: '\x1b[34m',
|
|
8
|
+
// Bright colors
|
|
9
|
+
BRIGHT_RED: '\x1b[91m',
|
|
10
|
+
BRIGHT_GREEN: '\x1b[92m',
|
|
11
|
+
BRIGHT_YELLOW: '\x1b[93m',
|
|
12
|
+
};
|
|
13
|
+
const EMOJI__BY_COLOR_KEY = {
|
|
14
|
+
RED: '❌',
|
|
15
|
+
BRIGHT_RED: '❌',
|
|
16
|
+
YELLOW: '⚠️',
|
|
17
|
+
BRIGHT_YELLOW: '⚠️',
|
|
18
|
+
GREEN: '✅',
|
|
19
|
+
BRIGHT_GREEN: '✅',
|
|
20
|
+
};
|
|
21
|
+
const consoleColorize = (color, text) => {
|
|
22
|
+
const emoji = color ? `${EMOJI__BY_COLOR_KEY[color]} ` : '';
|
|
23
|
+
return `${emoji}${TERMINAL_COLOR__BY_KEY[color]}${text}${TERMINAL_COLOR__BY_KEY.RESET}`;
|
|
24
|
+
};
|
|
25
|
+
export { consoleColorize };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './process-runner.mjs';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { initProcessCatchErrorLogger } from './process-runner.mjs';
|
|
2
|
+
class ProcessManager {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.processes = new Set();
|
|
5
|
+
this.setupCleanupHandlers();
|
|
6
|
+
}
|
|
7
|
+
static getInstance() {
|
|
8
|
+
ProcessManager.instance || (ProcessManager.instance = new ProcessManager());
|
|
9
|
+
return ProcessManager.instance;
|
|
10
|
+
}
|
|
11
|
+
setupCleanupHandlers() {
|
|
12
|
+
process.on('SIGINT', () => this.cleanup('SIGINT'));
|
|
13
|
+
process.on('SIGTERM', () => this.cleanup('SIGTERM'));
|
|
14
|
+
process.on('uncaughtException', (error) => {
|
|
15
|
+
console.error('Uncaught Exception:', error);
|
|
16
|
+
this.cleanup('uncaughtException');
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
cleanup(signal) {
|
|
20
|
+
console.log(`\nCleaning up processes (signal: ${signal})...`);
|
|
21
|
+
this.processes.forEach((proc) => {
|
|
22
|
+
if (!proc.killed) {
|
|
23
|
+
proc.kill('SIGTERM');
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
this.processes.clear();
|
|
27
|
+
process.exit();
|
|
28
|
+
}
|
|
29
|
+
trackProcess(proc) {
|
|
30
|
+
this.processes.add(proc);
|
|
31
|
+
proc.on('exit', () => {
|
|
32
|
+
this.processes.delete(proc);
|
|
33
|
+
});
|
|
34
|
+
proc.on('error', (error) => {
|
|
35
|
+
initProcessCatchErrorLogger('ProcessManager.trackProcess', error);
|
|
36
|
+
this.processes.delete(proc);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
getRunningProcessesCount() {
|
|
40
|
+
return this.processes.size;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const processManager = ProcessManager.getInstance();
|
|
44
|
+
export { processManager };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { execSync, spawn } from 'child_process';
|
|
2
|
+
import { consoleColorize } from '../index.mjs';
|
|
3
|
+
import { processManager } from './process-manager.mjs';
|
|
4
|
+
function initProcessCatchErrorLogger(commandName, error, commandParam) {
|
|
5
|
+
const commandParamLog = commandParam ? ` ${commandParam} ` : ' ';
|
|
6
|
+
if (error instanceof Error) {
|
|
7
|
+
// Log
|
|
8
|
+
console.error(consoleColorize('BRIGHT_RED', `[mainset cli][${commandName}]${commandParamLog}Failed:`), error.message);
|
|
9
|
+
// Exit
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
// Log
|
|
14
|
+
console.error(consoleColorize('BRIGHT_RED', `[mainset cli][${commandName}]${commandParamLog}Failed with an unknown error:`), error);
|
|
15
|
+
// Exit
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Executes a short-lived command synchronously.
|
|
21
|
+
* The entire command string, including its arguments, must be passed.
|
|
22
|
+
*
|
|
23
|
+
* Example: execImmediateCommand('rspack --config ./config/rspack.config.ts');
|
|
24
|
+
*/
|
|
25
|
+
function execImmediateCommand(fullCommandString) {
|
|
26
|
+
try {
|
|
27
|
+
execSync(fullCommandString, { stdio: 'inherit' });
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
initProcessCatchErrorLogger('execImmediateCommand', error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Runs a long-lived streaming command asynchronously.
|
|
35
|
+
* The command and its arguments must be passed separately.
|
|
36
|
+
*
|
|
37
|
+
* Example: runStreamingCommand('rspack', ['serve', '--config', './config/rspack.config.ts']);
|
|
38
|
+
*/
|
|
39
|
+
function runStreamingCommand(command, args) {
|
|
40
|
+
try {
|
|
41
|
+
const child = spawn(command, args, {
|
|
42
|
+
stdio: 'inherit',
|
|
43
|
+
shell: true,
|
|
44
|
+
});
|
|
45
|
+
// Track the process using ProcessManager as it could live in the background after crashing
|
|
46
|
+
// Examples: server stacks when files removed while server is running
|
|
47
|
+
// 1. rm -rf ./dist
|
|
48
|
+
// 2. rm -rf ./node_modules
|
|
49
|
+
processManager.trackProcess(child);
|
|
50
|
+
child.on('exit', (code) => process.exit(code !== null && code !== void 0 ? code : 1));
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
initProcessCatchErrorLogger('runStreamingCommand', error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export { execImmediateCommand, initProcessCatchErrorLogger, runStreamingCommand, };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { NODE_ENV } from '../runtime/index.mjs';
|
|
2
|
+
import { consoleColorize } from './console-colorize.mjs';
|
|
3
|
+
function verifyOrSetNodeEnv() {
|
|
4
|
+
if (!process.env.NODE_ENV) {
|
|
5
|
+
console.warn(consoleColorize('BRIGHT_YELLOW', `[mainset cli] NODE_ENV is not set. Falling back to "${NODE_ENV.PRODUCTION}".`));
|
|
6
|
+
process.env.NODE_ENV = NODE_ENV.PRODUCTION;
|
|
7
|
+
}
|
|
8
|
+
else if (!Object.values(NODE_ENV).includes(process.env.NODE_ENV)) {
|
|
9
|
+
console.warn(consoleColorize('BRIGHT_YELLOW', `[mainset cli] Unsupported NODE_ENV "${process.env.NODE_ENV}". Falling back to "${NODE_ENV.PRODUCTION}".`));
|
|
10
|
+
process.env.NODE_ENV = NODE_ENV.PRODUCTION;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export { verifyOrSetNodeEnv };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare function execTypeScriptCompileSourceCode({ configPath, }: {
|
|
2
|
+
configPath: string;
|
|
3
|
+
}): Promise<void>;
|
|
4
|
+
declare function runTypeScriptCompileSourceCode({ configPath, }: {
|
|
5
|
+
configPath: string;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
declare function execTypeScriptCompileTypeOnly(): Promise<void>;
|
|
8
|
+
declare function runTypeScriptCompileTypeOnly(): Promise<void>;
|
|
9
|
+
export { execTypeScriptCompileSourceCode, execTypeScriptCompileTypeOnly, runTypeScriptCompileSourceCode, runTypeScriptCompileTypeOnly, };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare function resolveHostPackageNodeModulesPath(hostPackageName: string, dependencyPackageName: string): string;
|
|
2
|
+
declare function resolveHostPackageBinForCLICommandPath(hostPackageName: string, dependencyPackageName: string, cliCommandName?: string): Promise<string>;
|
|
3
|
+
export { resolveHostPackageBinForCLICommandPath, resolveHostPackageNodeModulesPath, };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Express } from 'express';
|
|
2
|
+
interface ServeStaticConfig {
|
|
3
|
+
rootPath?: string;
|
|
4
|
+
publicPath?: string;
|
|
5
|
+
}
|
|
6
|
+
interface ExpressBaseAppConfig {
|
|
7
|
+
listenPort?: number;
|
|
8
|
+
serveStatics?: ServeStaticConfig[];
|
|
9
|
+
}
|
|
10
|
+
declare class ExpressBaseApp {
|
|
11
|
+
private readonly listenPort;
|
|
12
|
+
readonly app: Express;
|
|
13
|
+
constructor(customExpressConfig?: Partial<ExpressBaseAppConfig>);
|
|
14
|
+
private appUseStatic;
|
|
15
|
+
startListening(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export { ExpressBaseApp };
|
|
18
|
+
export type { ExpressBaseAppConfig };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { SSRConfigParams } from './ssr-server-config-loader.mjs';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ExpressBaseAppConfig } from '../express-base-app/index.mjs';
|
|
2
|
+
interface SSRConfigParams extends Partial<ExpressBaseAppConfig> {
|
|
3
|
+
renderSSRContentByPath: Record<string, // URL path to render SSR content
|
|
4
|
+
(_params: {
|
|
5
|
+
reqUrl: string;
|
|
6
|
+
fullUrl: string;
|
|
7
|
+
}) => Promise<string>>;
|
|
8
|
+
}
|
|
9
|
+
declare const ssrServerConfig: SSRConfigParams;
|
|
10
|
+
export { ssrServerConfig };
|
|
11
|
+
export type { SSRConfigParams };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare const TERMINAL_COLOR__BY_KEY: {
|
|
2
|
+
readonly RESET: "\u001B[0m";
|
|
3
|
+
readonly RED: "\u001B[31m";
|
|
4
|
+
readonly GREEN: "\u001B[32m";
|
|
5
|
+
readonly YELLOW: "\u001B[33m";
|
|
6
|
+
readonly BLUE: "\u001B[34m";
|
|
7
|
+
readonly BRIGHT_RED: "\u001B[91m";
|
|
8
|
+
readonly BRIGHT_GREEN: "\u001B[92m";
|
|
9
|
+
readonly BRIGHT_YELLOW: "\u001B[93m";
|
|
10
|
+
};
|
|
11
|
+
declare const consoleColorize: (color: keyof typeof TERMINAL_COLOR__BY_KEY, text: string) => string;
|
|
12
|
+
export { consoleColorize };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './process-runner.mjs';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ChildProcess } from 'child_process';
|
|
2
|
+
declare class ProcessManager {
|
|
3
|
+
private static instance;
|
|
4
|
+
private processes;
|
|
5
|
+
private constructor();
|
|
6
|
+
static getInstance(): ProcessManager;
|
|
7
|
+
private setupCleanupHandlers;
|
|
8
|
+
private cleanup;
|
|
9
|
+
trackProcess(proc: ChildProcess): void;
|
|
10
|
+
getRunningProcessesCount(): number;
|
|
11
|
+
}
|
|
12
|
+
declare const processManager: ProcessManager;
|
|
13
|
+
export { processManager };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare function initProcessCatchErrorLogger(commandName: string, error: Error | unknown, commandParam?: string): void;
|
|
2
|
+
/**
|
|
3
|
+
* Executes a short-lived command synchronously.
|
|
4
|
+
* The entire command string, including its arguments, must be passed.
|
|
5
|
+
*
|
|
6
|
+
* Example: execImmediateCommand('rspack --config ./config/rspack.config.ts');
|
|
7
|
+
*/
|
|
8
|
+
declare function execImmediateCommand(fullCommandString: string): void;
|
|
9
|
+
/**
|
|
10
|
+
* Runs a long-lived streaming command asynchronously.
|
|
11
|
+
* The command and its arguments must be passed separately.
|
|
12
|
+
*
|
|
13
|
+
* Example: runStreamingCommand('rspack', ['serve', '--config', './config/rspack.config.ts']);
|
|
14
|
+
*/
|
|
15
|
+
declare function runStreamingCommand(command: string, args: string[]): void;
|
|
16
|
+
export { execImmediateCommand, initProcessCatchErrorLogger, runStreamingCommand, };
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mainset/cli",
|
|
3
|
+
"version": "0.1.0-rc.1",
|
|
4
|
+
"description": "A unified CLI tool for accelerating development, based on mainset vision of front-end infrastructure",
|
|
5
|
+
"homepage": "https://github.com/mainset/dev-stack-fe/tree/main/packages/cli",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/mainset/dev-stack-fe/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/mainset/dev-stack-fe.git"
|
|
12
|
+
},
|
|
13
|
+
"license": "CC-BY-NC-4.0",
|
|
14
|
+
"author": "yevhen uzhva",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"exports": {
|
|
21
|
+
"./runtime": {
|
|
22
|
+
"types": "./dist/types/runtime/index.d.mts",
|
|
23
|
+
"import": "./dist/esm/runtime/index.mjs"
|
|
24
|
+
},
|
|
25
|
+
"./process-env-type": "./dist/types/@types/process.env.d.ts",
|
|
26
|
+
"./ssr-server": {
|
|
27
|
+
"types": "./dist/types/services/ssr-server/index.d.mts"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"bin": {
|
|
31
|
+
"ms-cli": "./dist/esm/mainset-cli.mjs"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@types/node": "^24.0.3",
|
|
35
|
+
"commander": "^14.0.0",
|
|
36
|
+
"cors": "^2.8.5",
|
|
37
|
+
"cross-env": "^7.0.3",
|
|
38
|
+
"express": "^5.1.0",
|
|
39
|
+
"http-proxy-middleware": "^3.0.5"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/cors": "^2.8.19",
|
|
43
|
+
"@types/express": "^5.0.3",
|
|
44
|
+
"@types/node": "^24.0.3",
|
|
45
|
+
"@mainset/dev-stack-fe": "^0.1.0-rc.1"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@mainset/dev-stack-fe": "0.1.0"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build:source": "node ./node_modules/@mainset/dev-stack-fe/node_modules/typescript/bin/tsc --project ./tsconfig.json",
|
|
52
|
+
"build:type": "node ./node_modules/@mainset/dev-stack-fe/node_modules/typescript/bin/tsc --project ./tsconfig.build-type.json",
|
|
53
|
+
"build": "npm run purge:dist && npm run build:source && npm run build:type",
|
|
54
|
+
"dev": "cross-env NODE_ENV=development npm run build && node ./dist/esm/mainset-cli.mjs source-code --exec watch",
|
|
55
|
+
"purge:dist": "rm -rf ./dist"
|
|
56
|
+
}
|
|
57
|
+
}
|