@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
|
@@ -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
|
|
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(
|
|
17
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
160
|
-
|
|
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
|
|
214
|
-
|
|
215
|
-
|
|
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 (
|
|
221
|
-
|
|
222
|
-
|
|
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(
|
|
193
|
+
await runSelectiveLint(files);
|
|
226
194
|
}
|
|
227
195
|
|
|
228
196
|
main().catch((error) => {
|