@lark-apaas/fullstack-cli 1.1.63-alpha.20260826190313 → 1.1.63-alpha.20260827022254

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/dist/index.js CHANGED
@@ -2514,17 +2514,6 @@ function buildDefaultRules(opts) {
2514
2514
  command: "node scripts/hooks/run-precommit.js",
2515
2515
  overwrite: false
2516
2516
  },
2517
- // 1d. Nest 开发态由平台 launcher 选择 SWC;已有声明保持用户版本/依赖分区。
2518
- {
2519
- type: "ensure-dev-dependency",
2520
- name: "@swc/cli",
2521
- version: "^0.5.2"
2522
- },
2523
- {
2524
- type: "ensure-dev-dependency",
2525
- name: "@swc/core",
2526
- version: "^1.16.1"
2527
- },
2528
2517
  // 2. 智能合并 nest-cli.json 配置(保留用户自定义的 assets、plugins 等)
2529
2518
  {
2530
2519
  from: "templates/nest-cli.json",
@@ -2599,19 +2588,6 @@ function buildDefaultRules(opts) {
2599
2588
  name: "lint",
2600
2589
  to: "node ./scripts/lint.js",
2601
2590
  ifStartsWith: "concurrently "
2602
- },
2603
- // 9a. 只迁移模板生成的精确默认值;用户追加参数或自定义命令保持不动。
2604
- {
2605
- type: "patch-script",
2606
- name: "dev:server",
2607
- to: "NODE_ENV=development node ./scripts/dev-server.js",
2608
- ifEquals: "NODE_ENV=development nest start --watch"
2609
- },
2610
- {
2611
- type: "patch-script",
2612
- name: "dev:server",
2613
- to: "NODE_ENV=development node ./scripts/dev-server.js",
2614
- ifEquals: "nest start --watch"
2615
2591
  }
2616
2592
  ];
2617
2593
  if (!opts.disableGenOpenapi) {
@@ -2791,9 +2767,7 @@ async function run2(options) {
2791
2767
  }
2792
2768
  const stack = resolveStack(userProjectRoot);
2793
2769
  try {
2794
- console.log(
2795
- `[fullstack-cli] Starting sync${stack ? ` (stack: ${stack})` : ""}...`
2796
- );
2770
+ console.log(`[fullstack-cli] Starting sync${stack ? ` (stack: ${stack})` : ""}...`);
2797
2771
  const config = genSyncConfig(stack, {
2798
2772
  disableGenOpenapi: options.disableGenOpenapi ?? false
2799
2773
  });
@@ -2812,9 +2786,7 @@ async function run2(options) {
2812
2786
  activateGitHooks(userProjectRoot);
2813
2787
  } catch (error) {
2814
2788
  const message = error instanceof Error ? error.message : String(error);
2815
- console.warn(
2816
- `[fullstack-cli] \u26A0 Failed to activate git hooks: ${message}`
2817
- );
2789
+ console.warn(`[fullstack-cli] \u26A0 Failed to activate git hooks: ${message}`);
2818
2790
  }
2819
2791
  }
2820
2792
  console.log("[fullstack-cli] Sync completed successfully \u2705");
@@ -2834,9 +2806,7 @@ function resolveStack(userProjectRoot) {
2834
2806
  return typeof meta.stack === "string" ? meta.stack : void 0;
2835
2807
  } catch (error) {
2836
2808
  const message = error instanceof Error ? error.message : String(error);
2837
- console.warn(
2838
- `[fullstack-cli] \u26A0 Failed to read .spark/meta.json, fallback to default sync: ${message}`
2839
- );
2809
+ console.warn(`[fullstack-cli] \u26A0 Failed to read .spark/meta.json, fallback to default sync: ${message}`);
2840
2810
  return void 0;
2841
2811
  }
2842
2812
  }
@@ -2857,22 +2827,12 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
2857
2827
  }
