@appthen/cli 1.2.3 → 1.2.5
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 +898 -381
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -31527,6 +31527,16 @@ var pluginFactory$5 = function (_a) {
|
|
|
31527
31527
|
COMMON_CHUNK_NAME.FileUtilDefine,
|
|
31528
31528
|
],
|
|
31529
31529
|
});
|
|
31530
|
+
// 添加 defaultProps 静态属性(仅在非空对象时生成)
|
|
31531
|
+
if (ir.defaultProps && typeof ir.defaultProps === 'object' && Object.keys(ir.defaultProps).length > 0) {
|
|
31532
|
+
next.chunks.push({
|
|
31533
|
+
type: ChunkType.STRING,
|
|
31534
|
+
fileType: FileType.JSX,
|
|
31535
|
+
name: CLASS_DEFINE_CHUNK_NAME.StaticVar,
|
|
31536
|
+
content: "static defaultProps = ".concat(JSON.stringify(ir.defaultProps, null, 2), ";"),
|
|
31537
|
+
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
|
|
31538
|
+
});
|
|
31539
|
+
}
|
|
31530
31540
|
next.chunks.push({
|
|
31531
31541
|
type: ChunkType.STRING,
|
|
31532
31542
|
fileType: FileType.JSX,
|
|
@@ -31563,7 +31573,10 @@ var pluginFactory$5 = function (_a) {
|
|
|
31563
31573
|
fileType: FileType.JSX,
|
|
31564
31574
|
name: REACT_CHUNK_NAME.ClassDidMountEnd,
|
|
31565
31575
|
content: '}',
|
|
31566
|
-
linkAfter: [
|
|
31576
|
+
linkAfter: [
|
|
31577
|
+
REACT_CHUNK_NAME.ClassDidMountContent,
|
|
31578
|
+
REACT_CHUNK_NAME.ClassDidMountStart,
|
|
31579
|
+
],
|
|
31567
31580
|
});
|
|
31568
31581
|
next.chunks.push({
|
|
31569
31582
|
type: ChunkType.STRING,
|
|
@@ -36990,11 +37003,11 @@ var lastTimeKey$1 = '$__cacheTime';
|
|
|
36990
37003
|
* @returns {Promise<number>} 错误码
|
|
36991
37004
|
*/
|
|
36992
37005
|
function run(args, options) {
|
|
36993
|
-
var _a, _b, _c, _d, _e
|
|
37006
|
+
var _a, _b, _c, _d, _e;
|
|
36994
37007
|
return __awaiter(this, void 0, void 0, function () {
|
|
36995
|
-
var cacheDirPath, keyCacheDirPath, currentLastTimeKey, cacheTime, afterTime, result, schema, project, documents, componentDocs, packageJSON, projectDocuments, projectDocumentNames_1, subPageDocumentNames_1, clientType, isWeb, solution, outputPath_1, builder, envInfoItem,
|
|
36996
|
-
return __generator(this, function (
|
|
36997
|
-
switch (
|
|
37008
|
+
var cacheDirPath, keyCacheDirPath, currentLastTimeKey, cacheTime, afterTime, result, schema, project, documents, componentDocs, packageJSON, projectDocuments, projectDocumentNames_1, subPageDocumentNames_1, clientType, isWeb, solution, outputPath_1, builder, envInfoItem, generatedSourceCodes, publisher, subPageRoot_1, subPagePath, subPagePathIsExist, getPageUrl_1, transformFilePath, existFiles, existSubFiles, _f, files, syncMap, _loop_1, i, indexPage_1, indexPageUrl_1, globalStyle, globalStyleWithoutFirstLine, globalStyle, globalStyleWithoutFirstLine, appContent, appContentWithImport, utilsFilePath, portalImportCode, haveUpdate, installCmd, e_1;
|
|
37009
|
+
return __generator(this, function (_g) {
|
|
37010
|
+
switch (_g.label) {
|
|
36998
37011
|
case 0:
|
|
36999
37012
|
cacheDirPath = path__default["default"].join(os__default["default"].homedir(), '.cache', 'mengti_temp');
|
|
37000
37013
|
keyCacheDirPath = path__default["default"].join(os__default["default"].homedir(), '.cache', 'mengti_translate');
|
|
@@ -37003,9 +37016,9 @@ function run(args, options) {
|
|
|
37003
37016
|
removeDir(keyCacheDirPath);
|
|
37004
37017
|
}
|
|
37005
37018
|
currentLastTimeKey = path__default["default"].join(process.cwd() + '/' + (options.output || '')) + lastTimeKey$1;
|
|
37006
|
-
|
|
37019
|
+
_g.label = 1;
|
|
37007
37020
|
case 1:
|
|
37008
|
-
|
|
37021
|
+
_g.trys.push([1, 15, , 16]);
|
|
37009
37022
|
cacheTime = cache$1.getKey(currentLastTimeKey);
|
|
37010
37023
|
console.log('[最后同步时间] ', cacheTime ? new Date(Number(cacheTime)).toLocaleString() : '无');
|
|
37011
37024
|
afterTime = cacheTime && !options.clear ? Number(cacheTime) : 0;
|
|
@@ -37021,7 +37034,7 @@ function run(args, options) {
|
|
|
37021
37034
|
afterTime: afterTime,
|
|
37022
37035
|
})];
|
|
37023
37036
|
case 2:
|
|
37024
|
-
result =
|
|
37037
|
+
result = _g.sent();
|
|
37025
37038
|
console.log('[INFO] 项目下载完成... ');
|
|
37026
37039
|
schema = result.schema;
|
|
37027
37040
|
console.log('🔍 原始路由数据:',
|
|
@@ -37039,7 +37052,7 @@ function run(args, options) {
|
|
|
37039
37052
|
return [4 /*yield*/, updateProjectTemplate(solution)];
|
|
37040
37053
|
case 3:
|
|
37041
37054
|
// 更新项目模板
|
|
37042
|
-
|
|
37055
|
+
_g.sent();
|
|
37043
37056
|
console.log('[INFO] 项目模板更新完成... ');
|
|
37044
37057
|
// 检查是否有文件需要更新
|
|
37045
37058
|
if (!project || documents.length === 0) {
|
|
@@ -37061,15 +37074,17 @@ function run(args, options) {
|
|
|
37061
37074
|
}
|
|
37062
37075
|
}
|
|
37063
37076
|
console.log('[INFO] 处理环境配置... ');
|
|
37064
|
-
schemaStr = JSON.stringify(
|
|
37065
|
-
|
|
37077
|
+
// const schemaStr = JSON.stringify(
|
|
37078
|
+
// schema.componentsTree?.slice(0, 20).map((item) => item.fileName)
|
|
37079
|
+
// );
|
|
37080
|
+
// console.log('schemaStr: ', schemaStr);
|
|
37066
37081
|
// const isHaveCheckicon = schemaStr.indexOf('icon.style');
|
|
37067
37082
|
// console.log('isHaveCheck', schemaStr.slice(isHaveCheckicon - 20000, isHaveCheckicon + 20000));
|
|
37068
37083
|
// 生成代码
|
|
37069
37084
|
console.log('[INFO] 开始生成代码... ');
|
|
37070
37085
|
return [4 /*yield*/, builder.generateProject(JSON.parse(JSON.stringify(schema)))];
|
|
37071
37086
|
case 4:
|
|
37072
|
-
generatedSourceCodes =
|
|
37087
|
+
generatedSourceCodes = _g.sent();
|
|
37073
37088
|
console.log('[INFO] 代码生成完成... ');
|
|
37074
37089
|
generatedSourceCodes.files = generatedSourceCodes.files.filter(function (item) { return item.ext === 'css' || item.ext === 'jsx'; });
|
|
37075
37090
|
console.log('[INFO] 过滤代码... ');
|
|
@@ -37086,7 +37101,7 @@ function run(args, options) {
|
|
|
37086
37101
|
createProjectFolder: false,
|
|
37087
37102
|
})];
|
|
37088
37103
|
case 5:
|
|
37089
|
-
|
|
37104
|
+
_g.sent();
|
|
37090
37105
|
console.log('[INFO] 代码生成完成... ');
|
|
37091
37106
|
if (!fs.existsSync("./".concat(outputPath_1, "/"))) {
|
|
37092
37107
|
fs.mkdirSync("./".concat(outputPath_1, "/"), {
|
|
@@ -37121,20 +37136,20 @@ function run(args, options) {
|
|
|
37121
37136
|
};
|
|
37122
37137
|
return [4 /*yield*/, getAllFile("./".concat(outputPath_1, "/"))];
|
|
37123
37138
|
case 6:
|
|
37124
|
-
existFiles =
|
|
37139
|
+
existFiles = _g.sent();
|
|
37125
37140
|
if (!subPagePathIsExist) return [3 /*break*/, 8];
|
|
37126
37141
|
return [4 /*yield*/, getAllFile(subPagePath)];
|
|
37127
37142
|
case 7:
|
|
37128
|
-
|
|
37143
|
+
_f = _g.sent();
|
|
37129
37144
|
return [3 /*break*/, 9];
|
|
37130
37145
|
case 8:
|
|
37131
|
-
|
|
37132
|
-
|
|
37146
|
+
_f = [];
|
|
37147
|
+
_g.label = 9;
|
|
37133
37148
|
case 9:
|
|
37134
|
-
existSubFiles =
|
|
37149
|
+
existSubFiles = _f;
|
|
37135
37150
|
return [4 /*yield*/, getAllFile(cacheDirPath + '/')];
|
|
37136
37151
|
case 10:
|
|
37137
|
-
files =
|
|
37152
|
+
files = _g.sent();
|
|
37138
37153
|
syncMap = {
|
|
37139
37154
|
components: existFiles
|
|
37140
37155
|
.filter(function (_) { return ['tsx', 'jsx'].includes(_.ext) && _.path.includes('components'); })
|
|
@@ -37186,9 +37201,9 @@ function run(args, options) {
|
|
|
37186
37201
|
.map(function (_) { return getPageUrl_1(_, subPageRoot_1); }),
|
|
37187
37202
|
};
|
|
37188
37203
|
_loop_1 = function (i) {
|
|
37189
|
-
var file, fileName_1, extName, cssFilePath, cssStr, doc,
|
|
37190
|
-
return __generator(this, function (
|
|
37191
|
-
switch (
|
|
37204
|
+
var file, fileName_1, extName, cssFilePath, cssStr, doc, _h, code, images, svgs, configJsCode, iconsFile, iconsConsts, index, svg, index, image, e_2, realFilePath;
|
|
37205
|
+
return __generator(this, function (_j) {
|
|
37206
|
+
switch (_j.label) {
|
|
37192
37207
|
case 0:
|
|
37193
37208
|
file = files[i];
|
|
37194
37209
|
if (process.env.DEV) {
|
|
@@ -37205,8 +37220,8 @@ function run(args, options) {
|
|
|
37205
37220
|
if (!(file.fileName === 'utils.js')) return [3 /*break*/, 2];
|
|
37206
37221
|
return [4 /*yield*/, transformUtils(file, schema, project, solution)];
|
|
37207
37222
|
case 1:
|
|
37208
|
-
|
|
37209
|
-
|
|
37223
|
+
_j.sent();
|
|
37224
|
+
_j.label = 2;
|
|
37210
37225
|
case 2:
|
|
37211
37226
|
if (extName === 'css' || extName === 'scss') {
|
|
37212
37227
|
cssFilePath = file.path + '/' + file.fileName;
|
|
@@ -37255,7 +37270,7 @@ function run(args, options) {
|
|
|
37255
37270
|
}
|
|
37256
37271
|
return [4 /*yield*/, transformJsx(file, solution, outputPath_1)];
|
|
37257
37272
|
case 3:
|
|
37258
|
-
|
|
37273
|
+
_h = _j.sent(), code = _h.code, images = _h.images, svgs = _h.svgs;
|
|
37259
37274
|
console.log('[BUILD SUCCESS]', file.name);
|
|
37260
37275
|
// 写入暂存文件夹
|
|
37261
37276
|
fs.writeFileSync(file.path + '/' + file.fileName, code);
|
|
@@ -37301,23 +37316,23 @@ function run(args, options) {
|
|
|
37301
37316
|
.join('\n'));
|
|
37302
37317
|
}
|
|
37303
37318
|
index = 0;
|
|
37304
|
-
|
|
37319
|
+
_j.label = 4;
|
|
37305
37320
|
case 4:
|
|
37306
37321
|
if (!(index < images.length)) return [3 /*break*/, 9];
|
|
37307
37322
|
image = images[index];
|
|
37308
37323
|
if (!(image.url && image.fileName)) return [3 /*break*/, 8];
|
|
37309
|
-
|
|
37324
|
+
_j.label = 5;
|
|
37310
37325
|
case 5:
|
|
37311
|
-
|
|
37326
|
+
_j.trys.push([5, 7, , 8]);
|
|
37312
37327
|
if (!fs.existsSync(file.path + '/images')) {
|
|
37313
37328
|
fs.mkdirSync(file.path + '/images');
|
|
37314
37329
|
}
|
|
37315
37330
|
return [4 /*yield*/, downloadFile(image.url, file.path + '/images/' + image.fileName)];
|
|
37316
37331
|
case 6:
|
|
37317
|
-
|
|
37332
|
+
_j.sent();
|
|
37318
37333
|
return [3 /*break*/, 8];
|
|
37319
37334
|
case 7:
|
|
37320
|
-
e_2 =
|
|
37335
|
+
e_2 = _j.sent();
|
|
37321
37336
|
console.log('[downloadFile Error] ', e_2);
|
|
37322
37337
|
return [3 /*break*/, 8];
|
|
37323
37338
|
case 8:
|
|
@@ -37334,35 +37349,32 @@ function run(args, options) {
|
|
|
37334
37349
|
if (fs.existsSync(realFilePath)) {
|
|
37335
37350
|
removeDir(realFilePath);
|
|
37336
37351
|
}
|
|
37337
|
-
console.log('realFilePath: ', realFilePath, doc === null || doc === void 0 ? void 0 : doc.fileName, doc === null || doc === void 0 ? void 0 : doc.type);
|
|
37338
37352
|
if ((doc === null || doc === void 0 ? void 0 : doc.type) === 'Page') {
|
|
37339
|
-
console.log('realFilePath: ', realFilePath);
|
|
37340
37353
|
fs.copySync("".concat(cacheDirPath, "/src/pages/").concat(file.name), realFilePath.replace(file.name, doc.fileName));
|
|
37341
37354
|
}
|
|
37342
37355
|
if ((doc === null || doc === void 0 ? void 0 : doc.type) === 'Component') {
|
|
37343
|
-
console.log('realFilePath1: ', realFilePath);
|
|
37344
37356
|
fs.copySync("".concat(cacheDirPath, "/src/components/").concat(file.name), realFilePath.replace(file.name, doc.fileName));
|
|
37345
37357
|
}
|
|
37346
|
-
|
|
37358
|
+
_j.label = 10;
|
|
37347
37359
|
case 10: return [2 /*return*/];
|
|
37348
37360
|
}
|
|
37349
37361
|
});
|
|
37350
37362
|
};
|
|
37351
37363
|
i = 0;
|
|
37352
|
-
|
|
37364
|
+
_g.label = 11;
|
|
37353
37365
|
case 11:
|
|
37354
37366
|
if (!(i < files.length)) return [3 /*break*/, 14];
|
|
37355
37367
|
return [5 /*yield**/, _loop_1(i)];
|
|
37356
37368
|
case 12:
|
|
37357
|
-
|
|
37358
|
-
|
|
37369
|
+
_g.sent();
|
|
37370
|
+
_g.label = 13;
|
|
37359
37371
|
case 13:
|
|
37360
37372
|
i++;
|
|
37361
37373
|
return [3 /*break*/, 11];
|
|
37362
37374
|
case 14:
|
|
37363
37375
|
// 更新同步时间
|
|
37364
37376
|
cache$1.setKey(currentLastTimeKey, String(Date.now()));
|
|
37365
|
-
indexPage_1 = (
|
|
37377
|
+
indexPage_1 = (_e = project.appConfig) === null || _e === void 0 ? void 0 : _e.indexPage;
|
|
37366
37378
|
if (indexPage_1) {
|
|
37367
37379
|
// 首页排序
|
|
37368
37380
|
syncMap.pages = syncMap.pages.sort(function (a, b) {
|
|
@@ -37453,7 +37465,7 @@ function run(args, options) {
|
|
|
37453
37465
|
console.log("[INFO ".concat(new Date().toLocaleString(), "] \u4EE3\u7801\u589E\u91CF\u540C\u6B65\u5B8C\u6210"));
|
|
37454
37466
|
return [2 /*return*/, 0];
|
|
37455
37467
|
case 15:
|
|
37456
|
-
e_1 =
|
|
37468
|
+
e_1 = _g.sent();
|
|
37457
37469
|
console.log(chalk__default["default"].red(getErrorMessage(e_1) || "Unexpected error: ".concat(e_1)));
|
|
37458
37470
|
// 保存缓存
|
|
37459
37471
|
cache$1.removeKey(currentLastTimeKey);
|
|
@@ -37880,37 +37892,7 @@ function create(options) {
|
|
|
37880
37892
|
console.log('[e] ', e_1);
|
|
37881
37893
|
// return {} as any;
|
|
37882
37894
|
throw e_1;
|
|
37883
|
-
case 7:
|
|
37884
|
-
// await createProjectFromTemplate(options.template);
|
|
37885
|
-
// await createProjectFromTemplate('https://cdn.appthen.cn/templates/appthen-vite-starter.zip', 'my-new-project');
|
|
37886
|
-
// const { projectType } = await inquirer.prompt([
|
|
37887
|
-
// {
|
|
37888
|
-
// type: 'list',
|
|
37889
|
-
// name: 'projectType',
|
|
37890
|
-
// message: 'Which type of project do you want to initialize?',
|
|
37891
|
-
// choices: ['Vite Project', 'Taro Project', 'Asset Package Project'],
|
|
37892
|
-
// },
|
|
37893
|
-
// ]);
|
|
37894
|
-
// switch (projectType) {
|
|
37895
|
-
// case 'Vite Project':
|
|
37896
|
-
// console.log('projectType: ', projectType);
|
|
37897
|
-
// // Initialize a Vite project
|
|
37898
|
-
// // await require('../dist/index.js').initViteProject(options);
|
|
37899
|
-
// break;
|
|
37900
|
-
// case 'Taro Project':
|
|
37901
|
-
// console.log('projectType: ', projectType);
|
|
37902
|
-
// // Initialize a Taro project
|
|
37903
|
-
// // await require('../dist/index.js').initTaroProject(options);
|
|
37904
|
-
// break;
|
|
37905
|
-
// case 'Asset Package Project':
|
|
37906
|
-
// console.log('projectType: ', projectType);
|
|
37907
|
-
// // Initialize an asset package project
|
|
37908
|
-
// // await require('../dist/index.js').initAssetPackageProject(options);
|
|
37909
|
-
// break;
|
|
37910
|
-
// default:
|
|
37911
|
-
// console.error('Unknown project type');
|
|
37912
|
-
// }
|
|
37913
|
-
return [2 /*return*/, 1];
|
|
37895
|
+
case 7: return [2 /*return*/, 1];
|
|
37914
37896
|
}
|
|
37915
37897
|
});
|
|
37916
37898
|
});
|
|
@@ -41243,7 +41225,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41243
41225
|
return !!this.state.files[filePath];
|
|
41244
41226
|
};
|
|
41245
41227
|
/**
|
|
41246
|
-
* 🆕
|
|
41228
|
+
* 🆕 读取影子空间中的文件内容(带缓存)
|
|
41247
41229
|
*/
|
|
41248
41230
|
ShadowSpace.prototype.readFile = function (filePath) {
|
|
41249
41231
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -41273,6 +41255,38 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41273
41255
|
});
|
|
41274
41256
|
});
|
|
41275
41257
|
};
|
|
41258
|
+
/**
|
|
41259
|
+
* 🆕 实时读取文件内容(直接从文件系统,不使用缓存)
|
|
41260
|
+
*/
|
|
41261
|
+
ShadowSpace.prototype.readRealTimeFile = function (filePath) {
|
|
41262
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
41263
|
+
var fullPath, content, error_4;
|
|
41264
|
+
return __generator(this, function (_a) {
|
|
41265
|
+
switch (_a.label) {
|
|
41266
|
+
case 0:
|
|
41267
|
+
_a.trys.push([0, 3, , 4]);
|
|
41268
|
+
fullPath = path__default["default"].join(this.config.projectRoot, filePath);
|
|
41269
|
+
// 检查文件是否存在
|
|
41270
|
+
return [4 /*yield*/, fs__default$1["default"].access(fullPath)];
|
|
41271
|
+
case 1:
|
|
41272
|
+
// 检查文件是否存在
|
|
41273
|
+
_a.sent();
|
|
41274
|
+
return [4 /*yield*/, fs__default$1["default"].readFile(fullPath, 'utf8')];
|
|
41275
|
+
case 2:
|
|
41276
|
+
content = _a.sent();
|
|
41277
|
+
console.log("[ShadowSpace] \u5B9E\u65F6\u8BFB\u53D6\u6587\u4EF6\u6210\u529F: ".concat(filePath, ", \u957F\u5EA6: ").concat(content.length));
|
|
41278
|
+
// 可选:更新内存缓存以确保一致性
|
|
41279
|
+
this.contentCache.set(filePath, content);
|
|
41280
|
+
return [2 /*return*/, content];
|
|
41281
|
+
case 3:
|
|
41282
|
+
error_4 = _a.sent();
|
|
41283
|
+
console.warn("[ShadowSpace] \u5B9E\u65F6\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25: ".concat(filePath), error_4);
|
|
41284
|
+
return [2 /*return*/, null];
|
|
41285
|
+
case 4: return [2 /*return*/];
|
|
41286
|
+
}
|
|
41287
|
+
});
|
|
41288
|
+
});
|
|
41289
|
+
};
|
|
41276
41290
|
/**
|
|
41277
41291
|
* 标记文件为远程修改
|
|
41278
41292
|
* 当编辑器通过WebSocket修改文件后调用此方法
|
|
@@ -41280,7 +41294,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41280
41294
|
ShadowSpace.prototype.markAsRemoteModified = function (filePaths) {
|
|
41281
41295
|
var _a;
|
|
41282
41296
|
return __awaiter(this, void 0, void 0, function () {
|
|
41283
|
-
var now, hasChanges, filePaths_1, filePaths_1_1, filePath, fullPath, stats, content, hash, existingFile, remoteHash,
|
|
41297
|
+
var now, hasChanges, filePaths_1, filePaths_1_1, filePath, fullPath, stats, content, hash, existingFile, remoteHash, error_5, e_6_1;
|
|
41284
41298
|
var e_6, _b;
|
|
41285
41299
|
return __generator(this, function (_c) {
|
|
41286
41300
|
switch (_c.label) {
|
|
@@ -41330,8 +41344,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41330
41344
|
});
|
|
41331
41345
|
return [3 /*break*/, 7];
|
|
41332
41346
|
case 6:
|
|
41333
|
-
|
|
41334
|
-
console.warn("\u6807\u8BB0\u8FDC\u7A0B\u4FEE\u6539\u5931\u8D25 ".concat(filePath, ":"),
|
|
41347
|
+
error_5 = _c.sent();
|
|
41348
|
+
console.warn("\u6807\u8BB0\u8FDC\u7A0B\u4FEE\u6539\u5931\u8D25 ".concat(filePath, ":"), error_5);
|
|
41335
41349
|
return [3 /*break*/, 7];
|
|
41336
41350
|
case 7:
|
|
41337
41351
|
filePaths_1_1 = filePaths_1.next();
|
|
@@ -41408,7 +41422,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41408
41422
|
*/
|
|
41409
41423
|
ShadowSpace.prototype.getSpaceSnapshots = function (_spaceId) {
|
|
41410
41424
|
return __awaiter(this, void 0, void 0, function () {
|
|
41411
|
-
var snapshots, _a, _b, _c, filePath, shadowEntry,
|
|
41425
|
+
var snapshots, _a, _b, _c, filePath, shadowEntry, error_6;
|
|
41412
41426
|
var e_8, _d;
|
|
41413
41427
|
return __generator(this, function (_e) {
|
|
41414
41428
|
switch (_e.label) {
|
|
@@ -41448,8 +41462,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41448
41462
|
console.log("[ShadowSpace] \u83B7\u53D6\u7A7A\u95F4\u5FEB\u7167: ".concat(snapshots.length, " \u4E2A\u6587\u4EF6"));
|
|
41449
41463
|
return [2 /*return*/, snapshots];
|
|
41450
41464
|
case 2:
|
|
41451
|
-
|
|
41452
|
-
console.error("[ShadowSpace] \u83B7\u53D6\u7A7A\u95F4\u5FEB\u7167\u5931\u8D25:",
|
|
41465
|
+
error_6 = _e.sent();
|
|
41466
|
+
console.error("[ShadowSpace] \u83B7\u53D6\u7A7A\u95F4\u5FEB\u7167\u5931\u8D25:", error_6);
|
|
41453
41467
|
return [2 /*return*/, []]; // 返回空数组而不是 undefined
|
|
41454
41468
|
case 3: return [2 /*return*/];
|
|
41455
41469
|
}
|
|
@@ -41510,7 +41524,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41510
41524
|
*/
|
|
41511
41525
|
ShadowSpace.prototype.saveSpaceConfig = function () {
|
|
41512
41526
|
return __awaiter(this, void 0, void 0, function () {
|
|
41513
|
-
var configFile, config,
|
|
41527
|
+
var configFile, config, error_8;
|
|
41514
41528
|
return __generator(this, function (_a) {
|
|
41515
41529
|
switch (_a.label) {
|
|
41516
41530
|
case 0:
|
|
@@ -41535,8 +41549,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41535
41549
|
console.log("[ShadowSpace] \u7A7A\u95F4\u914D\u7F6E\u5DF2\u4FDD\u5B58: ".concat(configFile));
|
|
41536
41550
|
return [3 /*break*/, 5];
|
|
41537
41551
|
case 4:
|
|
41538
|
-
|
|
41539
|
-
console.warn("[ShadowSpace] \u4FDD\u5B58\u7A7A\u95F4\u914D\u7F6E\u5931\u8D25:",
|
|
41552
|
+
error_8 = _a.sent();
|
|
41553
|
+
console.warn("[ShadowSpace] \u4FDD\u5B58\u7A7A\u95F4\u914D\u7F6E\u5931\u8D25:", error_8);
|
|
41540
41554
|
return [3 /*break*/, 5];
|
|
41541
41555
|
case 5: return [2 /*return*/];
|
|
41542
41556
|
}
|
|
@@ -41548,7 +41562,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41548
41562
|
*/
|
|
41549
41563
|
ShadowSpace.prototype.migrateOldStateFiles = function () {
|
|
41550
41564
|
return __awaiter(this, void 0, void 0, function () {
|
|
41551
|
-
var appthenDir, files, oldStateFiles, oldStateFiles_1, oldStateFiles_1_1, oldFile, oldFilePath, oldState, backupFile, e_9_1,
|
|
41565
|
+
var appthenDir, files, oldStateFiles, oldStateFiles_1, oldStateFiles_1_1, oldFile, oldFilePath, oldState, backupFile, e_9_1, error_9;
|
|
41552
41566
|
var e_9, _a;
|
|
41553
41567
|
var _this = this;
|
|
41554
41568
|
return __generator(this, function (_b) {
|
|
@@ -41614,8 +41628,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41614
41628
|
return [7 /*endfinally*/];
|
|
41615
41629
|
case 11: return [3 /*break*/, 13];
|
|
41616
41630
|
case 12:
|
|
41617
|
-
|
|
41618
|
-
console.warn("[ShadowSpace] \u8FC1\u79FB\u65E7\u72B6\u6001\u6587\u4EF6\u5931\u8D25:",
|
|
41631
|
+
error_9 = _b.sent();
|
|
41632
|
+
console.warn("[ShadowSpace] \u8FC1\u79FB\u65E7\u72B6\u6001\u6587\u4EF6\u5931\u8D25:", error_9);
|
|
41619
41633
|
return [3 /*break*/, 13];
|
|
41620
41634
|
case 13: return [2 /*return*/];
|
|
41621
41635
|
}
|
|
@@ -41624,7 +41638,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41624
41638
|
};
|
|
41625
41639
|
ShadowSpace.prototype.getShadowContent = function (filePath) {
|
|
41626
41640
|
return __awaiter(this, void 0, void 0, function () {
|
|
41627
|
-
var localPath, content,
|
|
41641
|
+
var localPath, content, error_10;
|
|
41628
41642
|
return __generator(this, function (_a) {
|
|
41629
41643
|
switch (_a.label) {
|
|
41630
41644
|
case 0:
|
|
@@ -41642,8 +41656,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41642
41656
|
this.contentCache.set(filePath, content);
|
|
41643
41657
|
return [2 /*return*/, content];
|
|
41644
41658
|
case 3:
|
|
41645
|
-
|
|
41646
|
-
console.warn("\u65E0\u6CD5\u83B7\u53D6\u5F71\u5B50\u5185\u5BB9: ".concat(filePath),
|
|
41659
|
+
error_10 = _a.sent();
|
|
41660
|
+
console.warn("\u65E0\u6CD5\u83B7\u53D6\u5F71\u5B50\u5185\u5BB9: ".concat(filePath), error_10);
|
|
41647
41661
|
return [2 /*return*/, ''];
|
|
41648
41662
|
case 4: return [2 /*return*/];
|
|
41649
41663
|
}
|
|
@@ -41717,7 +41731,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41717
41731
|
};
|
|
41718
41732
|
ShadowSpace.prototype.writeLocalFile = function (filePath, content) {
|
|
41719
41733
|
return __awaiter(this, void 0, void 0, function () {
|
|
41720
|
-
var fullPath,
|
|
41734
|
+
var fullPath, error_11;
|
|
41721
41735
|
return __generator(this, function (_a) {
|
|
41722
41736
|
switch (_a.label) {
|
|
41723
41737
|
case 0:
|
|
@@ -41740,9 +41754,9 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41740
41754
|
console.log("[ShadowSpace] \u6587\u4EF6\u5199\u5165\u6210\u529F: ".concat(fullPath));
|
|
41741
41755
|
return [3 /*break*/, 5];
|
|
41742
41756
|
case 4:
|
|
41743
|
-
|
|
41744
|
-
console.error("[ShadowSpace] \u6587\u4EF6\u5199\u5165\u5931\u8D25: ".concat(fullPath),
|
|
41745
|
-
throw
|
|
41757
|
+
error_11 = _a.sent();
|
|
41758
|
+
console.error("[ShadowSpace] \u6587\u4EF6\u5199\u5165\u5931\u8D25: ".concat(fullPath), error_11);
|
|
41759
|
+
throw error_11;
|
|
41746
41760
|
case 5: return [2 /*return*/];
|
|
41747
41761
|
}
|
|
41748
41762
|
});
|
|
@@ -41750,7 +41764,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41750
41764
|
};
|
|
41751
41765
|
ShadowSpace.prototype.scanLocalFiles = function () {
|
|
41752
41766
|
return __awaiter(this, void 0, void 0, function () {
|
|
41753
|
-
var files, pattern, options, filePaths, filePaths_2, filePaths_2_1, filePath, fullPath, content, stats,
|
|
41767
|
+
var files, pattern, options, filePaths, filePaths_2, filePaths_2_1, filePath, fullPath, content, stats, error_12, e_11_1;
|
|
41754
41768
|
var e_11, _a;
|
|
41755
41769
|
return __generator(this, function (_b) {
|
|
41756
41770
|
switch (_b.label) {
|
|
@@ -41790,8 +41804,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41790
41804
|
});
|
|
41791
41805
|
return [3 /*break*/, 7];
|
|
41792
41806
|
case 6:
|
|
41793
|
-
|
|
41794
|
-
console.warn("\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25: ".concat(filePath),
|
|
41807
|
+
error_12 = _b.sent();
|
|
41808
|
+
console.warn("\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25: ".concat(filePath), error_12);
|
|
41795
41809
|
return [3 /*break*/, 7];
|
|
41796
41810
|
case 7:
|
|
41797
41811
|
filePaths_2_1 = filePaths_2.next();
|
|
@@ -41992,7 +42006,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41992
42006
|
*/
|
|
41993
42007
|
ShadowSpace.prototype.onFileChanged = function (filePath) {
|
|
41994
42008
|
return __awaiter(this, void 0, void 0, function () {
|
|
41995
|
-
var relativePath, shadowEntry, content, hash, stats,
|
|
42009
|
+
var relativePath, shadowEntry, content, hash, stats, error_14;
|
|
41996
42010
|
return __generator(this, function (_a) {
|
|
41997
42011
|
switch (_a.label) {
|
|
41998
42012
|
case 0:
|
|
@@ -42026,8 +42040,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
42026
42040
|
});
|
|
42027
42041
|
return [3 /*break*/, 6];
|
|
42028
42042
|
case 5:
|
|
42029
|
-
|
|
42030
|
-
console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u53D8\u66F4\u5931\u8D25: ".concat(relativePath),
|
|
42043
|
+
error_14 = _a.sent();
|
|
42044
|
+
console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u53D8\u66F4\u5931\u8D25: ".concat(relativePath), error_14);
|
|
42031
42045
|
return [3 /*break*/, 6];
|
|
42032
42046
|
case 6: return [2 /*return*/];
|
|
42033
42047
|
}
|
|
@@ -42039,7 +42053,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
42039
42053
|
*/
|
|
42040
42054
|
ShadowSpace.prototype.onFileAdded = function (filePath) {
|
|
42041
42055
|
return __awaiter(this, void 0, void 0, function () {
|
|
42042
|
-
var relativePath, content, hash, stats,
|
|
42056
|
+
var relativePath, content, hash, stats, error_15;
|
|
42043
42057
|
return __generator(this, function (_a) {
|
|
42044
42058
|
switch (_a.label) {
|
|
42045
42059
|
case 0:
|
|
@@ -42066,8 +42080,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
42066
42080
|
});
|
|
42067
42081
|
return [3 /*break*/, 5];
|
|
42068
42082
|
case 4:
|
|
42069
|
-
|
|
42070
|
-
console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u65B0\u589E\u5931\u8D25: ".concat(relativePath),
|
|
42083
|
+
error_15 = _a.sent();
|
|
42084
|
+
console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u65B0\u589E\u5931\u8D25: ".concat(relativePath), error_15);
|
|
42071
42085
|
return [3 /*break*/, 5];
|
|
42072
42086
|
case 5: return [2 /*return*/];
|
|
42073
42087
|
}
|
|
@@ -42199,6 +42213,8 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42199
42213
|
this.currentUserId = null;
|
|
42200
42214
|
// 🆕 变更聚合器
|
|
42201
42215
|
this.changeAggregator = null;
|
|
42216
|
+
// 🆕 实时读取配置
|
|
42217
|
+
this.useRealtimeFileRead = true;
|
|
42202
42218
|
this.shadowSpace = shadowSpace;
|
|
42203
42219
|
this.socketStore = socketStore;
|
|
42204
42220
|
}
|
|
@@ -42209,6 +42225,13 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42209
42225
|
this.currentUserId = userId;
|
|
42210
42226
|
console.log("[ShadowSpace] \u8BBE\u7F6E\u5F53\u524D\u7528\u6237ID: ".concat(userId));
|
|
42211
42227
|
};
|
|
42228
|
+
/**
|
|
42229
|
+
* 设置是否使用实时文件读取
|
|
42230
|
+
*/
|
|
42231
|
+
ShadowSpaceCommandHandler.prototype.setRealtimeFileRead = function (enabled) {
|
|
42232
|
+
this.useRealtimeFileRead = enabled;
|
|
42233
|
+
console.log("[ShadowSpace] \u5B9E\u65F6\u6587\u4EF6\u8BFB\u53D6\u5DF2".concat(enabled ? '启用' : '禁用'));
|
|
42234
|
+
};
|
|
42212
42235
|
/**
|
|
42213
42236
|
* 处理WebSocket消息
|
|
42214
42237
|
*/
|
|
@@ -42271,14 +42294,14 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42271
42294
|
console.log('[ShadowSpaceCommandHandler] 获取文件内容 - message:', JSON.stringify(message, null, 2));
|
|
42272
42295
|
console.log('[ShadowSpaceCommandHandler] 获取文件内容 - message.path:', message.path);
|
|
42273
42296
|
console.log('[ShadowSpaceCommandHandler] 获取文件内容 - message.message.path:', (_b = message.message) === null || _b === void 0 ? void 0 : _b.path);
|
|
42274
|
-
return [4 /*yield*/, this.getFileContent(((_c = message.message) === null || _c === void 0 ? void 0 : _c.path) || message.path)];
|
|
42297
|
+
return [4 /*yield*/, this.getFileContent(((_c = message.message) === null || _c === void 0 ? void 0 : _c.path) || message.path, this.useRealtimeFileRead)];
|
|
42275
42298
|
case 5:
|
|
42276
|
-
// 🆕 修复:路径在 message.message.path
|
|
42299
|
+
// 🆕 修复:路径在 message.message.path 中,使用配置的实时读取选项
|
|
42277
42300
|
result = _j.sent();
|
|
42278
42301
|
return [3 /*break*/, 27];
|
|
42279
|
-
case 6: return [4 /*yield*/, this.getFilesContent(((_d = message.message) === null || _d === void 0 ? void 0 : _d.paths) || message.paths)];
|
|
42302
|
+
case 6: return [4 /*yield*/, this.getFilesContent(((_d = message.message) === null || _d === void 0 ? void 0 : _d.paths) || message.paths, this.useRealtimeFileRead)];
|
|
42280
42303
|
case 7:
|
|
42281
|
-
// 🆕 修复:路径在 message.message.paths
|
|
42304
|
+
// 🆕 修复:路径在 message.message.paths 中,使用配置的实时读取选项
|
|
42282
42305
|
result = _j.sent();
|
|
42283
42306
|
return [3 /*break*/, 27];
|
|
42284
42307
|
case 8: return [4 /*yield*/, this.applyChanges(message.changes)];
|
|
@@ -42387,9 +42410,10 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42387
42410
|
/**
|
|
42388
42411
|
* 2. 获取单个文件内容
|
|
42389
42412
|
*/
|
|
42390
|
-
ShadowSpaceCommandHandler.prototype.getFileContent = function (filePath) {
|
|
42413
|
+
ShadowSpaceCommandHandler.prototype.getFileContent = function (filePath, readRealtime) {
|
|
42414
|
+
if (readRealtime === void 0) { readRealtime = true; }
|
|
42391
42415
|
return __awaiter(this, void 0, void 0, function () {
|
|
42392
|
-
var normalizedPath, changes, change, fileContent,
|
|
42416
|
+
var normalizedPath, realTimeContent, result_1, readError_1, changes, change, fileContent, result_2, readError_2, result;
|
|
42393
42417
|
return __generator(this, function (_a) {
|
|
42394
42418
|
switch (_a.label) {
|
|
42395
42419
|
case 0:
|
|
@@ -42399,25 +42423,59 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42399
42423
|
normalizedPath = filePath.startsWith('/')
|
|
42400
42424
|
? filePath.substring(1)
|
|
42401
42425
|
: filePath;
|
|
42402
|
-
console.log("[ShadowSpace] \u83B7\u53D6\u6587\u4EF6\u5185\u5BB9: ".concat(filePath, " -> \u6807\u51C6\u5316\u4E3A: ").concat(normalizedPath));
|
|
42403
|
-
return [
|
|
42426
|
+
console.log("[ShadowSpace] \u83B7\u53D6\u6587\u4EF6\u5185\u5BB9: ".concat(filePath, " -> \u6807\u51C6\u5316\u4E3A: ").concat(normalizedPath, ", \u5B9E\u65F6\u8BFB\u53D6: ").concat(readRealtime));
|
|
42427
|
+
if (!readRealtime) return [3 /*break*/, 4];
|
|
42428
|
+
_a.label = 1;
|
|
42404
42429
|
case 1:
|
|
42430
|
+
_a.trys.push([1, 3, , 4]);
|
|
42431
|
+
return [4 /*yield*/, this.shadowSpace.readRealTimeFile(normalizedPath)];
|
|
42432
|
+
case 2:
|
|
42433
|
+
realTimeContent = _a.sent();
|
|
42434
|
+
if (realTimeContent !== null) {
|
|
42435
|
+
console.log("[ShadowSpace] \u6210\u529F\u8BFB\u53D6\u5B9E\u65F6\u6587\u4EF6: ".concat(normalizedPath));
|
|
42436
|
+
result_1 = {
|
|
42437
|
+
path: normalizedPath,
|
|
42438
|
+
action: 'read',
|
|
42439
|
+
version: 1,
|
|
42440
|
+
timestamp: Date.now(),
|
|
42441
|
+
diff: {
|
|
42442
|
+
before: '',
|
|
42443
|
+
after: realTimeContent,
|
|
42444
|
+
},
|
|
42445
|
+
metadata: {
|
|
42446
|
+
beforeSize: 0,
|
|
42447
|
+
afterSize: Buffer.byteLength(realTimeContent, 'utf8'),
|
|
42448
|
+
encoding: 'utf8',
|
|
42449
|
+
},
|
|
42450
|
+
};
|
|
42451
|
+
console.log("[ShadowSpace] \u5B9E\u65F6\u8BFB\u53D6\u6587\u4EF6\u6210\u529F: ".concat(normalizedPath, ", \u5927\u5C0F: ").concat(result_1.metadata.afterSize, " \u5B57\u8282"));
|
|
42452
|
+
return [2 /*return*/, result_1];
|
|
42453
|
+
}
|
|
42454
|
+
return [3 /*break*/, 4];
|
|
42455
|
+
case 3:
|
|
42456
|
+
readError_1 = _a.sent();
|
|
42457
|
+
console.warn("[ShadowSpace] \u5B9E\u65F6\u8BFB\u53D6\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u7F13\u5B58: ".concat(normalizedPath), readError_1);
|
|
42458
|
+
return [3 /*break*/, 4];
|
|
42459
|
+
case 4: return [4 /*yield*/, this.shadowSpace.detectChanges()];
|
|
42460
|
+
case 5:
|
|
42405
42461
|
changes = _a.sent();
|
|
42406
42462
|
change = changes.find(function (c) { return c.path === normalizedPath; });
|
|
42407
|
-
|
|
42463
|
+
console.log('change: ', change);
|
|
42464
|
+
if (!change) return [3 /*break*/, 6];
|
|
42408
42465
|
console.log("[ShadowSpace] \u5728\u53D8\u66F4\u5217\u8868\u4E2D\u627E\u5230\u6587\u4EF6: ".concat(normalizedPath));
|
|
42409
|
-
return [3 /*break*/,
|
|
42410
|
-
case
|
|
42466
|
+
return [3 /*break*/, 11];
|
|
42467
|
+
case 6:
|
|
42411
42468
|
console.log("[ShadowSpace] \u6587\u4EF6\u4E0D\u5728\u53D8\u66F4\u5217\u8868\u4E2D\uFF0C\u5C1D\u8BD5\u76F4\u63A5\u4ECE\u5F71\u5B50\u7A7A\u95F4\u8BFB\u53D6: ".concat(normalizedPath));
|
|
42412
|
-
_a.label =
|
|
42413
|
-
case
|
|
42414
|
-
_a.trys.push([
|
|
42469
|
+
_a.label = 7;
|
|
42470
|
+
case 7:
|
|
42471
|
+
_a.trys.push([7, 9, , 10]);
|
|
42415
42472
|
return [4 /*yield*/, this.shadowSpace.readFile(normalizedPath)];
|
|
42416
|
-
case
|
|
42473
|
+
case 8:
|
|
42417
42474
|
fileContent = _a.sent();
|
|
42475
|
+
console.log('fileContent: ', fileContent);
|
|
42418
42476
|
if (fileContent !== null) {
|
|
42419
42477
|
console.log("[ShadowSpace] \u6210\u529F\u4ECE\u5F71\u5B50\u7A7A\u95F4\u8BFB\u53D6\u6587\u4EF6: ".concat(normalizedPath));
|
|
42420
|
-
|
|
42478
|
+
result_2 = {
|
|
42421
42479
|
path: normalizedPath,
|
|
42422
42480
|
action: 'read',
|
|
42423
42481
|
version: 1,
|
|
@@ -42432,19 +42490,19 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42432
42490
|
encoding: 'utf8',
|
|
42433
42491
|
},
|
|
42434
42492
|
};
|
|
42435
|
-
console.log("[ShadowSpace] \u76F4\u63A5\u8BFB\u53D6\u6587\u4EF6\u6210\u529F: ".concat(normalizedPath, ", \u5927\u5C0F: ").concat(
|
|
42436
|
-
return [2 /*return*/,
|
|
42493
|
+
console.log("[ShadowSpace] \u76F4\u63A5\u8BFB\u53D6\u6587\u4EF6\u6210\u529F: ".concat(normalizedPath, ", \u5927\u5C0F: ").concat(result_2.metadata.afterSize, " \u5B57\u8282"));
|
|
42494
|
+
return [2 /*return*/, result_2];
|
|
42437
42495
|
}
|
|
42438
|
-
return [3 /*break*/,
|
|
42439
|
-
case
|
|
42440
|
-
|
|
42441
|
-
console.error("[ShadowSpace] \u76F4\u63A5\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25: ".concat(normalizedPath),
|
|
42442
|
-
return [3 /*break*/,
|
|
42443
|
-
case
|
|
42496
|
+
return [3 /*break*/, 10];
|
|
42497
|
+
case 9:
|
|
42498
|
+
readError_2 = _a.sent();
|
|
42499
|
+
console.error("[ShadowSpace] \u76F4\u63A5\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25: ".concat(normalizedPath), readError_2);
|
|
42500
|
+
return [3 /*break*/, 10];
|
|
42501
|
+
case 10:
|
|
42444
42502
|
// 如果都失败了,抛出错误
|
|
42445
42503
|
console.error("[ShadowSpace] \u83B7\u53D6\u6587\u4EF6\u5185\u5BB9\u5931\u8D25: \u6587\u4EF6\u672A\u627E\u5230: ".concat(normalizedPath));
|
|
42446
42504
|
throw new Error("File not found in shadow space: ".concat(normalizedPath));
|
|
42447
|
-
case
|
|
42505
|
+
case 11:
|
|
42448
42506
|
result = {
|
|
42449
42507
|
path: normalizedPath,
|
|
42450
42508
|
action: change.action,
|
|
@@ -42473,9 +42531,10 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42473
42531
|
/**
|
|
42474
42532
|
* 3. 批量获取文件内容
|
|
42475
42533
|
*/
|
|
42476
|
-
ShadowSpaceCommandHandler.prototype.getFilesContent = function (filePaths) {
|
|
42534
|
+
ShadowSpaceCommandHandler.prototype.getFilesContent = function (filePaths, readRealtime) {
|
|
42535
|
+
if (readRealtime === void 0) { readRealtime = true; }
|
|
42477
42536
|
return __awaiter(this, void 0, void 0, function () {
|
|
42478
|
-
var
|
|
42537
|
+
var results, filePaths_1, filePaths_1_1, filePath, normalizedPath, realTimeContent, shadowContent, error_2, e_1_1, result;
|
|
42479
42538
|
var e_1, _a;
|
|
42480
42539
|
return __generator(this, function (_b) {
|
|
42481
42540
|
switch (_b.label) {
|
|
@@ -42483,48 +42542,79 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42483
42542
|
if (!Array.isArray(filePaths) || filePaths.length === 0) {
|
|
42484
42543
|
throw new Error('File paths array is required');
|
|
42485
42544
|
}
|
|
42486
|
-
console.log("[ShadowSpace] \u6279\u91CF\u83B7\u53D6\u6587\u4EF6\u5185\u5BB9: ".concat(filePaths.length, " \u4E2A\u6587\u4EF6"));
|
|
42487
|
-
console.log("[ShadowSpace] \u6279\u91CF\u83B7\u53D6\u6587\u4EF6\u8DEF\u5F84:", filePaths.slice(0, 5)); // 显示前5个路径
|
|
42488
|
-
return [4 /*yield*/, this.shadowSpace.detectChanges()];
|
|
42489
|
-
case 1:
|
|
42490
|
-
changes = _b.sent();
|
|
42545
|
+
console.log("[ShadowSpace] \u6279\u91CF\u83B7\u53D6\u6587\u4EF6\u5185\u5BB9: ".concat(filePaths.length, " \u4E2A\u6587\u4EF6, \u5B9E\u65F6\u8BFB\u53D6: ").concat(readRealtime));
|
|
42491
42546
|
results = [];
|
|
42492
|
-
|
|
42493
|
-
|
|
42494
|
-
|
|
42495
|
-
|
|
42496
|
-
|
|
42497
|
-
|
|
42498
|
-
|
|
42499
|
-
|
|
42500
|
-
|
|
42501
|
-
|
|
42502
|
-
|
|
42503
|
-
|
|
42504
|
-
|
|
42505
|
-
|
|
42506
|
-
|
|
42507
|
-
|
|
42508
|
-
|
|
42509
|
-
|
|
42510
|
-
|
|
42511
|
-
|
|
42512
|
-
|
|
42513
|
-
|
|
42514
|
-
|
|
42515
|
-
|
|
42516
|
-
|
|
42517
|
-
|
|
42518
|
-
|
|
42519
|
-
|
|
42547
|
+
_b.label = 1;
|
|
42548
|
+
case 1:
|
|
42549
|
+
_b.trys.push([1, 10, 11, 12]);
|
|
42550
|
+
filePaths_1 = __values(filePaths), filePaths_1_1 = filePaths_1.next();
|
|
42551
|
+
_b.label = 2;
|
|
42552
|
+
case 2:
|
|
42553
|
+
if (!!filePaths_1_1.done) return [3 /*break*/, 9];
|
|
42554
|
+
filePath = filePaths_1_1.value;
|
|
42555
|
+
normalizedPath = filePath.startsWith('/')
|
|
42556
|
+
? filePath.substring(1)
|
|
42557
|
+
: filePath;
|
|
42558
|
+
console.log("[ShadowSpace] \u6279\u91CF\u5904\u7406: ".concat(filePath, " -> ").concat(normalizedPath));
|
|
42559
|
+
_b.label = 3;
|
|
42560
|
+
case 3:
|
|
42561
|
+
_b.trys.push([3, 7, , 8]);
|
|
42562
|
+
if (!readRealtime) return [3 /*break*/, 5];
|
|
42563
|
+
return [4 /*yield*/, this.shadowSpace.readRealTimeFile(normalizedPath)];
|
|
42564
|
+
case 4:
|
|
42565
|
+
realTimeContent = _b.sent();
|
|
42566
|
+
if (realTimeContent !== null) {
|
|
42567
|
+
results.push({
|
|
42568
|
+
path: normalizedPath,
|
|
42569
|
+
action: 'read',
|
|
42570
|
+
version: 1,
|
|
42571
|
+
timestamp: Date.now(),
|
|
42572
|
+
diff: {
|
|
42573
|
+
before: '',
|
|
42574
|
+
after: realTimeContent,
|
|
42575
|
+
},
|
|
42576
|
+
});
|
|
42577
|
+
return [3 /*break*/, 8];
|
|
42520
42578
|
}
|
|
42521
|
-
|
|
42522
|
-
|
|
42523
|
-
|
|
42524
|
-
|
|
42525
|
-
|
|
42526
|
-
|
|
42579
|
+
_b.label = 5;
|
|
42580
|
+
case 5: return [4 /*yield*/, this.shadowSpace.readFile(normalizedPath)];
|
|
42581
|
+
case 6:
|
|
42582
|
+
shadowContent = _b.sent();
|
|
42583
|
+
if (shadowContent !== null) {
|
|
42584
|
+
results.push({
|
|
42585
|
+
path: normalizedPath,
|
|
42586
|
+
action: 'read',
|
|
42587
|
+
version: 1,
|
|
42588
|
+
timestamp: Date.now(),
|
|
42589
|
+
diff: {
|
|
42590
|
+
before: '',
|
|
42591
|
+
after: shadowContent,
|
|
42592
|
+
},
|
|
42593
|
+
});
|
|
42594
|
+
}
|
|
42595
|
+
else {
|
|
42596
|
+
console.warn("[ShadowSpace] \u6279\u91CF\u83B7\u53D6\u4E2D\u672A\u627E\u5230\u6587\u4EF6: ".concat(normalizedPath));
|
|
42597
|
+
}
|
|
42598
|
+
return [3 /*break*/, 8];
|
|
42599
|
+
case 7:
|
|
42600
|
+
error_2 = _b.sent();
|
|
42601
|
+
console.warn("[ShadowSpace] \u6279\u91CF\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25: ".concat(normalizedPath), error_2);
|
|
42602
|
+
return [3 /*break*/, 8];
|
|
42603
|
+
case 8:
|
|
42604
|
+
filePaths_1_1 = filePaths_1.next();
|
|
42605
|
+
return [3 /*break*/, 2];
|
|
42606
|
+
case 9: return [3 /*break*/, 12];
|
|
42607
|
+
case 10:
|
|
42608
|
+
e_1_1 = _b.sent();
|
|
42609
|
+
e_1 = { error: e_1_1 };
|
|
42610
|
+
return [3 /*break*/, 12];
|
|
42611
|
+
case 11:
|
|
42612
|
+
try {
|
|
42613
|
+
if (filePaths_1_1 && !filePaths_1_1.done && (_a = filePaths_1.return)) _a.call(filePaths_1);
|
|
42527
42614
|
}
|
|
42615
|
+
finally { if (e_1) throw e_1.error; }
|
|
42616
|
+
return [7 /*endfinally*/];
|
|
42617
|
+
case 12:
|
|
42528
42618
|
result = {
|
|
42529
42619
|
files: results,
|
|
42530
42620
|
requestedCount: filePaths.length,
|
|
@@ -42652,9 +42742,9 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42652
42742
|
}
|
|
42653
42743
|
console.log("[ShadowSpace] \u5220\u9664\u6587\u4EF6: ".concat(filePath));
|
|
42654
42744
|
allFiles = this.shadowSpace.getAllFilePaths();
|
|
42655
|
-
console.log(
|
|
42745
|
+
console.log('[ShadowSpace] 当前影子空间中的文件: ', allFiles);
|
|
42656
42746
|
console.log("[ShadowSpace] \u8981\u5220\u9664\u7684\u6587\u4EF6\u8DEF\u5F84: \"".concat(filePath, "\""));
|
|
42657
|
-
console.log(
|
|
42747
|
+
console.log('[ShadowSpace] 文件是否存在:', this.shadowSpace.hasFile(filePath) ? '是' : '否');
|
|
42658
42748
|
return [4 /*yield*/, this.shadowSpace.deleteFile(filePath)];
|
|
42659
42749
|
case 1:
|
|
42660
42750
|
deleted = _a.sent();
|
|
@@ -42810,7 +42900,7 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42810
42900
|
*/
|
|
42811
42901
|
ShadowSpaceCommandHandler.prototype.detectEditorChanges = function (spaceId, editorSnapshots) {
|
|
42812
42902
|
return __awaiter(this, void 0, void 0, function () {
|
|
42813
|
-
var safeEditorSnapshots, spaceSnapshots, changes, summary,
|
|
42903
|
+
var safeEditorSnapshots, spaceSnapshots, changes, summary, error_3;
|
|
42814
42904
|
return __generator(this, function (_a) {
|
|
42815
42905
|
switch (_a.label) {
|
|
42816
42906
|
case 0:
|
|
@@ -42846,11 +42936,11 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42846
42936
|
},
|
|
42847
42937
|
}];
|
|
42848
42938
|
case 3:
|
|
42849
|
-
|
|
42850
|
-
console.error("[ShadowSpace] \u68C0\u6D4B\u53D8\u66F4\u5931\u8D25:",
|
|
42939
|
+
error_3 = _a.sent();
|
|
42940
|
+
console.error("[ShadowSpace] \u68C0\u6D4B\u53D8\u66F4\u5931\u8D25:", error_3);
|
|
42851
42941
|
return [2 /*return*/, {
|
|
42852
42942
|
success: false,
|
|
42853
|
-
error:
|
|
42943
|
+
error: error_3 instanceof Error ? error_3.message : '检测变更失败',
|
|
42854
42944
|
}];
|
|
42855
42945
|
case 4: return [2 /*return*/];
|
|
42856
42946
|
}
|
|
@@ -47578,186 +47668,411 @@ function executeShadowSpaceDebug(options) {
|
|
|
47578
47668
|
});
|
|
47579
47669
|
}
|
|
47580
47670
|
|
|
47581
|
-
|
|
47582
|
-
|
|
47671
|
+
/**
|
|
47672
|
+
* 统一的TSX/JSX验证器
|
|
47673
|
+
* 同时支持CLI和编辑器使用
|
|
47674
|
+
*/
|
|
47675
|
+
var UnifiedTSXValidator = /** @class */ (function () {
|
|
47676
|
+
function UnifiedTSXValidator(debug) {
|
|
47677
|
+
if (debug === void 0) { debug = false; }
|
|
47678
|
+
this.debug = false;
|
|
47679
|
+
this.debug = debug;
|
|
47583
47680
|
}
|
|
47584
47681
|
/**
|
|
47585
|
-
*
|
|
47682
|
+
* 验证TSX文件内容
|
|
47586
47683
|
*/
|
|
47587
|
-
|
|
47684
|
+
UnifiedTSXValidator.prototype.validate = function (content, filename) {
|
|
47685
|
+
var _this = this;
|
|
47686
|
+
if (filename === void 0) { filename = 'unknown.tsx'; }
|
|
47687
|
+
this.content = content;
|
|
47688
|
+
this.filename = filename;
|
|
47588
47689
|
var issues = [];
|
|
47589
47690
|
try {
|
|
47590
|
-
|
|
47591
|
-
var ast = parser$1.parse(content, {
|
|
47691
|
+
var ast_1 = parser$1.parse(content, {
|
|
47592
47692
|
sourceType: 'module',
|
|
47593
47693
|
plugins: ['jsx', 'typescript', 'decorators-legacy', 'classProperties'],
|
|
47594
47694
|
errorRecovery: true,
|
|
47695
|
+
allowReturnOutsideFunction: true,
|
|
47595
47696
|
});
|
|
47596
|
-
|
|
47597
|
-
|
|
47598
|
-
|
|
47599
|
-
|
|
47600
|
-
|
|
47601
|
-
|
|
47602
|
-
|
|
47603
|
-
|
|
47604
|
-
|
|
47605
|
-
|
|
47606
|
-
|
|
47607
|
-
|
|
47608
|
-
|
|
47609
|
-
|
|
47610
|
-
|
|
47611
|
-
|
|
47612
|
-
|
|
47613
|
-
},
|
|
47614
|
-
});
|
|
47615
|
-
// 检查必需的结构
|
|
47616
|
-
this.checkRequiredStructures(ast, content, issues);
|
|
47697
|
+
this.log('AST解析完成');
|
|
47698
|
+
// 执行所有检查,每个检查都包装在try-catch中
|
|
47699
|
+
this.safeCheck('checkFileStructure', function () { return _this.checkFileStructure(ast_1, issues); });
|
|
47700
|
+
this.safeCheck('checkComponentDefinition', function () { return _this.checkComponentDefinition(ast_1, issues); });
|
|
47701
|
+
this.safeCheck('checkRenderMethod', function () { return _this.checkRenderMethod(ast_1, issues); });
|
|
47702
|
+
this.safeCheck('checkVariableDeclarations', function () { return _this.checkVariableDeclarations(ast_1, issues); });
|
|
47703
|
+
this.safeCheck('checkConditionalRendering', function () { return _this.checkConditionalRendering(ast_1, issues); });
|
|
47704
|
+
this.safeCheck('checkListRendering', function () { return _this.checkListRendering(ast_1, issues); });
|
|
47705
|
+
this.safeCheck('checkStyleUsage', function () { return _this.checkStyleUsage(ast_1, issues); });
|
|
47706
|
+
this.safeCheck('checkStateManagement', function () { return _this.checkStateManagement(ast_1, issues); });
|
|
47707
|
+
this.safeCheck('checkDataSourceUsage', function () { return _this.checkDataSourceUsage(ast_1, issues); });
|
|
47708
|
+
this.safeCheck('checkTypeScriptSyntaxInMethods', function () { return _this.checkTypeScriptSyntaxInMethods(ast_1, issues); });
|
|
47709
|
+
this.log("\u68C0\u67E5\u5B8C\u6210\uFF0C\u53D1\u73B0 ".concat(issues.length, " \u4E2A\u95EE\u9898"));
|
|
47710
|
+
return {
|
|
47711
|
+
isCompliant: issues.filter(function (issue) { return issue.type === 'error'; }).length === 0,
|
|
47712
|
+
issues: issues,
|
|
47713
|
+
};
|
|
47617
47714
|
}
|
|
47618
47715
|
catch (error) {
|
|
47619
|
-
|
|
47620
|
-
|
|
47621
|
-
|
|
47622
|
-
|
|
47623
|
-
|
|
47624
|
-
|
|
47716
|
+
this.log("\u89E3\u6790\u9519\u8BEF: ".concat(error.message));
|
|
47717
|
+
return {
|
|
47718
|
+
isCompliant: false,
|
|
47719
|
+
issues: [{
|
|
47720
|
+
type: 'error',
|
|
47721
|
+
code: 'PARSE_ERROR',
|
|
47722
|
+
message: "\u4EE3\u7801\u89E3\u6790\u5931\u8D25: ".concat(error.message),
|
|
47723
|
+
suggestion: '检查代码语法是否正确',
|
|
47724
|
+
line: 1,
|
|
47725
|
+
column: 0,
|
|
47726
|
+
}],
|
|
47727
|
+
};
|
|
47625
47728
|
}
|
|
47626
|
-
return {
|
|
47627
|
-
isCompliant: issues.filter(function (issue) { return issue.type === 'error'; }).length === 0,
|
|
47628
|
-
issues: issues,
|
|
47629
|
-
};
|
|
47630
47729
|
};
|
|
47631
47730
|
/**
|
|
47632
|
-
*
|
|
47731
|
+
* 检查文件结构
|
|
47633
47732
|
*/
|
|
47634
|
-
|
|
47635
|
-
|
|
47636
|
-
|
|
47637
|
-
var
|
|
47638
|
-
|
|
47639
|
-
|
|
47640
|
-
|
|
47733
|
+
UnifiedTSXValidator.prototype.checkFileStructure = function (ast, issues) {
|
|
47734
|
+
var _this = this;
|
|
47735
|
+
this.log('开始检查文件结构');
|
|
47736
|
+
var hasReactComponent = false;
|
|
47737
|
+
traverse__default["default"](ast, {
|
|
47738
|
+
ClassDeclaration: function (path) {
|
|
47739
|
+
var _a;
|
|
47740
|
+
var className = (_a = path.node.id) === null || _a === void 0 ? void 0 : _a.name;
|
|
47741
|
+
_this.log("\u53D1\u73B0\u7C7B: ".concat(className));
|
|
47742
|
+
// 检查是否有继承自React.Component的类(支持 extends Component 和 extends React.Component)
|
|
47743
|
+
if (_this.isReactComponent(path.node.superClass)) {
|
|
47744
|
+
hasReactComponent = true;
|
|
47745
|
+
_this.log("\u53D1\u73B0React\u7EC4\u4EF6\u7C7B: ".concat(className));
|
|
47746
|
+
}
|
|
47747
|
+
},
|
|
47641
47748
|
});
|
|
47642
|
-
|
|
47643
|
-
|
|
47644
|
-
|
|
47645
|
-
var isInEventHandler = this.isInEventHandler(path);
|
|
47646
|
-
if (isInEventHandler)
|
|
47647
|
-
return;
|
|
47648
|
-
// 检查是否在非 JSX 返回的回调函数中
|
|
47649
|
-
var isInNonJSXCallback = this.isInNonJSXCallback(path);
|
|
47650
|
-
if (isInNonJSXCallback)
|
|
47651
|
-
return;
|
|
47652
|
-
// 检查是否在返回 JSX 的回调函数中(如 .map())
|
|
47653
|
-
var isInJSXCallback = this.isInJSXCallback(path);
|
|
47654
|
-
if (isInJSXCallback) {
|
|
47655
|
-
// 这种情况需要报错
|
|
47656
|
-
var _a = this.getLocation(path, content), line_1 = _a.line, column_1 = _a.column;
|
|
47657
|
-
var snippet_1 = this.extractCodeSnippet(content, line_1);
|
|
47658
|
-
issues.push({
|
|
47659
|
-
type: 'error',
|
|
47660
|
-
code: 'CALLBACK_VARIABLE_DECLARATION',
|
|
47661
|
-
message: '返回 JSX 的回调函数中不能包含变量声明',
|
|
47662
|
-
suggestion: '将变量声明移到回调函数外部,或使用内联表达式',
|
|
47663
|
-
line: line_1,
|
|
47664
|
-
column: column_1,
|
|
47665
|
-
codeSnippet: snippet_1.snippet,
|
|
47666
|
-
snippetStartLine: snippet_1.startLine,
|
|
47667
|
-
snippetEndLine: snippet_1.endLine,
|
|
47668
|
-
});
|
|
47669
|
-
return;
|
|
47749
|
+
// 不再强制要求Document类,只要有React组件类即可
|
|
47750
|
+
if (!hasReactComponent) {
|
|
47751
|
+
issues.push(this.createIssue('MISSING_REACT_COMPONENT', 'error', '缺少React组件类定义,必须定义一个继承自React.Component的类', '请定义组件类,如: class MyComponent extends React.Component 或 class MyComponent extends Component', 1));
|
|
47670
47752
|
}
|
|
47671
|
-
|
|
47672
|
-
|
|
47673
|
-
|
|
47674
|
-
|
|
47675
|
-
|
|
47676
|
-
|
|
47677
|
-
|
|
47678
|
-
|
|
47679
|
-
|
|
47680
|
-
|
|
47681
|
-
|
|
47682
|
-
|
|
47683
|
-
|
|
47753
|
+
};
|
|
47754
|
+
/**
|
|
47755
|
+
* 检查组件定义
|
|
47756
|
+
*/
|
|
47757
|
+
UnifiedTSXValidator.prototype.checkComponentDefinition = function (ast, issues) {
|
|
47758
|
+
var _this = this;
|
|
47759
|
+
this.log('开始检查组件定义');
|
|
47760
|
+
traverse__default["default"](ast, {
|
|
47761
|
+
ClassDeclaration: function (path) {
|
|
47762
|
+
var e_1, _a;
|
|
47763
|
+
var _b;
|
|
47764
|
+
// 检查所有继承自React.Component的类
|
|
47765
|
+
if (_this.isReactComponent(path.node.superClass)) {
|
|
47766
|
+
var className = (_b = path.node.id) === null || _b === void 0 ? void 0 : _b.name;
|
|
47767
|
+
_this.log("\u68C0\u67E5React\u7EC4\u4EF6\u7C7B: ".concat(className));
|
|
47768
|
+
// 检查render方法
|
|
47769
|
+
var hasRender = false;
|
|
47770
|
+
try {
|
|
47771
|
+
for (var _c = __values(path.node.body.body), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
47772
|
+
var member = _d.value;
|
|
47773
|
+
if (member.type === 'ClassMethod' && member.key.name === 'render') {
|
|
47774
|
+
hasRender = true;
|
|
47775
|
+
}
|
|
47776
|
+
// 检查constructor
|
|
47777
|
+
if (member.type === 'ClassMethod' && member.key.name === 'constructor') {
|
|
47778
|
+
issues.push(_this.createIssueFromNode('CONSTRUCTOR_NOT_ALLOWED', 'error', "".concat(className, "\u7C7B\u4E2D\u4E0D\u5141\u8BB8\u4F7F\u7528constructor"), '请使用state属性直接定义状态,使用componentDidMount进行初始化', member));
|
|
47779
|
+
}
|
|
47780
|
+
}
|
|
47781
|
+
}
|
|
47782
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
47783
|
+
finally {
|
|
47784
|
+
try {
|
|
47785
|
+
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
47786
|
+
}
|
|
47787
|
+
finally { if (e_1) throw e_1.error; }
|
|
47788
|
+
}
|
|
47789
|
+
// 移除对state属性的强制检查,React组件可以不定义state
|
|
47790
|
+
if (!hasRender) {
|
|
47791
|
+
issues.push(_this.createIssueFromNode('MISSING_RENDER_METHOD', 'error', "".concat(className, "\u7C7B\u5FC5\u987B\u5B9A\u4E49render\u65B9\u6CD5"), '请添加: render() { return <View>...</View> }', path.node));
|
|
47792
|
+
}
|
|
47793
|
+
}
|
|
47794
|
+
},
|
|
47684
47795
|
});
|
|
47685
47796
|
};
|
|
47686
47797
|
/**
|
|
47687
|
-
*
|
|
47798
|
+
* 检查render方法
|
|
47688
47799
|
*/
|
|
47689
|
-
|
|
47690
|
-
|
|
47800
|
+
UnifiedTSXValidator.prototype.checkRenderMethod = function (ast, issues) {
|
|
47801
|
+
var _this = this;
|
|
47802
|
+
this.log('开始检查render方法');
|
|
47803
|
+
traverse__default["default"](ast, {
|
|
47804
|
+
ClassMethod: function (path) {
|
|
47805
|
+
var e_2, _a, e_3, _b;
|
|
47806
|
+
if (path.node.key.name === 'render') {
|
|
47807
|
+
var body = path.node.body.body;
|
|
47808
|
+
try {
|
|
47809
|
+
// 检查变量声明
|
|
47810
|
+
for (var body_1 = __values(body), body_1_1 = body_1.next(); !body_1_1.done; body_1_1 = body_1.next()) {
|
|
47811
|
+
var statement = body_1_1.value;
|
|
47812
|
+
if (statement.type === 'VariableDeclaration') {
|
|
47813
|
+
// 检查是否在事件处理函数中
|
|
47814
|
+
if (!_this.isInEventHandler(path)) {
|
|
47815
|
+
issues.push(_this.createIssueFromNode('RENDER_VARIABLE_DECLARATION', 'error', 'render方法中不允许声明变量', '直接使用this.state访问状态', statement));
|
|
47816
|
+
}
|
|
47817
|
+
}
|
|
47818
|
+
// 检查函数声明
|
|
47819
|
+
if (statement.type === 'FunctionDeclaration') {
|
|
47820
|
+
issues.push(_this.createIssueFromNode('RENDER_FUNCTION_DECLARATION', 'error', 'render方法中不允许声明函数', '将函数声明移到render方法外部', statement));
|
|
47821
|
+
}
|
|
47822
|
+
// 检查if语句
|
|
47823
|
+
if (statement.type === 'IfStatement') {
|
|
47824
|
+
issues.push(_this.createIssueFromNode('RENDER_IF_STATEMENT', 'error', 'render方法中不允许使用if语句进行条件渲染', '请使用JSX中的条件渲染语法 {condition && <View>}', statement));
|
|
47825
|
+
}
|
|
47826
|
+
}
|
|
47827
|
+
}
|
|
47828
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
47829
|
+
finally {
|
|
47830
|
+
try {
|
|
47831
|
+
if (body_1_1 && !body_1_1.done && (_a = body_1.return)) _a.call(body_1);
|
|
47832
|
+
}
|
|
47833
|
+
finally { if (e_2) throw e_2.error; }
|
|
47834
|
+
}
|
|
47835
|
+
// 检查是否有return语句
|
|
47836
|
+
var hasReturn = false;
|
|
47837
|
+
try {
|
|
47838
|
+
for (var body_2 = __values(body), body_2_1 = body_2.next(); !body_2_1.done; body_2_1 = body_2.next()) {
|
|
47839
|
+
var statement = body_2_1.value;
|
|
47840
|
+
if (statement.type === 'ReturnStatement') {
|
|
47841
|
+
hasReturn = true;
|
|
47842
|
+
break;
|
|
47843
|
+
}
|
|
47844
|
+
}
|
|
47845
|
+
}
|
|
47846
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
47847
|
+
finally {
|
|
47848
|
+
try {
|
|
47849
|
+
if (body_2_1 && !body_2_1.done && (_b = body_2.return)) _b.call(body_2);
|
|
47850
|
+
}
|
|
47851
|
+
finally { if (e_3) throw e_3.error; }
|
|
47852
|
+
}
|
|
47853
|
+
if (!hasReturn) {
|
|
47854
|
+
issues.push(_this.createIssueFromNode('MISSING_RETURN', 'error', 'render方法必须返回JSX元素', '请在render方法末尾添加return语句', path.node));
|
|
47855
|
+
}
|
|
47856
|
+
}
|
|
47857
|
+
},
|
|
47858
|
+
});
|
|
47859
|
+
};
|
|
47860
|
+
/**
|
|
47861
|
+
* 检查变量声明 - 兼容TSXComplianceChecker的逻辑
|
|
47862
|
+
*/
|
|
47863
|
+
UnifiedTSXValidator.prototype.checkVariableDeclarations = function (ast, issues) {
|
|
47864
|
+
var _this = this;
|
|
47865
|
+
this.log('开始检查变量声明');
|
|
47866
|
+
traverse__default["default"](ast, {
|
|
47867
|
+
VariableDeclarator: function (path) {
|
|
47868
|
+
// 检查是否在 render 方法中
|
|
47869
|
+
var renderMethod = path.findParent(function (p) {
|
|
47870
|
+
return p.isClassMethod() &&
|
|
47871
|
+
t__namespace.isIdentifier(p.node.key) &&
|
|
47872
|
+
p.node.key.name === 'render';
|
|
47873
|
+
});
|
|
47874
|
+
if (!renderMethod)
|
|
47875
|
+
return;
|
|
47876
|
+
// 检查是否在事件处理函数中
|
|
47877
|
+
if (_this.isInEventHandler(path))
|
|
47878
|
+
return;
|
|
47879
|
+
// 检查是否在非JSX回调函数中
|
|
47880
|
+
if (_this.isInNonJSXCallback(path))
|
|
47881
|
+
return;
|
|
47882
|
+
// 检查是否在返回JSX的回调函数中
|
|
47883
|
+
if (_this.isInJSXCallback(path)) {
|
|
47884
|
+
issues.push(_this.createIssueFromNode('CALLBACK_VARIABLE_DECLARATION', 'error', '返回JSX的回调函数中不能包含变量声明', '将变量声明移到回调函数外部,或使用内联表达式', path.node));
|
|
47885
|
+
return;
|
|
47886
|
+
}
|
|
47887
|
+
// 其他在render方法中的变量声明都是错误的
|
|
47888
|
+
issues.push(_this.createIssueFromNode('RENDER_VARIABLE_DECLARATION', 'error', 'render()方法中不能包含变量声明', '移除所有const/let/var声明,直接使用this.state.xxx', path.node));
|
|
47889
|
+
},
|
|
47890
|
+
});
|
|
47891
|
+
};
|
|
47892
|
+
/**
|
|
47893
|
+
* 检查条件渲染
|
|
47894
|
+
*/
|
|
47895
|
+
UnifiedTSXValidator.prototype.checkConditionalRendering = function (ast, issues) {
|
|
47896
|
+
var _this = this;
|
|
47897
|
+
this.log('开始检查条件渲染');
|
|
47898
|
+
traverse__default["default"](ast, {
|
|
47899
|
+
JSXExpressionContainer: function (path) {
|
|
47900
|
+
var expression = path.node.expression;
|
|
47901
|
+
if (expression.type === 'LogicalExpression') {
|
|
47902
|
+
// 检查右侧是否包含JSX元素
|
|
47903
|
+
var hasJSXInRight = _this.hasJSXInNode(expression.right);
|
|
47904
|
+
if (hasJSXInRight && expression.operator !== '&&') {
|
|
47905
|
+
issues.push(_this.createIssueFromNode('INVALID_CONDITIONAL_OPERATOR', 'error', '条件渲染必须使用&&运算符,不支持其他运算符', '请使用 && 运算符进行条件渲染', path.node));
|
|
47906
|
+
}
|
|
47907
|
+
if (hasJSXInRight && expression.left.type === 'Identifier') {
|
|
47908
|
+
issues.push(_this.createIssueFromNode('VARIABLE_IN_CONDITIONAL', 'error', '条件渲染中不允许使用变量', '请直接使用this.state访问状态', path.node));
|
|
47909
|
+
}
|
|
47910
|
+
}
|
|
47911
|
+
},
|
|
47912
|
+
});
|
|
47913
|
+
};
|
|
47914
|
+
/**
|
|
47915
|
+
* 检查列表渲染
|
|
47916
|
+
*/
|
|
47917
|
+
UnifiedTSXValidator.prototype.checkListRendering = function (ast, issues) {
|
|
47918
|
+
var _this = this;
|
|
47919
|
+
this.log('开始检查列表渲染');
|
|
47920
|
+
traverse__default["default"](ast, {
|
|
47921
|
+
CallExpression: function (path) {
|
|
47922
|
+
if (path.node.callee.type === 'MemberExpression' &&
|
|
47923
|
+
path.node.callee.property.name === 'map') {
|
|
47924
|
+
// 检查是否在render方法的JSX中使用
|
|
47925
|
+
if (_this.isInRenderJSX(path)) {
|
|
47926
|
+
var parent_1 = path.parentPath;
|
|
47927
|
+
if (parent_1.node.type === 'VariableDeclaration') {
|
|
47928
|
+
issues.push(_this.createIssueFromNode('LIST_RENDER_VARIABLE', 'error', '列表渲染中不允许使用变量', '请直接使用map方法渲染', path.node));
|
|
47929
|
+
}
|
|
47930
|
+
}
|
|
47931
|
+
}
|
|
47932
|
+
},
|
|
47933
|
+
});
|
|
47934
|
+
};
|
|
47935
|
+
/**
|
|
47936
|
+
* 检查样式使用
|
|
47937
|
+
*/
|
|
47938
|
+
UnifiedTSXValidator.prototype.checkStyleUsage = function (ast, issues) {
|
|
47939
|
+
var _this = this;
|
|
47940
|
+
this.log('开始检查样式使用');
|
|
47941
|
+
traverse__default["default"](ast, {
|
|
47942
|
+
JSXAttribute: function (path) {
|
|
47943
|
+
var _a;
|
|
47944
|
+
if (path.node.name.name === 'inlineStyle') {
|
|
47945
|
+
var parent_2 = path.parentPath.node;
|
|
47946
|
+
var componentName = (_a = parent_2.name) === null || _a === void 0 ? void 0 : _a.name;
|
|
47947
|
+
if (componentName !== 'View' && componentName !== 'Text') {
|
|
47948
|
+
issues.push(_this.createIssueFromNode('INVALID_INLINE_STYLE', 'error', 'inlineStyle属性仅支持View和Text组件使用', '请检查组件类型或使用其他样式属性', path.node));
|
|
47949
|
+
}
|
|
47950
|
+
}
|
|
47951
|
+
},
|
|
47952
|
+
});
|
|
47953
|
+
};
|
|
47954
|
+
/**
|
|
47955
|
+
* 检查状态管理
|
|
47956
|
+
*/
|
|
47957
|
+
UnifiedTSXValidator.prototype.checkStateManagement = function (ast, issues) {
|
|
47958
|
+
var _this = this;
|
|
47959
|
+
this.log('开始检查状态管理');
|
|
47960
|
+
traverse__default["default"](ast, {
|
|
47961
|
+
AssignmentExpression: function (path) {
|
|
47962
|
+
if (_this.isDirectStateMutation(path.node.left)) {
|
|
47963
|
+
issues.push(_this.createIssueFromNode('DIRECT_STATE_MUTATION', 'error', '不允许直接修改state', '请使用this.setState方法', path.node));
|
|
47964
|
+
}
|
|
47965
|
+
},
|
|
47966
|
+
});
|
|
47967
|
+
};
|
|
47968
|
+
/**
|
|
47969
|
+
* 检查数据源使用
|
|
47970
|
+
*/
|
|
47971
|
+
UnifiedTSXValidator.prototype.checkDataSourceUsage = function (ast, issues) {
|
|
47972
|
+
var _this = this;
|
|
47973
|
+
this.log('开始检查数据源使用');
|
|
47974
|
+
traverse__default["default"](ast, {
|
|
47975
|
+
CallExpression: function (path) {
|
|
47976
|
+
var _a;
|
|
47977
|
+
if (_this.isDataSourceLoadCall(path.node)) {
|
|
47978
|
+
var isInRender = false;
|
|
47979
|
+
var isInCallback = false;
|
|
47980
|
+
var currentPath = path;
|
|
47981
|
+
while (currentPath) {
|
|
47982
|
+
var node = currentPath.node;
|
|
47983
|
+
if (node.type === 'ClassMethod' && ((_a = node.key) === null || _a === void 0 ? void 0 : _a.name) === 'render') {
|
|
47984
|
+
isInRender = true;
|
|
47985
|
+
}
|
|
47986
|
+
if ((node.type === 'ArrowFunctionExpression' || node.type === 'FunctionExpression')) {
|
|
47987
|
+
var parentPath = currentPath.parentPath;
|
|
47988
|
+
if ((parentPath === null || parentPath === void 0 ? void 0 : parentPath.node.type) === 'JSXExpressionContainer') {
|
|
47989
|
+
isInCallback = true;
|
|
47990
|
+
break;
|
|
47991
|
+
}
|
|
47992
|
+
}
|
|
47993
|
+
currentPath = currentPath.parentPath;
|
|
47994
|
+
}
|
|
47995
|
+
if (isInRender && !isInCallback) {
|
|
47996
|
+
issues.push(_this.createIssueFromNode('DATA_SOURCE_IN_RENDER', 'error', 'render方法中不允许直接调用数据源', '请在回调函数中调用数据源', path.node));
|
|
47997
|
+
}
|
|
47998
|
+
}
|
|
47999
|
+
},
|
|
48000
|
+
});
|
|
48001
|
+
};
|
|
48002
|
+
// ========== 辅助方法 ==========
|
|
48003
|
+
UnifiedTSXValidator.prototype.isReactComponent = function (superClass) {
|
|
48004
|
+
if (!superClass)
|
|
48005
|
+
return false;
|
|
48006
|
+
// 支持 extends React.Component
|
|
48007
|
+
if (superClass.type === 'MemberExpression' &&
|
|
48008
|
+
superClass.object.name === 'React' &&
|
|
48009
|
+
superClass.property.name === 'Component') {
|
|
48010
|
+
return true;
|
|
48011
|
+
}
|
|
48012
|
+
// 支持 extends Component 和 extends Component<IProps, IState>
|
|
48013
|
+
// 泛型参数不会影响标识符本身的识别
|
|
48014
|
+
if (superClass.type === 'Identifier' &&
|
|
48015
|
+
superClass.name === 'Component') {
|
|
48016
|
+
return true;
|
|
48017
|
+
}
|
|
48018
|
+
// 额外检查:如果父节点是TSExpressionWithTypeArguments,检查其expression
|
|
48019
|
+
// 这种情况出现在 extends Component<IProps, IState> 中
|
|
48020
|
+
if (superClass.type === 'TSExpressionWithTypeArguments' &&
|
|
48021
|
+
superClass.expression &&
|
|
48022
|
+
superClass.expression.type === 'Identifier' &&
|
|
48023
|
+
superClass.expression.name === 'Component') {
|
|
48024
|
+
return true;
|
|
48025
|
+
}
|
|
48026
|
+
return false;
|
|
48027
|
+
};
|
|
48028
|
+
UnifiedTSXValidator.prototype.isReactComponentSuperClass = function (path) {
|
|
48029
|
+
var superClass = path.node.superClass;
|
|
48030
|
+
return this.isReactComponent(superClass);
|
|
48031
|
+
};
|
|
48032
|
+
UnifiedTSXValidator.prototype.hasJSXInNode = function (node) {
|
|
48033
|
+
if (!node)
|
|
48034
|
+
return false;
|
|
48035
|
+
if (node.type === 'JSXElement' || node.type === 'JSXFragment')
|
|
48036
|
+
return true;
|
|
48037
|
+
if (node.type === 'ConditionalExpression') {
|
|
48038
|
+
return this.hasJSXInNode(node.consequent) || this.hasJSXInNode(node.alternate);
|
|
48039
|
+
}
|
|
48040
|
+
return false;
|
|
48041
|
+
};
|
|
48042
|
+
UnifiedTSXValidator.prototype.isInEventHandler = function (path) {
|
|
47691
48043
|
var jsxAttribute = path.findParent(function (p) { return p.isJSXAttribute(); });
|
|
47692
48044
|
if (jsxAttribute && t__namespace.isJSXIdentifier(jsxAttribute.node.name)) {
|
|
47693
48045
|
var attrName = jsxAttribute.node.name.name;
|
|
47694
|
-
// 检查是否是事件处理属性(onXxx)
|
|
47695
48046
|
if (/^on[A-Z]/.test(attrName)) {
|
|
47696
48047
|
return true;
|
|
47697
48048
|
}
|
|
47698
48049
|
}
|
|
47699
|
-
// 检查是否在 addEventListener 回调中
|
|
47700
|
-
var callExpression = path.findParent(function (p) { return p.isCallExpression(); });
|
|
47701
|
-
if (callExpression && t__namespace.isMemberExpression(callExpression.node.callee)) {
|
|
47702
|
-
var memberExpr = callExpression.node.callee;
|
|
47703
|
-
if (t__namespace.isIdentifier(memberExpr.property) &&
|
|
47704
|
-
memberExpr.property.name === 'addEventListener') {
|
|
47705
|
-
return true;
|
|
47706
|
-
}
|
|
47707
|
-
}
|
|
47708
48050
|
return false;
|
|
47709
48051
|
};
|
|
47710
|
-
|
|
47711
|
-
* 检查是否在非 JSX 返回的回调函数中
|
|
47712
|
-
*/
|
|
47713
|
-
TSXComplianceChecker.isInNonJSXCallback = function (path) {
|
|
47714
|
-
// 查找父级函数
|
|
48052
|
+
UnifiedTSXValidator.prototype.isInNonJSXCallback = function (path) {
|
|
47715
48053
|
var parentFunction = path.findParent(function (p) { return p.isArrowFunctionExpression() || p.isFunctionExpression(); });
|
|
47716
48054
|
if (!parentFunction)
|
|
47717
48055
|
return false;
|
|
47718
|
-
|
|
47719
|
-
var jsxAttribute = parentFunction.findParent(function (p) {
|
|
47720
|
-
return p.isJSXAttribute();
|
|
47721
|
-
});
|
|
48056
|
+
var jsxAttribute = parentFunction.findParent(function (p) { return p.isJSXAttribute(); });
|
|
47722
48057
|
if (jsxAttribute && t__namespace.isJSXIdentifier(jsxAttribute.node.name)) {
|
|
47723
48058
|
var attrName = jsxAttribute.node.name.name;
|
|
47724
|
-
// 这些属性通常不返回 JSX
|
|
47725
48059
|
var nonJSXAttributes = [
|
|
47726
|
-
'beforeUpload',
|
|
47727
|
-
'
|
|
47728
|
-
'onChange',
|
|
47729
|
-
'onFinish',
|
|
47730
|
-
'onSubmit',
|
|
47731
|
-
'onSuccess',
|
|
47732
|
-
'onError',
|
|
47733
|
-
'onProgress',
|
|
47734
|
-
'request',
|
|
47735
|
-
'dataHandler',
|
|
48060
|
+
'beforeUpload', 'customRequest', 'onChange', 'onFinish',
|
|
48061
|
+
'onSubmit', 'onSuccess', 'onError', 'onProgress', 'request', 'dataHandler'
|
|
47736
48062
|
];
|
|
47737
48063
|
if (nonJSXAttributes.includes(attrName)) {
|
|
47738
48064
|
return true;
|
|
47739
48065
|
}
|
|
47740
48066
|
}
|
|
47741
|
-
|
|
47742
|
-
var returnsJSX = this.functionReturnsJSX(parentFunction);
|
|
47743
|
-
// 如果不返回 JSX,则认为是非 JSX 回调
|
|
47744
|
-
return !returnsJSX;
|
|
48067
|
+
return !this.functionReturnsJSX(parentFunction);
|
|
47745
48068
|
};
|
|
47746
|
-
|
|
47747
|
-
* 检查是否在返回 JSX 的回调函数中
|
|
47748
|
-
*/
|
|
47749
|
-
TSXComplianceChecker.isInJSXCallback = function (path) {
|
|
47750
|
-
// 查找父级函数
|
|
48069
|
+
UnifiedTSXValidator.prototype.isInJSXCallback = function (path) {
|
|
47751
48070
|
var parentFunction = path.findParent(function (p) { return p.isArrowFunctionExpression() || p.isFunctionExpression(); });
|
|
47752
48071
|
if (!parentFunction)
|
|
47753
48072
|
return false;
|
|
47754
|
-
// 检查函数是否返回 JSX
|
|
47755
48073
|
return this.functionReturnsJSX(parentFunction);
|
|
47756
48074
|
};
|
|
47757
|
-
|
|
47758
|
-
* 检查函数是否返回 JSX
|
|
47759
|
-
*/
|
|
47760
|
-
TSXComplianceChecker.functionReturnsJSX = function (functionPath) {
|
|
48075
|
+
UnifiedTSXValidator.prototype.functionReturnsJSX = function (functionPath) {
|
|
47761
48076
|
var returnsJSX = false;
|
|
47762
48077
|
functionPath.traverse({
|
|
47763
48078
|
ReturnStatement: function (path) {
|
|
@@ -47766,7 +48081,6 @@ var TSXComplianceChecker = /** @class */ (function () {
|
|
|
47766
48081
|
}
|
|
47767
48082
|
},
|
|
47768
48083
|
JSXElement: function (path) {
|
|
47769
|
-
// 如果函数体直接包含 JSX(箭头函数的隐式返回)
|
|
47770
48084
|
if (path.parent === functionPath.node.body) {
|
|
47771
48085
|
returnsJSX = true;
|
|
47772
48086
|
}
|
|
@@ -47774,76 +48088,280 @@ var TSXComplianceChecker = /** @class */ (function () {
|
|
|
47774
48088
|
});
|
|
47775
48089
|
return returnsJSX;
|
|
47776
48090
|
};
|
|
48091
|
+
UnifiedTSXValidator.prototype.isInRenderJSX = function (path) {
|
|
48092
|
+
var isInRender = false;
|
|
48093
|
+
var isInJSX = false;
|
|
48094
|
+
var currentPath = path;
|
|
48095
|
+
while (currentPath) {
|
|
48096
|
+
if (currentPath.node.type === 'ClassMethod' && currentPath.node.key.name === 'render') {
|
|
48097
|
+
isInRender = true;
|
|
48098
|
+
}
|
|
48099
|
+
if (currentPath.node.type === 'JSXExpressionContainer') {
|
|
48100
|
+
isInJSX = true;
|
|
48101
|
+
}
|
|
48102
|
+
currentPath = currentPath.parentPath;
|
|
48103
|
+
}
|
|
48104
|
+
return isInRender && isInJSX;
|
|
48105
|
+
};
|
|
48106
|
+
UnifiedTSXValidator.prototype.isDirectStateMutation = function (left) {
|
|
48107
|
+
return (left.type === 'MemberExpression' &&
|
|
48108
|
+
left.object.type === 'MemberExpression' &&
|
|
48109
|
+
left.object.object.type === 'ThisExpression' &&
|
|
48110
|
+
left.object.property.name === 'state');
|
|
48111
|
+
};
|
|
48112
|
+
UnifiedTSXValidator.prototype.isDataSourceLoadCall = function (node) {
|
|
48113
|
+
return (node.callee.type === 'MemberExpression' &&
|
|
48114
|
+
node.callee.object.type === 'MemberExpression' &&
|
|
48115
|
+
node.callee.object.object.type === 'MemberExpression' &&
|
|
48116
|
+
node.callee.object.object.object.type === 'ThisExpression' &&
|
|
48117
|
+
node.callee.object.object.property.name === 'dataSourceMap' &&
|
|
48118
|
+
node.callee.property.name === 'load');
|
|
48119
|
+
};
|
|
48120
|
+
UnifiedTSXValidator.prototype.createIssueFromNode = function (code, type, message, suggestion, node) {
|
|
48121
|
+
var loc = node.loc;
|
|
48122
|
+
return {
|
|
48123
|
+
type: type,
|
|
48124
|
+
code: code,
|
|
48125
|
+
message: message,
|
|
48126
|
+
suggestion: suggestion,
|
|
48127
|
+
line: loc ? loc.start.line : 1,
|
|
48128
|
+
column: loc ? loc.start.column : 0,
|
|
48129
|
+
};
|
|
48130
|
+
};
|
|
48131
|
+
UnifiedTSXValidator.prototype.createIssue = function (code, type, message, suggestion, line, column) {
|
|
48132
|
+
if (column === void 0) { column = 0; }
|
|
48133
|
+
return {
|
|
48134
|
+
type: type,
|
|
48135
|
+
code: code,
|
|
48136
|
+
message: message,
|
|
48137
|
+
suggestion: suggestion,
|
|
48138
|
+
line: line,
|
|
48139
|
+
column: column,
|
|
48140
|
+
};
|
|
48141
|
+
};
|
|
47777
48142
|
/**
|
|
47778
|
-
*
|
|
48143
|
+
* 检查TypeScript语法在组件方法中
|
|
47779
48144
|
*/
|
|
47780
|
-
|
|
47781
|
-
var
|
|
47782
|
-
|
|
47783
|
-
|
|
47784
|
-
|
|
47785
|
-
|
|
47786
|
-
|
|
47787
|
-
|
|
47788
|
-
|
|
47789
|
-
|
|
47790
|
-
|
|
47791
|
-
|
|
47792
|
-
|
|
48145
|
+
UnifiedTSXValidator.prototype.checkTypeScriptSyntaxInMethods = function (ast, issues) {
|
|
48146
|
+
var _this = this;
|
|
48147
|
+
this.log('开始检查TypeScript语法在组件方法中');
|
|
48148
|
+
// 找到React组件类并检查方法
|
|
48149
|
+
traverse__default["default"](ast, {
|
|
48150
|
+
ClassDeclaration: function (path) {
|
|
48151
|
+
var _a;
|
|
48152
|
+
if (_this.isReactComponent(path.node.superClass)) {
|
|
48153
|
+
var className = (_a = path.node.id) === null || _a === void 0 ? void 0 : _a.name;
|
|
48154
|
+
_this.log("\u68C0\u67E5TypeScript\u8BED\u6CD5\u5728\u7EC4\u4EF6\u7C7B: ".concat(className));
|
|
48155
|
+
// 检查类中的所有方法
|
|
48156
|
+
path.node.body.body.forEach(function (member) {
|
|
48157
|
+
var _a;
|
|
48158
|
+
if (member.type === 'ClassMethod') {
|
|
48159
|
+
var methodName_1 = (_a = member.key) === null || _a === void 0 ? void 0 : _a.name;
|
|
48160
|
+
// 跳过render方法的TypeScript语法检查(render方法本身已经单独处理)
|
|
48161
|
+
if (methodName_1 === 'render')
|
|
48162
|
+
return;
|
|
48163
|
+
// 检查方法参数中的TypeScript语法
|
|
48164
|
+
member.params.forEach(function (param, index) {
|
|
48165
|
+
// 检查是否有类型注解
|
|
48166
|
+
if (param.typeAnnotation) {
|
|
48167
|
+
issues.push(_this.createIssueFromNode('TYPESCRIPT_IN_METHOD_PARAMS', 'error', "\u65B9\u6CD5 ".concat(methodName_1, " \u7684\u7B2C ").concat(index + 1, " \u4E2A\u53C2\u6570\u5305\u542BTypeScript\u7C7B\u578B\u6CE8\u89E3"), "\u8BF7\u79FB\u9664\u53C2\u6570\u7684\u7C7B\u578B\u6CE8\u89E3\uFF0C\u4F7F\u7528\u7EAFJavaScript\u8BED\u6CD5\uFF0C\u5982\u5C06 '".concat(param.name.name || param.name, ": string' \u6539\u4E3A '").concat(param.name.name || param.name, "'"), param));
|
|
48168
|
+
}
|
|
48169
|
+
});
|
|
48170
|
+
// 检查方法返回值的TypeScript语法
|
|
48171
|
+
if (member.returnType) {
|
|
48172
|
+
issues.push(_this.createIssueFromNode('TYPESCRIPT_IN_RETURN_TYPE', 'error', "\u65B9\u6CD5 ".concat(methodName_1, " \u5305\u542BTypeScript\u8FD4\u56DE\u503C\u7C7B\u578B\u6CE8\u89E3"), "\u8BF7\u79FB\u9664\u8FD4\u56DE\u503C\u7684\u7C7B\u578B\u6CE8\u89E3\uFF0C\u4F7F\u7528\u7EAFJavaScript\u8BED\u6CD5", member));
|
|
48173
|
+
}
|
|
48174
|
+
// 检查方法中是否包含JSX返回
|
|
48175
|
+
if (_this.methodContainsJSX(member)) {
|
|
48176
|
+
issues.push(_this.createIssueFromNode('METHOD_CONTAINS_JSX', 'error', "\u65B9\u6CD5 ".concat(methodName_1, " \u4E0D\u80FD\u5305\u542B JSX \u8BED\u6CD5"), '只有 render() 方法可以包含 JSX,其他方法只处理逻辑', member));
|
|
48177
|
+
}
|
|
48178
|
+
// 检查方法体中的变量声明的TypeScript语法
|
|
48179
|
+
// 直接遍历AST节点而不使用traverse
|
|
48180
|
+
_this.checkVariableTypeAnnotationsInNode(member, methodName_1, issues);
|
|
48181
|
+
}
|
|
48182
|
+
});
|
|
48183
|
+
}
|
|
48184
|
+
},
|
|
48185
|
+
});
|
|
48186
|
+
};
|
|
48187
|
+
/**
|
|
48188
|
+
* 检查方法中是否包含JSX语法
|
|
48189
|
+
*/
|
|
48190
|
+
UnifiedTSXValidator.prototype.methodContainsJSX = function (methodNode) {
|
|
48191
|
+
var e_4, _a;
|
|
48192
|
+
if (!methodNode || !methodNode.body)
|
|
48193
|
+
return false;
|
|
48194
|
+
var containsJSX = false;
|
|
48195
|
+
var checkJSX = function (node) {
|
|
48196
|
+
if (!node)
|
|
47793
48197
|
return;
|
|
47794
|
-
|
|
47795
|
-
|
|
47796
|
-
|
|
47797
|
-
|
|
47798
|
-
|
|
47799
|
-
|
|
47800
|
-
|
|
47801
|
-
|
|
47802
|
-
|
|
47803
|
-
|
|
47804
|
-
|
|
47805
|
-
|
|
47806
|
-
|
|
47807
|
-
|
|
47808
|
-
|
|
47809
|
-
|
|
47810
|
-
|
|
47811
|
-
|
|
47812
|
-
|
|
47813
|
-
|
|
47814
|
-
|
|
48198
|
+
if (node.type === 'JSXElement' || node.type === 'JSXFragment') {
|
|
48199
|
+
containsJSX = true;
|
|
48200
|
+
return true; // 找到JSX,停止递归
|
|
48201
|
+
}
|
|
48202
|
+
// 递归检查子节点
|
|
48203
|
+
for (var key in node) {
|
|
48204
|
+
if (node[key] && typeof node[key] === 'object') {
|
|
48205
|
+
if (checkJSX(node[key])) {
|
|
48206
|
+
return true;
|
|
48207
|
+
}
|
|
48208
|
+
}
|
|
48209
|
+
}
|
|
48210
|
+
return false;
|
|
48211
|
+
};
|
|
48212
|
+
// 检查方法体中的所有语句
|
|
48213
|
+
if (Array.isArray(methodNode.body.body)) {
|
|
48214
|
+
try {
|
|
48215
|
+
for (var _b = __values(methodNode.body.body), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
48216
|
+
var statement = _c.value;
|
|
48217
|
+
if (checkJSX(statement)) {
|
|
48218
|
+
return true;
|
|
48219
|
+
}
|
|
48220
|
+
}
|
|
48221
|
+
}
|
|
48222
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
48223
|
+
finally {
|
|
48224
|
+
try {
|
|
48225
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
48226
|
+
}
|
|
48227
|
+
finally { if (e_4) throw e_4.error; }
|
|
47815
48228
|
}
|
|
47816
48229
|
}
|
|
48230
|
+
else if (methodNode.body) {
|
|
48231
|
+
if (checkJSX(methodNode.body)) {
|
|
48232
|
+
return true;
|
|
48233
|
+
}
|
|
48234
|
+
}
|
|
48235
|
+
return containsJSX;
|
|
47817
48236
|
};
|
|
47818
48237
|
/**
|
|
47819
|
-
*
|
|
48238
|
+
* 递归检查节点中的变量类型注解
|
|
47820
48239
|
*/
|
|
47821
|
-
|
|
47822
|
-
|
|
48240
|
+
UnifiedTSXValidator.prototype.checkVariableTypeAnnotationsInNode = function (node, methodName, issues) {
|
|
48241
|
+
var _this = this;
|
|
48242
|
+
if (!node)
|
|
48243
|
+
return;
|
|
48244
|
+
// 如果是数组,遍历每个元素
|
|
48245
|
+
if (Array.isArray(node)) {
|
|
48246
|
+
node.forEach(function (item) { return _this.checkVariableTypeAnnotationsInNode(item, methodName, issues); });
|
|
48247
|
+
return;
|
|
48248
|
+
}
|
|
48249
|
+
// 检查变量声明
|
|
48250
|
+
if (node.type === 'VariableDeclaration') {
|
|
48251
|
+
node.declarations.forEach(function (declaration) {
|
|
48252
|
+
if (declaration.id && declaration.id.typeAnnotation) {
|
|
48253
|
+
issues.push(_this.createIssueFromNode('TYPESCRIPT_IN_VARIABLES', 'error', "\u65B9\u6CD5 ".concat(methodName, " \u4E2D\u7684\u53D8\u91CF\u58F0\u660E\u5305\u542BTypeScript\u7C7B\u578B\u6CE8\u89E3"), "\u8BF7\u79FB\u9664\u53D8\u91CF\u7684\u7C7B\u578B\u6CE8\u89E3\uFF0C\u4F7F\u7528\u7EAFJavaScript\u8BED\u6CD5\uFF0C\u5982\u5C06 'let name: string' \u6539\u4E3A 'let name'", declaration));
|
|
48254
|
+
}
|
|
48255
|
+
});
|
|
48256
|
+
}
|
|
48257
|
+
// 递归检查子节点
|
|
48258
|
+
if (node.body && Array.isArray(node.body)) {
|
|
48259
|
+
node.body.forEach(function (child) { return _this.checkVariableTypeAnnotationsInNode(child, methodName, issues); });
|
|
48260
|
+
}
|
|
48261
|
+
else if (node.body) {
|
|
48262
|
+
this.checkVariableTypeAnnotationsInNode(node.body, methodName, issues);
|
|
48263
|
+
}
|
|
48264
|
+
if (node.consequent) {
|
|
48265
|
+
this.checkVariableTypeAnnotationsInNode(node.consequent, methodName, issues);
|
|
48266
|
+
}
|
|
48267
|
+
if (node.alternate) {
|
|
48268
|
+
this.checkVariableTypeAnnotationsInNode(node.alternate, methodName, issues);
|
|
48269
|
+
}
|
|
48270
|
+
if (node.expression) {
|
|
48271
|
+
this.checkVariableTypeAnnotationsInNode(node.expression, methodName, issues);
|
|
48272
|
+
}
|
|
47823
48273
|
};
|
|
47824
48274
|
/**
|
|
47825
|
-
*
|
|
48275
|
+
* 安全地执行检查方法,避免异常传播
|
|
47826
48276
|
*/
|
|
47827
|
-
|
|
47828
|
-
|
|
48277
|
+
UnifiedTSXValidator.prototype.safeCheck = function (methodName, checkFunction) {
|
|
48278
|
+
try {
|
|
48279
|
+
checkFunction();
|
|
48280
|
+
}
|
|
48281
|
+
catch (error) {
|
|
48282
|
+
this.log("".concat(methodName, " \u68C0\u67E5\u65F6\u53D1\u751F\u9519\u8BEF: ").concat(error.message));
|
|
48283
|
+
// 不抛出异常,只记录日志
|
|
48284
|
+
}
|
|
48285
|
+
};
|
|
48286
|
+
UnifiedTSXValidator.prototype.log = function (message) {
|
|
48287
|
+
if (this.debug) {
|
|
48288
|
+
console.log("[UnifiedTSXValidator] ".concat(message));
|
|
48289
|
+
}
|
|
47829
48290
|
};
|
|
47830
48291
|
/**
|
|
47831
|
-
*
|
|
48292
|
+
* 生成简化的错误信息(兼容编辑器使用)
|
|
47832
48293
|
*/
|
|
47833
|
-
|
|
47834
|
-
|
|
47835
|
-
|
|
48294
|
+
UnifiedTSXValidator.prototype.generateSimpleErrors = function (result) {
|
|
48295
|
+
return result.issues
|
|
48296
|
+
.filter(function (issue) { return issue.type === 'error'; })
|
|
48297
|
+
.map(function (issue) {
|
|
48298
|
+
var location = issue.line ? " (\u7B2C".concat(issue.line, "\u884C)") : '';
|
|
48299
|
+
return "[".concat(issue.code, "] ").concat(issue.message).concat(location);
|
|
48300
|
+
});
|
|
47836
48301
|
};
|
|
47837
48302
|
/**
|
|
47838
|
-
*
|
|
48303
|
+
* 生成详细报告(兼容CLI使用)
|
|
47839
48304
|
*/
|
|
47840
|
-
|
|
47841
|
-
var
|
|
47842
|
-
|
|
47843
|
-
|
|
47844
|
-
|
|
47845
|
-
|
|
48305
|
+
UnifiedTSXValidator.prototype.generateReport = function (result) {
|
|
48306
|
+
var isCompliant = result.isCompliant, issues = result.issues;
|
|
48307
|
+
var report = '=== TSX 规范检查报告 ===\n';
|
|
48308
|
+
report += "\u6587\u4EF6: ".concat(this.filename, "\n");
|
|
48309
|
+
if (isCompliant) {
|
|
48310
|
+
report += '✅ 检查通过:文件符合 TSX 规范\n';
|
|
48311
|
+
}
|
|
48312
|
+
else {
|
|
48313
|
+
var errorCount = issues.filter(function (issue) { return issue.type === 'error'; }).length;
|
|
48314
|
+
report += "\u274C \u68C0\u67E5\u5931\u8D25\uFF1A\u53D1\u73B0 ".concat(errorCount, " \u4E2A\u9519\u8BEF\n\n");
|
|
48315
|
+
report += '--- 问题详情 ---\n';
|
|
48316
|
+
issues.forEach(function (issue, index) {
|
|
48317
|
+
var icon = issue.type === 'error' ? '❌' : '⚠️';
|
|
48318
|
+
report += "".concat(index + 1, ". ").concat(icon, " [").concat(issue.code, "] ").concat(issue.message, "\n");
|
|
48319
|
+
if (issue.line) {
|
|
48320
|
+
report += " \uD83D\uDCCD \u4F4D\u7F6E: \u7B2C ".concat(issue.line, " \u884C\n");
|
|
48321
|
+
}
|
|
48322
|
+
report += " \uD83D\uDCA1 \u5EFA\u8BAE: ".concat(issue.suggestion, "\n\n");
|
|
48323
|
+
});
|
|
48324
|
+
}
|
|
48325
|
+
return report;
|
|
48326
|
+
};
|
|
48327
|
+
return UnifiedTSXValidator;
|
|
48328
|
+
}());
|
|
48329
|
+
|
|
48330
|
+
var TSXComplianceChecker = /** @class */ (function () {
|
|
48331
|
+
function TSXComplianceChecker() {
|
|
48332
|
+
}
|
|
48333
|
+
/**
|
|
48334
|
+
* 使用统一验证器检查 TSX 规范
|
|
48335
|
+
*/
|
|
48336
|
+
TSXComplianceChecker.checkTSXCompliance = function (content, filename) {
|
|
48337
|
+
var _this = this;
|
|
48338
|
+
try {
|
|
48339
|
+
var result = this.validator.validate(content, filename);
|
|
48340
|
+
// 转换为兼容的格式
|
|
48341
|
+
var compliantIssues = result.issues.map(function (issue) { return (__assign(__assign({}, issue), {
|
|
48342
|
+
// 为CLI添加代码片段
|
|
48343
|
+
codeSnippet: issue.line ? _this.extractCodeSnippet(content, issue.line).snippet : undefined, snippetStartLine: issue.line ? _this.extractCodeSnippet(content, issue.line).startLine : undefined, snippetEndLine: issue.line ? _this.extractCodeSnippet(content, issue.line).endLine : undefined })); });
|
|
48344
|
+
return {
|
|
48345
|
+
isCompliant: result.isCompliant,
|
|
48346
|
+
issues: compliantIssues,
|
|
48347
|
+
};
|
|
48348
|
+
}
|
|
48349
|
+
catch (error) {
|
|
48350
|
+
// 捕获任何异常并返回合规结果,而不是让异常向上传播
|
|
48351
|
+
return {
|
|
48352
|
+
isCompliant: false,
|
|
48353
|
+
issues: [{
|
|
48354
|
+
type: 'error',
|
|
48355
|
+
code: 'VALIDATION_ERROR',
|
|
48356
|
+
message: "\u9A8C\u8BC1\u8FC7\u7A0B\u53D1\u751F\u9519\u8BEF: ".concat(error.message),
|
|
48357
|
+
suggestion: '请检查代码语法或联系开发团队',
|
|
48358
|
+
line: 1,
|
|
48359
|
+
column: 0,
|
|
48360
|
+
}],
|
|
48361
|
+
};
|
|
48362
|
+
}
|
|
47846
48363
|
};
|
|
48364
|
+
// 移除了所有旧的检查方法,现在使用UnifiedTSXValidator
|
|
47847
48365
|
/**
|
|
47848
48366
|
* 提取代码片段
|
|
47849
48367
|
*/
|
|
@@ -47865,34 +48383,33 @@ var TSXComplianceChecker = /** @class */ (function () {
|
|
|
47865
48383
|
};
|
|
47866
48384
|
};
|
|
47867
48385
|
/**
|
|
47868
|
-
*
|
|
48386
|
+
* 生成检查报告(使用统一验证器)
|
|
47869
48387
|
*/
|
|
47870
48388
|
TSXComplianceChecker.generateReport = function (result, filename) {
|
|
47871
|
-
|
|
47872
|
-
|
|
47873
|
-
|
|
47874
|
-
|
|
47875
|
-
|
|
47876
|
-
|
|
47877
|
-
|
|
47878
|
-
|
|
47879
|
-
|
|
47880
|
-
|
|
47881
|
-
|
|
47882
|
-
|
|
47883
|
-
|
|
47884
|
-
|
|
47885
|
-
|
|
47886
|
-
|
|
47887
|
-
report += " \uD83D\uDCA1 \u5EFA\u8BAE: ".concat(issue.suggestion, "\n");
|
|
47888
|
-
if (issue.codeSnippet) {
|
|
47889
|
-
report += " \uD83D\uDCDD \u4EE3\u7801\u7247\u6BB5:\n".concat(issue.codeSnippet, "\n");
|
|
47890
|
-
}
|
|
47891
|
-
report += '\n';
|
|
47892
|
-
});
|
|
48389
|
+
this.validator = new UnifiedTSXValidator(false);
|
|
48390
|
+
return this.validator.generateReport(result);
|
|
48391
|
+
};
|
|
48392
|
+
/**
|
|
48393
|
+
* 提取代码片段(保留原有逻辑)
|
|
48394
|
+
*/
|
|
48395
|
+
TSXComplianceChecker.extractCodeSnippet = function (content, lineNumber, contextLines) {
|
|
48396
|
+
if (contextLines === void 0) { contextLines = 3; }
|
|
48397
|
+
var lines = content.split('\n');
|
|
48398
|
+
var startLine = Math.max(1, lineNumber - contextLines);
|
|
48399
|
+
var endLine = Math.min(lines.length, lineNumber + contextLines);
|
|
48400
|
+
var snippetLines = [];
|
|
48401
|
+
for (var i = startLine; i <= endLine; i++) {
|
|
48402
|
+
var line = lines[i - 1] || '';
|
|
48403
|
+
var prefix = i === lineNumber ? '>>> ' : ' ';
|
|
48404
|
+
snippetLines.push("".concat(prefix).concat(i.toString().padStart(3), ": ").concat(line));
|
|
47893
48405
|
}
|
|
47894
|
-
return
|
|
48406
|
+
return {
|
|
48407
|
+
snippet: snippetLines.join('\n'),
|
|
48408
|
+
startLine: startLine,
|
|
48409
|
+
endLine: endLine,
|
|
48410
|
+
};
|
|
47895
48411
|
};
|
|
48412
|
+
TSXComplianceChecker.validator = new UnifiedTSXValidator(false);
|
|
47896
48413
|
return TSXComplianceChecker;
|
|
47897
48414
|
}());
|
|
47898
48415
|
|