easybuild-nox 1.0.0
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 +21 -0
- package/README.md +405 -0
- package/bin/easy.js +71 -0
- package/easy.config.js +58 -0
- package/package.json +69 -0
- package/src/commands/analyze.js +203 -0
- package/src/commands/build.js +80 -0
- package/src/commands/clean.js +109 -0
- package/src/commands/config.js +104 -0
- package/src/commands/db.js +423 -0
- package/src/commands/deploy.js +203 -0
- package/src/commands/dev.js +188 -0
- package/src/commands/docker.js +264 -0
- package/src/commands/electron.js +210 -0
- package/src/commands/env.js +302 -0
- package/src/commands/generate.js +556 -0
- package/src/commands/health.js +261 -0
- package/src/commands/info.js +139 -0
- package/src/commands/init.js +794 -0
- package/src/commands/lint.js +111 -0
- package/src/commands/modules.js +333 -0
- package/src/commands/package.js +265 -0
- package/src/commands/proxy.js +73 -0
- package/src/commands/run.js +199 -0
- package/src/commands/test.js +104 -0
- package/src/index.js +30 -0
- package/src/targets/docker.js +201 -0
- package/src/targets/electron.js +157 -0
- package/src/targets/frontend.js +391 -0
- package/src/targets/library.js +164 -0
- package/src/targets/node.js +146 -0
- package/src/utils/config.js +191 -0
- package/src/utils/detector.js +407 -0
- package/src/utils/globalConfig.js +106 -0
- package/src/utils/logger.js +98 -0
- package/src/utils/modules.js +571 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const logger = require('../utils/logger');
|
|
5
|
+
|
|
6
|
+
class ElectronBuilder {
|
|
7
|
+
constructor(projectInfo, config) {
|
|
8
|
+
this.projectInfo = projectInfo;
|
|
9
|
+
this.config = config;
|
|
10
|
+
this.outDir = config.outDir || 'release';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async build(options) {
|
|
14
|
+
logger.section('Building Electron Application');
|
|
15
|
+
|
|
16
|
+
// Ensure electron-builder config exists
|
|
17
|
+
await this.ensureConfig();
|
|
18
|
+
|
|
19
|
+
// Build for specified platforms
|
|
20
|
+
const platforms = this.getPlatforms(options.platform);
|
|
21
|
+
const arch = this.getArch(options.arch);
|
|
22
|
+
|
|
23
|
+
for (const platform of platforms) {
|
|
24
|
+
await this.buildForPlatform(platform, arch, options);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async ensureConfig() {
|
|
29
|
+
const configPath = path.join(process.cwd(), 'electron-builder.yml');
|
|
30
|
+
const configJsonPath = path.join(process.cwd(), 'electron-builder.json');
|
|
31
|
+
|
|
32
|
+
if (!(await fs.pathExists(configPath)) && !(await fs.pathExists(configJsonPath))) {
|
|
33
|
+
logger.info('Generating electron-builder configuration...');
|
|
34
|
+
|
|
35
|
+
const pkg = await fs.readJson(path.join(process.cwd(), 'package.json'));
|
|
36
|
+
const electronConfig = this.config.electron || {};
|
|
37
|
+
|
|
38
|
+
const builderConfig = {
|
|
39
|
+
appId: `com.${pkg.name || 'app'}.electron`,
|
|
40
|
+
productName: pkg.name || 'Electron App',
|
|
41
|
+
directories: {
|
|
42
|
+
output: electronConfig.output || 'release',
|
|
43
|
+
},
|
|
44
|
+
files: [
|
|
45
|
+
'electron/**/*',
|
|
46
|
+
'dist/**/*',
|
|
47
|
+
'package.json',
|
|
48
|
+
],
|
|
49
|
+
mac: {
|
|
50
|
+
category: 'public.app-category.developer-tools',
|
|
51
|
+
icon: electronConfig.icon || null,
|
|
52
|
+
target: [
|
|
53
|
+
{ target: 'dmg', arch: ['x64', 'arm64'] },
|
|
54
|
+
{ target: 'zip', arch: ['x64', 'arm64'] },
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
win: {
|
|
58
|
+
icon: electronConfig.icon || null,
|
|
59
|
+
target: [
|
|
60
|
+
{ target: 'nsis', arch: ['x64'] },
|
|
61
|
+
{ target: 'portable', arch: ['x64'] },
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
linux: {
|
|
65
|
+
icon: electronConfig.icon || null,
|
|
66
|
+
target: [
|
|
67
|
+
{ target: 'AppImage', arch: ['x64'] },
|
|
68
|
+
{ target: 'deb', arch: ['x64'] },
|
|
69
|
+
{ target: 'rpm', arch: ['x64'] },
|
|
70
|
+
],
|
|
71
|
+
category: 'Development',
|
|
72
|
+
},
|
|
73
|
+
nsis: {
|
|
74
|
+
oneClick: false,
|
|
75
|
+
allowToChangeInstallationDirectory: true,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Try to use js-yaml for YAML output
|
|
80
|
+
try {
|
|
81
|
+
const yaml = require('js-yaml');
|
|
82
|
+
await fs.writeFile(configPath, yaml.dump(builderConfig));
|
|
83
|
+
} catch {
|
|
84
|
+
// Fallback to JSON
|
|
85
|
+
await fs.writeJson(configJsonPath, builderConfig, { spaces: 2 });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
logger.success('electron-builder configuration generated');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getPlatforms(platform) {
|
|
93
|
+
if (platform === 'all' || platform === 'current') {
|
|
94
|
+
if (platform === 'current') {
|
|
95
|
+
// Build for current platform only
|
|
96
|
+
switch (process.platform) {
|
|
97
|
+
case 'win32': return ['win'];
|
|
98
|
+
case 'darwin': return ['mac'];
|
|
99
|
+
default: return ['linux'];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return ['win', 'mac', 'linux'];
|
|
103
|
+
}
|
|
104
|
+
return [platform];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
getArch(arch) {
|
|
108
|
+
if (arch === 'all') return ['x64', 'arm64'];
|
|
109
|
+
if (arch === 'current') return [process.arch === 'arm64' ? 'arm64' : 'x64'];
|
|
110
|
+
return [arch];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async buildForPlatform(platform, archList, options) {
|
|
114
|
+
logger.info(`Building for ${platform} (${archList.join(', ')})...`);
|
|
115
|
+
|
|
116
|
+
const args = ['electron-builder'];
|
|
117
|
+
|
|
118
|
+
// Platform
|
|
119
|
+
switch (platform) {
|
|
120
|
+
case 'win':
|
|
121
|
+
args.push('--win');
|
|
122
|
+
break;
|
|
123
|
+
case 'mac':
|
|
124
|
+
args.push('--mac');
|
|
125
|
+
break;
|
|
126
|
+
case 'linux':
|
|
127
|
+
args.push('--linux');
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Architecture
|
|
132
|
+
for (const a of archList) {
|
|
133
|
+
args.push(`--${a}`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Other options
|
|
137
|
+
if (options.minify === false) args.push('--config', 'minify=false');
|
|
138
|
+
|
|
139
|
+
const child = spawn('npx', args, {
|
|
140
|
+
stdio: 'inherit',
|
|
141
|
+
shell: true,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
return new Promise((resolve, reject) => {
|
|
145
|
+
child.on('close', (code) => {
|
|
146
|
+
if (code === 0) {
|
|
147
|
+
logger.success(`Build completed for ${platform}`);
|
|
148
|
+
resolve();
|
|
149
|
+
} else {
|
|
150
|
+
reject(new Error(`Build failed for ${platform}`));
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
module.exports = ElectronBuilder;
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const logger = require('../utils/logger');
|
|
5
|
+
|
|
6
|
+
class FrontendBuilder {
|
|
7
|
+
constructor(projectInfo, config) {
|
|
8
|
+
this.projectInfo = projectInfo;
|
|
9
|
+
this.config = config;
|
|
10
|
+
this.outDir = config.outDir || 'dist';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async build(options) {
|
|
14
|
+
logger.section('Building Frontend Application');
|
|
15
|
+
|
|
16
|
+
const framework = this.projectInfo.framework?.name;
|
|
17
|
+
|
|
18
|
+
switch (framework) {
|
|
19
|
+
// Vite-based
|
|
20
|
+
case 'react':
|
|
21
|
+
case 'vue':
|
|
22
|
+
case 'svelte':
|
|
23
|
+
case 'solid':
|
|
24
|
+
case 'preact':
|
|
25
|
+
case 'lit':
|
|
26
|
+
case 'alpine':
|
|
27
|
+
case 'htmx':
|
|
28
|
+
await this.buildWithVite(options);
|
|
29
|
+
break;
|
|
30
|
+
|
|
31
|
+
// Angular
|
|
32
|
+
case 'angular':
|
|
33
|
+
await this.buildWithAngular(options);
|
|
34
|
+
break;
|
|
35
|
+
|
|
36
|
+
// Full-stack frameworks
|
|
37
|
+
case 'nextjs':
|
|
38
|
+
await this.buildNextjs(options);
|
|
39
|
+
break;
|
|
40
|
+
case 'nuxt':
|
|
41
|
+
await this.buildNuxt(options);
|
|
42
|
+
break;
|
|
43
|
+
case 'remix':
|
|
44
|
+
await this.buildRemix(options);
|
|
45
|
+
break;
|
|
46
|
+
case 'gatsby':
|
|
47
|
+
await this.buildGatsby(options);
|
|
48
|
+
break;
|
|
49
|
+
case 'astro':
|
|
50
|
+
await this.buildAstro(options);
|
|
51
|
+
break;
|
|
52
|
+
case 'sveltekit':
|
|
53
|
+
await this.buildSvelteKit(options);
|
|
54
|
+
break;
|
|
55
|
+
case 'solidstart':
|
|
56
|
+
await this.buildSolidStart(options);
|
|
57
|
+
break;
|
|
58
|
+
case 'qwik':
|
|
59
|
+
await this.buildQwik(options);
|
|
60
|
+
break;
|
|
61
|
+
case 'analog':
|
|
62
|
+
await this.buildAnalog(options);
|
|
63
|
+
break;
|
|
64
|
+
case 'fresh':
|
|
65
|
+
await this.buildFresh(options);
|
|
66
|
+
break;
|
|
67
|
+
case 'tanstack':
|
|
68
|
+
await this.buildTanStack(options);
|
|
69
|
+
break;
|
|
70
|
+
case 'waku':
|
|
71
|
+
await this.buildWaku(options);
|
|
72
|
+
break;
|
|
73
|
+
|
|
74
|
+
default:
|
|
75
|
+
await this.buildWithVite(options);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async buildWithVite(options) {
|
|
80
|
+
logger.info('Building with Vite...');
|
|
81
|
+
|
|
82
|
+
const args = ['vite', 'build'];
|
|
83
|
+
|
|
84
|
+
const child = spawn('npx', args, {
|
|
85
|
+
stdio: 'inherit',
|
|
86
|
+
shell: true,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
child.on('close', (code) => {
|
|
91
|
+
if (code === 0) {
|
|
92
|
+
logger.success('Build completed with Vite');
|
|
93
|
+
resolve();
|
|
94
|
+
} else {
|
|
95
|
+
reject(new Error('Vite build failed'));
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async buildWithAngular(options) {
|
|
102
|
+
logger.info('Building with Angular CLI...');
|
|
103
|
+
|
|
104
|
+
const args = ['ng', 'build', '--configuration', 'production'];
|
|
105
|
+
|
|
106
|
+
const child = spawn('npx', args, {
|
|
107
|
+
stdio: 'inherit',
|
|
108
|
+
shell: true,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return new Promise((resolve, reject) => {
|
|
112
|
+
child.on('close', (code) => {
|
|
113
|
+
if (code === 0) {
|
|
114
|
+
logger.success('Build completed with Angular');
|
|
115
|
+
resolve();
|
|
116
|
+
} else {
|
|
117
|
+
reject(new Error('Angular build failed'));
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async buildNextjs(options) {
|
|
124
|
+
logger.info('Building Next.js application...');
|
|
125
|
+
|
|
126
|
+
const args = ['next', 'build'];
|
|
127
|
+
|
|
128
|
+
const child = spawn('npx', args, {
|
|
129
|
+
stdio: 'inherit',
|
|
130
|
+
shell: true,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
child.on('close', (code) => {
|
|
135
|
+
if (code === 0) {
|
|
136
|
+
logger.success('Build completed with Next.js');
|
|
137
|
+
resolve();
|
|
138
|
+
} else {
|
|
139
|
+
reject(new Error('Next.js build failed'));
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async buildNuxt(options) {
|
|
146
|
+
logger.info('Building Nuxt application...');
|
|
147
|
+
|
|
148
|
+
const pkg = await fs.readJson(path.join(process.cwd(), 'package.json'));
|
|
149
|
+
const hasNuxt3 = pkg.devDependencies?.nuxt?.startsWith('3') || pkg.dependencies?.nuxt?.startsWith('3');
|
|
150
|
+
|
|
151
|
+
const args = hasNuxt3 ? ['nuxt', 'build'] : ['nuxt', 'generate'];
|
|
152
|
+
|
|
153
|
+
const child = spawn('npx', args, {
|
|
154
|
+
stdio: 'inherit',
|
|
155
|
+
shell: true,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
return new Promise((resolve, reject) => {
|
|
159
|
+
child.on('close', (code) => {
|
|
160
|
+
if (code === 0) {
|
|
161
|
+
logger.success('Build completed with Nuxt');
|
|
162
|
+
resolve();
|
|
163
|
+
} else {
|
|
164
|
+
reject(new Error('Nuxt build failed'));
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async buildRemix(options) {
|
|
171
|
+
logger.info('Building Remix application...');
|
|
172
|
+
|
|
173
|
+
const args = ['remix', 'build'];
|
|
174
|
+
|
|
175
|
+
const child = spawn('npx', args, {
|
|
176
|
+
stdio: 'inherit',
|
|
177
|
+
shell: true,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
return new Promise((resolve, reject) => {
|
|
181
|
+
child.on('close', (code) => {
|
|
182
|
+
if (code === 0) {
|
|
183
|
+
logger.success('Build completed with Remix');
|
|
184
|
+
resolve();
|
|
185
|
+
} else {
|
|
186
|
+
reject(new Error('Remix build failed'));
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async buildGatsby(options) {
|
|
193
|
+
logger.info('Building Gatsby application...');
|
|
194
|
+
|
|
195
|
+
const args = ['gatsby', 'build'];
|
|
196
|
+
|
|
197
|
+
const child = spawn('npx', args, {
|
|
198
|
+
stdio: 'inherit',
|
|
199
|
+
shell: true,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
return new Promise((resolve, reject) => {
|
|
203
|
+
child.on('close', (code) => {
|
|
204
|
+
if (code === 0) {
|
|
205
|
+
logger.success('Build completed with Gatsby');
|
|
206
|
+
resolve();
|
|
207
|
+
} else {
|
|
208
|
+
reject(new Error('Gatsby build failed'));
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async buildAstro(options) {
|
|
215
|
+
logger.info('Building Astro application...');
|
|
216
|
+
|
|
217
|
+
const args = ['astro', 'build'];
|
|
218
|
+
|
|
219
|
+
const child = spawn('npx', args, {
|
|
220
|
+
stdio: 'inherit',
|
|
221
|
+
shell: true,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
return new Promise((resolve, reject) => {
|
|
225
|
+
child.on('close', (code) => {
|
|
226
|
+
if (code === 0) {
|
|
227
|
+
logger.success('Build completed with Astro');
|
|
228
|
+
resolve();
|
|
229
|
+
} else {
|
|
230
|
+
reject(new Error('Astro build failed'));
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async buildSvelteKit(options) {
|
|
237
|
+
logger.info('Building SvelteKit application...');
|
|
238
|
+
|
|
239
|
+
const args = ['svelte-kit', 'build'];
|
|
240
|
+
|
|
241
|
+
const child = spawn('npx', args, {
|
|
242
|
+
stdio: 'inherit',
|
|
243
|
+
shell: true,
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return new Promise((resolve, reject) => {
|
|
247
|
+
child.on('close', (code) => {
|
|
248
|
+
if (code === 0) {
|
|
249
|
+
logger.success('Build completed with SvelteKit');
|
|
250
|
+
resolve();
|
|
251
|
+
} else {
|
|
252
|
+
reject(new Error('SvelteKit build failed'));
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async buildSolidStart(options) {
|
|
259
|
+
logger.info('Building SolidStart application...');
|
|
260
|
+
|
|
261
|
+
const args = ['solid-start', 'build'];
|
|
262
|
+
|
|
263
|
+
const child = spawn('npx', args, {
|
|
264
|
+
stdio: 'inherit',
|
|
265
|
+
shell: true,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
return new Promise((resolve, reject) => {
|
|
269
|
+
child.on('close', (code) => {
|
|
270
|
+
if (code === 0) {
|
|
271
|
+
logger.success('Build completed with SolidStart');
|
|
272
|
+
resolve();
|
|
273
|
+
} else {
|
|
274
|
+
reject(new Error('SolidStart build failed'));
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
async buildQwik(options) {
|
|
281
|
+
logger.info('Building Qwik application...');
|
|
282
|
+
|
|
283
|
+
const args = ['qwik', 'build'];
|
|
284
|
+
|
|
285
|
+
const child = spawn('npx', args, {
|
|
286
|
+
stdio: 'inherit',
|
|
287
|
+
shell: true,
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
return new Promise((resolve, reject) => {
|
|
291
|
+
child.on('close', (code) => {
|
|
292
|
+
if (code === 0) {
|
|
293
|
+
logger.success('Build completed with Qwik');
|
|
294
|
+
resolve();
|
|
295
|
+
} else {
|
|
296
|
+
reject(new Error('Qwik build failed'));
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
async buildAnalog(options) {
|
|
303
|
+
logger.info('Building Analog application...');
|
|
304
|
+
|
|
305
|
+
const args = ['ng', 'build'];
|
|
306
|
+
|
|
307
|
+
const child = spawn('npx', args, {
|
|
308
|
+
stdio: 'inherit',
|
|
309
|
+
shell: true,
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
return new Promise((resolve, reject) => {
|
|
313
|
+
child.on('close', (code) => {
|
|
314
|
+
if (code === 0) {
|
|
315
|
+
logger.success('Build completed with Analog');
|
|
316
|
+
resolve();
|
|
317
|
+
} else {
|
|
318
|
+
reject(new Error('Analog build failed'));
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
async buildFresh(options) {
|
|
325
|
+
logger.info('Building Fresh application...');
|
|
326
|
+
|
|
327
|
+
const args = ['deno', 'task', 'build'];
|
|
328
|
+
|
|
329
|
+
const child = spawn('npx', args, {
|
|
330
|
+
stdio: 'inherit',
|
|
331
|
+
shell: true,
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
return new Promise((resolve, reject) => {
|
|
335
|
+
child.on('close', (code) => {
|
|
336
|
+
if (code === 0) {
|
|
337
|
+
logger.success('Build completed with Fresh');
|
|
338
|
+
resolve();
|
|
339
|
+
} else {
|
|
340
|
+
reject(new Error('Fresh build failed'));
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async buildTanStack(options) {
|
|
347
|
+
logger.info('Building TanStack application...');
|
|
348
|
+
|
|
349
|
+
const args = ['tanstack-start', 'build'];
|
|
350
|
+
|
|
351
|
+
const child = spawn('npx', args, {
|
|
352
|
+
stdio: 'inherit',
|
|
353
|
+
shell: true,
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
return new Promise((resolve, reject) => {
|
|
357
|
+
child.on('close', (code) => {
|
|
358
|
+
if (code === 0) {
|
|
359
|
+
logger.success('Build completed with TanStack');
|
|
360
|
+
resolve();
|
|
361
|
+
} else {
|
|
362
|
+
reject(new Error('TanStack build failed'));
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
async buildWaku(options) {
|
|
369
|
+
logger.info('Building Waku application...');
|
|
370
|
+
|
|
371
|
+
const args = ['waku', 'build'];
|
|
372
|
+
|
|
373
|
+
const child = spawn('npx', args, {
|
|
374
|
+
stdio: 'inherit',
|
|
375
|
+
shell: true,
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
return new Promise((resolve, reject) => {
|
|
379
|
+
child.on('close', (code) => {
|
|
380
|
+
if (code === 0) {
|
|
381
|
+
logger.success('Build completed with Waku');
|
|
382
|
+
resolve();
|
|
383
|
+
} else {
|
|
384
|
+
reject(new Error('Waku build failed'));
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
module.exports = FrontendBuilder;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const logger = require('../utils/logger');
|
|
5
|
+
|
|
6
|
+
class LibraryBuilder {
|
|
7
|
+
constructor(projectInfo, config) {
|
|
8
|
+
this.projectInfo = projectInfo;
|
|
9
|
+
this.config = config;
|
|
10
|
+
this.outDir = config.outDir || 'dist';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async build(options) {
|
|
14
|
+
logger.section('Building Library');
|
|
15
|
+
|
|
16
|
+
// Check if TypeScript project
|
|
17
|
+
if (this.projectInfo.isTypeScript) {
|
|
18
|
+
await this.buildTypeScript(options);
|
|
19
|
+
} else {
|
|
20
|
+
await this.buildJavaScript(options);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async buildTypeScript(options) {
|
|
25
|
+
logger.info('Building TypeScript library...');
|
|
26
|
+
|
|
27
|
+
// Check for tsconfig.json
|
|
28
|
+
const tsconfigPath = path.join(process.cwd(), 'tsconfig.json');
|
|
29
|
+
if (!(await fs.pathExists(tsconfigPath))) {
|
|
30
|
+
logger.info('Generating tsconfig.json...');
|
|
31
|
+
await this.generateTsConfig();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const args = ['tsc'];
|
|
35
|
+
|
|
36
|
+
if (options.sourcemap) args.push('--sourceMap');
|
|
37
|
+
if (options.watch) args.push('--watch');
|
|
38
|
+
|
|
39
|
+
const child = spawn('npx', args, {
|
|
40
|
+
stdio: 'inherit',
|
|
41
|
+
shell: true,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
child.on('close', (code) => {
|
|
46
|
+
if (code === 0) {
|
|
47
|
+
logger.success('TypeScript build completed');
|
|
48
|
+
resolve();
|
|
49
|
+
} else {
|
|
50
|
+
reject(new Error('TypeScript build failed'));
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async buildJavaScript(options) {
|
|
57
|
+
logger.info('Building JavaScript library...');
|
|
58
|
+
|
|
59
|
+
const pkg = await fs.readJson(path.join(process.cwd(), 'package.json'));
|
|
60
|
+
const entryPoint = this.config.entry || pkg.main || 'src/index.js';
|
|
61
|
+
|
|
62
|
+
// Use esbuild for JavaScript
|
|
63
|
+
const args = [
|
|
64
|
+
'esbuild',
|
|
65
|
+
entryPoint,
|
|
66
|
+
'--bundle',
|
|
67
|
+
'--platform=node',
|
|
68
|
+
'--target=node18',
|
|
69
|
+
`--outdir=${options.outDir || this.outDir}`,
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
if (options.minify) args.push('--minify');
|
|
73
|
+
if (options.sourcemap) args.push('--sourcemap');
|
|
74
|
+
|
|
75
|
+
// Generate multiple formats
|
|
76
|
+
await this.buildFormat(entryPoint, 'cjs', options);
|
|
77
|
+
await this.buildFormat(entryPoint, 'esm', options);
|
|
78
|
+
|
|
79
|
+
// Generate package.json for exports
|
|
80
|
+
await this.generateExports(pkg);
|
|
81
|
+
|
|
82
|
+
logger.success('JavaScript build completed');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async buildFormat(entryPoint, format, options) {
|
|
86
|
+
const outDir = path.join(options.outDir || this.outDir, format);
|
|
87
|
+
|
|
88
|
+
const args = [
|
|
89
|
+
'esbuild',
|
|
90
|
+
entryPoint,
|
|
91
|
+
'--bundle',
|
|
92
|
+
'--platform=node',
|
|
93
|
+
'--target=node18',
|
|
94
|
+
`--format=${format}`,
|
|
95
|
+
`--outdir=${outDir}`,
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
if (options.minify) args.push('--minify');
|
|
99
|
+
if (options.sourcemap) args.push('--sourcemap');
|
|
100
|
+
|
|
101
|
+
const child = spawn('npx', args, {
|
|
102
|
+
stdio: 'inherit',
|
|
103
|
+
shell: true,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
child.on('close', (code) => {
|
|
108
|
+
if (code === 0) {
|
|
109
|
+
resolve();
|
|
110
|
+
} else {
|
|
111
|
+
reject(new Error(`${format} build failed`));
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async generateTsConfig() {
|
|
118
|
+
const tsconfig = {
|
|
119
|
+
compilerOptions: {
|
|
120
|
+
target: 'ES2020',
|
|
121
|
+
module: 'commonjs',
|
|
122
|
+
lib: ['ES2020'],
|
|
123
|
+
declaration: true,
|
|
124
|
+
strict: true,
|
|
125
|
+
noImplicitAny: true,
|
|
126
|
+
strictNullChecks: true,
|
|
127
|
+
noImplicitThis: true,
|
|
128
|
+
alwaysStrict: true,
|
|
129
|
+
outDir: './dist',
|
|
130
|
+
rootDir: './src',
|
|
131
|
+
},
|
|
132
|
+
include: ['src/**/*'],
|
|
133
|
+
exclude: ['node_modules', 'dist'],
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
await fs.writeJson(path.join(process.cwd(), 'tsconfig.json'), tsconfig, { spaces: 2 });
|
|
137
|
+
logger.success('tsconfig.json generated');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async generateExports(pkg) {
|
|
141
|
+
const distPath = path.join(process.cwd(), 'dist');
|
|
142
|
+
|
|
143
|
+
// Update package.json with exports
|
|
144
|
+
const updatedPkg = {
|
|
145
|
+
...pkg,
|
|
146
|
+
main: 'dist/cjs/index.js',
|
|
147
|
+
module: 'dist/esm/index.js',
|
|
148
|
+
types: 'dist/types/index.d.ts',
|
|
149
|
+
exports: {
|
|
150
|
+
'.': {
|
|
151
|
+
import: './dist/esm/index.js',
|
|
152
|
+
require: './dist/cjs/index.js',
|
|
153
|
+
types: './dist/types/index.d.ts',
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
files: ['dist'],
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
await fs.writeJson(path.join(process.cwd(), 'package.json'), updatedPkg, { spaces: 2 });
|
|
160
|
+
logger.success('package.json exports updated');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = LibraryBuilder;
|