@shuji-bonji/pdf-reader-mcp 0.2.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.
Files changed (129) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/LICENSE +21 -0
  3. package/README.ja.md +190 -0
  4. package/README.md +206 -0
  5. package/dist/constants.d.ts +22 -0
  6. package/dist/constants.d.ts.map +1 -0
  7. package/dist/constants.js +23 -0
  8. package/dist/constants.js.map +1 -0
  9. package/dist/index.d.ts +9 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +35 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/schemas/common.d.ts +14 -0
  14. package/dist/schemas/common.d.ts.map +1 -0
  15. package/dist/schemas/common.js +26 -0
  16. package/dist/schemas/common.js.map +1 -0
  17. package/dist/schemas/tier1.d.ts +104 -0
  18. package/dist/schemas/tier1.d.ts.map +1 -0
  19. package/dist/schemas/tier1.js +77 -0
  20. package/dist/schemas/tier1.js.map +1 -0
  21. package/dist/schemas/tier2.d.ts +68 -0
  22. package/dist/schemas/tier2.d.ts.map +1 -0
  23. package/dist/schemas/tier2.js +42 -0
  24. package/dist/schemas/tier2.js.map +1 -0
  25. package/dist/schemas/tier3.d.ts +44 -0
  26. package/dist/schemas/tier3.d.ts.map +1 -0
  27. package/dist/schemas/tier3.js +28 -0
  28. package/dist/schemas/tier3.js.map +1 -0
  29. package/dist/services/pdfjs-service.d.ts +65 -0
  30. package/dist/services/pdfjs-service.d.ts.map +1 -0
  31. package/dist/services/pdfjs-service.js +520 -0
  32. package/dist/services/pdfjs-service.js.map +1 -0
  33. package/dist/services/pdflib-service.d.ts +35 -0
  34. package/dist/services/pdflib-service.d.ts.map +1 -0
  35. package/dist/services/pdflib-service.js +318 -0
  36. package/dist/services/pdflib-service.js.map +1 -0
  37. package/dist/services/url-fetcher.d.ts +8 -0
  38. package/dist/services/url-fetcher.d.ts.map +1 -0
  39. package/dist/services/url-fetcher.js +40 -0
  40. package/dist/services/url-fetcher.js.map +1 -0
  41. package/dist/services/validation-service.d.ts +49 -0
  42. package/dist/services/validation-service.d.ts.map +1 -0
  43. package/dist/services/validation-service.js +670 -0
  44. package/dist/services/validation-service.js.map +1 -0
  45. package/dist/tools/index.d.ts +10 -0
  46. package/dist/tools/index.d.ts.map +1 -0
  47. package/dist/tools/index.js +46 -0
  48. package/dist/tools/index.js.map +1 -0
  49. package/dist/tools/tier1/get-metadata.d.ts +6 -0
  50. package/dist/tools/tier1/get-metadata.d.ts.map +1 -0
  51. package/dist/tools/tier1/get-metadata.js +49 -0
  52. package/dist/tools/tier1/get-metadata.js.map +1 -0
  53. package/dist/tools/tier1/get-page-count.d.ts +6 -0
  54. package/dist/tools/tier1/get-page-count.d.ts.map +1 -0
  55. package/dist/tools/tier1/get-page-count.js +50 -0
  56. package/dist/tools/tier1/get-page-count.js.map +1 -0
  57. package/dist/tools/tier1/read-images.d.ts +6 -0
  58. package/dist/tools/tier1/read-images.d.ts.map +1 -0
  59. package/dist/tools/tier1/read-images.js +79 -0
  60. package/dist/tools/tier1/read-images.js.map +1 -0
  61. package/dist/tools/tier1/read-text.d.ts +6 -0
  62. package/dist/tools/tier1/read-text.d.ts.map +1 -0
  63. package/dist/tools/tier1/read-text.js +57 -0
  64. package/dist/tools/tier1/read-text.js.map +1 -0
  65. package/dist/tools/tier1/read-url.d.ts +6 -0
  66. package/dist/tools/tier1/read-url.d.ts.map +1 -0
  67. package/dist/tools/tier1/read-url.js +64 -0
  68. package/dist/tools/tier1/read-url.js.map +1 -0
  69. package/dist/tools/tier1/search-text.d.ts +6 -0
  70. package/dist/tools/tier1/search-text.d.ts.map +1 -0
  71. package/dist/tools/tier1/search-text.js +62 -0
  72. package/dist/tools/tier1/search-text.js.map +1 -0
  73. package/dist/tools/tier1/summarize.d.ts +6 -0
  74. package/dist/tools/tier1/summarize.d.ts.map +1 -0
  75. package/dist/tools/tier1/summarize.js +70 -0
  76. package/dist/tools/tier1/summarize.js.map +1 -0
  77. package/dist/tools/tier2/inspect-annotations.d.ts +6 -0
  78. package/dist/tools/tier2/inspect-annotations.d.ts.map +1 -0
  79. package/dist/tools/tier2/inspect-annotations.js +47 -0
  80. package/dist/tools/tier2/inspect-annotations.js.map +1 -0
  81. package/dist/tools/tier2/inspect-fonts.d.ts +6 -0
  82. package/dist/tools/tier2/inspect-fonts.d.ts.map +1 -0
  83. package/dist/tools/tier2/inspect-fonts.js +54 -0
  84. package/dist/tools/tier2/inspect-fonts.js.map +1 -0
  85. package/dist/tools/tier2/inspect-signatures.d.ts +6 -0
  86. package/dist/tools/tier2/inspect-signatures.d.ts.map +1 -0
  87. package/dist/tools/tier2/inspect-signatures.js +48 -0
  88. package/dist/tools/tier2/inspect-signatures.js.map +1 -0
  89. package/dist/tools/tier2/inspect-structure.d.ts +6 -0
  90. package/dist/tools/tier2/inspect-structure.d.ts.map +1 -0
  91. package/dist/tools/tier2/inspect-structure.js +46 -0
  92. package/dist/tools/tier2/inspect-structure.js.map +1 -0
  93. package/dist/tools/tier2/inspect-tags.d.ts +6 -0
  94. package/dist/tools/tier2/inspect-tags.d.ts.map +1 -0
  95. package/dist/tools/tier2/inspect-tags.js +46 -0
  96. package/dist/tools/tier2/inspect-tags.js.map +1 -0
  97. package/dist/tools/tier3/compare-structure.d.ts +6 -0
  98. package/dist/tools/tier3/compare-structure.d.ts.map +1 -0
  99. package/dist/tools/tier3/compare-structure.js +47 -0
  100. package/dist/tools/tier3/compare-structure.js.map +1 -0
  101. package/dist/tools/tier3/validate-metadata.d.ts +6 -0
  102. package/dist/tools/tier3/validate-metadata.d.ts.map +1 -0
  103. package/dist/tools/tier3/validate-metadata.js +57 -0
  104. package/dist/tools/tier3/validate-metadata.js.map +1 -0
  105. package/dist/tools/tier3/validate-tagged.d.ts +6 -0
  106. package/dist/tools/tier3/validate-tagged.d.ts.map +1 -0
  107. package/dist/tools/tier3/validate-tagged.js +56 -0
  108. package/dist/tools/tier3/validate-tagged.js.map +1 -0
  109. package/dist/types.d.ts +226 -0
  110. package/dist/types.d.ts.map +1 -0
  111. package/dist/types.js +5 -0
  112. package/dist/types.js.map +1 -0
  113. package/dist/utils/batch-processor.d.ts +60 -0
  114. package/dist/utils/batch-processor.d.ts.map +1 -0
  115. package/dist/utils/batch-processor.js +72 -0
  116. package/dist/utils/batch-processor.js.map +1 -0
  117. package/dist/utils/error-handler.d.ts +23 -0
  118. package/dist/utils/error-handler.d.ts.map +1 -0
  119. package/dist/utils/error-handler.js +76 -0
  120. package/dist/utils/error-handler.js.map +1 -0
  121. package/dist/utils/formatter.d.ts +64 -0
  122. package/dist/utils/formatter.d.ts.map +1 -0
  123. package/dist/utils/formatter.js +379 -0
  124. package/dist/utils/formatter.js.map +1 -0
  125. package/dist/utils/pdf-helpers.d.ts +22 -0
  126. package/dist/utils/pdf-helpers.d.ts.map +1 -0
  127. package/dist/utils/pdf-helpers.js +68 -0
  128. package/dist/utils/pdf-helpers.js.map +1 -0
  129. package/package.json +78 -0
