@linyjs/cli 0.0.2
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/DESIGN.md +901 -0
- package/README.md +596 -0
- package/ZERO_CONFIG_GUIDE.md +462 -0
- package/dist/commands/dev.d.ts +15 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +153 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/init.d.ts +15 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +60 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/pack.d.ts +14 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +257 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/builder.d.ts +27 -0
- package/dist/utils/builder.d.ts.map +1 -0
- package/dist/utils/builder.js +383 -0
- package/dist/utils/builder.js.map +1 -0
- package/package.json +27 -0
- package/src/commands/dev.ts +191 -0
- package/src/commands/init.ts +75 -0
- package/src/commands/pack.ts +315 -0
- package/src/index.ts +84 -0
- package/src/utils/builder.ts +472 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart builder for plugin projects
|
|
3
|
+
*
|
|
4
|
+
* Design Philosophy:
|
|
5
|
+
* - Zero configuration required
|
|
6
|
+
* - CLI handles all build details automatically
|
|
7
|
+
* - Users just write TypeScript/TSX code
|
|
8
|
+
* - Sensible defaults and optimizations out of the box
|
|
9
|
+
*/
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import { execSync } from 'child_process';
|
|
13
|
+
import chalk from 'chalk';
|
|
14
|
+
import ora from 'ora';
|
|
15
|
+
/**
|
|
16
|
+
* Detect build system and execute build
|
|
17
|
+
*/
|
|
18
|
+
export async function buildProject(options) {
|
|
19
|
+
const startTime = Date.now();
|
|
20
|
+
const { projectRoot, verbose } = options;
|
|
21
|
+
const spinner = ora('Detecting build system...').start();
|
|
22
|
+
// Step 1: Detect build system
|
|
23
|
+
const buildSystem = detectBuildSystem(projectRoot);
|
|
24
|
+
if (!buildSystem) {
|
|
25
|
+
spinner.fail('No build system detected');
|
|
26
|
+
console.error(chalk.red('\nPlease add a build script to package.json:'));
|
|
27
|
+
console.error(chalk.gray(' "scripts": { "build": "tsc" }'));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
spinner.succeed(`Build system detected: ${buildSystem.name}`);
|
|
31
|
+
if (verbose) {
|
|
32
|
+
console.log(chalk.gray(' Type:'), buildSystem.type);
|
|
33
|
+
console.log(chalk.gray(' Config:'), buildSystem.configFile || 'none');
|
|
34
|
+
}
|
|
35
|
+
// Step 2: Execute build
|
|
36
|
+
const buildSpinner = ora('Building project...').start();
|
|
37
|
+
try {
|
|
38
|
+
let outputDir;
|
|
39
|
+
// DEFAULT: Always use esbuild for optimal bundles
|
|
40
|
+
// Users don't need to configure webpack/rollup themselves
|
|
41
|
+
if (buildSystem.type === 'typescript' || buildSystem.type === 'custom') {
|
|
42
|
+
// Even if project has tsc, we use esbuild for better optimization
|
|
43
|
+
if (verbose) {
|
|
44
|
+
console.log(chalk.yellow('\n💡 Using esbuild for optimized bundle (ignoring tsc config)'));
|
|
45
|
+
}
|
|
46
|
+
outputDir = await buildWithEsbuild(projectRoot, buildSystem, options, verbose);
|
|
47
|
+
}
|
|
48
|
+
else if (buildSystem.type === 'esbuild') {
|
|
49
|
+
// Project already uses esbuild, use it directly
|
|
50
|
+
outputDir = await buildWithEsbuild(projectRoot, buildSystem, options, verbose);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// For webpack/rollup, still prefer our esbuild approach
|
|
54
|
+
if (verbose) {
|
|
55
|
+
console.log(chalk.yellow('\n💡 Using CLI built-in esbuild (ignoring webpack/rollup config)'));
|
|
56
|
+
}
|
|
57
|
+
outputDir = await buildWithEsbuild(projectRoot, buildSystem, options, verbose);
|
|
58
|
+
}
|
|
59
|
+
// Step 3: Collect output files
|
|
60
|
+
const files = collectOutputFiles(outputDir);
|
|
61
|
+
const size = calculateTotalSize(files);
|
|
62
|
+
const duration = Date.now() - startTime;
|
|
63
|
+
buildSpinner.succeed(`Build completed in ${duration}ms`);
|
|
64
|
+
if (verbose) {
|
|
65
|
+
console.log(chalk.gray(' Output directory:'), outputDir);
|
|
66
|
+
console.log(chalk.gray(' Total files:'), files.length);
|
|
67
|
+
console.log(chalk.gray(' Total size:'), formatFileSize(size));
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
success: true,
|
|
71
|
+
outputDir,
|
|
72
|
+
files,
|
|
73
|
+
size,
|
|
74
|
+
duration
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
buildSpinner.fail('Build failed');
|
|
79
|
+
if (error instanceof Error) {
|
|
80
|
+
console.error(chalk.red('\nBuild error:'));
|
|
81
|
+
console.error(error.message);
|
|
82
|
+
if (verbose && 'stdout' in error) {
|
|
83
|
+
console.error(chalk.gray('\nDetailed output:'));
|
|
84
|
+
console.error(error.stdout?.toString());
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Detect build system from project configuration
|
|
92
|
+
*/
|
|
93
|
+
function detectBuildSystem(projectRoot) {
|
|
94
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
95
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
99
|
+
const buildScript = packageJson.scripts?.build || '';
|
|
100
|
+
// Check for TypeScript
|
|
101
|
+
if (fs.existsSync(path.join(projectRoot, 'tsconfig.json'))) {
|
|
102
|
+
if (buildScript.includes('tsc') || buildScript.includes('typescript')) {
|
|
103
|
+
return {
|
|
104
|
+
type: 'typescript',
|
|
105
|
+
name: 'TypeScript Compiler',
|
|
106
|
+
configFile: 'tsconfig.json',
|
|
107
|
+
command: buildScript
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Check for esbuild
|
|
112
|
+
if (buildScript.includes('esbuild')) {
|
|
113
|
+
return {
|
|
114
|
+
type: 'esbuild',
|
|
115
|
+
name: 'esbuild',
|
|
116
|
+
configFile: null,
|
|
117
|
+
command: buildScript
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// Check for webpack
|
|
121
|
+
if (fs.existsSync(path.join(projectRoot, 'webpack.config.js')) ||
|
|
122
|
+
fs.existsSync(path.join(projectRoot, 'webpack.config.ts'))) {
|
|
123
|
+
return {
|
|
124
|
+
type: 'webpack',
|
|
125
|
+
name: 'Webpack',
|
|
126
|
+
configFile: 'webpack.config.js',
|
|
127
|
+
command: buildScript
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// Check for rollup
|
|
131
|
+
if (fs.existsSync(path.join(projectRoot, 'rollup.config.js'))) {
|
|
132
|
+
return {
|
|
133
|
+
type: 'rollup',
|
|
134
|
+
name: 'Rollup',
|
|
135
|
+
configFile: 'rollup.config.js',
|
|
136
|
+
command: buildScript
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// Default to npm run build
|
|
140
|
+
if (buildScript) {
|
|
141
|
+
return {
|
|
142
|
+
type: 'custom',
|
|
143
|
+
name: 'Custom Build Script',
|
|
144
|
+
configFile: null,
|
|
145
|
+
command: buildScript
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Build with TypeScript compiler
|
|
152
|
+
*/
|
|
153
|
+
async function buildWithTsc(projectRoot, buildSystem, verbose) {
|
|
154
|
+
// Read tsconfig.json to get output directory
|
|
155
|
+
const tsconfigPath = path.join(projectRoot, 'tsconfig.json');
|
|
156
|
+
const tsconfig = JSON.parse(fs.readFileSync(tsconfigPath, 'utf-8'));
|
|
157
|
+
const outputDir = tsconfig.compilerOptions?.outDir || 'dist';
|
|
158
|
+
// Execute tsc
|
|
159
|
+
execSync('npx tsc', {
|
|
160
|
+
stdio: verbose ? 'inherit' : 'pipe',
|
|
161
|
+
cwd: projectRoot
|
|
162
|
+
});
|
|
163
|
+
return path.join(projectRoot, outputDir);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Build with esbuild (DEFAULT strategy)
|
|
167
|
+
* This is the recommended approach for production builds
|
|
168
|
+
*/
|
|
169
|
+
async function buildWithEsbuild(projectRoot, buildSystem, options, verbose) {
|
|
170
|
+
const outputDir = path.join(projectRoot, 'dist');
|
|
171
|
+
// Ensure output directory exists
|
|
172
|
+
if (!fs.existsSync(outputDir)) {
|
|
173
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
174
|
+
}
|
|
175
|
+
// Detect entry points (smart detection)
|
|
176
|
+
const serverEntry = findEntryFile(projectRoot, 'server');
|
|
177
|
+
const clientEntry = findEntryFile(projectRoot, 'client');
|
|
178
|
+
if (!serverEntry && !clientEntry) {
|
|
179
|
+
throw new Error('No entry files found. Expected src/server/index.ts or src/client/index.tsx');
|
|
180
|
+
}
|
|
181
|
+
// Default external dependencies (Ling framework provides these)
|
|
182
|
+
const defaultExternal = [
|
|
183
|
+
'react',
|
|
184
|
+
'react-dom',
|
|
185
|
+
'express',
|
|
186
|
+
'@linyjs/*',
|
|
187
|
+
'@ling/*'
|
|
188
|
+
];
|
|
189
|
+
const externalDeps = options.external || defaultExternal;
|
|
190
|
+
// Build server bundle (if exists)
|
|
191
|
+
if (serverEntry) {
|
|
192
|
+
const serverOutput = path.join(outputDir, 'server', 'index.js');
|
|
193
|
+
const serverCmd = [
|
|
194
|
+
'npx esbuild',
|
|
195
|
+
serverEntry,
|
|
196
|
+
'--bundle',
|
|
197
|
+
`--outfile=${serverOutput}`,
|
|
198
|
+
'--format=esm',
|
|
199
|
+
'--platform=node',
|
|
200
|
+
'--target=node18',
|
|
201
|
+
...externalDeps.map(dep => `--external:${dep}`),
|
|
202
|
+
options.minify !== false ? '--minify' : '', // Default to minify
|
|
203
|
+
'--sourcemap',
|
|
204
|
+
'--log-level=warning'
|
|
205
|
+
].filter(Boolean).join(' ');
|
|
206
|
+
if (verbose) {
|
|
207
|
+
console.log(chalk.cyan('\n🔨 Building server bundle...'));
|
|
208
|
+
console.log(chalk.gray(' Entry:'), serverEntry);
|
|
209
|
+
console.log(chalk.gray(' Output:'), serverOutput);
|
|
210
|
+
console.log(chalk.gray(' Command:'), serverCmd);
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
execSync(serverCmd, {
|
|
214
|
+
stdio: verbose ? 'inherit' : 'pipe',
|
|
215
|
+
cwd: projectRoot
|
|
216
|
+
});
|
|
217
|
+
if (verbose) {
|
|
218
|
+
const size = fs.statSync(serverOutput).size;
|
|
219
|
+
console.log(chalk.green(' ✓ Server bundle created'), chalk.gray(`(${formatFileSize(size)})`));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
throw new Error(`Server build failed: ${error.message}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Build client bundle (if exists)
|
|
227
|
+
if (clientEntry) {
|
|
228
|
+
const clientOutput = path.join(outputDir, 'client', 'index.js');
|
|
229
|
+
// For client bundle, we need different external dependencies
|
|
230
|
+
// Server-only packages should NOT be bundled in client
|
|
231
|
+
const clientExternal = [
|
|
232
|
+
// ⚠️ IMPORTANT: React and ReactDOM MUST be externalized
|
|
233
|
+
// All plugins must share the SAME React instance to avoid:
|
|
234
|
+
// - Context identity issues (createContext from different React instances are not equal)
|
|
235
|
+
// - Hook ordering problems (different React versions have different internal structures)
|
|
236
|
+
// - Memory leaks (multiple React renderers running simultaneously)
|
|
237
|
+
// - Dependency injection failures (contexts/services created by one React can't be used by another)
|
|
238
|
+
'react', // Provided by SSR host application
|
|
239
|
+
'react-dom', // Provided by SSR host application
|
|
240
|
+
'react-dom/client', // Provided by SSR host application
|
|
241
|
+
// UI slots interface is type-only, safe to external
|
|
242
|
+
'@linyjs/ui-slots-interface',
|
|
243
|
+
// Explicitly exclude server-only packages
|
|
244
|
+
// These should never appear in client code, but just in case:
|
|
245
|
+
'express',
|
|
246
|
+
'@linyjs/server-module-interface', // Server-only interface (type-only)
|
|
247
|
+
'@linyjs/mongodb', // Server-only service
|
|
248
|
+
// NOTE: @linyjs/client-module-interface is NOT externalized
|
|
249
|
+
// because it contains runtime values (React Context, Hooks)
|
|
250
|
+
// that must be included in the client bundle
|
|
251
|
+
];
|
|
252
|
+
// Merge with user-provided externals (if any)
|
|
253
|
+
if (options.external) {
|
|
254
|
+
options.external.forEach(dep => {
|
|
255
|
+
if (!clientExternal.includes(dep)) {
|
|
256
|
+
clientExternal.push(dep);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
const clientCmd = [
|
|
261
|
+
'npx esbuild',
|
|
262
|
+
clientEntry,
|
|
263
|
+
'--bundle',
|
|
264
|
+
`--outfile=${clientOutput}`,
|
|
265
|
+
'--format=esm',
|
|
266
|
+
'--platform=browser',
|
|
267
|
+
'--target=es2020',
|
|
268
|
+
...clientExternal.map(dep => `--external:${dep}`),
|
|
269
|
+
options.minify !== false ? '--minify' : '',
|
|
270
|
+
'--sourcemap',
|
|
271
|
+
'--log-level=warning'
|
|
272
|
+
].filter(Boolean).join(' ');
|
|
273
|
+
if (verbose) {
|
|
274
|
+
console.log(chalk.cyan('\n🔨 Building client bundle...'));
|
|
275
|
+
console.log(chalk.gray(' Entry:'), clientEntry);
|
|
276
|
+
console.log(chalk.gray(' Output:'), clientOutput);
|
|
277
|
+
console.log(chalk.gray(' Command:'), clientCmd);
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
execSync(clientCmd, {
|
|
281
|
+
stdio: verbose ? 'inherit' : 'pipe',
|
|
282
|
+
cwd: projectRoot
|
|
283
|
+
});
|
|
284
|
+
if (verbose) {
|
|
285
|
+
const size = fs.statSync(clientOutput).size;
|
|
286
|
+
console.log(chalk.green(' ✓ Client bundle created'), chalk.gray(`(${formatFileSize(size)})`));
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
throw new Error(`Client build failed: ${error.message}`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return outputDir;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Build with npm run build (fallback)
|
|
297
|
+
*/
|
|
298
|
+
async function buildWithNpm(projectRoot, verbose) {
|
|
299
|
+
execSync('npm run build', {
|
|
300
|
+
stdio: verbose ? 'inherit' : 'pipe',
|
|
301
|
+
cwd: projectRoot
|
|
302
|
+
});
|
|
303
|
+
// Try to detect output directory
|
|
304
|
+
const possibleDirs = ['dist', 'build', 'lib'];
|
|
305
|
+
for (const dir of possibleDirs) {
|
|
306
|
+
const fullPath = path.join(projectRoot, dir);
|
|
307
|
+
if (fs.existsSync(fullPath)) {
|
|
308
|
+
return fullPath;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return path.join(projectRoot, 'dist');
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Find entry file for server or client
|
|
315
|
+
*/
|
|
316
|
+
function findEntryFile(projectRoot, type) {
|
|
317
|
+
const possibleEntries = [
|
|
318
|
+
`src/${type}/index.ts`,
|
|
319
|
+
`src/${type}/index.tsx`,
|
|
320
|
+
`src/${type}.ts`,
|
|
321
|
+
`src/${type}.tsx`,
|
|
322
|
+
`${type}/index.ts`
|
|
323
|
+
];
|
|
324
|
+
for (const entry of possibleEntries) {
|
|
325
|
+
const fullPath = path.join(projectRoot, entry);
|
|
326
|
+
if (fs.existsSync(fullPath)) {
|
|
327
|
+
return entry;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Collect all output files
|
|
334
|
+
*/
|
|
335
|
+
function collectOutputFiles(outputDir) {
|
|
336
|
+
const files = [];
|
|
337
|
+
function walk(dir) {
|
|
338
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
339
|
+
for (const entry of entries) {
|
|
340
|
+
const fullPath = path.join(dir, entry.name);
|
|
341
|
+
if (entry.isDirectory()) {
|
|
342
|
+
// Skip node_modules and .git
|
|
343
|
+
if (entry.name === 'node_modules' || entry.name === '.git') {
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
walk(fullPath);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
files.push(fullPath);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
walk(outputDir);
|
|
354
|
+
return files;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Calculate total size of files
|
|
358
|
+
*/
|
|
359
|
+
function calculateTotalSize(files) {
|
|
360
|
+
return files.reduce((total, file) => {
|
|
361
|
+
try {
|
|
362
|
+
const stats = fs.statSync(file);
|
|
363
|
+
return total + stats.size;
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
return total;
|
|
367
|
+
}
|
|
368
|
+
}, 0);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Format file size
|
|
372
|
+
*/
|
|
373
|
+
function formatFileSize(bytes) {
|
|
374
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
|
375
|
+
let size = bytes;
|
|
376
|
+
let unitIndex = 0;
|
|
377
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
378
|
+
size /= 1024;
|
|
379
|
+
unitIndex++;
|
|
380
|
+
}
|
|
381
|
+
return `${size.toFixed(2)} ${units[unitIndex]}`;
|
|
382
|
+
}
|
|
383
|
+
//# sourceMappingURL=builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/utils/builder.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@linyjs/cli",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"ling": "./dist/index.js"
|
|
7
|
+
},
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc -b",
|
|
12
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"cleye": "^1.3.0",
|
|
16
|
+
"archiver": "^6.0.0",
|
|
17
|
+
"chalk": "^5.0.0",
|
|
18
|
+
"fs-extra": "^11.0.0",
|
|
19
|
+
"ora": "^7.0.0",
|
|
20
|
+
"esbuild": "^0.20.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"typescript": "^5.7.0",
|
|
24
|
+
"@types/archiver": "^6.0.0",
|
|
25
|
+
"@types/fs-extra": "^11.0.0"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev command - Quick plugin development workflow
|
|
3
|
+
*
|
|
4
|
+
* Packs the plugin, copies to extensions folder, and registers in packages.json
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
import ora from 'ora';
|
|
11
|
+
import { packPlugin } from './pack.js';
|
|
12
|
+
|
|
13
|
+
interface DevOptions {
|
|
14
|
+
target?: string;
|
|
15
|
+
verbose: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Execute dev workflow: pack -> copy -> register
|
|
20
|
+
*/
|
|
21
|
+
export async function devPlugin(options: DevOptions) {
|
|
22
|
+
const projectRoot = process.cwd();
|
|
23
|
+
|
|
24
|
+
console.log(chalk.blue('🚀 Ling Plugin Dev Mode\n'));
|
|
25
|
+
|
|
26
|
+
// Step 1: Pack the plugin
|
|
27
|
+
const spinner1 = ora('Packing plugin...').start();
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// Create temporary output directory
|
|
31
|
+
const tempOutputDir = path.join(projectRoot, '.ling-tmp');
|
|
32
|
+
|
|
33
|
+
await packPlugin({
|
|
34
|
+
output: tempOutputDir,
|
|
35
|
+
build: true,
|
|
36
|
+
verbose: options.verbose
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Find the generated .mpk file
|
|
40
|
+
const mpkFiles = fs.readdirSync(tempOutputDir).filter(f => f.endsWith('.mpk'));
|
|
41
|
+
|
|
42
|
+
if (mpkFiles.length === 0) {
|
|
43
|
+
spinner1.fail('No .mpk file generated');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const mpkFile = mpkFiles[0];
|
|
48
|
+
const mpkPath = path.join(tempOutputDir, mpkFile);
|
|
49
|
+
|
|
50
|
+
spinner1.succeed(`Plugin packed: ${mpkFile}`);
|
|
51
|
+
|
|
52
|
+
// Step 2: Determine target extensions directory
|
|
53
|
+
const targetDir = options.target || findExtensionsDir(projectRoot);
|
|
54
|
+
|
|
55
|
+
if (!targetDir) {
|
|
56
|
+
spinner1.fail('Cannot find extensions directory');
|
|
57
|
+
console.error(chalk.red('\nPlease specify target directory with --target option:'));
|
|
58
|
+
console.error(chalk.gray(' npx @linyjs/cli dev --target /path/to/ling/packages/ssr/extensions'));
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Step 3: Extract and copy to extensions
|
|
63
|
+
const spinner2 = ora('Installing to extensions...').start();
|
|
64
|
+
|
|
65
|
+
const pluginName = mpkFile.replace('.mpk', '').replace(/-\d+\.\d+\.\d+$/, '');
|
|
66
|
+
const installPath = path.join(targetDir, pluginName);
|
|
67
|
+
|
|
68
|
+
// Remove old installation if exists
|
|
69
|
+
if (fs.existsSync(installPath)) {
|
|
70
|
+
fs.rmSync(installPath, { recursive: true, force: true });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Create installation directory
|
|
74
|
+
fs.mkdirSync(installPath, { recursive: true });
|
|
75
|
+
|
|
76
|
+
// Extract .mpk file (it's a ZIP)
|
|
77
|
+
await extractMpk(mpkPath, installPath);
|
|
78
|
+
|
|
79
|
+
spinner2.succeed(`Installed to: ${installPath}`);
|
|
80
|
+
|
|
81
|
+
// Step 4: Register in packages.json
|
|
82
|
+
const spinner3 = ora('Registering plugin...').start();
|
|
83
|
+
|
|
84
|
+
const packagesJsonPath = path.join(targetDir, 'packages.json');
|
|
85
|
+
|
|
86
|
+
let packages: any[] = [];
|
|
87
|
+
|
|
88
|
+
if (fs.existsSync(packagesJsonPath)) {
|
|
89
|
+
const content = fs.readFileSync(packagesJsonPath, 'utf-8');
|
|
90
|
+
packages = JSON.parse(content);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Read manifest from installed plugin
|
|
94
|
+
const manifestPath = path.join(installPath, 'manifest.json');
|
|
95
|
+
let manifest: any = {};
|
|
96
|
+
|
|
97
|
+
if (fs.existsSync(manifestPath)) {
|
|
98
|
+
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Check if already registered
|
|
102
|
+
const existingIndex = packages.findIndex(p => p.name === pluginName);
|
|
103
|
+
|
|
104
|
+
const packageInfo = {
|
|
105
|
+
name: pluginName,
|
|
106
|
+
version: manifest.version || '1.0.0',
|
|
107
|
+
installPath: `extensions/${pluginName}`,
|
|
108
|
+
status: 'enabled',
|
|
109
|
+
installTime: Date.now(),
|
|
110
|
+
manifest: {
|
|
111
|
+
name: manifest.name || pluginName,
|
|
112
|
+
version: manifest.version || '1.0.0',
|
|
113
|
+
description: manifest.description || '',
|
|
114
|
+
author: manifest.author || '',
|
|
115
|
+
serverEntry: manifest.serverEntry || 'server/index.js',
|
|
116
|
+
clientEntry: manifest.clientEntry || 'client/index.js'
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
if (existingIndex >= 0) {
|
|
121
|
+
packages[existingIndex] = packageInfo;
|
|
122
|
+
spinner3.succeed(`Plugin updated in packages.json`);
|
|
123
|
+
} else {
|
|
124
|
+
packages.push(packageInfo);
|
|
125
|
+
spinner3.succeed(`Plugin registered in packages.json`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Write packages.json
|
|
129
|
+
fs.writeFileSync(packagesJsonPath, JSON.stringify(packages, null, 2) + '\n', 'utf-8');
|
|
130
|
+
|
|
131
|
+
// Cleanup temporary files
|
|
132
|
+
if (fs.existsSync(tempOutputDir)) {
|
|
133
|
+
fs.rmSync(tempOutputDir, { recursive: true, force: true });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Show success message
|
|
137
|
+
console.log('\n' + chalk.green('✓ Development setup complete!\n'));
|
|
138
|
+
console.log(chalk.cyan('Plugin installed:'));
|
|
139
|
+
console.log(` Name: ${chalk.bold(pluginName)}`);
|
|
140
|
+
console.log(` Path: ${chalk.gray(installPath)}`);
|
|
141
|
+
console.log(` Status: ${chalk.green('enabled')}\n`);
|
|
142
|
+
|
|
143
|
+
console.log(chalk.cyan('Next steps:'));
|
|
144
|
+
console.log(` 1. Restart SSR server:`);
|
|
145
|
+
console.log(` ${chalk.gray('cd packages/ssr && npx tsx src/demo/dev-server-with-pkg.tsx')}`);
|
|
146
|
+
console.log(` 2. Or use hot reload (if supported)`);
|
|
147
|
+
console.log(` 3. Test your plugin in the browser\n`);
|
|
148
|
+
|
|
149
|
+
} catch (error) {
|
|
150
|
+
spinner1.fail('Dev workflow failed');
|
|
151
|
+
console.error(chalk.red('\nError:'), error instanceof Error ? error.message : error);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Find extensions directory relative to project root
|
|
158
|
+
*/
|
|
159
|
+
function findExtensionsDir(projectRoot: string): string | null {
|
|
160
|
+
// Try common paths
|
|
161
|
+
const candidates = [
|
|
162
|
+
path.join(projectRoot, '..', 'ssr', 'extensions'),
|
|
163
|
+
path.join(projectRoot, '..', '..', 'packages', 'ssr', 'extensions'),
|
|
164
|
+
path.join(projectRoot, 'packages', 'ssr', 'extensions'),
|
|
165
|
+
];
|
|
166
|
+
|
|
167
|
+
for (const candidate of candidates) {
|
|
168
|
+
if (fs.existsSync(candidate)) {
|
|
169
|
+
return candidate;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Extract .mpk file (ZIP format) to target directory
|
|
178
|
+
*/
|
|
179
|
+
async function extractMpk(mpkPath: string, targetDir: string): Promise<void> {
|
|
180
|
+
// Use unzipper or similar library
|
|
181
|
+
// For now, use system unzip command
|
|
182
|
+
const { execSync } = await import('child_process');
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
execSync(`unzip -o "${mpkPath}" -d "${targetDir}"`, {
|
|
186
|
+
stdio: 'pipe'
|
|
187
|
+
});
|
|
188
|
+
} catch (error) {
|
|
189
|
+
throw new Error('Failed to extract .mpk file. Make sure unzip is installed.');
|
|
190
|
+
}
|
|
191
|
+
}
|