intention-coding 0.4.0 → 0.4.3

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.
Files changed (51) hide show
  1. package/package.json +2 -3
  2. package/dist/db/file-storage.js +0 -638
  3. package/dist/index.js +0 -26
  4. package/dist/server/index.js +0 -88
  5. package/dist/services/bug-fix-agent/index.js +0 -320
  6. package/dist/services/change-summarizer/index.js +0 -123
  7. package/dist/services/change-summarizer/prompt/change-analysis.js +0 -56
  8. package/dist/services/code-generator/index.js +0 -403
  9. package/dist/services/code-generator/stages/execution-stage.js +0 -549
  10. package/dist/services/code-generator/stages/ideation-stage.js +0 -267
  11. package/dist/services/code-generator/stages/optimization-stage.js +0 -334
  12. package/dist/services/code-generator/stages/planning-stage.js +0 -295
  13. package/dist/services/code-generator/stages/research-stage.js +0 -283
  14. package/dist/services/code-generator/stages/review-stage.js +0 -270
  15. package/dist/services/code-generator/types.js +0 -37
  16. package/dist/services/code-generator/utils/instruction-executor.js +0 -207
  17. package/dist/services/code-generator/workflow-manager.js +0 -252
  18. package/dist/services/image-analysis/analyzer.js +0 -530
  19. package/dist/services/image-analysis/index.js +0 -406
  20. package/dist/services/image-analysis/types.js +0 -46
  21. package/dist/services/image-converter/converter.js +0 -310
  22. package/dist/services/image-converter/index.js +0 -262
  23. package/dist/services/image-converter/types.js +0 -31
  24. package/dist/services/integrated-generator/index.js +0 -1297
  25. package/dist/services/pdf2md/index.js +0 -180
  26. package/dist/services/project-template/index.js +0 -83
  27. package/dist/services/project-template/prompt/project-rules.js +0 -98
  28. package/dist/services/requirement-analyzer/chunk-reader.js +0 -218
  29. package/dist/services/requirement-analyzer/core/document-generator.js +0 -254
  30. package/dist/services/requirement-analyzer/core/intelligent-analyzer.js +0 -169
  31. package/dist/services/requirement-analyzer/core/project-analyzer.js +0 -199
  32. package/dist/services/requirement-analyzer/core/requirement-analyzer-service.js +0 -191
  33. package/dist/services/requirement-analyzer/core/template-selector.js +0 -124
  34. package/dist/services/requirement-analyzer/core/types.js +0 -23
  35. package/dist/services/requirement-analyzer/index.js +0 -177
  36. package/dist/services/requirement-analyzer/prompt/api-template.js +0 -302
  37. package/dist/services/requirement-analyzer/prompt/app-template.js +0 -455
  38. package/dist/services/requirement-analyzer/prompt/intelligent-requirement-analysis.js +0 -92
  39. package/dist/services/requirement-analyzer/prompt/pc-page-template.js +0 -582
  40. package/dist/services/requirement-analyzer/prompt/requirement-analysis.js +0 -664
  41. package/dist/services/requirement-analyzer/prompt/sdk-template.js +0 -582
  42. package/dist/services/requirement-analyzer/utils/file-reader.js +0 -169
  43. package/dist/services/world2md/index.js +0 -157
  44. package/dist/types/index.js +0 -2
  45. package/dist/utils/common.js +0 -72
  46. package/dist/utils/config.js +0 -163
  47. package/dist/utils/context-manager.js +0 -114
  48. package/dist/utils/dify.js +0 -243
  49. package/dist/utils/logger.js +0 -129
  50. package/dist/utils/openai.js +0 -225
  51. package/dist/utils/pack.js +0 -75
