@lark-apaas/fullstack-cli 1.1.68-alpha.20260920222630 → 1.1.68-alpha.20260930060426

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/fullstack-cli",
3
- "version": "1.1.68-alpha.20260920222630",
3
+ "version": "1.1.68-alpha.20260930060426",
4
4
  "description": "CLI tool for fullstack template management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -6,78 +6,47 @@ const { spawnSync } = require('node:child_process');
6
6
 
7
7
  const SEP = ' ' + '─'.repeat(36);
8
8
 
9
- function failAndExit(step, body) {
9
+ function failAndExit(step, body, code) {
10
10
  process.stderr.write('\n✗ pre-commit failed: ' + step + '\n');
11
+ process.stderr.write(' command: npm run lint\n');
11
12
  process.stderr.write(SEP + '\n');
12
13
  if (body && body.length > 0) {
13
- process.stderr.write(body.replace(/\s+$/, '') + '\n');
14
+ process.stderr.write(body);
15
+ if (!body.endsWith('\n')) process.stderr.write('\n');
14
16
  }
15
17
  process.stderr.write(SEP + '\n');
16
- process.stderr.write(' bypass: git commit --no-verify\n');
17
- process.exit(1);
18
- }
19
-
20
- function getStagedFiles() {
21
- const res = spawnSync(
22
- 'git',
23
- ['diff', '--cached', '--name-status', '--find-renames', '-z'],
24
- {
25
- cwd: process.cwd(),
26
- stdio: ['ignore', 'pipe', 'pipe'],
27
- encoding: 'utf8',
28
- },
18
+ process.stderr.write(
19
+ ' 修复可编辑代码并重跑 npm run lint(原项目完整检查)。\n'
29
20
  );
30
- if (res.error) {
31
- failAndExit('staged files', String(res.error.message || res.error));
32
- }
33
- if (res.status !== 0) {
34
- failAndExit('staged files', `${res.stdout || ''}\n${res.stderr || ''}`);
35
- }
36
-
37
- const fields = (res.stdout || '').split('\0');
38
- const files = [];
39
- for (let index = 0; index < fields.length;) {
40
- const status = fields[index++];
41
- if (!status) break;
42
- const sourcePath = fields[index++];
43
- if (!sourcePath) failAndExit('staged files', `Malformed git diff output for status ${status}`);
44
-
45
- if (status.startsWith('R') || status.startsWith('C')) {
46
- const destinationPath = fields[index++];
47
- if (!destinationPath) failAndExit('staged files', `Malformed git diff output for status ${status}`);
48
- // Renames can cross client/server/shared boundaries. Keep both paths so
49
- // lint.js can select every affected typecheck, while ignoring a missing
50
- // source path for file-level linters. Copies do not remove the source.
51
- if (status.startsWith('R')) files.push(sourcePath);
52
- files.push(destinationPath);
53
- continue;
54
- }
55
-
56
- files.push(sourcePath);
57
- }
58
- return files;
21
+ process.stderr.write(
22
+ ' 命中平台受保护路径时停止反复编辑该文件或检查配置;记录路径、规则和检查原始输出,交有权限的平台维护者修复并复查。\n'
23
+ );
24
+ process.stderr.write(' 检查仍未通过;不得声称检查或提交成功。\n');
25
+ process.exit(code);
59
26
  }
60
27
 
61
28
  function runLint() {
62
29
  const cwd = process.cwd();
63
- const stagedFiles = getStagedFiles();
64
- if (stagedFiles.length === 0) {
65
- process.stdout.write('[pre-commit] No staged files to lint\n');
66
- return;
67
- }
68
-
69
- const res = spawnSync('npm', ['run', 'lint', '--', '--files', ...stagedFiles], {
30
+ const res = spawnSync('npm', ['run', 'lint'], {
70
31
  cwd,
71
32
  stdio: ['ignore', 'pipe', 'pipe'],
72
33
  env: process.env,
73
34
  });
74
35
  if (res.error) {
75
- failAndExit('lint', String(res.error.message || res.error));
36
+ failAndExit('lint', String(res.error.message || res.error), 1);
76
37
  }
77
38
  if (res.status !== 0) {
78
39
  const stdout = res.stdout ? res.stdout.toString() : '';
79
40
  const stderr = res.stderr ? res.stderr.toString() : '';
80
- failAndExit('lint', stdout + '\n' + stderr);
41
+ const body =
42
+ stdout +
43
+ (stdout && stderr && !stdout.endsWith('\n') ? '\n' : '') +
44
+ stderr;
45
+ failAndExit(
46
+ 'lint',
47
+ body + (res.signal ? '\nTerminated by signal: ' + res.signal : ''),
48
+ res.status ?? 1
49
+ );
81
50
  }
82
51
  }
83
52
 
@@ -40,6 +40,12 @@ function normalizeProjectFile(filePath) {
40
40
  const absolutePath = path.isAbsolute(filePath)
41
41
  ? filePath
42
42
  : path.resolve(cwd, filePath);
43
+
44
+ if (!fs.existsSync(absolutePath)) {
45
+ console.warn(`[lint] Skip missing file: ${filePath}`);
46
+ return null;
47
+ }
48
+
43
49
  const relativePath = path.relative(cwd, absolutePath);
44
50
  if (relativePath.startsWith('..')) {
45
51
  console.warn(`[lint] Skip file outside project: ${filePath}`);
@@ -58,15 +64,6 @@ function parseFilesArg(argv) {
58
64
  return argv.slice(filesIndex + 1).filter(Boolean);
59
65
  }
60
66
 
61
- function parseMode(argv) {
62
- if (argv.length === 0) return { type: 'default' };
63
- if (argv.length === 1 && argv[0] === '--typecheck') return { type: 'typecheck' };
64
- if (argv[0] === '--files' && argv.length > 1 && argv.slice(1).every(arg => !arg.startsWith('--'))) {
65
- return { type: 'files', files: argv.slice(1) };
66
- }
67
- throw new Error('Usage: lint.js [--typecheck | --files <paths...>]');
68
- }
69
-
70
67
  function isEslintTarget(filePath) {
71
68
  return /\.(c|m)?(j|t)sx?$/.test(filePath);
72
69
  }
@@ -110,14 +107,6 @@ function canRunStylelint() {
110
107
  return STYLELINT_CONFIG_FILES.some(file => fs.existsSync(path.join(cwd, file)));
111
108
  }
112
109
 
113
- function packageScripts() {
114
- try {
115
- return JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8')).scripts || {};
116
- } catch {
117
- return {};
118
- }
119
- }
120
-
121
110
  async function runDefaultLint() {
122
111
  const taskSpecs = [
123
112
  [getBinName('npm'), ['run', 'eslint']],
@@ -133,19 +122,6 @@ async function runDefaultLint() {
133
122
  process.exit(await runTasksSerially(taskSpecs));
134
123
  }
135
124
 
136
- async function runTypeCheck() {
137
- const scripts = packageScripts();
138
- const names = ['type:check:server', 'type:check:client'];
139
- const missing = names.filter(name => !scripts[name]);
140
- if (missing.length > 0) {
141
- throw new Error(`Missing required npm scripts: ${missing.join(', ')}`);
142
- }
143
-
144
- process.exit(await runTasksSerially(
145
- names.map(name => [getBinName('npm'), ['run', name]]),
146
- ));
147
- }
148
-
149
125
  async function runSelectiveLint(inputFiles) {
150
126
  const normalizedFiles = Array.from(
151
127
  new Set(inputFiles.map(normalizeProjectFile).filter(Boolean)),
@@ -156,15 +132,8 @@ async function runSelectiveLint(inputFiles) {
156
132
  process.exit(0);
157
133
  }
158
134
 
159
- // Deleted files and the source side of renames must still select the
160
- // affected project typecheck, but must not be passed to file-level linters.
161
- const existingFiles = normalizedFiles.filter(filePath => {
162
- const exists = fs.existsSync(path.join(cwd, filePath));
163
- if (!exists) console.warn(`[lint] Skip missing file-level target: ${filePath}`);
164
- return exists;
165
- });
166
- const eslintFiles = existingFiles.filter(isEslintTarget);
167
- const stylelintFiles = existingFiles.filter(isStylelintTarget);
135
+ const eslintFiles = normalizedFiles.filter(isEslintTarget);
136
+ const stylelintFiles = normalizedFiles.filter(isStylelintTarget);
168
137
  const typeCheckFiles = normalizedFiles.filter(isTypeCheckTarget);
169
138
 
170
139
  const clientTypeFiles = [];
@@ -210,19 +179,18 @@ async function runSelectiveLint(inputFiles) {
210
179
  }
211
180
 
212
181
  async function main() {
213
- const args = process.argv.slice(2);
214
- const mode = parseMode(args);
215
- if (mode.type === 'typecheck') {
216
- await runTypeCheck();
182
+ const files = parseFilesArg(process.argv.slice(2));
183
+ if (files === null) {
184
+ await runDefaultLint();
217
185
  return;
218
186
  }
219
187
 
220
- if (mode.type === 'default') {
221
- await runDefaultLint();
222
- return;
188
+ if (files.length === 0) {
189
+ console.error('[lint] --files requires at least one file path');
190
+ process.exit(1);
223
191
  }
224
192
 
225
- await runSelectiveLint(mode.files);
193
+ await runSelectiveLint(files);
226
194
  }
227
195
 
228
196
  main().catch((error) => {