2858
2828
  if (rule.type === "add-script") {
2859
2829
  const packageJsonPath = path5.join(userProjectRoot, "package.json");
2860
- addScript(
2861
- packageJsonPath,
2862
- rule.name,
2863
- rule.command,
2864
- rule.overwrite ?? false
2865
- );
2866
- return;
2867
- }
2868
- if (rule.type === "ensure-dev-dependency") {
2869
- const packageJsonPath = path5.join(userProjectRoot, "package.json");
2870
- ensureDevDependency(packageJsonPath, rule.name, rule.version);
2830
+ addScript(packageJsonPath, rule.name, rule.command, rule.overwrite ?? false);
2871
2831
  return;
2872
2832
  }
2873
2833
  if (rule.type === "patch-script") {
2874
2834
  const packageJsonPath = path5.join(userProjectRoot, "package.json");
2875
- patchScript(packageJsonPath, rule);
2835
+ patchScript(packageJsonPath, rule.name, rule.to, rule.ifStartsWith);
2876
2836
  return;
2877
2837
  }
2878
2838
  if (rule.type === "add-line") {
@@ -2900,12 +2860,7 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
2900
2860
  syncDirectory(srcPath, destPath, rule.overwrite ?? true);
2901
2861
  break;
2902
2862
  case "file":
2903
- syncFile(
2904
- srcPath,
2905
- destPath,
2906
- rule.overwrite ?? true,
2907
- rule.onlyIfExists ?? false
2908
- );
2863
+ syncFile(srcPath, destPath, rule.overwrite ?? true, rule.onlyIfExists ?? false);
2909
2864
  break;
2910
2865
  case "append":
2911
2866
  appendToFile(srcPath, destPath);
@@ -2914,9 +2869,7 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
2914
2869
  }
2915
2870
  function syncFile(src, dest, overwrite = true, onlyIfExists = false) {
2916
2871
  if (onlyIfExists && !fs7.existsSync(dest)) {
2917
- console.log(
2918
- `[fullstack-cli] \u25CB ${path5.basename(dest)} (skipped, target not exists)`
2919
- );
2872
+ console.log(`[fullstack-cli] \u25CB ${path5.basename(dest)} (skipped, target not exists)`);
2920
2873
  return;
2921
2874
  }
2922
2875
  const destDir = path5.dirname(dest);
@@ -2924,9 +2877,7 @@ function syncFile(src, dest, overwrite = true, onlyIfExists = false) {
2924
2877
  fs7.mkdirSync(destDir, { recursive: true });
2925
2878
  }
2926
2879
  if (fs7.existsSync(dest) && !overwrite) {
2927
- console.log(
2928
- `[fullstack-cli] \u25CB ${path5.basename(dest)} (skipped, already exists)`
2929
- );
2880
+ console.log(`[fullstack-cli] \u25CB ${path5.basename(dest)} (skipped, already exists)`);
2930
2881
  return;
2931
2882
  }
2932
2883
  fs7.copyFileSync(src, dest);
@@ -2953,9 +2904,7 @@ function syncDirectory(src, dest, overwrite = true) {
2953
2904
  }
2954
2905
  });
2955
2906
  if (count > 0) {
2956
- console.log(
2957
- `[fullstack-cli] Synced ${count} files to ${path5.basename(dest)}/`
2958
- );
2907
+ console.log(`[fullstack-cli] Synced ${count} files to ${path5.basename(dest)}/`);
2959
2908
  }
2960
2909
  }