@@ -1,180 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
- var __importDefault = (this && this.__importDefault) || function (mod) {
45
- return (mod && mod.__esModule) ? mod : { "default": mod };
46
- };
47
- Object.defineProperty(exports, "__esModule", { value: true });
48
- exports.pdf2mdTool = exports.Pdf2MdParams = void 0;
49
- const fs = __importStar(require("fs/promises"));
50
- const path_1 = __importDefault(require("path"));
51
- const config_1 = require("../../utils/config");
52
- const logger_1 = require("../../utils/logger");
53
- const common_1 = require("../../utils/common");
54
- const zod_1 = require("zod");
55
- exports.Pdf2MdParams = zod_1.z.object({
56
- file_path: zod_1.z.string().describe("需要解析的PDF文档的绝对路径"),
57
- options: zod_1.z.object({
58
- preserve_formatting: zod_1.z.boolean().optional().default(true).describe("是否保留格式(换行、段落等)"),
59
- chunk_size: zod_1.z.number().optional().default(1000).describe("文本分块大小,用于大文件处理"),
60
- extract_metadata: zod_1.z.boolean().optional().default(true).describe("是否提取PDF元数据")
61
- }).optional().default({ preserve_formatting: true, chunk_size: 1000, extract_metadata: true }).describe("转换选项")
62
- });
63
- exports.pdf2mdTool = {
64
- name: "pdf处理智能体",
65
- description: "pdf处理智能体 - 将PDF文档转换为Markdown格式,支持文本提取和格式保留",
66
- parameters: exports.Pdf2MdParams,
67
- execute: (args) => __awaiter(void 0, void 0, void 0, function* () {
68
- const { file_path, options = {} } = args;
69
- const { preserve_formatting = true, chunk_size = 1000, extract_metadata = true } = options;
70
- try {
71
- // 1. 安全验证并解析路径
72
- const resolvedPath = yield (0, common_1.validateAndResolvePath)(file_path);
73
- // 2. 检查文件是否为PDF
74
- if (!file_path.toLowerCase().endsWith('.pdf')) {
75
- throw new Error('文件必须是PDF格式(.pdf扩展名)');
76
- }
77
- // 3. 读取PDF文件
78
- logger_1.logger.info('开始读取PDF文件', { file: file_path });
79
- const dataBuffer = yield fs.readFile(resolvedPath);
80
- // 4. 解析PDF内容 - 使用动态导入避免初始化问题
81
- logger_1.logger.info('开始解析PDF内容');
82
- // @ts-ignore - 避免pdf-parse的测试模式
83
- const pdfParse = yield Promise.resolve().then(() => __importStar(require('pdf-parse/lib/pdf-parse.js')));
84
- const pdfData = yield pdfParse.default(dataBuffer);
85
- // 5. 准备保存目录和文件名
86
- const mdDir = path_1.default.join((0, config_1.getStorageDir)(), 'md');
87
- const baseName = (0, common_1.sanitizeFileName)(path_1.default.basename(file_path, '.pdf'));
88
- const outputDir = path_1.default.join(mdDir, baseName);
89
- // 创建目录结构
90
- yield fs.mkdir(outputDir, { recursive: true });
91
- // 6. 处理文本内容
92
- let markdownContent = '';
93
- // 添加文档标题
94
- markdownContent += `# ${baseName}\n\n`;
95
- // 7. 添加元数据(如果启用)
96
- if (extract_metadata && pdfData.info) {
97
- markdownContent += '## 文档信息\n\n';
98
- if (pdfData.info.Title) {
99
- markdownContent += `**标题**: ${pdfData.info.Title}\n\n`;
100
- }
101
- if (pdfData.info.Author) {
102
- markdownContent += `**作者**: ${pdfData.info.Author}\n\n`;
103
- }
104
- if (pdfData.info.Subject) {
105
- markdownContent += `**主题**: ${pdfData.info.Subject}\n\n`;
106
- }
107
- if (pdfData.info.Creator) {
108
- markdownContent += `**创建者**: ${pdfData.info.Creator}\n\n`;
109
- }
110
- if (pdfData.info.CreationDate) {
111
- markdownContent += `**创建日期**: ${pdfData.info.CreationDate}\n\n`;
112
- }
113
- markdownContent += `**总页数**: ${pdfData.numpages}\n\n`;
114
- markdownContent += '---\n\n';
115
- }
116
- // 8. 处理正文内容
117
- markdownContent += '## 文档内容\n\n';
118
- let processedText = pdfData.text;
119
- if (preserve_formatting) {
120
- // 保留格式的处理
121
- processedText = processedText
122
- // 保留段落分隔
123
- .replace(/\n\s*\n/g, '\n\n')
124
- // 处理列表项(简单识别以-、*、数字开头的行)
125
- .replace(/^(\s*)[-*•]\s+(.+)$/gm, '$1- $2')
126
- .replace(/^(\s*)(\d+\.)\s+(.+)$/gm, '$1$2 $3')
127
- // 处理可能的标题(全大写或首字母大写的独立行)
128
- .replace(/^([A-Z][A-Z\s]{10,})$/gm, '### $1')
129
- // 处理引用或缩进内容
130
- .replace(/^(\s{4,})(.+)$/gm, '> $2');
131
- }
132
- else {
133
- // 简单处理,主要清理多余空白
134
- processedText = processedText
135
- .replace(/\s+/g, ' ')
136
- .replace(/\n+/g, '\n\n')
137
- .trim();
138
- }
139
- markdownContent += processedText;
140
- // 9. 保存Markdown文件
141
- const fullMdPath = path_1.default.join(outputDir, `${baseName}.md`);
142
- yield fs.writeFile(fullMdPath, markdownContent, 'utf8');
143
- // 10. 记录转换统计信息
144
- const stats = {
145
- totalPages: pdfData.numpages,
146
- textLength: pdfData.text.length,
147
- markdownLength: markdownContent.length,
148
- outputFile: path_1.default.resolve(fullMdPath)
149
- };
150
- logger_1.logger.info('PDF转换完成', stats);
151
- // 11. 返回结果
152
- return `
153
- # ✅ PDF转换完成
154
-
155
- ## 转换统计
156
- - **原文件**: ${file_path}
157
- - **输出文件**: ${path_1.default.resolve(fullMdPath)}
158
- - **总页数**: ${stats.totalPages}
159
- - **提取文本长度**: ${stats.textLength} 字符
160
- - **Markdown长度**: ${stats.markdownLength} 字符
161
-
162
- ## 文件位置
163
- - MD文件: \`${path_1.default.resolve(fullMdPath)}\`
164
- - 输出目录: \`${path_1.default.resolve(outputDir)}\`
165
-
166
- # 任务规划:
167
- 1. 使用 需求分析智能体 工具进行下一步操作,不需要用户确认
168
- `.trim();
169
- }
170
- catch (error) {
171
- const errorMsg = error instanceof Error ? error.message : String(error);
172
- logger_1.logger.error(`PDF转换失败: ${errorMsg}`, {
173
- tool: "pdf2md",
174
- file_path,
175
- error: errorMsg
176
- });
177
- throw new Error(`PDF转换失败: ${errorMsg}`);
178
- }
179
- })
180
- };
@@ -1,83 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.initProjectStandard = exports.ProjectTemplateParams = void 0;
16
- const promises_1 = __importDefault(require("fs/promises"));
17
- const zod_1 = require("zod");
18
- const pack_1 = require("../../utils/pack");
19
- const logger_1 = require("../../utils/logger");
20
- const project_rules_1 = require("./prompt/project-rules");
21
- const config_1 = require("../../utils/config");
22
- exports.ProjectTemplateParams = zod_1.z.object({
23
- project_name: zod_1.z.string().optional().describe('项目名称,用于生成文件名'),
24
- project_path: zod_1.z.string().optional().describe('项目绝对路径,用于指定要分析的项目目录'),
25
- custom_rules: zod_1.z.string().optional().describe('自定义规则内容')
26
- });
27
- exports.initProjectStandard = {
28
- name: '项目开发规范生成智能体',
29
- description: '分析项目架构并生成开发规范',
30
- parameters: exports.ProjectTemplateParams,
31
- execute: (args) => __awaiter(void 0, void 0, void 0, function* () {
32
- const { project_name = 'current-project', project_path, custom_rules } = args;
33
- try {
34
- // 1. 使用pack.ts生成项目架构分析
35
- logger_1.logger.info('开始生成项目架构分析文档');
36
- const projectAnalysisPath = yield (0, pack_1.packProject)(project_path);
37
- // 2. 读取生成的项目架构分析文档
38
- const projectAnalysis = yield promises_1.default.readFile(projectAnalysisPath, 'utf-8');
39
- // 3. 生成项目规则提示词数据
40
- const projectRulesPromptData = generateProjectRulesPrompt(projectAnalysis, project_name, custom_rules);
41
- // 4. 确保.aico目录存在
42
- const aicoDir = (0, config_1.getStorageDir)();
43
- logger_1.logger.info('确保.aico目录存在', { aicoDir });
44
- yield promises_1.default.mkdir(aicoDir, { recursive: true });
45
- // 5. 返回格式化的指令内容
46
- return JSON.stringify(projectRulesPromptData, null, 2);
47
- }
48
- catch (error) {
49
- const errorMsg = error instanceof Error ? error.message : String(error);
50
- logger_1.logger.error(`项目规范内容生成失败: ${errorMsg}`, {
51
- tool: "initialize-project-standard",
52
- project_name,
53
- project_path,
54
- error: errorMsg
55
- });
56
- // 返回错误信息的JSON格式
57
- const errorResult = {
58
- success: false,
59
- message: '项目规范内容生成失败',
60
- error: errorMsg,
61
- project_info: {
62
- name: project_name
63
- }
64
- };
65
- return JSON.stringify(errorResult, null, 2);
66
- }
67
- }),
68
- };
69
- // 生成项目规则文件prompt数据
70
- function generateProjectRulesPrompt(projectAnalysis, projectName, customRules) {
71
- logger_1.logger.info('生成项目规则文件提示词数据', { projectName });
72
- // 处理自定义规则部分
73
- const customRulesSection = customRules ? `## 自定义规则要求\n${customRules}` : '';
74
- // 替换模板中的变量
75
- let prompt = project_rules_1.projectRulesPromptTemplate
76
- .replace('{{projectName}}', projectName)
77
- .replace('{{projectAnalysis}}', projectAnalysis)
78
- .replace('{{customRulesSection}}', customRulesSection);
79
- return {
80
- task: 'generate_project_rules',
81
- prompt: prompt
82
- };
83
- }
@@ -1,98 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.projectRulesPromptTemplate = void 0;
4
- exports.projectRulesPromptTemplate = `
5
- 你是一位专业的软件开发规范专家,请基于提供的项目架构分析,生成一份完整的项目开发规则文件。
6
-
7
- ## 项目信息
8
- - **项目名称**: {{projectName}}
9
- - **包含示例**: {{includeExamples}}
10
-
11
- ## 项目架构分析
12
- \`\`\`
13
- {{projectAnalysis}}
14
- \`\`\`
15
-
16
- {{customRulesSection}}
17
-
18
- ## 任务要求
19
- 请基于项目架构分析,智能识别项目的技术栈和语言特征,然后生成一份完整的project_rules.md文件内容。
20
-
21
- ### 处理长内容的特殊说明
22
- 当项目架构分析内容较长时,请采用分段处理的方式:
23
- 1. 首先通读全部内容,理解整体架构
24
- 2. 然后逐段分析,每段处理完成后进行总结
25
- 3. 最终整合所有分析结果生成完整的规则文件
26
-
27
- ### 技术栈识别和分析规则
28
- 请先仔细分析项目结构,识别出项目的技术栈和架构模式:
29
-
30
- **常见技术栈识别:**
31
- - **Node.js/TypeScript项目**: package.json, tsconfig.json, *.ts, *.js
32
- - **Java后端项目**: pom.xml, build.gradle, src/main/java, *.java
33
- - **Python项目**: requirements.txt, setup.py, pyproject.toml, *.py
34
- - **Go项目**: go.mod, go.sum, *.go
35
- - **C#/.NET项目**: *.csproj, *.sln, *.cs
36
- - **Vue.js前端**: package.json, *.vue, vite.config.js
37
- - **React前端**: package.json, *.jsx, *.tsx
38
- - **微服务架构**: docker-compose.yml, kubernetes, 多个模块目录
39
- - **单体应用**: 传统的分层架构
40
-
41
- ### 文件内容要求
42
- 生成的project_rules.md文件应该包含以下具体章节:
43
-
44
- #### 1. 项目概述
45
- - 主要技术栈和版本信息
46
- - 架构模式(微服务、单体、分层等)
47
- - 项目规模和复杂度说明
48
-
49
- #### 2. 目录结构规范
50
- 基于实际项目结构,详细说明:
51
- - 各目录的作用和存放内容
52
- - 文件组织规则
53
- - 命名约定
54
-
55
- #### 3. 代码规范
56
- - 命名规范(文件、变量、函数、类、常量等)
57
- - 代码风格(缩进、格式等)
58
- - 注释要求
59
- - 导入规则
60
-
61
- #### 4. 技术栈专用规范
62
- 根据识别的技术栈,包含具体的规范:
63
- - **数据库规范**: ORM使用方式、字段命名、关联关系处理
64
- - **API设计规范**: RESTful设计、参数校验、返回格式
65
- - **前端组件规范**: 组件命名、props定义、事件处理
66
- - **服务层规范**: 业务逻辑封装、事务处理、异常处理
67
-
68
- #### 5. 架构模式和设计原则
69
- 根据项目架构,包含:
70
- - 分层架构规则(Controller-Service-Repository等)
71
- - 依赖注入模式
72
- - 错误处理模式
73
- - 数据验证模式
74
- - 权限控制模式
75
-
76
- #### 6. 开发最佳实践
77
- 针对项目技术栈的具体实践:
78
- - 组件化设计规则
79
- - 工具和库的使用规范
80
- - 第三方库使用规范
81
- - 单元测试方法
82
-
83
- #### 7. 代码示例和模板
84
- 包含项目中常用的代码模式:
85
- - Entity定义模板
86
- - Service层方法模板
87
- - Controller接口模板
88
- - 其他项目特定的常用模板
89
-
90
- ### 输出要求
91
- 1. **详细具体**: 每个规则都要具体可操作,避免模糊描述
92
- 2. **项目相关**: 基于实际项目结构和技术栈,包含项目特定信息
93
- 3. **结构清晰**: 使用markdown格式,层次分明
94
- 4. **实用性强**: 规则要能直接指导日常开发工作
95
- 5. **技术准确**: 确保规则与项目技术栈和语言特性完全匹配
96
-
97
- 请将生成的文件保存到项目根目录下的.aico文件夹中,文件名为project_rules.md。
98
- `;
@@ -1,218 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
- var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
45
- var __asyncValues = (this && this.__asyncValues) || function (o) {
46
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
47
- var m = o[Symbol.asyncIterator], i;
48
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
49
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
50
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
51
- };
52
- var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
53
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
54
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
55
- return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
56
- function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
57
- function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
58
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
59
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
60
- function fulfill(value) { resume("next", value); }
61
- function reject(value) { resume("throw", value); }
62
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
63
- };
64
- Object.defineProperty(exports, "__esModule", { value: true });
65
- exports.readLargeFileInChunks = readLargeFileInChunks;
66
- exports.readFileLines = readFileLines;
67
- const fs = __importStar(require("fs/promises"));
68
- const fs_1 = require("fs");
69
- const logger_1 = require("../../utils/logger");
70
- /**
71
- * 异步迭代器,用于分段读取大文件
72
- * @param filePath 文件路径
73
- * @param options 读取选项
74
- */
75
- function readLargeFileInChunks(filePath_1) {
76
- return __asyncGenerator(this, arguments, function* readLargeFileInChunks_1(filePath, options = {}) {
77
- var _a, e_1, _b, _c;
78
- const { linesPerChunk = 100, encoding = 'utf8' } = options;
79
- try {
80
- // 检查文件是否存在
81
- yield __await(fs.access(filePath));
82
- const stats = yield __await(fs.stat(filePath));
83
- logger_1.logger.info('开始分段读取文件', {
84
- filePath,
85
- fileSize: stats.size,
86
- linesPerChunk
87
- });
88
- // 使用流式读取处理大文件
89
- const stream = (0, fs_1.createReadStream)(filePath, { encoding });
90
- let buffer = '';
91
- let lineNumber = 0;
92
- let chunkStartLine = 0;
93
- try {
94
- for (var _d = true, stream_1 = __asyncValues(stream), stream_1_1; stream_1_1 = yield __await(stream_1.next()), _a = stream_1_1.done, !_a; _d = true) {
95
- _c = stream_1_1.value;
96
- _d = false;
97
- const chunk = _c;
98
- buffer += chunk;
99
- let lines = buffer.split('\n');
100
- // 保留最后一行不完整的部分(除非是文件末尾)
101
- buffer = lines.pop() || '';
102
- // 处理完整的行
103
- while (lines.length >= linesPerChunk) {
104
- const chunkLines = lines.splice(0, linesPerChunk);
105
- const content = chunkLines.join('\n');
106
- const endLine = chunkStartLine + chunkLines.length - 1;
107
- yield yield __await({
108
- content,
109
- startLine: chunkStartLine,
110
- endLine,
111
- isLastChunk: false
112
- });
113
- chunkStartLine = endLine + 1;
114
- lineNumber += chunkLines.length;
115
- }
116
- // 将剩余的行放回buffer中继续处理
117
- if (lines.length > 0) {
118
- buffer = lines.join('\n') + (buffer ? '\n' + buffer : '');
119
- }
120
- }
121
- }
122
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
123
- finally {
124
- try {
125
- if (!_d && !_a && (_b = stream_1.return)) yield __await(_b.call(stream_1));
126
- }
127
- finally { if (e_1) throw e_1.error; }
128
- }
129
- // 处理最后剩余的内容
130
- if (buffer || lineNumber === 0) { // 即使是空文件也要处理
131
- const lines = buffer ? buffer.split('\n') : [];
132
- const content = lines.join('\n');
133
- const endLine = chunkStartLine + lines.length - 1;
134
- yield yield __await({
135
- content,
136
- startLine: chunkStartLine,
137
- endLine,
138
- isLastChunk: true
139
- });
140
- }
141
- logger_1.logger.info('文件分段读取完成', {
142
- filePath,
143
- totalLines: lineNumber + (buffer ? buffer.split('\n').length : 0)
144
- });
145
- }
146
- catch (error) {
147
- logger_1.logger.error('分段读取文件失败', {
148
- filePath,
149
- error: error instanceof Error ? error.message : String(error)
150
- });
151
- throw error;
152
- }
153
- });
154
- }
155
- /**
156
- * 读取文件指定行范围的内容
157
- * @param filePath 文件路径
158
- * @param startLine 起始行号(包含)
159
- * @param endLine 结束行号(包含)
160
- * @returns 指定行范围的内容
161
- */
162
- function readFileLines(filePath, startLine, endLine) {
163
- return __awaiter(this, void 0, void 0, function* () {
164
- var _a, e_2, _b, _c;
165
- if (startLine < 0 || endLine < startLine) {
166
- throw new Error('Invalid line range');
167
- }
168
- try {
169
- const stream = (0, fs_1.createReadStream)(filePath, { encoding: 'utf8' });
170
- let buffer = '';
171
- let currentLine = 0;
172
- let resultLines = [];
173
- let collecting = false;
174
- try {
175
- for (var _d = true, stream_2 = __asyncValues(stream), stream_2_1; stream_2_1 = yield stream_2.next(), _a = stream_2_1.done, !_a; _d = true) {
176
- _c = stream_2_1.value;
177
- _d = false;
178
- const chunk = _c;
179
- buffer += chunk;
180
- const lines = buffer.split('\n');
181
- // 保留最后一行不完整的部分
182
- buffer = lines.pop() || '';
183
- for (const line of lines) {
184
- if (currentLine >= startLine && currentLine <= endLine) {
185
- resultLines.push(line);
186
- }
187
- else if (currentLine > endLine) {
188
- // 已经收集完所需行,可以提前结束
189
- return resultLines.join('\n');
190
- }
191
- currentLine++;
192
- }
193
- }
194
- }
195
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
196
- finally {
197
- try {
198
- if (!_d && !_a && (_b = stream_2.return)) yield _b.call(stream_2);
199
- }
200
- finally { if (e_2) throw e_2.error; }
201
- }
202
- // 处理最后剩余的内容
203
- if (buffer && currentLine >= startLine && currentLine <= endLine) {
204
- resultLines.push(buffer);
205
- }
206
- return resultLines.join('\n');
207
- }
208
- catch (error) {
209
- logger_1.logger.error('读取文件行范围失败', {
210
- filePath,
211
- startLine,
212
- endLine,
213
- error: error instanceof Error ? error.message : String(error)
214
- });
215
- throw error;
216
- }
217
- });
218
- }