@be-link/smart-test 1.0.1-beta.30 → 1.0.1-beta.31
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/bin/smart-test.js +84 -57
- package/dist/cli/commands/preset.d.ts +2 -4
- package/dist/cli/commands/preset.d.ts.map +1 -1
- package/dist/cli/commands/record-only.d.ts +2 -3
- package/dist/cli/commands/record-only.d.ts.map +1 -1
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/index.esm.mjs +42 -2
- package/dist/index.js +42 -2
- package/dist/prompts/mock-generation.prompt.d.ts.map +1 -1
- package/dist/utils/data-compressor.d.ts +8 -0
- package/dist/utils/data-compressor.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/bin/smart-test.js
CHANGED
|
@@ -254,6 +254,43 @@ function compressAndStringify(data, options = {}) {
|
|
|
254
254
|
const compressed = compressResponseData(data, options);
|
|
255
255
|
return stringifyCompressedData(compressed);
|
|
256
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* 检测数据是否已经被压缩过
|
|
259
|
+
* 通过检查是否存在 __compressed__ 或 __truncated__ 标记来判断
|
|
260
|
+
*
|
|
261
|
+
* @param data - 要检测的数据
|
|
262
|
+
* @returns 是否已压缩
|
|
263
|
+
*/
|
|
264
|
+
function isCompressedData(data) {
|
|
265
|
+
if (data === null || data === undefined) {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
// 检查顶层是否有压缩标记
|
|
269
|
+
if (typeof data === 'object' && !Array.isArray(data)) {
|
|
270
|
+
const obj = data;
|
|
271
|
+
if (obj.__compressed__ === true || obj.__truncated__ === true) {
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// 递归检查对象内部
|
|
276
|
+
function check(value, depth = 0) {
|
|
277
|
+
if (depth > 10 || value === null || value === undefined) {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
if (Array.isArray(value)) {
|
|
281
|
+
return value.some((item) => check(item, depth + 1));
|
|
282
|
+
}
|
|
283
|
+
if (typeof value === 'object') {
|
|
284
|
+
const obj = value;
|
|
285
|
+
if (obj.__compressed__ === true || obj.__truncated__ === true) {
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
return Object.values(obj).some((v) => check(v, depth + 1));
|
|
289
|
+
}
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
return check(data);
|
|
293
|
+
}
|
|
257
294
|
|
|
258
295
|
const SMART_TEST_CONFIG_FILENAME = 'smart-test.config.ts';
|
|
259
296
|
const PLAYWRIGHT_CONFIG_FILENAME = 'playwright.config.ts';
|
|
@@ -435,22 +472,9 @@ function getSubDirectories$1(dirPath) {
|
|
|
435
472
|
.sort();
|
|
436
473
|
}
|
|
437
474
|
/**
|
|
438
|
-
* 执行 preset 命令 -
|
|
439
|
-
*
|
|
440
|
-
* @param presetName - 预设名称(必填)
|
|
475
|
+
* 执行 preset 命令 - 创建录制预设配置文件(固定使用 index 名称)
|
|
441
476
|
*/
|
|
442
|
-
async function executePresetCommand(
|
|
443
|
-
if (!presetName) {
|
|
444
|
-
console.error('❌ 错误: 请指定预设名称');
|
|
445
|
-
console.log('\n用法: smart-test preset <name>');
|
|
446
|
-
console.log('示例: smart-test preset login\n');
|
|
447
|
-
process.exit(1);
|
|
448
|
-
}
|
|
449
|
-
// 验证名称格式
|
|
450
|
-
if (!/^[a-zA-Z0-9-_]+$/.test(presetName)) {
|
|
451
|
-
console.error('❌ 错误: 预设名称只能包含字母、数字、连字符和下划线');
|
|
452
|
-
process.exit(1);
|
|
453
|
-
}
|
|
477
|
+
async function executePresetCommand() {
|
|
454
478
|
try {
|
|
455
479
|
const cwd = process.cwd();
|
|
456
480
|
// 加载环境变量
|
|
@@ -493,6 +517,7 @@ async function executePresetCommand(presetName) {
|
|
|
493
517
|
});
|
|
494
518
|
}
|
|
495
519
|
console.log(`\n📋 预设文件将保存到: ${presetDir}/`);
|
|
520
|
+
console.log(`📝 文件名称: index.preset.ts\n`);
|
|
496
521
|
// 询问用户选择子目录
|
|
497
522
|
const selectedDir = await prompts.select({
|
|
498
523
|
message: '请选择预设文件存放位置:',
|
|
@@ -517,14 +542,14 @@ async function executePresetCommand(presetName) {
|
|
|
517
542
|
// 用户选择了现有子目录
|
|
518
543
|
subDir = selectedDir;
|
|
519
544
|
}
|
|
520
|
-
//
|
|
545
|
+
// 计算最终路径(固定使用 index 名称)
|
|
521
546
|
const finalPresetDir = subDir ? path.join(fullPresetDir, subDir) : fullPresetDir;
|
|
522
|
-
const presetFileName =
|
|
547
|
+
const presetFileName = 'index.preset.ts';
|
|
523
548
|
const presetFilePath = path.join(finalPresetDir, presetFileName);
|
|
524
549
|
// 检查文件是否存在
|
|
525
550
|
if (node_fs.existsSync(presetFilePath)) {
|
|
526
551
|
console.error(`\n❌ 错误: 文件已存在: ${presetFilePath}`);
|
|
527
|
-
console.log('
|
|
552
|
+
console.log(' 该目录下已经有预设文件,请选择其他目录或删除现有文件\n');
|
|
528
553
|
process.exit(1);
|
|
529
554
|
}
|
|
530
555
|
// 确保目录存在
|
|
@@ -532,10 +557,12 @@ async function executePresetCommand(presetName) {
|
|
|
532
557
|
// 读取模板并写入
|
|
533
558
|
const templatePath = findTemplate();
|
|
534
559
|
let templateContent = node_fs.readFileSync(templatePath, 'utf-8');
|
|
560
|
+
// 修改模板中的 caseName 为 'index'
|
|
561
|
+
templateContent = templateContent.replace(/caseName:\s*'[^']*'/, "caseName: 'index'");
|
|
535
562
|
// 如果有子目录,在模板中添加 subDir 配置
|
|
536
563
|
if (subDir) {
|
|
537
564
|
// 在 caseName 后添加 subDir
|
|
538
|
-
templateContent = templateContent.replace(/(caseName:\s*'
|
|
565
|
+
templateContent = templateContent.replace(/(caseName:\s*'index',)/, `$1\n\n // 子目录(生成的 Mock 和测试文件也会放在对应子目录下)\n subDir: '${subDir}',`);
|
|
539
566
|
}
|
|
540
567
|
node_fs.writeFileSync(presetFilePath, templateContent, 'utf-8');
|
|
541
568
|
const relativePath = path.relative(cwd, presetFilePath);
|
|
@@ -546,8 +573,8 @@ async function executePresetCommand(presetName) {
|
|
|
546
573
|
if (subDir) {
|
|
547
574
|
console.log('💡 提示:');
|
|
548
575
|
console.log(` 生成的文件将保存在对应子目录下:`);
|
|
549
|
-
console.log(` - Mock 文件: ${config.recording?.mockDir || 'tests/mock'}/${subDir}
|
|
550
|
-
console.log(` - 测试文件: ${config.recording?.testDir || 'tests/e2e'}/${subDir}
|
|
576
|
+
console.log(` - Mock 文件: ${config.recording?.mockDir || 'tests/mock'}/${subDir}/index.mock.ts`);
|
|
577
|
+
console.log(` - 测试文件: ${config.recording?.testDir || 'tests/e2e'}/${subDir}/index.spec.ts\n`);
|
|
551
578
|
}
|
|
552
579
|
}
|
|
553
580
|
catch (error) {
|
|
@@ -1478,8 +1505,11 @@ function buildMockGenerationPrompt(options) {
|
|
|
1478
1505
|
sections.push('');
|
|
1479
1506
|
sections.push('**真实响应数据(已压缩,数组只保留首个元素展示结构):**');
|
|
1480
1507
|
sections.push('```json');
|
|
1481
|
-
//
|
|
1482
|
-
|
|
1508
|
+
// 检测数据是否已压缩,如果已压缩则直接序列化,否则先压缩
|
|
1509
|
+
const responseJson = isCompressedData(api.responseData)
|
|
1510
|
+
? stringifyCompressedData(api.responseData)
|
|
1511
|
+
: compressAndStringify(api.responseData, { maxArrayLength: 1, maxStringLength: 200 });
|
|
1512
|
+
sections.push(responseJson);
|
|
1483
1513
|
sections.push('```');
|
|
1484
1514
|
sections.push('');
|
|
1485
1515
|
});
|
|
@@ -2148,7 +2178,9 @@ function printPresetConfig(preset, config) {
|
|
|
2148
2178
|
console.log(` 排除 API: ${excludeApiPatterns.length > 0 ? excludeApiPatterns.join(', ') : '无'} (来自配置)\n`);
|
|
2149
2179
|
}
|
|
2150
2180
|
/**
|
|
2151
|
-
* 准备 session
|
|
2181
|
+
* 准备 session 数据用于保存
|
|
2182
|
+
* - 排除截图以减小文件大小
|
|
2183
|
+
* - 压缩 API 响应数据以减小文件大小并优化后续生成
|
|
2152
2184
|
*/
|
|
2153
2185
|
function prepareSessionForSave$1(session) {
|
|
2154
2186
|
return {
|
|
@@ -2163,6 +2195,15 @@ function prepareSessionForSave$1(session) {
|
|
|
2163
2195
|
timestamp: screenshot.timestamp,
|
|
2164
2196
|
description: screenshot.description,
|
|
2165
2197
|
})),
|
|
2198
|
+
// 压缩 API 响应数据(数组只保留首个元素,截断长字符串)
|
|
2199
|
+
apis: session.apis.map((api) => ({
|
|
2200
|
+
...api,
|
|
2201
|
+
responseData: compressResponseData(api.responseData, {
|
|
2202
|
+
maxArrayLength: 1,
|
|
2203
|
+
maxStringLength: 200,
|
|
2204
|
+
addMetaInfo: true,
|
|
2205
|
+
}),
|
|
2206
|
+
})),
|
|
2166
2207
|
};
|
|
2167
2208
|
}
|
|
2168
2209
|
/**
|
|
@@ -2337,12 +2378,11 @@ function getSubDirectories(dirPath) {
|
|
|
2337
2378
|
.sort();
|
|
2338
2379
|
}
|
|
2339
2380
|
/**
|
|
2340
|
-
* 执行纯录制命令 -
|
|
2381
|
+
* 执行纯录制命令 - 只录制操作,保存数据,不生成代码(固定使用 index 名称)
|
|
2341
2382
|
*
|
|
2342
2383
|
* @param pageUrl - 页面 URL
|
|
2343
|
-
* @param outputName - 输出文件名称(不含后缀)
|
|
2344
2384
|
*/
|
|
2345
|
-
async function executeRecordOnlyCommand(pageUrl
|
|
2385
|
+
async function executeRecordOnlyCommand(pageUrl) {
|
|
2346
2386
|
console.log('\n╔════════════════════════════════════════════╗');
|
|
2347
2387
|
console.log('║ 🎬 Smart-Test 纯录制模式 ║');
|
|
2348
2388
|
console.log('╚════════════════════════════════════════════╝\n');
|
|
@@ -2390,6 +2430,7 @@ async function executeRecordOnlyCommand(pageUrl, outputName) {
|
|
|
2390
2430
|
});
|
|
2391
2431
|
}
|
|
2392
2432
|
console.log(`📁 录制数据将保存到: ${mockDir}/`);
|
|
2433
|
+
console.log(`📝 文件名称: index.session.json\n`);
|
|
2393
2434
|
// 询问用户选择子目录
|
|
2394
2435
|
const selectedDir = await prompts.select({
|
|
2395
2436
|
message: '请选择录制数据存放位置:',
|
|
@@ -2414,14 +2455,13 @@ async function executeRecordOnlyCommand(pageUrl, outputName) {
|
|
|
2414
2455
|
// 用户选择了现有子目录
|
|
2415
2456
|
subDir = selectedDir;
|
|
2416
2457
|
}
|
|
2417
|
-
//
|
|
2458
|
+
// 计算最终输出目录(固定使用 index 名称)
|
|
2418
2459
|
const finalMockDir = subDir ? path.join(fullMockDir, subDir) : fullMockDir;
|
|
2419
2460
|
const relativeMockDir = subDir ? `${mockDir}/${subDir}` : mockDir;
|
|
2420
2461
|
// 确保目录存在
|
|
2421
2462
|
await ensureDir(finalMockDir);
|
|
2422
2463
|
console.log('\n📋 录制配置:');
|
|
2423
2464
|
console.log(` 页面 URL: ${pageUrl}`);
|
|
2424
|
-
console.log(` 输出名称: ${outputName}`);
|
|
2425
2465
|
console.log(` 输出目录: ${relativeMockDir}`);
|
|
2426
2466
|
console.log(` API 匹配: ${apiPathPattern}`);
|
|
2427
2467
|
console.log(` 排除 API: ${excludeApiPatterns.length > 0 ? excludeApiPatterns.join(', ') : '无'}\n`);
|
|
@@ -2438,7 +2478,7 @@ async function executeRecordOnlyCommand(pageUrl, outputName) {
|
|
|
2438
2478
|
process.exit(1);
|
|
2439
2479
|
}
|
|
2440
2480
|
// 保存录制数据到 JSON 文件(排除截图以减小文件大小)
|
|
2441
|
-
const sessionFilePath = path.join(finalMockDir,
|
|
2481
|
+
const sessionFilePath = path.join(finalMockDir, 'index.session.json');
|
|
2442
2482
|
const sessionToSave = prepareSessionForSave(recordResult.session);
|
|
2443
2483
|
await writeJsonFile(sessionFilePath, sessionToSave);
|
|
2444
2484
|
console.log('\n╔════════════════════════════════════════════╗');
|
|
@@ -2468,7 +2508,9 @@ async function executeRecordOnlyCommand(pageUrl, outputName) {
|
|
|
2468
2508
|
}
|
|
2469
2509
|
}
|
|
2470
2510
|
/**
|
|
2471
|
-
* 准备 session
|
|
2511
|
+
* 准备 session 数据用于保存
|
|
2512
|
+
* - 排除截图以减小文件大小
|
|
2513
|
+
* - 压缩 API 响应数据以减小文件大小并优化后续生成
|
|
2472
2514
|
*/
|
|
2473
2515
|
function prepareSessionForSave(session) {
|
|
2474
2516
|
return {
|
|
@@ -2483,6 +2525,15 @@ function prepareSessionForSave(session) {
|
|
|
2483
2525
|
timestamp: screenshot.timestamp,
|
|
2484
2526
|
description: screenshot.description,
|
|
2485
2527
|
})),
|
|
2528
|
+
// 压缩 API 响应数据(数组只保留首个元素,截断长字符串)
|
|
2529
|
+
apis: session.apis.map((api) => ({
|
|
2530
|
+
...api,
|
|
2531
|
+
responseData: compressResponseData(api.responseData, {
|
|
2532
|
+
maxArrayLength: 1,
|
|
2533
|
+
maxStringLength: 200,
|
|
2534
|
+
addMetaInfo: true,
|
|
2535
|
+
}),
|
|
2536
|
+
})),
|
|
2486
2537
|
};
|
|
2487
2538
|
}
|
|
2488
2539
|
|
|
@@ -2562,19 +2613,7 @@ async function executeGuidedMode() {
|
|
|
2562
2613
|
await executeInitCommand();
|
|
2563
2614
|
break;
|
|
2564
2615
|
case 'preset': {
|
|
2565
|
-
|
|
2566
|
-
message: '请输入预设文件名称:',
|
|
2567
|
-
default: 'test-case',
|
|
2568
|
-
validate: (value) => {
|
|
2569
|
-
if (!value.trim())
|
|
2570
|
-
return '名称不能为空';
|
|
2571
|
-
if (!/^[a-zA-Z0-9-_]+$/.test(value)) {
|
|
2572
|
-
return '名称只能包含字母、数字、连字符和下划线';
|
|
2573
|
-
}
|
|
2574
|
-
return true;
|
|
2575
|
-
},
|
|
2576
|
-
});
|
|
2577
|
-
await executePresetCommand(presetName);
|
|
2616
|
+
await executePresetCommand();
|
|
2578
2617
|
break;
|
|
2579
2618
|
}
|
|
2580
2619
|
case 'record-only': {
|
|
@@ -2589,19 +2628,7 @@ async function executeGuidedMode() {
|
|
|
2589
2628
|
return true;
|
|
2590
2629
|
},
|
|
2591
2630
|
});
|
|
2592
|
-
|
|
2593
|
-
message: '请输入输出文件名称 (不含后缀):',
|
|
2594
|
-
default: 'recording',
|
|
2595
|
-
validate: (value) => {
|
|
2596
|
-
if (!value.trim())
|
|
2597
|
-
return '名称不能为空';
|
|
2598
|
-
if (!/^[a-zA-Z0-9-_]+$/.test(value)) {
|
|
2599
|
-
return '名称只能包含字母、数字、连字符和下划线';
|
|
2600
|
-
}
|
|
2601
|
-
return true;
|
|
2602
|
-
},
|
|
2603
|
-
});
|
|
2604
|
-
await executeRecordOnlyCommand(pageUrl, outputName);
|
|
2631
|
+
await executeRecordOnlyCommand(pageUrl);
|
|
2605
2632
|
break;
|
|
2606
2633
|
}
|
|
2607
2634
|
case 'record-and-generate': {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 执行 preset 命令 -
|
|
3
|
-
*
|
|
4
|
-
* @param presetName - 预设名称(必填)
|
|
2
|
+
* 执行 preset 命令 - 创建录制预设配置文件(固定使用 index 名称)
|
|
5
3
|
*/
|
|
6
|
-
export declare function executePresetCommand(
|
|
4
|
+
export declare function executePresetCommand(): Promise<void>;
|
|
7
5
|
//# sourceMappingURL=preset.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/preset.ts"],"names":[],"mappings":"AA4CA
|
|
1
|
+
{"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/preset.ts"],"names":[],"mappings":"AA4CA;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiI1D"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 执行纯录制命令 -
|
|
2
|
+
* 执行纯录制命令 - 只录制操作,保存数据,不生成代码(固定使用 index 名称)
|
|
3
3
|
*
|
|
4
4
|
* @param pageUrl - 页面 URL
|
|
5
|
-
* @param outputName - 输出文件名称(不含后缀)
|
|
6
5
|
*/
|
|
7
|
-
export declare function executeRecordOnlyCommand(pageUrl: string
|
|
6
|
+
export declare function executeRecordOnlyCommand(pageUrl: string): Promise<void>;
|
|
8
7
|
//# sourceMappingURL=record-only.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-only.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/record-only.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"record-only.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/record-only.ts"],"names":[],"mappings":"AA0BA;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+I7E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAYA;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkIzE"}
|
package/dist/index.esm.mjs
CHANGED
|
@@ -361,6 +361,43 @@ function compressAndStringify(data, options = {}) {
|
|
|
361
361
|
const compressed = compressResponseData(data, options);
|
|
362
362
|
return stringifyCompressedData(compressed);
|
|
363
363
|
}
|
|
364
|
+
/**
|
|
365
|
+
* 检测数据是否已经被压缩过
|
|
366
|
+
* 通过检查是否存在 __compressed__ 或 __truncated__ 标记来判断
|
|
367
|
+
*
|
|
368
|
+
* @param data - 要检测的数据
|
|
369
|
+
* @returns 是否已压缩
|
|
370
|
+
*/
|
|
371
|
+
function isCompressedData(data) {
|
|
372
|
+
if (data === null || data === undefined) {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
// 检查顶层是否有压缩标记
|
|
376
|
+
if (typeof data === 'object' && !Array.isArray(data)) {
|
|
377
|
+
const obj = data;
|
|
378
|
+
if (obj.__compressed__ === true || obj.__truncated__ === true) {
|
|
379
|
+
return true;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// 递归检查对象内部
|
|
383
|
+
function check(value, depth = 0) {
|
|
384
|
+
if (depth > 10 || value === null || value === undefined) {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
if (Array.isArray(value)) {
|
|
388
|
+
return value.some((item) => check(item, depth + 1));
|
|
389
|
+
}
|
|
390
|
+
if (typeof value === 'object') {
|
|
391
|
+
const obj = value;
|
|
392
|
+
if (obj.__compressed__ === true || obj.__truncated__ === true) {
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
return Object.values(obj).some((v) => check(v, depth + 1));
|
|
396
|
+
}
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
return check(data);
|
|
400
|
+
}
|
|
364
401
|
|
|
365
402
|
/**
|
|
366
403
|
* MD 片段缓存
|
|
@@ -478,8 +515,11 @@ function buildMockGenerationPrompt(options) {
|
|
|
478
515
|
sections.push('');
|
|
479
516
|
sections.push('**真实响应数据(已压缩,数组只保留首个元素展示结构):**');
|
|
480
517
|
sections.push('```json');
|
|
481
|
-
//
|
|
482
|
-
|
|
518
|
+
// 检测数据是否已压缩,如果已压缩则直接序列化,否则先压缩
|
|
519
|
+
const responseJson = isCompressedData(api.responseData)
|
|
520
|
+
? stringifyCompressedData(api.responseData)
|
|
521
|
+
: compressAndStringify(api.responseData, { maxArrayLength: 1, maxStringLength: 200 });
|
|
522
|
+
sections.push(responseJson);
|
|
483
523
|
sections.push('```');
|
|
484
524
|
sections.push('');
|
|
485
525
|
});
|
package/dist/index.js
CHANGED
|
@@ -382,6 +382,43 @@ function compressAndStringify(data, options = {}) {
|
|
|
382
382
|
const compressed = compressResponseData(data, options);
|
|
383
383
|
return stringifyCompressedData(compressed);
|
|
384
384
|
}
|
|
385
|
+
/**
|
|
386
|
+
* 检测数据是否已经被压缩过
|
|
387
|
+
* 通过检查是否存在 __compressed__ 或 __truncated__ 标记来判断
|
|
388
|
+
*
|
|
389
|
+
* @param data - 要检测的数据
|
|
390
|
+
* @returns 是否已压缩
|
|
391
|
+
*/
|
|
392
|
+
function isCompressedData(data) {
|
|
393
|
+
if (data === null || data === undefined) {
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
// 检查顶层是否有压缩标记
|
|
397
|
+
if (typeof data === 'object' && !Array.isArray(data)) {
|
|
398
|
+
const obj = data;
|
|
399
|
+
if (obj.__compressed__ === true || obj.__truncated__ === true) {
|
|
400
|
+
return true;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// 递归检查对象内部
|
|
404
|
+
function check(value, depth = 0) {
|
|
405
|
+
if (depth > 10 || value === null || value === undefined) {
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
408
|
+
if (Array.isArray(value)) {
|
|
409
|
+
return value.some((item) => check(item, depth + 1));
|
|
410
|
+
}
|
|
411
|
+
if (typeof value === 'object') {
|
|
412
|
+
const obj = value;
|
|
413
|
+
if (obj.__compressed__ === true || obj.__truncated__ === true) {
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
return Object.values(obj).some((v) => check(v, depth + 1));
|
|
417
|
+
}
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
return check(data);
|
|
421
|
+
}
|
|
385
422
|
|
|
386
423
|
/**
|
|
387
424
|
* MD 片段缓存
|
|
@@ -499,8 +536,11 @@ function buildMockGenerationPrompt(options) {
|
|
|
499
536
|
sections.push('');
|
|
500
537
|
sections.push('**真实响应数据(已压缩,数组只保留首个元素展示结构):**');
|
|
501
538
|
sections.push('```json');
|
|
502
|
-
//
|
|
503
|
-
|
|
539
|
+
// 检测数据是否已压缩,如果已压缩则直接序列化,否则先压缩
|
|
540
|
+
const responseJson = isCompressedData(api.responseData)
|
|
541
|
+
? stringifyCompressedData(api.responseData)
|
|
542
|
+
: compressAndStringify(api.responseData, { maxArrayLength: 1, maxStringLength: 200 });
|
|
543
|
+
sections.push(responseJson);
|
|
504
544
|
sections.push('```');
|
|
505
545
|
sections.push('');
|
|
506
546
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock-generation.prompt.d.ts","sourceRoot":"","sources":["../../src/prompts/mock-generation.prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,IAAI,EAAE,SAAS,EAAE,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,eAAO,MAAM,6BAA6B,QAIxC,CAAC;AAEH;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"mock-generation.prompt.d.ts","sourceRoot":"","sources":["../../src/prompts/mock-generation.prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,IAAI,EAAE,SAAS,EAAE,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,eAAO,MAAM,6BAA6B,QAIxC,CAAC;AAEH;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CA2C5E"}
|
|
@@ -51,4 +51,12 @@ export declare function stringifyCompressedData(data: unknown, indent?: number):
|
|
|
51
51
|
* @returns 压缩并格式化后的 JSON 字符串
|
|
52
52
|
*/
|
|
53
53
|
export declare function compressAndStringify(data: unknown, options?: CompressOptions): string;
|
|
54
|
+
/**
|
|
55
|
+
* 检测数据是否已经被压缩过
|
|
56
|
+
* 通过检查是否存在 __compressed__ 或 __truncated__ 标记来判断
|
|
57
|
+
*
|
|
58
|
+
* @param data - 要检测的数据
|
|
59
|
+
* @returns 是否已压缩
|
|
60
|
+
*/
|
|
61
|
+
export declare function isCompressedData(data: unknown): boolean;
|
|
54
62
|
//# sourceMappingURL=data-compressor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-compressor.d.ts","sourceRoot":"","sources":["../../src/utils/data-compressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAqBD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAkE1F;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,SAAI,GAAG,MAAM,CAYzE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAGzF"}
|
|
1
|
+
{"version":3,"file":"data-compressor.d.ts","sourceRoot":"","sources":["../../src/utils/data-compressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAqBD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAkE1F;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,SAAI,GAAG,MAAM,CAYzE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAGzF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAmCvD"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -5,5 +5,5 @@ export { writeFormattedFile, generateFileHeader, type WriteOptions } from './fil
|
|
|
5
5
|
export { toPascalCase, toCamelCase } from './string-utils';
|
|
6
6
|
export { fileExists } from './fs-utils';
|
|
7
7
|
export { getRelativeImportPath } from './path-utils';
|
|
8
|
-
export { compressResponseData, compressAndStringify, stringifyCompressedData, type CompressOptions, } from './data-compressor';
|
|
8
|
+
export { compressResponseData, compressAndStringify, stringifyCompressedData, isCompressedData, type CompressOptions, } from './data-compressor';
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,gBAAgB,EAChB,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC"}
|
package/package.json
CHANGED