@codemoreira/esad 1.3.6 → 1.3.8
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/bin/esad.js +88 -76
- package/package.json +4 -2
- package/src/cli/commands/build.js +53 -0
- package/src/cli/commands/deploy.js +31 -3
package/bin/esad.js
CHANGED
|
@@ -1,77 +1,89 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const { program } = require('commander');
|
|
4
|
-
const pkg = require('../package.json');
|
|
5
|
-
|
|
6
|
-
// Import Commands
|
|
7
|
-
const initCommand = require('../src/cli/commands/init');
|
|
8
|
-
const createModuleCommand = require('../src/cli/commands/createModule');
|
|
9
|
-
const createCdnCommand = require('../src/cli/commands/createCdn');
|
|
10
|
-
const deployCommand = require('../src/cli/commands/deploy');
|
|
11
|
-
const devCommand = require('../src/cli/commands/dev');
|
|
12
|
-
const hostCommand = require('../src/cli/commands/host');
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
.
|
|
22
|
-
.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.
|
|
31
|
-
.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
.
|
|
49
|
-
.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
.
|
|
58
|
-
.option('-i, --id <moduleId>', 'The Module ID to
|
|
59
|
-
.option('-
|
|
60
|
-
.description('
|
|
61
|
-
.action(async (options) => {
|
|
62
|
-
await
|
|
63
|
-
process.exit(0);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// --- COMMAND: esad
|
|
67
|
-
program
|
|
68
|
-
.command('
|
|
69
|
-
.option('-
|
|
70
|
-
.option('-
|
|
71
|
-
.
|
|
72
|
-
.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
2
|
+
|
|
3
|
+
const { program } = require('commander');
|
|
4
|
+
const pkg = require('../package.json');
|
|
5
|
+
|
|
6
|
+
// Import Commands
|
|
7
|
+
const initCommand = require('../src/cli/commands/init');
|
|
8
|
+
const createModuleCommand = require('../src/cli/commands/createModule');
|
|
9
|
+
const createCdnCommand = require('../src/cli/commands/createCdn');
|
|
10
|
+
const deployCommand = require('../src/cli/commands/deploy');
|
|
11
|
+
const devCommand = require('../src/cli/commands/dev');
|
|
12
|
+
const hostCommand = require('../src/cli/commands/host');
|
|
13
|
+
const buildCommand = require('../src/cli/commands/build');
|
|
14
|
+
|
|
15
|
+
program
|
|
16
|
+
.version(pkg.version)
|
|
17
|
+
.description('esad - Easy Super App Development Toolkit');
|
|
18
|
+
|
|
19
|
+
// --- COMMMAND: esad init ---
|
|
20
|
+
program
|
|
21
|
+
.command('init <project-name>')
|
|
22
|
+
.description('Scaffold a new ESAD workspace containing the Host App')
|
|
23
|
+
.action(async (name) => {
|
|
24
|
+
await initCommand(name);
|
|
25
|
+
process.exit(0);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// --- COMMAND: esad create-cdn ---
|
|
29
|
+
program
|
|
30
|
+
.command('create-cdn [cdn-name]')
|
|
31
|
+
.description('Scaffold the CDN / Registry backend')
|
|
32
|
+
.action(async (name) => {
|
|
33
|
+
await createCdnCommand(name);
|
|
34
|
+
process.exit(0);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// --- COMMAND: esad host ---
|
|
38
|
+
program
|
|
39
|
+
.command('host <subcommand>')
|
|
40
|
+
.description('Manage the Host App (dev, android, ios)')
|
|
41
|
+
.action(async (sub) => {
|
|
42
|
+
await hostCommand(sub);
|
|
43
|
+
process.exit(0);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// --- COMMAND: esad create-module ---
|
|
47
|
+
program
|
|
48
|
+
.command('create-module <module-name>')
|
|
49
|
+
.description('Scaffold a React Native mini-app automatically configured for Module Federation via ESAD')
|
|
50
|
+
.action(async (name) => {
|
|
51
|
+
await createModuleCommand(name);
|
|
52
|
+
process.exit(0);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// --- COMMAND: esad build ---
|
|
56
|
+
program
|
|
57
|
+
.command('build')
|
|
58
|
+
.option('-i, --id <moduleId>', 'The Module ID to build')
|
|
59
|
+
.option('-p, --platform <platform>', 'Platform to build for (android, ios)', 'android')
|
|
60
|
+
.description('Builds a production bundle for the host or a specific module')
|
|
61
|
+
.action(async (options) => {
|
|
62
|
+
await buildCommand(options);
|
|
63
|
+
process.exit(0);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// --- COMMAND: esad deploy ---
|
|
67
|
+
program
|
|
68
|
+
.command('deploy')
|
|
69
|
+
.option('-v, --version <semver>', 'Version number (e.g., 1.0.0)')
|
|
70
|
+
.option('-i, --id <moduleId>', 'The Module ID to deploy')
|
|
71
|
+
.option('-e, --entry <entryFileName>', 'The name of the main entry bundle (e.g., index.bundle)', 'index.bundle')
|
|
72
|
+
.description('Zips the local dist directory and uploads it to the configured deployment endpoint')
|
|
73
|
+
.action(async (options) => {
|
|
74
|
+
await deployCommand(options);
|
|
75
|
+
process.exit(0);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// --- COMMAND: esad dev ---
|
|
79
|
+
program
|
|
80
|
+
.command('dev')
|
|
81
|
+
.option('-i, --id <moduleId>', 'The Module ID to run in dev mode')
|
|
82
|
+
.option('-p, --port <port>', 'The port to run the dev server on', '8081')
|
|
83
|
+
.description('Starts the dev server and updates the external registry to bypass CDN')
|
|
84
|
+
.action(async (options) => {
|
|
85
|
+
await devCommand(options);
|
|
86
|
+
// Note: dev command has its own shutdown logic with SIGINT/SIGTERM
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemoreira/esad",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.8",
|
|
4
4
|
"description": "Easy Super App Development - Zero-Config CLI and DevTools for React Native Module Federation",
|
|
5
5
|
"main": "src/plugin/index.js",
|
|
6
6
|
"types": "./src/plugin/index.d.ts",
|
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
"chalk": "^4.1.2",
|
|
35
35
|
"commander": "^11.1.0",
|
|
36
36
|
"cross-spawn": "^7.0.3",
|
|
37
|
-
"
|
|
37
|
+
"form-data": "^4.0.0",
|
|
38
|
+
"fs-extra": "^11.2.0",
|
|
39
|
+
"node-fetch": "^2.7.0"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
40
42
|
"@rspack/core": "^1.7.9",
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const { runProcess } = require('../utils/process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const { getWorkspaceConfig } = require('../utils/config');
|
|
6
|
+
const { resolveProjectDir, listAvailableModules } = require('../utils/resolution');
|
|
7
|
+
|
|
8
|
+
module.exports = async (options) => {
|
|
9
|
+
let cwd = process.cwd();
|
|
10
|
+
|
|
11
|
+
// Enforce Workspace Root
|
|
12
|
+
const configObj = getWorkspaceConfig();
|
|
13
|
+
if (!configObj) {
|
|
14
|
+
console.error(chalk.red(`❌ Error: Call this command from the project root (esad.config.json not found).`));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const { projectName } = configObj.data;
|
|
19
|
+
|
|
20
|
+
if (options.id) {
|
|
21
|
+
const targetDir = resolveProjectDir(options.id, configObj);
|
|
22
|
+
if (!targetDir) {
|
|
23
|
+
console.error(chalk.red(`\n❌ Error: Module not found: ${options.id}`));
|
|
24
|
+
listAvailableModules(configObj);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
cwd = targetDir;
|
|
28
|
+
} else {
|
|
29
|
+
// Build host by default if in root
|
|
30
|
+
const hostDir = path.join(path.dirname(configObj.path), `${projectName}-host`);
|
|
31
|
+
if (fs.existsSync(hostDir)) cwd = hostDir;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const platform = options.platform || 'android';
|
|
35
|
+
|
|
36
|
+
console.log(`\n🏗️ Building production bundle for ${path.basename(cwd)} (${platform})...\n`);
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
// Run Re.Pack production build
|
|
40
|
+
await runProcess('npx', [
|
|
41
|
+
'react-native',
|
|
42
|
+
'webpack-bundle',
|
|
43
|
+
'--platform', platform,
|
|
44
|
+
'--dev', 'false'
|
|
45
|
+
], cwd);
|
|
46
|
+
|
|
47
|
+
console.log(chalk.green(`\n✅ Build complete! Assets generated in dist/ directory.`));
|
|
48
|
+
console.log(`👉 You can now run: esad deploy ${options.id ? `--id ${options.id}` : ''}\n`);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
console.error(chalk.red(`\n❌ Build failed: ${err.message}`));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
@@ -74,8 +74,36 @@ module.exports = async (options) => {
|
|
|
74
74
|
console.log(`🗜️ Zipped output to ${zipPath}`);
|
|
75
75
|
|
|
76
76
|
console.log(`🚀 Uploading to CDN via multipart POST...`);
|
|
77
|
-
// Note: Here we would use form-data + fetch or axios to upload to Simple CDN
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
try {
|
|
79
|
+
const FormData = require('form-data'); // Standard in Node versions, or use native if available
|
|
80
|
+
const form = new FormData();
|
|
81
|
+
form.append('version', version);
|
|
82
|
+
form.append('bundle', fs.createReadStream(zipPath));
|
|
83
|
+
|
|
84
|
+
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
|
|
85
|
+
|
|
86
|
+
// Simple CDN expects POST /api/admin/assets/:id/versions
|
|
87
|
+
const uploadUrl = deployUrl.includes('/versions') ? deployUrl : `${deployUrl}/versions`;
|
|
88
|
+
|
|
89
|
+
const response = await fetch(uploadUrl, {
|
|
90
|
+
method: 'POST',
|
|
91
|
+
body: form,
|
|
92
|
+
headers: form.getHeaders(),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (response.ok) {
|
|
96
|
+
const result = await response.json();
|
|
97
|
+
console.log(chalk.green(`✅ Successfully uploaded ${moduleId} v${version} to CDN!`));
|
|
98
|
+
console.log(`📄 Active Version is now: ${result.active_version}`);
|
|
99
|
+
} else {
|
|
100
|
+
const errorText = await response.text();
|
|
101
|
+
console.error(chalk.red(`❌ Failed to upload: ${response.status} ${response.statusText}`));
|
|
102
|
+
console.error(errorText);
|
|
103
|
+
}
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error(chalk.red(`❌ Error during upload: ${err.message}`));
|
|
106
|
+
} finally {
|
|
107
|
+
fs.unlinkSync(zipPath);
|
|
108
|
+
}
|
|
81
109
|
};
|