2961
2910
  function appendToFile(src, dest) {
@@ -2965,9 +2914,7 @@ function appendToFile(src, dest) {
2965
2914
  existingContent = fs7.readFileSync(dest, "utf-8");
2966
2915
  }
2967
2916
  if (existingContent.includes(content.trim())) {
2968
- console.log(
2969
- `[fullstack-cli] \u25CB ${path5.basename(dest)} (already contains content)`
2970
- );
2917
+ console.log(`[fullstack-cli] \u25CB ${path5.basename(dest)} (already contains content)`);
2971
2918
  return;
2972
2919
  }
2973
2920
  fs7.appendFileSync(dest, content);
@@ -3025,34 +2972,7 @@ function addScript(packageJsonPath, name, command, overwrite) {
3025
2972
  fs7.writeFileSync(packageJsonPath, JSON.stringify(pkg2, null, 2) + "\n");
3026
2973
  console.log(`[fullstack-cli] \u2713 scripts.${name}`);
3027
2974
  }
3028
- function ensureDevDependency(packageJsonPath, name, version) {
3029
- if (!fs7.existsSync(packageJsonPath)) {
3030
- console.log("[fullstack-cli] \u25CB package.json (not found)");
3031
- return;
3032
- }
3033
- try {
3034
- const content = fs7.readFileSync(packageJsonPath, "utf-8");
3035
- const pkg2 = JSON.parse(content);
3036
- const existingVersion = pkg2.dependencies?.[name] ?? pkg2.devDependencies?.[name];
3037
- if (existingVersion !== void 0) {
3038
- console.log(
3039
- `[fullstack-cli] \u25CB ${name} (already declared as ${existingVersion})`
3040
- );
3041
- return;
3042
- }
3043
- pkg2.devDependencies ?? (pkg2.devDependencies = {});
3044
- pkg2.devDependencies[name] = version;
3045
- fs7.writeFileSync(packageJsonPath, JSON.stringify(pkg2, null, 2) + "\n");
3046
- console.log(`[fullstack-cli] \u2713 devDependencies.${name} = ${version}`);
3047
- } catch (error) {
3048
- const message = error instanceof Error ? error.message : String(error);
3049
- console.warn(
3050
- `[fullstack-cli] \u26A0 Could not ensure dependency ${name}: ${message}`
3051
- );
3052
- }
3053
- }
3054
- function patchScript(packageJsonPath, rule) {
3055
- const { name, to } = rule;
2975
+ function patchScript(packageJsonPath, name, to, ifStartsWith) {
3056
2976
  if (!fs7.existsSync(packageJsonPath)) {
3057
2977
  console.log(`[fullstack-cli] \u25CB package.json (not found)`);
3058
2978
  return;
@@ -3069,8 +2989,7 @@ function patchScript(packageJsonPath, rule) {
3069
2989
  console.log(`[fullstack-cli] \u25CB scripts.${name} (already patched)`);
3070
2990
  return;
3071
2991
  }
3072
- const matches = rule.ifEquals !== void 0 ? current === rule.ifEquals : current.startsWith(rule.ifStartsWith);
3073
- if (!matches) {
2992
+ if (!current.startsWith(ifStartsWith)) {
3074
2993
  console.warn(
3075
2994
  `[fullstack-cli] \u26A0 Skipped patching scripts.${name} because it has been customized`
3076
2995
  );
@@ -3081,9 +3000,7 @@ function patchScript(packageJsonPath, rule) {
3081
3000
  console.log(`[fullstack-cli] \u2713 Patched scripts.${name}`);
3082
3001
  } catch (error) {
3083
3002
  const message = error instanceof Error ? error.message : String(error);
3084
- console.warn(
3085
- `[fullstack-cli] \u26A0 Could not patch scripts.${name}: ${message}`
3086
- );
3003
+ console.warn(`[fullstack-cli] \u26A0 Could not patch scripts.${name}: ${message}`);
3087
3004
  }
3088
3005
  }
3089
3006
  function addLineToFile(filePath, line) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/fullstack-cli",
3
- "version": "1.1.63-alpha.20260826190313",
3
+ "version": "1.1.63-alpha.20260827022254",
4
4
  "description": "CLI tool for fullstack template management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -154,6 +154,18 @@ if [ -d "$DIST_DIR/client" ]; then
154
154
  find "$DIST_DIR/client" -maxdepth 1 -name "*.html" -exec mv {} "$DIST_DIR/dist/client/" \;
155
155
  fi
156
156
 
157
+ # 拷贝 shared/static → dist/shared/static
158
+ # Nest server 生产从 process.cwd() + shared/static 读 (nestjs-core static.controller.ts:100),
159
+ # 生产 cwd = dist/, 所以目标是 dist/shared/static。coding-preset 的 static-assets plugin
160
+ # 之前 closeBundle 拷贝, 现在删除后交给 build.sh 显式做 (跟 jsPage 的 output_static rsync 对齐)。
161
+ # 排除 .ts/.tsx/.js/.jsx: 避免 shared/static/ 里若有开发脚本被误传到生产。
162
+ if [ -d "$ROOT_DIR/shared/static" ]; then
163
+ mkdir -p "$DIST_DIR/shared/static"
164
+ rsync -a --exclude='*.ts' --exclude='*.tsx' --exclude='*.js' --exclude='*.jsx' \
165
+ "$ROOT_DIR/shared/static/" "$DIST_DIR/shared/static/"
166
+ echo " Static → dist/shared/static/"
167
+ fi
168
+
157
169
  # server 相关产物准备(only_frontend_change=true 时跳过)
158
170
  if [[ "${only_frontend_change:-false}" == "true" ]]; then
159
171
  echo " [skip] 跳过 run.sh/.env 复制 (only_frontend_change=true)"
@@ -1,285 +0,0 @@
1
- 'use strict';
2
-
3
- const fs = require('node:fs');
4
- const path = require('node:path');
5
- const { spawn } = require('node:child_process');
6
-
7
- const FORWARDED_SIGNALS = ['SIGINT', 'SIGTERM'];
8
-
9
- function resolveBuilder(projectRoot) {
10
- const configPath = path.join(projectRoot, 'nest-cli.json');
11
- if (!fs.existsSync(configPath)) {
12
- return undefined;
13
- }
14
-
15
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
16
- const builder = config?.compilerOptions?.builder;
17
- if (typeof builder === 'string') {
18
- return builder;
19
- }
20
- if (
21
- builder &&
22
- typeof builder === 'object' &&
23
- typeof builder.type === 'string'
24
- ) {
25
- return builder.type;
26
- }
27
- return builder === undefined ? undefined : 'custom';
28
- }
29
-
30
- function findMissingSwcDependency(projectRoot) {
31
- for (const dependency of ['@swc/cli', '@swc/core']) {
32
- try {
33
- require.resolve(`${dependency}/package.json`, { paths: [projectRoot] });
34
- } catch {
35
- return dependency;
36
- }
37
- }
38
- return undefined;
39
- }
40
-
41
- function resolveNestEntrypoint(projectRoot) {
42
- return require.resolve('@nestjs/cli/bin/nest.js', { paths: [projectRoot] });
43
- }
44
-
45
- function resolveInsideProject(projectRoot, configuredPath) {
46
- const resolvedPath = path.resolve(projectRoot, configuredPath);
47
- const relativePath = path.relative(projectRoot, resolvedPath);
48
- if (
49
- relativePath === '..' ||
50
- relativePath.startsWith(`..${path.sep}`) ||
51
- path.isAbsolute(relativePath)
52
- ) {
53
- return undefined;
54
- }
55
- return resolvedPath;
56
- }
57
-
58
- function readJsonStringProperty(filePath, propertyName, fallback) {
59
- if (!fs.existsSync(filePath)) {
60
- return fallback;
61
- }
62
- const content = fs.readFileSync(filePath, 'utf8');
63
- const match = content.match(
64
- new RegExp(`"${propertyName}"\\s*:\\s*"([^"\\r\\n]+)"`)
65
- );
66
- return match?.[1] ?? fallback;
67
- }
68
-
69
- function cleanStaleSwcOutputs(projectRoot) {
70
- const nestConfigPath = path.join(projectRoot, 'nest-cli.json');
71
- const nestConfig = JSON.parse(fs.readFileSync(nestConfigPath, 'utf8'));
72
- const sourceRootName =
73
- typeof nestConfig.sourceRoot === 'string' ? nestConfig.sourceRoot : 'src';
74
- const tsConfigName =
75
- typeof nestConfig.compilerOptions?.tsConfigPath === 'string'
76
- ? nestConfig.compilerOptions.tsConfigPath
77
- : 'tsconfig.json';
78
- const tsConfigPath = resolveInsideProject(projectRoot, tsConfigName);
79
- const sourceRoot = resolveInsideProject(projectRoot, sourceRootName);
80
- if (!tsConfigPath || !sourceRoot || !fs.existsSync(sourceRoot)) {
81
- return 0;
82
- }
83
-
84
- const outDirName = readJsonStringProperty(tsConfigPath, 'outDir', 'dist');
85
- const rootDirName = readJsonStringProperty(
86
- tsConfigPath,
87
- 'rootDir',
88
- sourceRootName
89
- );
90
- const outDir = resolveInsideProject(projectRoot, outDirName);
91
- const rootDir = resolveInsideProject(projectRoot, rootDirName);
92
- if (!outDir) {
93
- return 0;
94
- }
95
- const emitRoots = [sourceRoot];
96
- if (rootDir && rootDir !== sourceRoot) {
97
- emitRoots.push(rootDir);
98
- }
99
-
100
- let removed = 0;
101
- const pendingDirectories = [sourceRoot];
102
- while (pendingDirectories.length > 0) {
103
- const currentDirectory = pendingDirectories.pop();
104
- for (const entry of fs.readdirSync(currentDirectory, {
105
- withFileTypes: true,
106
- })) {
107
- const sourcePath = path.join(currentDirectory, entry.name);
108
- if (entry.isDirectory()) {
109
- pendingDirectories.push(sourcePath);
110
- continue;
111
- }
112
- if (!entry.isFile() || entry.name.endsWith('.d.ts')) {
113
- continue;
114
- }
115
-
116
- const sourceExtension = ['.tsx', '.mts', '.cts', '.ts'].find(extension =>
117
- entry.name.endsWith(extension)
118
- );
119
- if (!sourceExtension) {
120
- continue;
121
- }
122
- const outputExtension =
123
- sourceExtension === '.mts'
124
- ? '.mjs'
125
- : sourceExtension === '.cts'
126
- ? '.cjs'
127
- : '.js';
128
- const declarationExtension =
129
- sourceExtension === '.mts'
130
- ? '.d.mts'
131
- : sourceExtension === '.cts'
132
- ? '.d.cts'
133
- : '.d.ts';
134
- const sourceBasePath = sourcePath.slice(0, -sourceExtension.length);
135
- for (const suffix of [
136
- outputExtension,
137
- `${outputExtension}.map`,
138
- declarationExtension,
139
- `${declarationExtension}.map`,
140
- ]) {
141
- const generatedSourceSibling = `${sourceBasePath}${suffix}`;
142
- if (fs.existsSync(generatedSourceSibling)) {
143
- fs.rmSync(generatedSourceSibling, { force: true });
144
- removed += 1;
145
- }
146
- }
147
-
148
- for (const emitRoot of emitRoots) {
149
- const relativeSourcePath = path.relative(emitRoot, sourcePath);
150
- if (
151
- relativeSourcePath === '..' ||
152
- relativeSourcePath.startsWith(`..${path.sep}`) ||
153
- path.isAbsolute(relativeSourcePath)
154
- ) {
155
- continue;
156
- }
157
-
158
- const outputBasePath = path.join(
159
- outDir,
160
- relativeSourcePath.slice(0, -sourceExtension.length)
161
- );
162
- for (const suffix of [
163
- outputExtension,
164
- `${outputExtension}.map`,
165
- declarationExtension,
166
- `${declarationExtension}.map`,
167
- ]) {
168
- const outputPath = `${outputBasePath}${suffix}`;
169
- if (fs.existsSync(outputPath)) {
170
- fs.rmSync(outputPath, { force: true });
171
- removed += 1;
172
- }
173
- }
174
- }
175
- }
176
- }
177
- return removed;
178
- }
179
-
180
- function startNest(projectRoot, nestArgs) {
181
- const child = spawn(
182
- process.execPath,
183
- [resolveNestEntrypoint(projectRoot), ...nestArgs],
184
- {
185
- cwd: projectRoot,
186
- env: process.env,
187
- stdio: 'inherit',
188
- }
189
- );
190
-
191
- const signalHandlers = new Map();
192
- for (const signal of FORWARDED_SIGNALS) {
193
- const handler = () => child.kill(signal);
194
- signalHandlers.set(signal, handler);
195
- process.once(signal, handler);
196
- }
197
-
198
- function removeSignalHandlers() {
199
- for (const [signal, handler] of signalHandlers) {
200
- process.removeListener(signal, handler);
201
- }
202
- }
203
-
204
- child.once('error', error => {
205
- removeSignalHandlers();
206
- console.error(
207
- `[miaoda:nest-compiler] failed to start Nest CLI: ${error.message}`
208
- );
209
- process.exitCode = 1;
210
- });
211
-
212
- child.once('exit', (code, signal) => {
213
- removeSignalHandlers();
214
- if (signal) {
215
- process.kill(process.pid, signal);
216
- return;
217
- }
218
- process.exitCode = code ?? 1;
219
- });
220
- }
221
-
222
- function main() {
223
- const projectRoot = process.cwd();
224
- const forwardedArgs = process.argv.slice(2);
225
- let explicitBuilder;
226
-
227
- try {
228
- explicitBuilder = resolveBuilder(projectRoot);
229
- } catch (error) {
230
- console.error(
231
- `[miaoda:nest-compiler] MIAODA_NEST_SWC_FALLBACK reason=invalid_nest_cli_config message=${JSON.stringify(error.message)}`
232
- );
233
- console.log('[miaoda:nest-compiler] MIAODA_NEST_COMPILER=tsc');
234
- startNest(projectRoot, ['start', '--watch', ...forwardedArgs]);
235
- return;
236
- }
237
-
238
- if (explicitBuilder && explicitBuilder !== 'swc') {
239
- console.log(
240
- `[miaoda:nest-compiler] MIAODA_NEST_COMPILER=${explicitBuilder}`
241
- );
242
- startNest(projectRoot, ['start', '--watch', ...forwardedArgs]);
243
- return;
244
- }
245
-
246
- const missingDependency = findMissingSwcDependency(projectRoot);
247
- if (missingDependency) {
248
- console.error(
249
- `[miaoda:nest-compiler] MIAODA_NEST_SWC_FALLBACK reason=missing_dependency dependency=${missingDependency}`
250
- );
251
- console.log('[miaoda:nest-compiler] MIAODA_NEST_COMPILER=tsc');
252
- startNest(projectRoot, ['start', '--watch', ...forwardedArgs]);
253
- return;
254
- }
255
-
256
- try {
257
- const removed = cleanStaleSwcOutputs(projectRoot);
258
- console.log(
259
- `[miaoda:nest-compiler] MIAODA_NEST_SWC_CLEANUP removed=${removed}`
260
- );
261
- } catch (error) {
262
- console.error(
263
- `[miaoda:nest-compiler] MIAODA_NEST_SWC_CLEANUP_FAILED message=${JSON.stringify(error.message)}`
264
- );
265
- }
266
- console.log('[miaoda:nest-compiler] MIAODA_NEST_COMPILER=swc');
267
- startNest(projectRoot, [
268
- 'start',
269
- '--watch',
270
- '--builder',
271
- 'swc',
272
- '--type-check',
273
- ...forwardedArgs,
274
- ]);
275
- }
276
-
277
- if (require.main === module) {
278
- main();
279
- }
280
-
281
- module.exports = {
282
- cleanStaleSwcOutputs,
283
- findMissingSwcDependency,
284
- resolveBuilder,
285
- };