@gmickel/gno 1.45.1 → 2.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/README.md +1 -1
- package/THIRD_PARTY_NOTICES.md +46 -0
- package/assets/skill/SKILL.md +7 -6
- package/assets/skill/cli-reference.md +14 -6
- package/assets/skill/mcp-reference.md +4 -1
- package/assets/spa-production.json.gz +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v2.0.0.zip +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v2.0.0.zip.sha256 +1 -0
- package/browser-extension/dist/chunk-4tc9v0ja.js +74 -0
- package/browser-extension/dist/manifest.json +1 -1
- package/browser-extension/dist/preview.html +1 -1
- package/browser-extension/dist/service-worker.js +32 -33
- package/bunfig.toml +2 -0
- package/package.json +40 -26
- package/spec/cli.md +30 -11
- package/spec/db/schema.sql +146 -1
- package/spec/mcp.md +26 -0
- package/src/app/context-runtime-types.ts +3 -0
- package/src/app/context-runtime.ts +2 -0
- package/src/cli/commands/ask.ts +6 -1
- package/src/cli/commands/daemon.ts +21 -8
- package/src/cli/commands/embed.ts +77 -41
- package/src/cli/commands/mcp/install.ts +20 -0
- package/src/cli/commands/mcp/paths.ts +25 -0
- package/src/cli/commands/mcp/status.ts +6 -0
- package/src/cli/detach.ts +3 -2
- package/src/cli/program.ts +6 -0
- package/src/config/types.ts +3 -3
- package/src/converters/adapters/markitdownTs/adapter.ts +1 -2
- package/src/converters/adapters/officeparser/adapter.ts +1 -2
- package/src/converters/versions.ts +6 -8
- package/src/core/context-evidence.ts +8 -4
- package/src/core/job-manager.ts +95 -13
- package/src/core/network-boundary-inventory.ts +10 -0
- package/src/core/shutdown-budget.ts +45 -0
- package/src/embed/backlog.ts +107 -4
- package/src/embed/batch.ts +42 -2
- package/src/embed/fingerprint.ts +16 -0
- package/src/embed/retry.ts +113 -5
- package/src/embed/variant-backlog.ts +105 -0
- package/src/embed/variant-plan.ts +62 -0
- package/src/embed/variant-retry.ts +113 -0
- package/src/ingestion/graph-reconciliation.ts +327 -0
- package/src/ingestion/sync.ts +9 -272
- package/src/llm/http-inference.ts +6 -0
- package/src/llm/httpEmbedding.ts +37 -6
- package/src/llm/httpGeneration.ts +18 -3
- package/src/llm/httpRerank.ts +23 -5
- package/src/llm/inference-cancellation.ts +168 -0
- package/src/llm/inference-scope.ts +202 -0
- package/src/llm/lazy-ports.ts +115 -0
- package/src/llm/native-worker/client.ts +541 -0
- package/src/llm/native-worker/dispatcher.ts +228 -0
- package/src/llm/native-worker/embedding-identity.ts +33 -0
- package/src/llm/native-worker/entry.ts +173 -0
- package/src/llm/native-worker/errors.ts +32 -0
- package/src/llm/native-worker/evaluation.ts +16 -0
- package/src/llm/native-worker/owned-exit.ts +108 -0
- package/src/llm/native-worker/owner.ts +141 -0
- package/src/llm/native-worker/ports.ts +317 -0
- package/src/llm/native-worker/protocol.ts +442 -0
- package/src/llm/native-worker/runtime-config.ts +92 -0
- package/src/llm/nodeLlamaCpp/adapter.ts +77 -20
- package/src/llm/nodeLlamaCpp/embedding.ts +130 -46
- package/src/llm/nodeLlamaCpp/generation.ts +34 -5
- package/src/llm/nodeLlamaCpp/lifecycle-options.ts +99 -0
- package/src/llm/nodeLlamaCpp/lifecycle.ts +209 -204
- package/src/llm/nodeLlamaCpp/rerank-capacity.ts +111 -0
- package/src/llm/nodeLlamaCpp/rerank.ts +118 -27
- package/src/llm/nodeLlamaCpp/simulator-handle.ts +73 -0
- package/src/llm/nodeLlamaCpp/simulator-install.ts +124 -0
- package/src/llm/nodeLlamaCpp/simulator-session.ts +240 -0
- package/src/llm/nodeLlamaCpp/simulator-types.ts +80 -0
- package/src/llm/types.ts +35 -5
- package/src/mcp/context.ts +27 -0
- package/src/mcp/http-transport.ts +12 -10
- package/src/mcp/server.ts +3 -0
- package/src/mcp/tool-profile.ts +30 -8
- package/src/mcp/tools/context.ts +8 -11
- package/src/mcp/tools/embed.ts +1 -1
- package/src/mcp/tools/index-cmd.ts +1 -1
- package/src/mcp/tools/index.ts +10 -8
- package/src/mcp/tools/query.ts +14 -30
- package/src/mcp/tools/vsearch.ts +1 -1
- package/src/pipeline/answer.ts +23 -3
- package/src/pipeline/claim-verifier.ts +6 -0
- package/src/pipeline/expansion.ts +43 -40
- package/src/pipeline/explain.ts +6 -2
- package/src/pipeline/filters.ts +63 -0
- package/src/pipeline/fusion.ts +29 -9
- package/src/pipeline/graph-retrieval.ts +29 -9
- package/src/pipeline/hybrid.ts +198 -55
- package/src/pipeline/hydration.ts +161 -0
- package/src/pipeline/owner-fusion.ts +87 -0
- package/src/pipeline/rerank.ts +35 -11
- package/src/pipeline/search.ts +13 -2
- package/src/pipeline/types.ts +5 -3
- package/src/pipeline/vsearch.ts +87 -7
- package/src/sdk/client.ts +47 -3
- package/src/sdk/embed.ts +63 -39
- package/src/serve/background-runtime.ts +1 -1
- package/src/serve/context.ts +41 -56
- package/src/serve/embed-scheduler.ts +58 -35
- package/src/serve/public/components/IndexingProgress.tsx +46 -60
- package/src/serve/public/globals.built.css +1 -1
- package/src/serve/public/lib/shiki-language-ids.ts +14 -0
- package/src/serve/resident-admission.ts +36 -36
- package/src/serve/resident-background-work.ts +20 -2
- package/src/serve/resident-request.ts +11 -5
- package/src/serve/resident-runtime.ts +97 -61
- package/src/serve/resident-shutdown.ts +153 -0
- package/src/serve/routes/api.ts +3 -1
- package/src/serve/server.ts +47 -26
- package/src/store/migrations/028-vector-variants.ts +54 -0
- package/src/store/migrations/029-graph-reference-state.ts +77 -0
- package/src/store/migrations/index.ts +4 -0
- package/src/store/sqlite/adapter.ts +251 -183
- package/src/store/sqlite/eligibility.ts +174 -0
- package/src/store/sqlite/graph-edge-application.ts +66 -0
- package/src/store/sqlite/graph-reference-state.ts +194 -0
- package/src/store/sqlite/legacy-vector-ownership.ts +79 -0
- package/src/store/types.ts +80 -12
- package/src/store/vector/eligibility.ts +36 -0
- package/src/store/vector/freshness.ts +33 -6
- package/src/store/vector/lazy.ts +81 -0
- package/src/store/vector/sqlite-vec.ts +106 -54
- package/src/store/vector/stats.ts +14 -3
- package/src/store/vector/types.ts +35 -2
- package/src/store/vector/variant-search.ts +192 -0
- package/src/store/vector/variants.ts +451 -0
- package/vendor/converters/markitdown-ts/LICENSE +21 -0
- package/vendor/converters/markitdown-ts/dist/index.cjs +1180 -0
- package/vendor/converters/markitdown-ts/dist/index.d.cts +46 -0
- package/vendor/converters/markitdown-ts/dist/index.d.mts +46 -0
- package/vendor/converters/markitdown-ts/dist/index.d.ts +46 -0
- package/vendor/converters/markitdown-ts/dist/index.mjs +1152 -0
- package/vendor/converters/markitdown-ts/package.json +77 -0
- package/vendor/converters/officeparser/LICENSE +21 -0
- package/vendor/converters/officeparser/dist/OfficeConverter.d.ts +47 -0
- package/vendor/converters/officeparser/dist/OfficeConverter.js +76 -0
- package/vendor/converters/officeparser/dist/OfficeGenerator.d.ts +23 -0
- package/vendor/converters/officeparser/dist/OfficeGenerator.js +73 -0
- package/vendor/converters/officeparser/dist/OfficeParser.d.ts +106 -0
- package/vendor/converters/officeparser/dist/OfficeParser.js +332 -0
- package/vendor/converters/officeparser/dist/cli.d.ts +28 -0
- package/vendor/converters/officeparser/dist/cli.js +381 -0
- package/vendor/converters/officeparser/dist/defaults.d.ts +41 -0
- package/vendor/converters/officeparser/dist/defaults.js +218 -0
- package/vendor/converters/officeparser/dist/generators/BaseGenerator.d.ts +107 -0
- package/vendor/converters/officeparser/dist/generators/BaseGenerator.js +248 -0
- package/vendor/converters/officeparser/dist/generators/ChunkingGenerator.d.ts +82 -0
- package/vendor/converters/officeparser/dist/generators/ChunkingGenerator.js +797 -0
- package/vendor/converters/officeparser/dist/generators/CsvGenerator.d.ts +38 -0
- package/vendor/converters/officeparser/dist/generators/CsvGenerator.js +245 -0
- package/vendor/converters/officeparser/dist/generators/EpubGenerator.d.ts +43 -0
- package/vendor/converters/officeparser/dist/generators/EpubGenerator.js +315 -0
- package/vendor/converters/officeparser/dist/generators/HtmlGenerator.d.ts +59 -0
- package/vendor/converters/officeparser/dist/generators/HtmlGenerator.js +1942 -0
- package/vendor/converters/officeparser/dist/generators/MarkdownGenerator.d.ts +96 -0
- package/vendor/converters/officeparser/dist/generators/MarkdownGenerator.js +1175 -0
- package/vendor/converters/officeparser/dist/generators/PdfGenerator.d.ts +22 -0
- package/vendor/converters/officeparser/dist/generators/PdfGenerator.js +194 -0
- package/vendor/converters/officeparser/dist/generators/RtfGenerator.d.ts +29 -0
- package/vendor/converters/officeparser/dist/generators/RtfGenerator.js +316 -0
- package/vendor/converters/officeparser/dist/generators/TextGenerator.d.ts +13 -0
- package/vendor/converters/officeparser/dist/generators/TextGenerator.js +201 -0
- package/vendor/converters/officeparser/dist/index.d.ts +60 -0
- package/vendor/converters/officeparser/dist/index.js +72 -0
- package/vendor/converters/officeparser/dist/index.mjs +18 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.d.ts +2621 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.iife.js +1336 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.mjs +1335 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.slim.d.ts +2621 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.slim.iife.js +1336 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.slim.mjs +1335 -0
- package/vendor/converters/officeparser/dist/parsers/CsvParser.d.ts +9 -0
- package/vendor/converters/officeparser/dist/parsers/CsvParser.js +115 -0
- package/vendor/converters/officeparser/dist/parsers/EpubParser.d.ts +8 -0
- package/vendor/converters/officeparser/dist/parsers/EpubParser.js +217 -0
- package/vendor/converters/officeparser/dist/parsers/ExcelParser.d.ts +32 -0
- package/vendor/converters/officeparser/dist/parsers/ExcelParser.js +736 -0
- package/vendor/converters/officeparser/dist/parsers/HtmlParser.d.ts +2 -0
- package/vendor/converters/officeparser/dist/parsers/HtmlParser.js +1287 -0
- package/vendor/converters/officeparser/dist/parsers/MarkdownParser.d.ts +2 -0
- package/vendor/converters/officeparser/dist/parsers/MarkdownParser.js +1272 -0
- package/vendor/converters/officeparser/dist/parsers/OpenOfficeParser.d.ts +31 -0
- package/vendor/converters/officeparser/dist/parsers/OpenOfficeParser.js +1819 -0
- package/vendor/converters/officeparser/dist/parsers/PdfParser.d.ts +67 -0
- package/vendor/converters/officeparser/dist/parsers/PdfParser.js +848 -0
- package/vendor/converters/officeparser/dist/parsers/PowerPointParser.d.ts +32 -0
- package/vendor/converters/officeparser/dist/parsers/PowerPointParser.js +950 -0
- package/vendor/converters/officeparser/dist/parsers/RtfParser.d.ts +187 -0
- package/vendor/converters/officeparser/dist/parsers/RtfParser.js +1801 -0
- package/vendor/converters/officeparser/dist/parsers/WordParser.d.ts +79 -0
- package/vendor/converters/officeparser/dist/parsers/WordParser.js +1177 -0
- package/vendor/converters/officeparser/dist/sbom.cdx.json +1763 -0
- package/vendor/converters/officeparser/dist/types.d.ts +2507 -0
- package/vendor/converters/officeparser/dist/types.js +107 -0
- package/vendor/converters/officeparser/dist/utils/astUtils.d.ts +16 -0
- package/vendor/converters/officeparser/dist/utils/astUtils.js +33 -0
- package/vendor/converters/officeparser/dist/utils/chartUtils.d.ts +6 -0
- package/vendor/converters/officeparser/dist/utils/chartUtils.js +257 -0
- package/vendor/converters/officeparser/dist/utils/configUtils.d.ts +44 -0
- package/vendor/converters/officeparser/dist/utils/configUtils.js +315 -0
- package/vendor/converters/officeparser/dist/utils/dateUtils.d.ts +17 -0
- package/vendor/converters/officeparser/dist/utils/dateUtils.js +69 -0
- package/vendor/converters/officeparser/dist/utils/envUtils.d.ts +29 -0
- package/vendor/converters/officeparser/dist/utils/envUtils.js +152 -0
- package/vendor/converters/officeparser/dist/utils/errorUtils.d.ts +72 -0
- package/vendor/converters/officeparser/dist/utils/errorUtils.js +245 -0
- package/vendor/converters/officeparser/dist/utils/imageUtils.d.ts +66 -0
- package/vendor/converters/officeparser/dist/utils/imageUtils.js +133 -0
- package/vendor/converters/officeparser/dist/utils/mathUtils.d.ts +42 -0
- package/vendor/converters/officeparser/dist/utils/mathUtils.js +385 -0
- package/vendor/converters/officeparser/dist/utils/moduleLoader.d.ts +18 -0
- package/vendor/converters/officeparser/dist/utils/moduleLoader.js +106 -0
- package/vendor/converters/officeparser/dist/utils/ocrUtils.d.ts +42 -0
- package/vendor/converters/officeparser/dist/utils/ocrUtils.js +428 -0
- package/vendor/converters/officeparser/dist/utils/sanitize.d.ts +148 -0
- package/vendor/converters/officeparser/dist/utils/sanitize.js +344 -0
- package/vendor/converters/officeparser/dist/utils/sheetUtils.d.ts +7 -0
- package/vendor/converters/officeparser/dist/utils/sheetUtils.js +35 -0
- package/vendor/converters/officeparser/dist/utils/styleMapper.d.ts +36 -0
- package/vendor/converters/officeparser/dist/utils/styleMapper.js +224 -0
- package/vendor/converters/officeparser/dist/utils/xmlUtils.d.ts +163 -0
- package/vendor/converters/officeparser/dist/utils/xmlUtils.js +461 -0
- package/vendor/converters/officeparser/dist/utils/zipUtils.d.ts +134 -0
- package/vendor/converters/officeparser/dist/utils/zipUtils.js +337 -0
- package/vendor/converters/officeparser/package.json +147 -0
- package/vendor/converters/upstream-manifest.json +124 -0
- package/vendor/dependency-fixes/README.md +77 -0
- package/vendor/dependency-fixes/vendor-converters.py +83 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.45.1.zip +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.45.1.zip.sha256 +0 -1
- package/browser-extension/dist/chunk-627emwpj.js +0 -75
- /package/browser-extension/dist/{chunk-ydfx5d7p.css → chunk-z74y8n8c.css} +0 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Office Parser - Main Entry Point
|
|
4
|
+
*
|
|
5
|
+
* This module provides the main `OfficeParser` class with a single static method
|
|
6
|
+
* that automatically detects file types and routes to the appropriate parser.
|
|
7
|
+
*
|
|
8
|
+
* **Supported Formats:**
|
|
9
|
+
* - DOCX (Word documents)
|
|
10
|
+
* - XLSX (Excel spreadsheets)
|
|
11
|
+
* - PPTX (PowerPoint presentations)
|
|
12
|
+
* - ODT, ODP, ODS (OpenDocument formats)
|
|
13
|
+
* - PDF (Portable Document Format)
|
|
14
|
+
* - RTF (Rich Text Format)
|
|
15
|
+
* - CSV (Comma-Separated Values)
|
|
16
|
+
* - MD (Markdown)
|
|
17
|
+
* - HTML (HyperText Markup Language)
|
|
18
|
+
* - EPUB (E-book format)
|
|
19
|
+
*
|
|
20
|
+
* **Usage:**
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import { OfficeParser } from 'officeparser';
|
|
23
|
+
*
|
|
24
|
+
* // Parse from file path
|
|
25
|
+
* const ast = await OfficeParser.parseOffice('document.docx', {
|
|
26
|
+
* extractAttachments: true,
|
|
27
|
+
* ocr: true
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // Parse from Buffer
|
|
31
|
+
* const buffer = fs.readFileSync('document.pdf');
|
|
32
|
+
* const ast = await OfficeParser.parseOffice(buffer);
|
|
33
|
+
*
|
|
34
|
+
* // Get plain text
|
|
35
|
+
* console.log((await ast.to('text')).value);
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @module OfficeParser
|
|
39
|
+
*/
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.OfficeParser = void 0;
|
|
42
|
+
const CsvParser_js_1 = require("./parsers/CsvParser.js");
|
|
43
|
+
const EpubParser_js_1 = require("./parsers/EpubParser.js");
|
|
44
|
+
const ExcelParser_js_1 = require("./parsers/ExcelParser.js");
|
|
45
|
+
const HtmlParser_js_1 = require("./parsers/HtmlParser.js");
|
|
46
|
+
const MarkdownParser_js_1 = require("./parsers/MarkdownParser.js");
|
|
47
|
+
const OpenOfficeParser_js_1 = require("./parsers/OpenOfficeParser.js");
|
|
48
|
+
const PdfParser_js_1 = require("./parsers/PdfParser.js");
|
|
49
|
+
const PowerPointParser_js_1 = require("./parsers/PowerPointParser.js");
|
|
50
|
+
const RtfParser_js_1 = require("./parsers/RtfParser.js");
|
|
51
|
+
const WordParser_js_1 = require("./parsers/WordParser.js");
|
|
52
|
+
const types_js_1 = require("./types.js");
|
|
53
|
+
const configUtils_js_1 = require("./utils/configUtils.js");
|
|
54
|
+
const envUtils_js_1 = require("./utils/envUtils.js");
|
|
55
|
+
const errorUtils_js_1 = require("./utils/errorUtils.js");
|
|
56
|
+
const moduleLoader_js_1 = require("./utils/moduleLoader.js");
|
|
57
|
+
const ocrUtils_js_1 = require("./utils/ocrUtils.js");
|
|
58
|
+
const zipUtils_js_1 = require("./utils/zipUtils.js");
|
|
59
|
+
/** What magic-byte sniffing reports for an archive it could not identify further. */
|
|
60
|
+
const GENERIC_ZIP_EXTENSION = 'zip';
|
|
61
|
+
/** The formats that are ZIP archives, and so cannot be contradicted by a bare `zip` result. */
|
|
62
|
+
const ZIP_BACKED_FILE_TYPES = new Set(['docx', 'xlsx', 'pptx', 'odt', 'ods', 'odp', 'epub']);
|
|
63
|
+
/**
|
|
64
|
+
* Upgrades a magic-byte result of `zip` (or none at all) into the specific office format the
|
|
65
|
+
* archive declares, by reading that declaration from inside the archive.
|
|
66
|
+
*
|
|
67
|
+
* Byte sniffing identifies an OOXML package by parsing `[Content_Types].xml`, but it walks the
|
|
68
|
+
* archive under fixed budgets and reports a plain `zip` when it runs out before finding that
|
|
69
|
+
* part. Since `zip` is not a format this library parses, a valid document then failed as an
|
|
70
|
+
* unsupported file type. Our own reader has no such budget, so it settles the question whenever
|
|
71
|
+
* sniffing is inconclusive.
|
|
72
|
+
*
|
|
73
|
+
* @param detected - What magic-byte sniffing reported, if anything
|
|
74
|
+
* @param buffer - The file content
|
|
75
|
+
* @param config - Resolved parser configuration, for its decompression limits
|
|
76
|
+
* @returns The resolved type, the original detection when nothing better is found, or undefined
|
|
77
|
+
*/
|
|
78
|
+
const resolveZipBackedType = async (detected, buffer, config) => {
|
|
79
|
+
if (detected && detected !== GENERIC_ZIP_EXTENSION)
|
|
80
|
+
return detected;
|
|
81
|
+
const resolved = await (0, zipUtils_js_1.detectOfficeTypeFromZip)(buffer, config.decompressionLimits ?? {});
|
|
82
|
+
return resolved ?? detected;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Main parser class providing office document parsing functionality.
|
|
86
|
+
*
|
|
87
|
+
* This class contains a single static method `parseOffice` that serves as the
|
|
88
|
+
* universal entry point for parsing any supported office document format.
|
|
89
|
+
*/
|
|
90
|
+
class OfficeParser {
|
|
91
|
+
/**
|
|
92
|
+
* Parses an office document and returns a structured AST.
|
|
93
|
+
*
|
|
94
|
+
* This method:
|
|
95
|
+
* 1. Accepts a file path, Buffer, or ArrayBuffer
|
|
96
|
+
* 2. Detects the file type (from extension or content)
|
|
97
|
+
* 3. Routes to the appropriate format-specific parser
|
|
98
|
+
* 4. Returns a unified AST structure
|
|
99
|
+
*
|
|
100
|
+
* **File Type Detection:**
|
|
101
|
+
* - If a file path is provided, uses the file extension
|
|
102
|
+
* - If a Buffer is provided, uses magic bytes detection (file-type library)
|
|
103
|
+
*
|
|
104
|
+
* **Supported Formats and Routes:**
|
|
105
|
+
* - `.docx` → WordParser (OOXML)
|
|
106
|
+
* - `.xlsx` → ExcelParser (OOXML)
|
|
107
|
+
* - `.pptx` → PowerPointParser (OOXML)
|
|
108
|
+
* - `.odt`, `.odp`, `.ods` → OpenOfficeParser (ODF)
|
|
109
|
+
* - `.pdf` → PdfParser (PDF.js)
|
|
110
|
+
* - `.rtf` → RtfParser (custom RTF parser)
|
|
111
|
+
* - `.csv` → CsvParser
|
|
112
|
+
* - `.md` → MarkdownParser
|
|
113
|
+
* - `.html` → HtmlParser
|
|
114
|
+
* - `.epub` → EpubParser
|
|
115
|
+
*
|
|
116
|
+
* @param file - File path (string), Buffer, or ArrayBuffer containing the document
|
|
117
|
+
* @param config - Optional configuration object (defaults applied for all omitted options)
|
|
118
|
+
* @returns A promise resolving to the parsed OfficeParserAST
|
|
119
|
+
* @throws {Error} If file doesn't exist, format is unsupported, or parsing fails
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* // Parse a DOCX file
|
|
124
|
+
* const ast = await OfficeParser.parseOffice('report.docx', {
|
|
125
|
+
* extractAttachments: true,
|
|
126
|
+
* includeRawContent: false
|
|
127
|
+
* });
|
|
128
|
+
*
|
|
129
|
+
* // Parse a Buffer with OCR enabled
|
|
130
|
+
* const buffer = await retrieveData('document.pdf').then(r => r.arrayBuffer());
|
|
131
|
+
* const ast = await OfficeParser.parseOffice(buffer, {
|
|
132
|
+
* ocr: true,
|
|
133
|
+
* ocrLanguage: 'eng+fra'
|
|
134
|
+
* });
|
|
135
|
+
*
|
|
136
|
+
* // Extract text
|
|
137
|
+
* const text = ast.toText();
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
static async parseOffice(file, configOrCallback, config) {
|
|
141
|
+
let callback;
|
|
142
|
+
let actualConfig = {};
|
|
143
|
+
if (typeof configOrCallback === 'function') {
|
|
144
|
+
callback = configOrCallback;
|
|
145
|
+
actualConfig = config || {};
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
actualConfig = configOrCallback || {};
|
|
149
|
+
}
|
|
150
|
+
const internalConfig = (0, configUtils_js_1.resolveParserConfig)(actualConfig);
|
|
151
|
+
const parsingWarnings = [];
|
|
152
|
+
const originalOnWarning = internalConfig.onWarning;
|
|
153
|
+
internalConfig.onWarning = (issue) => {
|
|
154
|
+
parsingWarnings.push(issue);
|
|
155
|
+
if (originalOnWarning)
|
|
156
|
+
originalOnWarning(issue);
|
|
157
|
+
};
|
|
158
|
+
let buffer = Buffer.alloc(0);
|
|
159
|
+
let ext = internalConfig.fileType ?? '';
|
|
160
|
+
let filePath;
|
|
161
|
+
try {
|
|
162
|
+
if (!file) {
|
|
163
|
+
throw (0, errorUtils_js_1.getOfficeError)(types_js_1.OfficeErrorType.IMPROPER_ARGUMENTS, internalConfig);
|
|
164
|
+
}
|
|
165
|
+
if (file instanceof ArrayBuffer) {
|
|
166
|
+
buffer = Buffer.from(file);
|
|
167
|
+
}
|
|
168
|
+
else if (file instanceof Uint8Array) {
|
|
169
|
+
buffer = Buffer.from(file.buffer, file.byteOffset, file.byteLength);
|
|
170
|
+
}
|
|
171
|
+
else if (Buffer.isBuffer(file)) {
|
|
172
|
+
buffer = file;
|
|
173
|
+
}
|
|
174
|
+
else if (typeof file === 'string') {
|
|
175
|
+
filePath = file;
|
|
176
|
+
(0, envUtils_js_1.assertNode)('path-parsing');
|
|
177
|
+
// Safe to use dynamic import here as we've asserted we are in Node.
|
|
178
|
+
// Modern bundlers will still see this, but our browser builds
|
|
179
|
+
// shim 'fs' so it won't crash at build time.
|
|
180
|
+
const fs = await import('fs');
|
|
181
|
+
if (!fs.existsSync(file)) {
|
|
182
|
+
throw (0, errorUtils_js_1.getOfficeError)(types_js_1.OfficeErrorType.FILE_DOES_NOT_EXIST, internalConfig, file);
|
|
183
|
+
}
|
|
184
|
+
if (fs.lstatSync(file).isDirectory()) {
|
|
185
|
+
throw (0, errorUtils_js_1.getOfficeError)(types_js_1.OfficeErrorType.LOCATION_NOT_FOUND, internalConfig, file);
|
|
186
|
+
}
|
|
187
|
+
buffer = fs.readFileSync(file);
|
|
188
|
+
ext = ext || file.split('.').pop() || '';
|
|
189
|
+
}
|
|
190
|
+
else if (file && typeof file.arrayBuffer === 'function') {
|
|
191
|
+
// Web Blob/File (or any BlobLike). Read its bytes; if it carries a filename, use
|
|
192
|
+
// the extension for type detection - never as a filesystem path. A nameless blob
|
|
193
|
+
// still resolves through the magic-byte sniffing below.
|
|
194
|
+
buffer = Buffer.from(await file.arrayBuffer());
|
|
195
|
+
const name = file.name;
|
|
196
|
+
if (!ext && typeof name === 'string' && name.includes('.')) {
|
|
197
|
+
ext = name.split('.').pop() || '';
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
throw (0, errorUtils_js_1.getOfficeError)(types_js_1.OfficeErrorType.INVALID_INPUT, internalConfig);
|
|
202
|
+
}
|
|
203
|
+
// Attempt to detect file type from buffer only if extension is unknown.
|
|
204
|
+
// This matches v6 behavior and prevents crashes in older Node environments
|
|
205
|
+
// where file-type 22.x might be incompatible.
|
|
206
|
+
if (buffer.length > 0 && !ext) {
|
|
207
|
+
let detected;
|
|
208
|
+
try {
|
|
209
|
+
const { fileTypeFromBuffer } = await (0, moduleLoader_js_1.loadFileType)();
|
|
210
|
+
const type = await fileTypeFromBuffer(buffer);
|
|
211
|
+
if (type) {
|
|
212
|
+
detected = type.ext;
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// If no extension could be detected and none was provided,
|
|
216
|
+
// it might be a text-based format (csv, md, html) which
|
|
217
|
+
// lack magic bytes. We'll let the switch default handle it.
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
// Log warning but don't crash; the switch below will handle unsupported/missing ext
|
|
222
|
+
(0, errorUtils_js_1.logWarning)(types_js_1.OfficeWarningType.FILE_TYPE_DETECTION_FAILED, internalConfig, { error });
|
|
223
|
+
}
|
|
224
|
+
ext = await resolveZipBackedType(detected, buffer, internalConfig) ?? '';
|
|
225
|
+
}
|
|
226
|
+
else if (buffer.length > 0 && ext) {
|
|
227
|
+
// If extension is known, we can optionally verify it, but we wrap it
|
|
228
|
+
// in a try-catch to avoid breaking Node 18 if file-type fails to load.
|
|
229
|
+
try {
|
|
230
|
+
const { fileTypeFromBuffer } = await (0, moduleLoader_js_1.loadFileType)();
|
|
231
|
+
const type = await fileTypeFromBuffer(buffer);
|
|
232
|
+
// A bare `zip` cannot contradict a caller who already said "this is a
|
|
233
|
+
// docx", so there is nothing a closer look could add. Skipping it keeps an
|
|
234
|
+
// explicit fileType the cheapest route, rather than making it pay for an
|
|
235
|
+
// archive scan that exists only to decide whether to warn.
|
|
236
|
+
const worthResolving = !(type?.ext === GENERIC_ZIP_EXTENSION && ZIP_BACKED_FILE_TYPES.has(ext.toLowerCase()));
|
|
237
|
+
const detected = worthResolving
|
|
238
|
+
? await resolveZipBackedType(type?.ext, buffer, internalConfig)
|
|
239
|
+
: type?.ext;
|
|
240
|
+
// A bare `zip` says only that the bytes are an archive, which every format
|
|
241
|
+
// on this path already is. Reporting it as a mismatch against the caller's
|
|
242
|
+
// own extension is noise, so only a resolved format is worth comparing.
|
|
243
|
+
if (detected && detected !== GENERIC_ZIP_EXTENSION && detected.toLowerCase() !== ext.toLowerCase()) {
|
|
244
|
+
// Mismatch found between authoritative extension and detected content
|
|
245
|
+
(0, errorUtils_js_1.logWarning)(types_js_1.OfficeWarningType.BUFFER_TYPE_MISMATCH, internalConfig, { detected, expected: ext });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
// Log warning so user knows verification could not be performed
|
|
250
|
+
(0, errorUtils_js_1.logWarning)(types_js_1.OfficeWarningType.FILE_TYPE_DETECTION_FAILED, internalConfig, { error });
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (!ext) {
|
|
254
|
+
throw (0, errorUtils_js_1.getOfficeError)(types_js_1.OfficeErrorType.IMPROPER_BUFFERS, internalConfig);
|
|
255
|
+
}
|
|
256
|
+
let result;
|
|
257
|
+
switch (ext.toLowerCase()) {
|
|
258
|
+
case 'docx':
|
|
259
|
+
result = await (0, WordParser_js_1.parseWord)(buffer, internalConfig);
|
|
260
|
+
break;
|
|
261
|
+
case 'pptx':
|
|
262
|
+
result = await (0, PowerPointParser_js_1.parsePowerPoint)(buffer, internalConfig);
|
|
263
|
+
break;
|
|
264
|
+
case 'xlsx':
|
|
265
|
+
result = await (0, ExcelParser_js_1.parseExcel)(buffer, internalConfig);
|
|
266
|
+
break;
|
|
267
|
+
case 'odt':
|
|
268
|
+
case 'odp':
|
|
269
|
+
case 'ods':
|
|
270
|
+
// The three ODF types share one parser, which needs to know which of them
|
|
271
|
+
// it is looking at. It normally reads that from the archive's mimetype
|
|
272
|
+
// entry; passing the resolved type along gives it something accurate to
|
|
273
|
+
// fall back on when that entry is missing.
|
|
274
|
+
//
|
|
275
|
+
// Overridden on a copy rather than on internalConfig: resolveParserConfig
|
|
276
|
+
// returns an already-complete config by reference, so writing to it would
|
|
277
|
+
// pin the caller's own object to this file's type and misroute every later
|
|
278
|
+
// parse that reused it.
|
|
279
|
+
result = await (0, OpenOfficeParser_js_1.parseOpenOffice)(buffer, { ...internalConfig, fileType: ext.toLowerCase() });
|
|
280
|
+
break;
|
|
281
|
+
case 'pdf':
|
|
282
|
+
result = await (0, PdfParser_js_1.parsePdf)(buffer, internalConfig);
|
|
283
|
+
break;
|
|
284
|
+
case 'rtf':
|
|
285
|
+
result = await (0, RtfParser_js_1.parseRtf)(buffer, internalConfig);
|
|
286
|
+
break;
|
|
287
|
+
case 'csv':
|
|
288
|
+
result = await (0, CsvParser_js_1.parseCsv)(buffer, internalConfig);
|
|
289
|
+
break;
|
|
290
|
+
case 'html':
|
|
291
|
+
result = await (0, HtmlParser_js_1.parseHtml)(buffer, internalConfig);
|
|
292
|
+
break;
|
|
293
|
+
case 'md':
|
|
294
|
+
result = await (0, MarkdownParser_js_1.parseMarkdown)(buffer, internalConfig);
|
|
295
|
+
break;
|
|
296
|
+
case 'epub':
|
|
297
|
+
result = await (0, EpubParser_js_1.parseEpub)(buffer, internalConfig);
|
|
298
|
+
break;
|
|
299
|
+
default:
|
|
300
|
+
throw (0, errorUtils_js_1.getOfficeError)(types_js_1.OfficeErrorType.EXTENSION_UNSUPPORTED, internalConfig, ext);
|
|
301
|
+
}
|
|
302
|
+
result.warnings = parsingWarnings;
|
|
303
|
+
if (callback)
|
|
304
|
+
callback(result);
|
|
305
|
+
return result;
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
// AbortError must pass through untouched so callers can distinguish a
|
|
309
|
+
// deliberate cancellation (err.name === 'AbortError') from a real parse failure.
|
|
310
|
+
// getWrappedError always creates a plain new Error(), which would strip the
|
|
311
|
+
// AbortError identity and break any instanceof / name checks on the caller side.
|
|
312
|
+
if (error?.name === 'AbortError')
|
|
313
|
+
throw error;
|
|
314
|
+
const wrappedError = (0, errorUtils_js_1.getWrappedError)(error, internalConfig, filePath);
|
|
315
|
+
if (callback)
|
|
316
|
+
callback(undefined, wrappedError);
|
|
317
|
+
throw wrappedError;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Terminates all active OCR workers and cleans up resources.
|
|
322
|
+
*
|
|
323
|
+
* This should be called when the application is shutting down or when OCR
|
|
324
|
+
* is no longer needed to prevent memory leaks and orphaned worker processes.
|
|
325
|
+
*
|
|
326
|
+
* @returns A promise that resolves when all workers have been terminated
|
|
327
|
+
*/
|
|
328
|
+
static async terminateOcr() {
|
|
329
|
+
await (0, ocrUtils_js_1.terminateOcr)();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
exports.OfficeParser = OfficeParser;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* officeparser CLI
|
|
4
|
+
*
|
|
5
|
+
* Allows running officeparser from the command line:
|
|
6
|
+
* npx officeparser file.docx
|
|
7
|
+
* officeparser file.docx --to=text
|
|
8
|
+
* officeparser file.docx --ocr --extractAttachments
|
|
9
|
+
*
|
|
10
|
+
* Options (--key=value, --key value, or bare flags):
|
|
11
|
+
* --to=json|text|md|html|csv|rtf|pdf|epub|chunks Convert AST to specified format (default: json)
|
|
12
|
+
* --output=path Save result to a file
|
|
13
|
+
* --fileType=docx|xlsx|... Override file type detection
|
|
14
|
+
* --ocr Enable OCR for images (default: false)
|
|
15
|
+
* --ocrConfig.language=eng OCR language (default: eng)
|
|
16
|
+
* --extractAttachments Extract embedded attachments (default: false)
|
|
17
|
+
* --ignoreNotes Ignore footnotes/endnotes/speaker notes (default: false)
|
|
18
|
+
* --ignoreComments Ignore inline comments (default: false)
|
|
19
|
+
* --ignoreHeadersAndFooters Ignore headers and footers (default: false)
|
|
20
|
+
* --ignoreSlideMasters Ignore slide masters (default: false)
|
|
21
|
+
* --ignoreInternalLinks Ignore internal links (default: false)
|
|
22
|
+
* --includeRawContent Include raw content in AST (default: false)
|
|
23
|
+
* --serializeRawContent Include stringified XML in metadata (default: true)
|
|
24
|
+
* --preserveXmlWhitespace Keep raw formatting space (default: false)
|
|
25
|
+
* --includeBreakNodes Include break nodes (DOCX only, default: false)
|
|
26
|
+
* --verbose Show full error stack traces and warning logs
|
|
27
|
+
*/
|
|
28
|
+
export {};
|