@robthepcguy/rag-vault 1.0.0
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/LICENSE +24 -0
- package/README.md +421 -0
- package/dist/bin/install-skills.d.ts +20 -0
- package/dist/bin/install-skills.d.ts.map +1 -0
- package/dist/bin/install-skills.js +196 -0
- package/dist/bin/install-skills.js.map +1 -0
- package/dist/chunker/index.d.ts +11 -0
- package/dist/chunker/index.d.ts.map +1 -0
- package/dist/chunker/index.js +6 -0
- package/dist/chunker/index.js.map +1 -0
- package/dist/chunker/semantic-chunker.d.ts +96 -0
- package/dist/chunker/semantic-chunker.d.ts.map +1 -0
- package/dist/chunker/semantic-chunker.js +267 -0
- package/dist/chunker/semantic-chunker.js.map +1 -0
- package/dist/chunker/sentence-splitter.d.ts +16 -0
- package/dist/chunker/sentence-splitter.d.ts.map +1 -0
- package/dist/chunker/sentence-splitter.js +114 -0
- package/dist/chunker/sentence-splitter.js.map +1 -0
- package/dist/embedder/index.d.ts +55 -0
- package/dist/embedder/index.d.ts.map +1 -0
- package/dist/embedder/index.js +146 -0
- package/dist/embedder/index.js.map +1 -0
- package/dist/errors/index.d.ts +73 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +170 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/html-parser.d.ts +14 -0
- package/dist/parser/html-parser.d.ts.map +1 -0
- package/dist/parser/html-parser.js +99 -0
- package/dist/parser/html-parser.js.map +1 -0
- package/dist/parser/index.d.ts +144 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +446 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/pdf-filter.d.ts +89 -0
- package/dist/parser/pdf-filter.d.ts.map +1 -0
- package/dist/parser/pdf-filter.js +304 -0
- package/dist/parser/pdf-filter.js.map +1 -0
- package/dist/server/index.d.ts +144 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +518 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/raw-data-utils.d.ts +81 -0
- package/dist/server/raw-data-utils.d.ts.map +1 -0
- package/dist/server/raw-data-utils.js +196 -0
- package/dist/server/raw-data-utils.js.map +1 -0
- package/dist/server/schemas.d.ts +186 -0
- package/dist/server/schemas.d.ts.map +1 -0
- package/dist/server/schemas.js +99 -0
- package/dist/server/schemas.js.map +1 -0
- package/dist/utils/config-parsers.d.ts +14 -0
- package/dist/utils/config-parsers.d.ts.map +1 -0
- package/dist/utils/config-parsers.js +47 -0
- package/dist/utils/config-parsers.js.map +1 -0
- package/dist/utils/config.d.ts +37 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +52 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/logger.d.ts +36 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +64 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/math.d.ts +34 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +73 -0
- package/dist/utils/math.js.map +1 -0
- package/dist/utils/process-handlers.d.ts +26 -0
- package/dist/utils/process-handlers.d.ts.map +1 -0
- package/dist/utils/process-handlers.js +69 -0
- package/dist/utils/process-handlers.js.map +1 -0
- package/dist/vectordb/index.d.ts +210 -0
- package/dist/vectordb/index.d.ts.map +1 -0
- package/dist/vectordb/index.js +613 -0
- package/dist/vectordb/index.js.map +1 -0
- package/dist/web/api-routes.d.ts +9 -0
- package/dist/web/api-routes.d.ts.map +1 -0
- package/dist/web/api-routes.js +127 -0
- package/dist/web/api-routes.js.map +1 -0
- package/dist/web/config-routes.d.ts +7 -0
- package/dist/web/config-routes.d.ts.map +1 -0
- package/dist/web/config-routes.js +54 -0
- package/dist/web/config-routes.js.map +1 -0
- package/dist/web/database-manager.d.ts +130 -0
- package/dist/web/database-manager.d.ts.map +1 -0
- package/dist/web/database-manager.js +382 -0
- package/dist/web/database-manager.js.map +1 -0
- package/dist/web/http-server.d.ts +28 -0
- package/dist/web/http-server.d.ts.map +1 -0
- package/dist/web/http-server.js +311 -0
- package/dist/web/http-server.js.map +1 -0
- package/dist/web/index.d.ts +3 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +114 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/middleware/async-handler.d.ts +17 -0
- package/dist/web/middleware/async-handler.d.ts.map +1 -0
- package/dist/web/middleware/async-handler.js +26 -0
- package/dist/web/middleware/async-handler.js.map +1 -0
- package/dist/web/middleware/auth.d.ts +22 -0
- package/dist/web/middleware/auth.d.ts.map +1 -0
- package/dist/web/middleware/auth.js +81 -0
- package/dist/web/middleware/auth.js.map +1 -0
- package/dist/web/middleware/error-handler.d.ts +36 -0
- package/dist/web/middleware/error-handler.d.ts.map +1 -0
- package/dist/web/middleware/error-handler.js +68 -0
- package/dist/web/middleware/error-handler.js.map +1 -0
- package/dist/web/middleware/index.d.ts +6 -0
- package/dist/web/middleware/index.d.ts.map +1 -0
- package/dist/web/middleware/index.js +19 -0
- package/dist/web/middleware/index.js.map +1 -0
- package/dist/web/middleware/rate-limit.d.ts +38 -0
- package/dist/web/middleware/rate-limit.d.ts.map +1 -0
- package/dist/web/middleware/rate-limit.js +116 -0
- package/dist/web/middleware/rate-limit.js.map +1 -0
- package/dist/web/middleware/request-logger.d.ts +52 -0
- package/dist/web/middleware/request-logger.d.ts.map +1 -0
- package/dist/web/middleware/request-logger.js +74 -0
- package/dist/web/middleware/request-logger.js.map +1 -0
- package/dist/web/types.d.ts +6 -0
- package/dist/web/types.d.ts.map +1 -0
- package/dist/web/types.js +4 -0
- package/dist/web/types.js.map +1 -0
- package/package.json +135 -0
- package/skills/rag-vault/SKILL.md +111 -0
- package/skills/rag-vault/references/html-ingestion.md +73 -0
- package/skills/rag-vault/references/query-optimization.md +57 -0
- package/skills/rag-vault/references/result-refinement.md +54 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { type EmbedderInterface } from './pdf-filter.js';
|
|
2
|
+
export { ParserFileOperationError, ParserValidationError } from '../errors/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* DocumentParser configuration
|
|
5
|
+
*/
|
|
6
|
+
export interface ParserConfig {
|
|
7
|
+
/** Security: allowed base directory */
|
|
8
|
+
baseDir: string;
|
|
9
|
+
/** Maximum file size (100MB) */
|
|
10
|
+
maxFileSize: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Document parser class (PDF/DOCX/TXT/MD/JSON support)
|
|
14
|
+
*
|
|
15
|
+
* Responsibilities:
|
|
16
|
+
* - File path validation (path traversal prevention)
|
|
17
|
+
* - File size validation (100MB limit)
|
|
18
|
+
* - Parse 5 formats (PDF/DOCX/TXT/MD/JSON)
|
|
19
|
+
*/
|
|
20
|
+
export declare class DocumentParser {
|
|
21
|
+
private readonly config;
|
|
22
|
+
constructor(config: ParserConfig);
|
|
23
|
+
/**
|
|
24
|
+
* File path validation (Absolute path requirement + Path traversal prevention)
|
|
25
|
+
*
|
|
26
|
+
* @param filePath - File path to validate (must be absolute)
|
|
27
|
+
* @throws ParserValidationError - When path is not absolute or outside BASE_DIR
|
|
28
|
+
*/
|
|
29
|
+
validateFilePath(filePath: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* File size validation (100MB limit)
|
|
32
|
+
*
|
|
33
|
+
* @param filePath - File path to validate
|
|
34
|
+
* @throws ParserValidationError - When file size exceeds limit
|
|
35
|
+
* @throws ParserFileOperationError - When file read fails
|
|
36
|
+
*/
|
|
37
|
+
validateFileSize(filePath: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* File parsing (auto format detection)
|
|
40
|
+
*
|
|
41
|
+
* @param filePath - File path to parse
|
|
42
|
+
* @returns Parsed text
|
|
43
|
+
* @throws ParserValidationError - Path traversal, size exceeded, unsupported format
|
|
44
|
+
* @throws ParserFileOperationError - File read failed, parse failed
|
|
45
|
+
*/
|
|
46
|
+
parseFile(filePath: string): Promise<string>;
|
|
47
|
+
/**
|
|
48
|
+
* PDF parsing with header/footer filtering
|
|
49
|
+
*
|
|
50
|
+
* Features:
|
|
51
|
+
* - Extracts text with position information (x, y, fontSize)
|
|
52
|
+
* - Semantic header/footer detection using embedding similarity
|
|
53
|
+
* - Uses hasEOL for proper line break handling
|
|
54
|
+
*
|
|
55
|
+
* @param filePath - PDF file path
|
|
56
|
+
* @param embedder - Embedder for semantic header/footer detection
|
|
57
|
+
* @returns Parsed text with header/footer removed
|
|
58
|
+
* @throws ParserFileOperationError - File read failed, parse failed
|
|
59
|
+
*/
|
|
60
|
+
parsePdf(filePath: string, embedder: EmbedderInterface): Promise<string>;
|
|
61
|
+
/**
|
|
62
|
+
* DOCX parsing (using mammoth)
|
|
63
|
+
*
|
|
64
|
+
* @param filePath - DOCX file path
|
|
65
|
+
* @returns Parsed text
|
|
66
|
+
* @throws ParserFileOperationError - File read failed, parse failed
|
|
67
|
+
*/
|
|
68
|
+
private parseDocx;
|
|
69
|
+
/**
|
|
70
|
+
* TXT parsing (using fs.readFile)
|
|
71
|
+
*
|
|
72
|
+
* @param filePath - TXT file path
|
|
73
|
+
* @returns Parsed text
|
|
74
|
+
* @throws ParserFileOperationError - File read failed
|
|
75
|
+
*/
|
|
76
|
+
private parseTxt;
|
|
77
|
+
/**
|
|
78
|
+
* MD parsing (using fs.readFile)
|
|
79
|
+
*
|
|
80
|
+
* @param filePath - MD file path
|
|
81
|
+
* @returns Parsed text
|
|
82
|
+
* @throws ParserFileOperationError - File read failed
|
|
83
|
+
*/
|
|
84
|
+
private parseMd;
|
|
85
|
+
/**
|
|
86
|
+
* JSON parsing - converts JSON to searchable text format
|
|
87
|
+
*
|
|
88
|
+
* Converts JSON objects to a key-value text format optimized for semantic search:
|
|
89
|
+
* - Preserves field names for keyword matching
|
|
90
|
+
* - Flattens nested structures with dot notation
|
|
91
|
+
* - Handles arrays by joining values
|
|
92
|
+
* - Falls back to JSONL parsing if JSON syntax fails
|
|
93
|
+
*
|
|
94
|
+
* @param filePath - JSON file path
|
|
95
|
+
* @returns Parsed text in "key: value" format
|
|
96
|
+
* @throws ParserFileOperationError - File read failed or invalid JSON/JSONL
|
|
97
|
+
*/
|
|
98
|
+
private parseJson;
|
|
99
|
+
/**
|
|
100
|
+
* JSONL parsing - parses line-delimited JSON files
|
|
101
|
+
*
|
|
102
|
+
* @param filePath - JSONL file path
|
|
103
|
+
* @returns Parsed text from all valid JSON objects
|
|
104
|
+
* @throws ParserFileOperationError - File read failed
|
|
105
|
+
*/
|
|
106
|
+
private parseJsonl;
|
|
107
|
+
/**
|
|
108
|
+
* Parse JSONL content (shared logic for parseJsonl and JSON fallback)
|
|
109
|
+
*
|
|
110
|
+
* @param content - Raw file content
|
|
111
|
+
* @param filePath - File path (for logging)
|
|
112
|
+
* @returns Parsed text from all valid JSON objects
|
|
113
|
+
*/
|
|
114
|
+
private parseJsonlContent;
|
|
115
|
+
/**
|
|
116
|
+
* Determine if a string value should be included based on RAG filtering rules
|
|
117
|
+
*
|
|
118
|
+
* Rules:
|
|
119
|
+
* 1. Exclude code-like strings (GUIDs, hex, underscore patterns) regardless of length
|
|
120
|
+
* 2. Keep strings >= 20 chars if they pass code check
|
|
121
|
+
* 3. Keep short strings with allowlisted keys if prose-like
|
|
122
|
+
* 4. Keep other short strings only if prose-like
|
|
123
|
+
*
|
|
124
|
+
* @param value - String value to check
|
|
125
|
+
* @param key - Field key name
|
|
126
|
+
* @returns true if the string should be included
|
|
127
|
+
*/
|
|
128
|
+
private shouldIncludeString;
|
|
129
|
+
/**
|
|
130
|
+
* Convert JSON value to searchable text format with RAG-appropriate filtering
|
|
131
|
+
*
|
|
132
|
+
* Filtering rules:
|
|
133
|
+
* - Numbers and booleans are excluded (metadata noise)
|
|
134
|
+
* - Null/undefined values are excluded
|
|
135
|
+
* - Empty arrays/objects are excluded
|
|
136
|
+
* - Strings are filtered by shouldIncludeString rules
|
|
137
|
+
*
|
|
138
|
+
* @param value - JSON value (object, array, or primitive)
|
|
139
|
+
* @param prefix - Key prefix for nested objects (dot notation)
|
|
140
|
+
* @returns Text representation
|
|
141
|
+
*/
|
|
142
|
+
private jsonToText;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAsFA,OAAO,EAAE,KAAK,iBAAiB,EAA8C,MAAM,iBAAiB,CAAA;AAGpG,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAMpF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAA;IACf,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAA;CACpB;AAMD;;;;;;;GAOG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,MAAM,EAAE,YAAY;IAIhC;;;;;OAKG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAmBxC;;;;;;OAMG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAgBxC;;;;;;;OAOG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBlD;;;;;;;;;;;;OAYG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IA4C9E;;;;;;OAMG;YACW,SAAS;IAUvB;;;;;;OAMG;YACW,QAAQ;IAUtB;;;;;;OAMG;YACW,OAAO;IAUrB;;;;;;;;;;;;OAYG;YACW,SAAS;IA8BvB;;;;;;OAMG;YACW,UAAU;IAUxB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,UAAU;CA+CnB"}
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// DocumentParser implementation with PDF/DOCX/TXT/MD/JSON/JSONL support
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.DocumentParser = exports.ParserValidationError = exports.ParserFileOperationError = void 0;
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const promises_1 = require("node:fs/promises");
|
|
10
|
+
const node_path_1 = require("node:path");
|
|
11
|
+
// ============================================
|
|
12
|
+
// RAG Content Filtering Constants
|
|
13
|
+
// ============================================
|
|
14
|
+
/**
|
|
15
|
+
* Minimum character threshold for string inclusion
|
|
16
|
+
* Strings >= 20 chars are always included
|
|
17
|
+
*/
|
|
18
|
+
const MIN_STRING_LENGTH = 20;
|
|
19
|
+
/**
|
|
20
|
+
* Maximum JSON content size (10MB) to prevent memory exhaustion
|
|
21
|
+
* during JSON parsing of large files
|
|
22
|
+
*/
|
|
23
|
+
const MAX_JSON_CONTENT_SIZE = 10 * 1024 * 1024;
|
|
24
|
+
/**
|
|
25
|
+
* Key allowlist for prose-related fields (case-insensitive partial match)
|
|
26
|
+
* These keys likely contain meaningful text even if short
|
|
27
|
+
*/
|
|
28
|
+
const PROSE_KEYS = [
|
|
29
|
+
'title',
|
|
30
|
+
'name',
|
|
31
|
+
'heading',
|
|
32
|
+
'caption',
|
|
33
|
+
'summary',
|
|
34
|
+
'scene',
|
|
35
|
+
'chapter',
|
|
36
|
+
'section',
|
|
37
|
+
'speaker',
|
|
38
|
+
'dialogue',
|
|
39
|
+
'line',
|
|
40
|
+
'text',
|
|
41
|
+
'description',
|
|
42
|
+
'content',
|
|
43
|
+
'body',
|
|
44
|
+
'message',
|
|
45
|
+
'note',
|
|
46
|
+
'comment',
|
|
47
|
+
'label',
|
|
48
|
+
];
|
|
49
|
+
/**
|
|
50
|
+
* Check if string looks like code/ID (should be filtered)
|
|
51
|
+
* Examples: "abc123-def456", "USR_001", "a1b2c3d4e5f6", GUIDs
|
|
52
|
+
*/
|
|
53
|
+
function looksLikeCode(str) {
|
|
54
|
+
// GUID pattern: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
55
|
+
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(str)) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
// Mostly digits, underscores, or hex characters (>50% non-letter)
|
|
59
|
+
const nonLetterRatio = (str.match(/[^a-zA-Z\s]/g) || []).length / str.length;
|
|
60
|
+
if (nonLetterRatio > 0.5) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
// Contains underscore - typical of IDs (e.g., USR_001, ACTIVE_V2, user_id)
|
|
64
|
+
if (str.includes('_')) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
// Ends with digit suffix typical of IDs (e.g., V2, rev3)
|
|
68
|
+
if (/[A-Z]\d+$/.test(str) || /^\d+[A-Z]/.test(str)) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Check if string looks like prose (should be kept)
|
|
75
|
+
* Examples: "Alice", "The Beginning", "Chapter One"
|
|
76
|
+
*/
|
|
77
|
+
function looksLikeProse(str) {
|
|
78
|
+
// Mostly letters and spaces with optional punctuation
|
|
79
|
+
const proseRatio = (str.match(/[a-zA-Z\s]/g) || []).length / str.length;
|
|
80
|
+
return proseRatio >= 0.7;
|
|
81
|
+
}
|
|
82
|
+
const mammoth_1 = __importDefault(require("mammoth"));
|
|
83
|
+
const pdf_mjs_1 = require("pdfjs-dist/legacy/build/pdf.mjs");
|
|
84
|
+
const index_js_1 = require("../errors/index.js");
|
|
85
|
+
const pdf_filter_js_1 = require("./pdf-filter.js");
|
|
86
|
+
// Re-export error classes for backwards compatibility
|
|
87
|
+
var index_js_2 = require("../errors/index.js");
|
|
88
|
+
Object.defineProperty(exports, "ParserFileOperationError", { enumerable: true, get: function () { return index_js_2.ParserFileOperationError; } });
|
|
89
|
+
Object.defineProperty(exports, "ParserValidationError", { enumerable: true, get: function () { return index_js_2.ParserValidationError; } });
|
|
90
|
+
// ============================================
|
|
91
|
+
// DocumentParser Class
|
|
92
|
+
// ============================================
|
|
93
|
+
/**
|
|
94
|
+
* Document parser class (PDF/DOCX/TXT/MD/JSON support)
|
|
95
|
+
*
|
|
96
|
+
* Responsibilities:
|
|
97
|
+
* - File path validation (path traversal prevention)
|
|
98
|
+
* - File size validation (100MB limit)
|
|
99
|
+
* - Parse 5 formats (PDF/DOCX/TXT/MD/JSON)
|
|
100
|
+
*/
|
|
101
|
+
class DocumentParser {
|
|
102
|
+
constructor(config) {
|
|
103
|
+
this.config = config;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* File path validation (Absolute path requirement + Path traversal prevention)
|
|
107
|
+
*
|
|
108
|
+
* @param filePath - File path to validate (must be absolute)
|
|
109
|
+
* @throws ParserValidationError - When path is not absolute or outside BASE_DIR
|
|
110
|
+
*/
|
|
111
|
+
validateFilePath(filePath) {
|
|
112
|
+
// Check if path is absolute
|
|
113
|
+
if (!(0, node_path_1.isAbsolute)(filePath)) {
|
|
114
|
+
throw new index_js_1.ParserValidationError(`File path must be absolute path (received: ${filePath}). Please provide an absolute path within BASE_DIR.`);
|
|
115
|
+
}
|
|
116
|
+
// Check if path is within BASE_DIR
|
|
117
|
+
const baseDir = (0, node_path_1.resolve)(this.config.baseDir);
|
|
118
|
+
const normalizedPath = (0, node_path_1.resolve)(filePath);
|
|
119
|
+
if (!normalizedPath.startsWith(baseDir)) {
|
|
120
|
+
throw new index_js_1.ParserValidationError(`File path must be within BASE_DIR (${baseDir}). Received path outside BASE_DIR: ${filePath}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* File size validation (100MB limit)
|
|
125
|
+
*
|
|
126
|
+
* @param filePath - File path to validate
|
|
127
|
+
* @throws ParserValidationError - When file size exceeds limit
|
|
128
|
+
* @throws ParserFileOperationError - When file read fails
|
|
129
|
+
*/
|
|
130
|
+
validateFileSize(filePath) {
|
|
131
|
+
try {
|
|
132
|
+
const stats = (0, node_fs_1.statSync)(filePath);
|
|
133
|
+
if (stats.size > this.config.maxFileSize) {
|
|
134
|
+
throw new index_js_1.ParserValidationError(`File size exceeds limit: ${stats.size} > ${this.config.maxFileSize}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
if (error instanceof index_js_1.ParserValidationError) {
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
throw new index_js_1.ParserFileOperationError(`Failed to check file size: ${filePath}`, error);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* File parsing (auto format detection)
|
|
146
|
+
*
|
|
147
|
+
* @param filePath - File path to parse
|
|
148
|
+
* @returns Parsed text
|
|
149
|
+
* @throws ParserValidationError - Path traversal, size exceeded, unsupported format
|
|
150
|
+
* @throws ParserFileOperationError - File read failed, parse failed
|
|
151
|
+
*/
|
|
152
|
+
async parseFile(filePath) {
|
|
153
|
+
// Validation
|
|
154
|
+
this.validateFilePath(filePath);
|
|
155
|
+
this.validateFileSize(filePath);
|
|
156
|
+
// Format detection (PDF uses parsePdf directly)
|
|
157
|
+
const ext = (0, node_path_1.extname)(filePath).toLowerCase();
|
|
158
|
+
switch (ext) {
|
|
159
|
+
case '.docx':
|
|
160
|
+
return await this.parseDocx(filePath);
|
|
161
|
+
case '.txt':
|
|
162
|
+
return await this.parseTxt(filePath);
|
|
163
|
+
case '.md':
|
|
164
|
+
return await this.parseMd(filePath);
|
|
165
|
+
case '.json':
|
|
166
|
+
return await this.parseJson(filePath);
|
|
167
|
+
case '.jsonl':
|
|
168
|
+
case '.ndjson':
|
|
169
|
+
return await this.parseJsonl(filePath);
|
|
170
|
+
default:
|
|
171
|
+
throw new index_js_1.ParserValidationError(`Unsupported file format: ${ext}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* PDF parsing with header/footer filtering
|
|
176
|
+
*
|
|
177
|
+
* Features:
|
|
178
|
+
* - Extracts text with position information (x, y, fontSize)
|
|
179
|
+
* - Semantic header/footer detection using embedding similarity
|
|
180
|
+
* - Uses hasEOL for proper line break handling
|
|
181
|
+
*
|
|
182
|
+
* @param filePath - PDF file path
|
|
183
|
+
* @param embedder - Embedder for semantic header/footer detection
|
|
184
|
+
* @returns Parsed text with header/footer removed
|
|
185
|
+
* @throws ParserFileOperationError - File read failed, parse failed
|
|
186
|
+
*/
|
|
187
|
+
async parsePdf(filePath, embedder) {
|
|
188
|
+
// Validation
|
|
189
|
+
this.validateFilePath(filePath);
|
|
190
|
+
this.validateFileSize(filePath);
|
|
191
|
+
try {
|
|
192
|
+
const buffer = await (0, promises_1.readFile)(filePath);
|
|
193
|
+
const pdf = await (0, pdf_mjs_1.getDocument)({
|
|
194
|
+
data: new Uint8Array(buffer),
|
|
195
|
+
useSystemFonts: true,
|
|
196
|
+
isEvalSupported: false,
|
|
197
|
+
}).promise;
|
|
198
|
+
// Extract text with position information from each page
|
|
199
|
+
const pages = [];
|
|
200
|
+
for (let i = 1; i <= pdf.numPages; i++) {
|
|
201
|
+
const page = await pdf.getPage(i);
|
|
202
|
+
const textContent = await page.getTextContent();
|
|
203
|
+
const items = textContent.items
|
|
204
|
+
.filter((item) => 'str' in item)
|
|
205
|
+
.map((item) => ({
|
|
206
|
+
text: item.str,
|
|
207
|
+
x: item.transform[4],
|
|
208
|
+
y: item.transform[5],
|
|
209
|
+
fontSize: Math.abs(item.transform[0]),
|
|
210
|
+
hasEOL: item.hasEOL ?? false,
|
|
211
|
+
}));
|
|
212
|
+
pages.push({ pageNum: i, items });
|
|
213
|
+
}
|
|
214
|
+
// Apply sentence-level header/footer filtering
|
|
215
|
+
// This handles variable content like page numbers ("7 of 75") using semantic similarity
|
|
216
|
+
const text = await (0, pdf_filter_js_1.filterPageBoundarySentences)(pages, embedder);
|
|
217
|
+
console.error(`Parsed PDF: ${filePath} (${text.length} characters, ${pdf.numPages} pages)`);
|
|
218
|
+
return text;
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
throw new index_js_1.ParserFileOperationError(`Failed to parse PDF: ${filePath}`, error);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* DOCX parsing (using mammoth)
|
|
226
|
+
*
|
|
227
|
+
* @param filePath - DOCX file path
|
|
228
|
+
* @returns Parsed text
|
|
229
|
+
* @throws ParserFileOperationError - File read failed, parse failed
|
|
230
|
+
*/
|
|
231
|
+
async parseDocx(filePath) {
|
|
232
|
+
try {
|
|
233
|
+
const result = await mammoth_1.default.extractRawText({ path: filePath });
|
|
234
|
+
console.error(`Parsed DOCX: ${filePath} (${result.value.length} characters)`);
|
|
235
|
+
return result.value;
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
throw new index_js_1.ParserFileOperationError(`Failed to parse DOCX: ${filePath}`, error);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* TXT parsing (using fs.readFile)
|
|
243
|
+
*
|
|
244
|
+
* @param filePath - TXT file path
|
|
245
|
+
* @returns Parsed text
|
|
246
|
+
* @throws ParserFileOperationError - File read failed
|
|
247
|
+
*/
|
|
248
|
+
async parseTxt(filePath) {
|
|
249
|
+
try {
|
|
250
|
+
const text = await (0, promises_1.readFile)(filePath, 'utf-8');
|
|
251
|
+
console.error(`Parsed TXT: ${filePath} (${text.length} characters)`);
|
|
252
|
+
return text;
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
throw new index_js_1.ParserFileOperationError(`Failed to parse TXT: ${filePath}`, error);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* MD parsing (using fs.readFile)
|
|
260
|
+
*
|
|
261
|
+
* @param filePath - MD file path
|
|
262
|
+
* @returns Parsed text
|
|
263
|
+
* @throws ParserFileOperationError - File read failed
|
|
264
|
+
*/
|
|
265
|
+
async parseMd(filePath) {
|
|
266
|
+
try {
|
|
267
|
+
const text = await (0, promises_1.readFile)(filePath, 'utf-8');
|
|
268
|
+
console.error(`Parsed MD: ${filePath} (${text.length} characters)`);
|
|
269
|
+
return text;
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
throw new index_js_1.ParserFileOperationError(`Failed to parse MD: ${filePath}`, error);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* JSON parsing - converts JSON to searchable text format
|
|
277
|
+
*
|
|
278
|
+
* Converts JSON objects to a key-value text format optimized for semantic search:
|
|
279
|
+
* - Preserves field names for keyword matching
|
|
280
|
+
* - Flattens nested structures with dot notation
|
|
281
|
+
* - Handles arrays by joining values
|
|
282
|
+
* - Falls back to JSONL parsing if JSON syntax fails
|
|
283
|
+
*
|
|
284
|
+
* @param filePath - JSON file path
|
|
285
|
+
* @returns Parsed text in "key: value" format
|
|
286
|
+
* @throws ParserFileOperationError - File read failed or invalid JSON/JSONL
|
|
287
|
+
*/
|
|
288
|
+
async parseJson(filePath) {
|
|
289
|
+
try {
|
|
290
|
+
const content = await (0, promises_1.readFile)(filePath, 'utf-8');
|
|
291
|
+
// Check size limit before parsing to prevent memory exhaustion
|
|
292
|
+
if (content.length > MAX_JSON_CONTENT_SIZE) {
|
|
293
|
+
throw new index_js_1.ParserValidationError(`JSON content size (${content.length} bytes) exceeds limit (${MAX_JSON_CONTENT_SIZE} bytes)`);
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
const data = JSON.parse(content);
|
|
297
|
+
const text = this.jsonToText(data);
|
|
298
|
+
console.error(`Parsed JSON: ${filePath} (${text.length} characters)`);
|
|
299
|
+
return text;
|
|
300
|
+
}
|
|
301
|
+
catch (e) {
|
|
302
|
+
if (e instanceof SyntaxError) {
|
|
303
|
+
// Fallback: try parsing as JSONL
|
|
304
|
+
console.error(`JSON parse failed, attempting JSONL fallback: ${filePath}`);
|
|
305
|
+
return this.parseJsonlContent(content, filePath);
|
|
306
|
+
}
|
|
307
|
+
throw e;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
if (error instanceof index_js_1.ParserFileOperationError)
|
|
312
|
+
throw error;
|
|
313
|
+
throw new index_js_1.ParserFileOperationError(`Failed to parse JSON: ${filePath}`, error);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* JSONL parsing - parses line-delimited JSON files
|
|
318
|
+
*
|
|
319
|
+
* @param filePath - JSONL file path
|
|
320
|
+
* @returns Parsed text from all valid JSON objects
|
|
321
|
+
* @throws ParserFileOperationError - File read failed
|
|
322
|
+
*/
|
|
323
|
+
async parseJsonl(filePath) {
|
|
324
|
+
try {
|
|
325
|
+
const content = await (0, promises_1.readFile)(filePath, 'utf-8');
|
|
326
|
+
return this.parseJsonlContent(content, filePath);
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
if (error instanceof index_js_1.ParserFileOperationError)
|
|
330
|
+
throw error;
|
|
331
|
+
throw new index_js_1.ParserFileOperationError(`Failed to parse JSONL: ${filePath}`, error);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Parse JSONL content (shared logic for parseJsonl and JSON fallback)
|
|
336
|
+
*
|
|
337
|
+
* @param content - Raw file content
|
|
338
|
+
* @param filePath - File path (for logging)
|
|
339
|
+
* @returns Parsed text from all valid JSON objects
|
|
340
|
+
*/
|
|
341
|
+
parseJsonlContent(content, filePath) {
|
|
342
|
+
const lines = content.split('\n').filter((line) => line.trim());
|
|
343
|
+
const results = [];
|
|
344
|
+
for (const [i, line] of lines.entries()) {
|
|
345
|
+
try {
|
|
346
|
+
const data = JSON.parse(line);
|
|
347
|
+
const text = this.jsonToText(data, `[${i}]`);
|
|
348
|
+
if (text.length > 0)
|
|
349
|
+
results.push(text);
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
// Skip malformed lines, continue processing
|
|
353
|
+
console.error(`JSONL line ${i + 1} skipped (invalid JSON)`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
console.error(`Parsed JSONL: ${filePath} (${results.length} objects)`);
|
|
357
|
+
return results.join('\n');
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Determine if a string value should be included based on RAG filtering rules
|
|
361
|
+
*
|
|
362
|
+
* Rules:
|
|
363
|
+
* 1. Exclude code-like strings (GUIDs, hex, underscore patterns) regardless of length
|
|
364
|
+
* 2. Keep strings >= 20 chars if they pass code check
|
|
365
|
+
* 3. Keep short strings with allowlisted keys if prose-like
|
|
366
|
+
* 4. Keep other short strings only if prose-like
|
|
367
|
+
*
|
|
368
|
+
* @param value - String value to check
|
|
369
|
+
* @param key - Field key name
|
|
370
|
+
* @returns true if the string should be included
|
|
371
|
+
*/
|
|
372
|
+
shouldIncludeString(value, key) {
|
|
373
|
+
// Always exclude code-like strings, regardless of length
|
|
374
|
+
if (looksLikeCode(value))
|
|
375
|
+
return false;
|
|
376
|
+
// Include strings >= 20 chars (already passed code check)
|
|
377
|
+
if (value.length >= MIN_STRING_LENGTH)
|
|
378
|
+
return true;
|
|
379
|
+
// Check key allowlist (case-insensitive partial match)
|
|
380
|
+
const keyLower = key.toLowerCase();
|
|
381
|
+
if (PROSE_KEYS.some((pk) => keyLower.includes(pk))) {
|
|
382
|
+
return true; // Keep if allowlisted key (already passed code check)
|
|
383
|
+
}
|
|
384
|
+
// For other keys, only keep if it looks like prose
|
|
385
|
+
return looksLikeProse(value);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Convert JSON value to searchable text format with RAG-appropriate filtering
|
|
389
|
+
*
|
|
390
|
+
* Filtering rules:
|
|
391
|
+
* - Numbers and booleans are excluded (metadata noise)
|
|
392
|
+
* - Null/undefined values are excluded
|
|
393
|
+
* - Empty arrays/objects are excluded
|
|
394
|
+
* - Strings are filtered by shouldIncludeString rules
|
|
395
|
+
*
|
|
396
|
+
* @param value - JSON value (object, array, or primitive)
|
|
397
|
+
* @param prefix - Key prefix for nested objects (dot notation)
|
|
398
|
+
* @returns Text representation
|
|
399
|
+
*/
|
|
400
|
+
jsonToText(value, prefix = '') {
|
|
401
|
+
if (value === null || value === undefined)
|
|
402
|
+
return '';
|
|
403
|
+
if (Array.isArray(value)) {
|
|
404
|
+
if (value.length === 0)
|
|
405
|
+
return '';
|
|
406
|
+
// Check if array contains objects
|
|
407
|
+
if (typeof value[0] === 'object' && value[0] !== null) {
|
|
408
|
+
// Array of objects: process each with index
|
|
409
|
+
return value
|
|
410
|
+
.map((item, index) => this.jsonToText(item, prefix ? `${prefix}[${index}]` : `[${index}]`))
|
|
411
|
+
.filter((text) => text.length > 0)
|
|
412
|
+
.join('\n');
|
|
413
|
+
}
|
|
414
|
+
// Array of primitives: filter by same rules
|
|
415
|
+
const key = prefix.split('.').pop() || '';
|
|
416
|
+
const validStrings = value
|
|
417
|
+
.filter((v) => typeof v === 'string' && this.shouldIncludeString(v, key))
|
|
418
|
+
.map((v) => String(v));
|
|
419
|
+
if (validStrings.length === 0)
|
|
420
|
+
return '';
|
|
421
|
+
return prefix ? `${prefix}: ${validStrings.join(', ')}` : validStrings.join(', ');
|
|
422
|
+
}
|
|
423
|
+
if (typeof value === 'object') {
|
|
424
|
+
const lines = [];
|
|
425
|
+
for (const [key, val] of Object.entries(value)) {
|
|
426
|
+
const newPrefix = prefix ? `${prefix}.${key}` : key;
|
|
427
|
+
const text = this.jsonToText(val, newPrefix);
|
|
428
|
+
if (text.length > 0) {
|
|
429
|
+
lines.push(text);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return lines.join('\n');
|
|
433
|
+
}
|
|
434
|
+
// String filtering with smart rules
|
|
435
|
+
if (typeof value === 'string') {
|
|
436
|
+
const key = prefix.split('.').pop() || '';
|
|
437
|
+
if (this.shouldIncludeString(value, key)) {
|
|
438
|
+
return prefix ? `${prefix}: ${value}` : value;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// Skip numbers and booleans (metadata noise)
|
|
442
|
+
return '';
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
exports.DocumentParser = DocumentParser;
|
|
446
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"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"}
|