@@ -0,0 +1,520 @@
1
+ /**
2
+ * pdfjs-dist wrapper service.
3
+ *
4
+ * Centralizes all pdfjs-dist interactions for reuse across tools.
5
+ */
6
+ import { OPS, getDocument, } from 'pdfjs-dist/legacy/build/pdf.mjs';
7
+ import { DEFAULT_SEARCH_CONTEXT } from '../constants.js';
8
+ import { detectEncryption } from './pdflib-service.js';
9
+ import { getFileSize, readPdfFile, resolvePageNumbers } from '../utils/pdf-helpers.js';
10
+ /**
11
+ * pdfjs-dist verbosity level: ERRORS only (suppress warnings from stdout).
12
+ * pdfjs-dist's warn() uses console.log internally, which pollutes the
13
+ * stdio JSON-RPC stream. Setting verbosity to 0 prevents this.
14
+ */
15
+ const PDFJS_VERBOSITY = 0; // VerbosityLevel.ERRORS
16
+ /**
17
+ * Load a PDF document from a file path.
18
+ */
19
+ export async function loadDocument(filePath) {
20
+ const data = await readPdfFile(filePath);
21
+ const doc = await getDocument({ data, useSystemFonts: true, verbosity: PDFJS_VERBOSITY }).promise;
22
+ return doc;
23
+ }
24
+ /**
25
+ * Load a PDF document from a Uint8Array.
26
+ */
27
+ export async function loadDocumentFromData(data) {
28
+ const doc = await getDocument({ data, useSystemFonts: true, verbosity: PDFJS_VERBOSITY }).promise;
29
+ return doc;
30
+ }
31
+ /**
32
+ * Get full metadata from a PDF document.
33
+ */
34
+ export async function getMetadata(filePath) {
35
+ const doc = await loadDocument(filePath);
36
+ try {
37
+ return await getMetadataFromDoc(doc, filePath);
38
+ }
39
+ finally {
40
+ await doc.destroy();
41
+ }
42
+ }
43
+ /**
44
+ * Get full metadata from a pre-loaded PDFDocumentProxy.
45
+ * Does NOT destroy the document — caller is responsible for lifecycle.
46
+ */
47
+ export async function getMetadataFromDoc(doc, filePath) {
48
+ const fileSize = await getFileSize(filePath);
49
+ const meta = await doc.getMetadata();
50
+ const info = meta.info;
51
+ // Check if tagged
52
+ const markInfo = await getMarkInfo(doc);
53
+ const isTagged = markInfo?.Marked === true;
54
+ // Check signatures (heuristic check via first few pages)
55
+ const hasSignatures = await checkSignatures(doc);
56
+ return {
57
+ title: asStringOrNull(info.Title),
58
+ author: asStringOrNull(info.Author),
59
+ subject: asStringOrNull(info.Subject),
60
+ keywords: asStringOrNull(info.Keywords),
61
+ creator: asStringOrNull(info.Creator),
62
+ producer: asStringOrNull(info.Producer),
63
+ creationDate: asStringOrNull(info.CreationDate),
64
+ modificationDate: asStringOrNull(info.ModDate),
65
+ pageCount: doc.numPages,
66
+ pdfVersion: asStringOrNull(info.PDFFormatVersion),
67
+ isLinearized: info.IsLinearized === true,
68
+ isEncrypted: await detectEncryption(filePath),
69
+ isTagged,
70
+ hasSignatures,
71
+ fileSize,
72
+ };
73
+ }
74
+ /**
75
+ * Extract text from a pre-loaded PDFDocumentProxy.
76
+ * Does NOT destroy the document — caller is responsible for lifecycle.
77
+ */
78
+ export async function extractTextFromDoc(doc, pages) {
79
+ const pageNumbers = resolvePageNumbers(pages, doc.numPages);
80
+ // 全ページを並列に処理(pdfjs-dist は並列ページアクセスが安全)
81
+ const results = await Promise.all(pageNumbers.map(async (pageNum) => {
82
+ const page = await doc.getPage(pageNum);
83
+ const text = await extractPageText(page);
84
+ return { page: pageNum, text };
85
+ }));
86
+ return results;
87
+ }
88
+ /**
89
+ * Extract text from specified pages (1-based).
90
+ */
91
+ export async function extractText(filePath, pages) {
92
+ const doc = await loadDocument(filePath);
93
+ try {
94
+ return await extractTextFromDoc(doc, pages);
95
+ }
96
+ finally {
97
+ await doc.destroy();
98
+ }
99
+ }
100
+ /**
101
+ * Search for text across all pages.
102
+ */
103
+ export async function searchText(filePath, query, contextChars = DEFAULT_SEARCH_CONTEXT, pages) {
104
+ const doc = await loadDocument(filePath);
105
+ const lowerQuery = query.toLowerCase();
106
+ try {
107
+ const pageNumbers = resolvePageNumbers(pages, doc.numPages);
108
+ // 全ページのテキストを並列に抽出
109
+ const pageTexts = await Promise.all(pageNumbers.map(async (pageNum) => {
110
+ const page = await doc.getPage(pageNum);
111
+ const fullText = await extractPageText(page);
112
+ return { pageNum, fullText };
113
+ }));
114
+ // 抽出済みテキストからマッチを検索(CPU処理のみ、同期で十分)
115
+ const matches = [];
116
+ for (const { pageNum, fullText } of pageTexts) {
117
+ const lines = fullText.split('\n');
118
+ for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
119
+ const line = lines[lineIdx];
120
+ const lowerLine = line.toLowerCase();
121
+ let searchStart = 0;
122
+ while (true) {
123
+ const idx = lowerLine.indexOf(lowerQuery, searchStart);
124
+ if (idx === -1)
125
+ break;
126
+ const matchText = line.slice(idx, idx + query.length);
127
+ const contextBefore = line.slice(Math.max(0, idx - contextChars), idx);
128
+ const contextAfter = line.slice(idx + query.length, Math.min(line.length, idx + query.length + contextChars));
129
+ matches.push({
130
+ page: pageNum,
131
+ lineIndex: lineIdx,
132
+ text: matchText,
133
+ contextBefore,
134
+ contextAfter,
135
+ });
136
+ searchStart = idx + query.length;
137
+ }
138
+ }
139
+ }
140
+ return matches;
141
+ }
142
+ finally {
143
+ await doc.destroy();
144
+ }
145
+ }
146
+ /**
147
+ * Count images from a pre-loaded PDFDocumentProxy.
148
+ * Does NOT destroy the document — caller is responsible for lifecycle.
149
+ */
150
+ export async function countImagesFromDoc(doc, pages) {
151
+ const pageNumbers = resolvePageNumbers(pages, doc.numPages);
152
+ // 全ページのオペレータリストを並列取得し、画像数を集計
153
+ const counts = await Promise.all(pageNumbers.map(async (pageNum) => {
154
+ const page = await doc.getPage(pageNum);
155
+ const opList = await page.getOperatorList();
156
+ let count = 0;
157
+ for (const op of opList.fnArray) {
158
+ if (op === OPS.paintImageXObject || op === OPS.paintInlineImageXObject) {
159
+ count++;
160
+ }
161
+ }
162
+ return count;
163
+ }));
164
+ return counts.reduce((sum, c) => sum + c, 0);
165
+ }
166
+ /**
167
+ * Count images on specified pages.
168
+ */
169
+ export async function countImages(filePath, pages) {
170
+ const doc = await loadDocument(filePath);
171
+ try {
172
+ return await countImagesFromDoc(doc, pages);
173
+ }
174
+ finally {
175
+ await doc.destroy();
176
+ }
177
+ }
178
+ /**
179
+ * Extract images from specified pages as base64.
180
+ * Returns both extracted images and counts of detected/skipped images.
181
+ */
182
+ export async function extractImages(filePath, pages) {
183
+ const doc = await loadDocument(filePath);
184
+ try {
185
+ const pageNumbers = resolvePageNumbers(pages, doc.numPages);
186
+ // 全ページの画像抽出を並列実行
187
+ const pageResults = await Promise.all(pageNumbers.map(async (pageNum) => {
188
+ const page = await doc.getPage(pageNum);
189
+ const opList = await page.getOperatorList();
190
+ const pageImages = [];
191
+ let pageDetected = 0;
192
+ let imageIndex = 0;
193
+ for (let i = 0; i < opList.fnArray.length; i++) {
194
+ const op = opList.fnArray[i];
195
+ if (op === OPS.paintImageXObject) {
196
+ pageDetected++;
197
+ try {
198
+ const imgName = opList.argsArray[i][0];
199
+ const objs = page.objs;
200
+ const imgData = objs.get(imgName);
201
+ if (imgData?.data) {
202
+ const base64 = Buffer.from(imgData.data).toString('base64');
203
+ const colorSpace = imgData.kind === 1 ? 'RGB' : imgData.kind === 2 ? 'RGBA' : 'Grayscale';
204
+ pageImages.push({
205
+ page: pageNum,
206
+ index: imageIndex,
207
+ width: imgData.width,
208
+ height: imgData.height,
209
+ colorSpace,
210
+ bitsPerComponent: 8,
211
+ dataBase64: base64,
212
+ });
213
+ }
214
+ }
215
+ catch {
216
+ // Some images may not be directly accessible; skip
217
+ }
218
+ imageIndex++;
219
+ }
220
+ }
221
+ return { pageImages, pageDetected };
222
+ }));
223
+ // 各ページの結果を集約
224
+ const images = pageResults.flatMap((r) => r.pageImages);
225
+ const detectedCount = pageResults.reduce((sum, r) => sum + r.pageDetected, 0);
226
+ return {
227
+ images,
228
+ detectedCount,
229
+ extractedCount: images.length,
230
+ skippedCount: detectedCount - images.length,
231
+ };
232
+ }
233
+ finally {
234
+ await doc.destroy();
235
+ }
236
+ }
237
+ // ─── Internal helpers ────────────────────────────────────────
238
+ /**
239
+ * Extract text from a single page with Y-coordinate-based line ordering.
240
+ */
241
+ async function extractPageText(page) {
242
+ const content = await page.getTextContent();
243
+ const items = content.items.filter((item) => 'str' in item && item.str !== undefined);
244
+ if (items.length === 0)
245
+ return '';
246
+ // Sort by Y descending (top to bottom), then X ascending (left to right)
247
+ items.sort((a, b) => {
248
+ const ay = a.transform[5];
249
+ const by = b.transform[5];
250
+ const yDiff = by - ay;
251
+ if (Math.abs(yDiff) > 2)
252
+ return yDiff; // Different lines
253
+ return a.transform[4] - b.transform[4]; // Same line, sort by X
254
+ });
255
+ // Group into lines based on Y-coordinate proximity
256
+ const lines = [];
257
+ let currentLine = [];
258
+ let lastY = items[0].transform[5];
259
+ for (const item of items) {
260
+ const y = item.transform[5];
261
+ if (Math.abs(y - lastY) > 2) {
262
+ // New line
263
+ if (currentLine.length > 0) {
264
+ lines.push(currentLine.join(' '));
265
+ currentLine = [];
266
+ }
267
+ }
268
+ currentLine.push(item.str);
269
+ lastY = y;
270
+ }
271
+ if (currentLine.length > 0) {
272
+ lines.push(currentLine.join(' '));
273
+ }
274
+ return lines.join('\n');
275
+ }
276
+ /**
277
+ * Get MarkInfo dictionary from the catalog.
278
+ */
279
+ async function getMarkInfo(doc) {
280
+ try {
281
+ const markInfo = await doc.getMarkInfo();
282
+ return markInfo;
283
+ }
284
+ catch {
285
+ return null;
286
+ }
287
+ }
288
+ /**
289
+ * Check if the document has digital signatures.
290
+ *
291
+ * NOTE: This is a heuristic check that only scans the first 5 pages
292
+ * for signature Widget annotations. It may miss signatures attached
293
+ * to later pages. For comprehensive signature analysis, use the
294
+ * `inspect_signatures` tool which uses AcroForm-based detection via pdf-lib.
295
+ */
296
+ async function checkSignatures(doc) {
297
+ try {
298
+ // 最初の5ページを並列チェックし、いずれかに署名フィールドがあれば true
299
+ const pagesToCheck = Math.min(doc.numPages, 5);
300
+ const pageNumbers = Array.from({ length: pagesToCheck }, (_, i) => i + 1);
301
+ const results = await Promise.all(pageNumbers.map(async (pageNum) => {
302
+ const page = await doc.getPage(pageNum);
303
+ const annotations = await page.getAnnotations();
304
+ return annotations.some((annot) => annot.subtype === 'Widget' && annot.fieldType === 'Sig');
305
+ }));
306
+ return results.some((hasSig) => hasSig);
307
+ }
308
+ catch {
309
+ return false;
310
+ }
311
+ }
312
+ function asStringOrNull(value) {
313
+ if (typeof value === 'string' && value.length > 0)
314
+ return value;
315
+ return null;
316
+ }
317
+ // ─── Tier 2: Structure analysis functions ────────────────
318
+ /**
319
+ * Analyze Tagged PDF structure tree from a pre-loaded document.
320
+ * Does NOT destroy the document — caller is responsible for lifecycle.
321
+ */
322
+ export async function analyzeTagsFromDoc(doc) {
323
+ // Check if tagged
324
+ const markInfo = await getMarkInfo(doc);
325
+ const isTagged = markInfo?.Marked === true;
326
+ if (!isTagged) {
327
+ return {
328
+ isTagged: false,
329
+ rootTag: null,
330
+ maxDepth: 0,
331
+ totalElements: 0,
332
+ roleCounts: {},
333
+ };
334
+ }
335
+ // 全ページの構造ツリーを並列取得
336
+ const pageNumbers = Array.from({ length: doc.numPages }, (_, i) => i + 1);
337
+ const pageResults = await Promise.all(pageNumbers.map(async (pageNum) => {
338
+ const page = await doc.getPage(pageNum);
339
+ try {
340
+ const tree = await page.getStructTree();
341
+ if (tree) {
342
+ const localRoleCounts = {};
343
+ const node = buildTagNode(tree, localRoleCounts, 1);
344
+ return { node, roleCounts: localRoleCounts };
345
+ }
346
+ }
347
+ catch {
348
+ // Some pages may not have structure tree
349
+ }
350
+ return null;
351
+ }));
352
+ // 各ページの結果を集約
353
+ const roleCounts = {};
354
+ let totalElements = 0;
355
+ let maxDepth = 0;
356
+ const rootChildren = [];
357
+ for (const result of pageResults) {
358
+ if (!result)
359
+ continue;
360
+ rootChildren.push(result.node);
361
+ totalElements += countTagElements(result.node);
362
+ maxDepth = Math.max(maxDepth, getTagDepth(result.node));
363
+ // ページごとの roleCounts をマージ
364
+ for (const [role, count] of Object.entries(result.roleCounts)) {
365
+ roleCounts[role] = (roleCounts[role] ?? 0) + count;
366
+ }
367
+ }
368
+ const rootTag = rootChildren.length > 0
369
+ ? { role: 'StructTreeRoot', children: rootChildren, contentCount: 0 }
370
+ : null;
371
+ if (rootTag) {
372
+ maxDepth += 1; // Account for the root level
373
+ }
374
+ return {
375
+ isTagged,
376
+ rootTag,
377
+ maxDepth,
378
+ totalElements,
379
+ roleCounts,
380
+ };
381
+ }
382
+ /**
383
+ * Analyze Tagged PDF structure tree.
384
+ */
385
+ export async function analyzeTags(filePath) {
386
+ const doc = await loadDocument(filePath);
387
+ try {
388
+ return await analyzeTagsFromDoc(doc);
389
+ }
390
+ finally {
391
+ await doc.destroy();
392
+ }
393
+ }
394
+ /**
395
+ * Analyze annotations across all pages.
396
+ */
397
+ export async function analyzeAnnotations(filePath, pages) {
398
+ const doc = await loadDocument(filePath);
399
+ try {
400
+ const pageNumbers = resolvePageNumbers(pages, doc.numPages);
401
+ const markupSubtypes = new Set([
402
+ 'Text',
403
+ 'FreeText',
404
+ 'Line',
405
+ 'Square',
406
+ 'Circle',
407
+ 'Polygon',
408
+ 'PolyLine',
409
+ 'Highlight',
410
+ 'Underline',
411
+ 'Squiggly',
412
+ 'StrikeOut',
413
+ 'Stamp',
414
+ 'Caret',
415
+ 'Ink',
416
+ 'Popup',
417
+ 'Redact',
418
+ ]);
419
+ // 全ページのアノテーションを並列取得
420
+ const pageResults = await Promise.all(pageNumbers.map(async (pageNum) => {
421
+ const page = await doc.getPage(pageNum);
422
+ const annots = await page.getAnnotations();
423
+ const pageAnnotations = [];
424
+ const pageBySubtype = {};
425
+ let pageHasLinks = false;
426
+ let pageHasForms = false;
427
+ let pageHasMarkup = false;
428
+ for (const annot of annots) {
429
+ const subtype = annot.subtype ?? 'Unknown';
430
+ pageBySubtype[subtype] = (pageBySubtype[subtype] ?? 0) + 1;
431
+ if (subtype === 'Link')
432
+ pageHasLinks = true;
433
+ if (subtype === 'Widget')
434
+ pageHasForms = true;
435
+ if (markupSubtypes.has(subtype))
436
+ pageHasMarkup = true;
437
+ pageAnnotations.push({
438
+ subtype,
439
+ page: pageNum,
440
+ rect: annot.rect ?? null,
441
+ contents: asStringOrNull(annot.contentsObj?.str) ?? asStringOrNull(annot.contents),
442
+ author: asStringOrNull(annot.titleObj?.str) ?? null,
443
+ modificationDate: asStringOrNull(annot.modificationDate) ?? null,
444
+ hasAppearance: annot.hasAppearance === true,
445
+ });
446
+ }
447
+ return {
448
+ pageNum,
449
+ annotations: pageAnnotations,
450
+ bySubtype: pageBySubtype,
451
+ hasLinks: pageHasLinks,
452
+ hasForms: pageHasForms,
453
+ hasMarkup: pageHasMarkup,
454
+ };
455
+ }));
456
+ // 各ページの結果を集約
457
+ const annotations = [];
458
+ const bySubtype = {};
459
+ const byPage = {};
460
+ let hasLinks = false;
461
+ let hasForms = false;
462
+ let hasMarkup = false;
463
+ for (const result of pageResults) {
464
+ annotations.push(...result.annotations);
465
+ byPage[result.pageNum] = result.annotations.length;
466
+ hasLinks = hasLinks || result.hasLinks;
467
+ hasForms = hasForms || result.hasForms;
468
+ hasMarkup = hasMarkup || result.hasMarkup;
469
+ for (const [subtype, count] of Object.entries(result.bySubtype)) {
470
+ bySubtype[subtype] = (bySubtype[subtype] ?? 0) + count;
471
+ }
472
+ }
473
+ return {
474
+ totalAnnotations: annotations.length,
475
+ bySubtype,
476
+ byPage,
477
+ annotations,
478
+ hasLinks,
479
+ hasForms,
480
+ hasMarkup,
481
+ };
482
+ }
483
+ finally {
484
+ await doc.destroy();
485
+ }
486
+ }
487
+ function buildTagNode(node, roleCounts, depth) {
488
+ const role = node.role ?? 'Unknown';
489
+ roleCounts[role] = (roleCounts[role] ?? 0) + 1;
490
+ const children = [];
491
+ let contentCount = 0;
492
+ if (node.children) {
493
+ for (const child of node.children) {
494
+ if ('role' in child) {
495
+ children.push(buildTagNode(child, roleCounts, depth + 1));
496
+ }
497
+ else {
498
+ contentCount++;
499
+ }
500
+ }
501
+ }
502
+ return { role, children, contentCount };
503
+ }
504
+ function countTagElements(node) {
505
+ let count = 1;
506
+ for (const child of node.children) {
507
+ count += countTagElements(child);
508
+ }
509
+ return count;
510
+ }
511
+ function getTagDepth(node) {
512
+ if (node.children.length === 0)
513
+ return 1;
514
+ let max = 0;
515
+ for (const child of node.children) {
516
+ max = Math.max(max, getTagDepth(child));
517
+ }
518
+ return max + 1;
519
+ }
520
+ //# sourceMappingURL=pdfjs-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdfjs-service.js","sourceRoot":"","sources":["../../src/services/pdfjs-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * pdf-lib wrapper service.
3
+ *
4
+ * Provides low-level PDF structure access via pdf-lib for Tier 2 tools.
5
+ * Runs alongside pdfjs-service.ts (which handles text/image extraction).
6
+ */
7
+ import { PDFDocument } from 'pdf-lib';
8
+ import type { FontInfo, SignaturesAnalysis, StructureAnalysis } from '../types.js';
9
+ /**
10
+ * Load a PDF document with pdf-lib.
11
+ */
12
+ export declare function loadWithPdfLib(filePath: string): Promise<PDFDocument>;
13
+ /**
14
+ * Check if a PDF is encrypted.
15
+ */
16
+ export declare function detectEncryption(filePath: string): Promise<boolean>;
17
+ /**
18
+ * Analyze PDF internal structure (catalog, page tree, objects).
19
+ */
20
+ export declare function analyzeStructure(filePath: string): Promise<StructureAnalysis>;
21
+ /** Font analysis result including font map and total pages scanned */
22
+ export interface FontAnalysisResult {
23
+ fontMap: Map<string, FontInfo>;
24
+ pagesScanned: number;
25
+ }
26
+ /**
27
+ * Analyze fonts across all pages using pdf-lib's low-level access.
28
+ * Returns font map and total pages scanned.
29
+ */
30
+ export declare function analyzeFontsWithPdfLib(filePath: string): Promise<FontAnalysisResult>;
31
+ /**
32
+ * Analyze digital signature fields.
33
+ */
34
+ export declare function analyzeSignatures(filePath: string): Promise<SignaturesAnalysis>;
35
+ //# sourceMappingURL=pdflib-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdflib-service.d.ts","sourceRoot":"","sources":["../../src/services/pdflib-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGL,WAAW,EAOZ,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAEV,QAAQ,EAIR,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAIrB;;GAEG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAO3E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWzE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiFnF;AAED,sEAAsE;AACtE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgF1F;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAqFrF"}