document-cli 1.10.0 → 1.11.1
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 +3 -3
- package/dist/cli.js +23 -170
- package/dist/index.cjs +21 -317
- package/dist/index.js +23 -319
- package/dist/{odb-structure-Du1w_hOU.js → odb-structure-CS2Eybob.js} +2 -151
- package/dist/{tui-BVeYd0ry.js → tui-Bw_z7xq6.js} +193 -207
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ graph TD
|
|
|
41
41
|
|
|
42
42
|
## Why
|
|
43
43
|
|
|
44
|
-
`documents.js` is a library, not a tool — everything it does happens through function calls from TypeScript/JavaScript. Most people who want to convert a docx to a PDF, extract an `.odb` table to CSV, or poke at a PDF's structure from a terminal don't want to write a script to do it. `document-cli` is that missing entry point: every one of documents.js's 27 direct conversion pairs, its generic converter, its `.odm`/`.odb` extraction functions, and its PDF inspector become a single command-line invocation, and its
|
|
44
|
+
`documents.js` is a library, not a tool — everything it does happens through function calls from TypeScript/JavaScript. Most people who want to convert a docx to a PDF, extract an `.odb` table to CSV, or poke at a PDF's structure from a terminal don't want to write a script to do it. `document-cli` is that missing entry point: every one of documents.js's 27 direct conversion pairs, its generic converter, its `.odm`/`.odb` extraction functions, and its PDF inspector become a single command-line invocation, and its seven live-view editors (docx/pptx/odt/odp/ods/odg/markdown) become a keyboard-driven terminal app that never needs a code editor open at all.
|
|
45
45
|
|
|
46
46
|
The CLI and the TUI are deliberately not two separate implementations of the same logic. The TUI's own document-opening, saving, and PDF-export code (`src/tui/format/`) calls the identical `documents.js` functions the CLI commands call — `openDocx`/`createDocx`/`docxToPdf` and their five siblings per format, plus `readOdbTables`/`readPdf` for the two read-only sources — so there is exactly one place either surface can drift from what documents.js itself does: nowhere.
|
|
47
47
|
|
|
@@ -165,9 +165,9 @@ Diagnostics and the summary line always go to stderr; stdout is reserved for the
|
|
|
165
165
|
|
|
166
166
|
Launch it either bare (`document-cli`, with no arguments) or explicitly with `document-cli tui [file]` — both open the same app; the explicit form additionally opens `file` immediately, skipping the launcher screen. The TUI needs an interactive terminal: a bare invocation with redirected stdout prints help text instead, and an explicit `tui` invocation with redirected stdout fails outright, since there's no terminal for Ink to draw into.
|
|
167
167
|
|
|
168
|
-
It supports the same
|
|
168
|
+
It supports the same seven formats documents.js's live-view editors cover — docx, pptx, odt, odp, ods, odg, markdown — each with a full navigate/edit/save experience built on that format's editor (paragraphs and runs for docx/odt/markdown, slides and shapes for pptx/odp, sheets and cells for ods, pages and vectors/shapes for odg), plus undo (whole-document snapshots taken before each committed mutation), search, a command palette, and PDF export straight from the open document. On a pptx or odp slide, `a` from the shape list also adds a real table (rows then columns, a two-step prompt) alongside the existing textbox/image choices, and `n` opens the slide's own speaker notes for either format — `PptxSlide` and `OdpSlide` both carry a real `.notes` getter/setter, so notes editing was never odp-specific, only gated that way until this phase removed the gate.
|
|
169
169
|
|
|
170
|
-
Markdown (`.md`/`.markdown`)
|
|
170
|
+
Markdown (`.md`/`.markdown`) shares the same paragraph/run/table body-list screens docx and odt already use, through documents.js's own `MarkdownEditor` (`openMarkdown`/`createMarkdownEditor`) — a genuine live view over a mutable `ContentDocument`, the same live-view contract every other editor here follows, even though there is no `XmlElement` tree underneath it the way there is for docx/odt (`MarkdownEditor.toMarkdownText()` re-serialises the whole document fresh on every call, rather than exposing a `toBytes()`). Appending a paragraph, appending a run, and toggling bold/italic all go through the identical reducer actions docx/odt use; a markdown run has no underline, colour, font family, or font size at all (CommonMark/GFM has no construct for any of the four), so those keys — along with image insertion, which `MarkdownParagraph` has no counterpart for — are simply absent from a markdown paragraph's own key hints rather than opening a prompt that could only end in a warning. A markdown table can be created and its cells edited through the same 'T' wizard and table-view screens docx/odt use, but GFM tables have no cell-merge concept, so a merge requested alongside table creation still creates the table (unmerged) and reports why the merge itself didn't happen. `:view-source` (markdown documents only) shows the literal text the document was opened with side by side with what a save would write right now — these can genuinely differ even with no edits made this session, from a heading-style, bullet-marker, or line-ending choice the writer normalises. Every save re-serialises the whole document fresh through `buildMarkdownText`, a deliberate, permanent consequence of structured editing rather than something to work around. Diagnostics from the read side (a clamped heading level, a dropped front-matter key, a fenced code block's own info string with nowhere to go, …) now surface into the same diagnostics panel a PDF export's own substitutions already populate, the moment a `.md` file is opened, not only on export. documents.js's own `createMarkdownEditor()` exists now, but this TUI does not yet wire a "new markdown document" flow into `:new`/the new-document picker, so a markdown document can still only be opened from an existing file.
|
|
171
171
|
|
|
172
172
|
Three further formats open read-only: a `.odb` browses its tables and rows with no write path at all (documents.js's own `.odb` support has no write direction to offer), a `.pdf` browses its pages and positioned items rather than being edited in place, and a `.xlsx` opens as a converted PDF preview — documents.js has no xlsx editor to hold a live view into, so opening one runs `xlsxToPdf` once at open time and browses the result through the identical page-list/page-items/item-detail screens a real `.pdf` uses, with the original bytes kept alongside so a later export re-runs `xlsxToPdf` with the caller's own fonts and diagnostics rather than reusing the fixed preview conversion. A `.odb` additionally browses its *structure* alongside its data: `f` from the table list opens the form browser and `r` the report browser, each listing what the database declares and opening one to show it in full — a form's own data source and field-bound controls (sub-forms nested under their parent), a report's data-source command, band and group structure, and every `rpt:` formula. Both are rendered through the same `src/odb-structure.ts` the `odb-forms`/`odb-reports` commands print, so the two views cannot drift apart, and search filters by line (`/SUM` narrows a long report to its aggregate expressions). A standalone `.odf` formula document has no TUI editor either — nothing to edit interactively, only a PDF conversion.
|
|
173
173
|
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as odbFormSummary, c as formatDocxExtrasLines, d as writeOutput, f as loadProvidedFonts, h as isDocumentFormat, i as formatOdbReportLines, l as readInput, m as inferFormatFromExtension, n as describeOdbReport, o as formatMetadataLines, r as formatOdbFormLines, s as presentMetadataEntries, t as describeOdbForm, u as resolveDefaultOutputPath } from "./odb-structure-
|
|
2
|
+
import { a as odbFormSummary, c as formatDocxExtrasLines, d as writeOutput, f as loadProvidedFonts, h as isDocumentFormat, i as formatOdbReportLines, l as readInput, m as inferFormatFromExtension, n as describeOdbReport, o as formatMetadataLines, r as formatOdbFormLines, s as presentMetadataEntries, t as describeOdbForm, u as resolveDefaultOutputPath } from "./odb-structure-CS2Eybob.js";
|
|
3
3
|
import { Command, CommanderError, InvalidArgumentError } from "commander";
|
|
4
4
|
import { writeFile } from "node:fs/promises";
|
|
5
|
-
import { HsqldbSqlEvaluationError, HsqldbSqlParseError, HsqldbSqlUnsupportedError, OdbNoEmbeddedDataSourceError, OdbReportNotSpecifiedError, OdbTableNotFoundError, OdbTableNotSpecifiedError, OdbUnsupportedFormatError, OdmUnresolvedSectionError, PdfEncryptedError, PdfParseError, UnrecognizedDocumentSchemaError,
|
|
5
|
+
import { HsqldbSqlEvaluationError, HsqldbSqlParseError, HsqldbSqlUnsupportedError, OdbNoEmbeddedDataSourceError, OdbReportNotSpecifiedError, OdbTableNotFoundError, OdbTableNotSpecifiedError, OdbUnsupportedFormatError, OdmUnresolvedSectionError, PdfEncryptedError, PdfParseError, UnrecognizedDocumentSchemaError, UnsupportedFontSourceFormatError, buildDocumentBytes, createLocalDocumentConverter, decodePackage, documentFromJson, documentPackageWithSchema, evaluateSelect, extractSourceFontsForFormat, hsqldbCellDisplayText, layoutDocumentWithSchema, odbReportToDocx, odbReportToOdt, odbReportToPdf, odbToCsv, odbToXlsx, odmToPdf, parseSelect, readDocumentMetadata, readDocxExtras, readOdbForms, readOdbInventory, readOdbReportContent, readOdbReports, readOdbTables, readPdf, setDocumentMetadata } from "documents.js";
|
|
6
6
|
import { basename, dirname, extname, join } from "node:path";
|
|
7
|
-
import { decodePackage as decodePackage$1
|
|
7
|
+
import { decodePackage as decodePackage$1 } from "odf.js";
|
|
8
8
|
import { existsSync, readFileSync } from "node:fs";
|
|
9
9
|
//#region src/runtime/abort.ts
|
|
10
10
|
function combineSignals(a, b) {
|
|
@@ -116,6 +116,7 @@ function mapErrorToExit(error, abortReason) {
|
|
|
116
116
|
if (abortReason === "timeout") return 124;
|
|
117
117
|
if (error instanceof OdmUnresolvedSectionError || error instanceof OdbTableNotSpecifiedError || error instanceof OdbTableNotFoundError || error instanceof OdbNoEmbeddedDataSourceError || error instanceof OdbUnsupportedFormatError || error instanceof OdbReportNotSpecifiedError) return 3;
|
|
118
118
|
if (error instanceof HsqldbSqlUnsupportedError || error instanceof HsqldbSqlParseError || error instanceof HsqldbSqlEvaluationError) return 1;
|
|
119
|
+
if (error instanceof UnsupportedFontSourceFormatError) return 2;
|
|
119
120
|
if (error instanceof PdfEncryptedError || error instanceof PdfParseError) return 1;
|
|
120
121
|
return 1;
|
|
121
122
|
}
|
|
@@ -306,27 +307,6 @@ function registerDocxExtrasCommand(program) {
|
|
|
306
307
|
}
|
|
307
308
|
//#endregion
|
|
308
309
|
//#region src/commands/fonts.ts
|
|
309
|
-
const FONT_SOURCE_FORMATS = {
|
|
310
|
-
docx: true,
|
|
311
|
-
pptx: true,
|
|
312
|
-
odt: true,
|
|
313
|
-
odp: true,
|
|
314
|
-
ods: true,
|
|
315
|
-
odg: true
|
|
316
|
-
};
|
|
317
|
-
function isFontSourceFormat(format) {
|
|
318
|
-
return format in FONT_SOURCE_FORMATS;
|
|
319
|
-
}
|
|
320
|
-
function resolveFontSourcePackage(format, bytes) {
|
|
321
|
-
if (format === "docx" || format === "pptx") return {
|
|
322
|
-
kind: format,
|
|
323
|
-
package: decodePackage(bytes)
|
|
324
|
-
};
|
|
325
|
-
return {
|
|
326
|
-
kind: "odf",
|
|
327
|
-
package: decodePackage$1(bytes)
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
310
|
async function runFonts(input, options) {
|
|
331
311
|
const command = "fonts";
|
|
332
312
|
const { signal, getAbortReason } = createRuntimeSignal({});
|
|
@@ -336,13 +316,8 @@ async function runFonts(input, options) {
|
|
|
336
316
|
process.stderr.write(`[${command}] cannot infer a document format from '${input}'; expected one of docx, pptx, odt, odp, ods, odg\n`);
|
|
337
317
|
return 2;
|
|
338
318
|
}
|
|
339
|
-
if (!isFontSourceFormat(format)) {
|
|
340
|
-
process.stderr.write(`[${command}] '${format}' documents carry no source-embedded font faces this command can extract; expected one of docx, pptx, odt, odp, ods, odg\n`);
|
|
341
|
-
return 2;
|
|
342
|
-
}
|
|
343
319
|
const inputBytes = await readInput(input, { signal });
|
|
344
|
-
const
|
|
345
|
-
const summaries = extractSourceFonts(source).map((face) => ({
|
|
320
|
+
const summaries = extractSourceFontsForFormat(format, new Uint8Array(inputBytes)).map((face) => ({
|
|
346
321
|
family: face.family,
|
|
347
322
|
bold: face.bold,
|
|
348
323
|
italic: face.italic,
|
|
@@ -387,23 +362,6 @@ function registerFormatsCommand(program) {
|
|
|
387
362
|
}
|
|
388
363
|
//#endregion
|
|
389
364
|
//#region src/commands/from-package.ts
|
|
390
|
-
function buildBytesForTarget(pkg, target) {
|
|
391
|
-
if (target === "pdf") {
|
|
392
|
-
if (pkg.layout === void 0) throw new Error("this DocumentPackage has no layout -- only a package dumped from a <format>-to-pdf or pdf-to-<format> conversion carries one; a bridge conversion's own dump (e.g. odt-to-docx) never does, so 'pdf' is not a reachable target from it");
|
|
393
|
-
return writePdf(pkg.layout);
|
|
394
|
-
}
|
|
395
|
-
switch (target) {
|
|
396
|
-
case "docx": return encodePackage(buildDocxPackage(pkg.content));
|
|
397
|
-
case "pptx": return encodePackage(buildPptxPackage(pkg.content));
|
|
398
|
-
case "odt": return encodePackage$1(buildOdtPackage(pkg.content));
|
|
399
|
-
case "odp": return encodePackage$1(buildOdpPackage(pkg.content));
|
|
400
|
-
case "ods": return encodePackage$1(buildOdsPackage(pkg.content));
|
|
401
|
-
case "odg": return encodePackage$1(buildOdgPackage(pkg.content));
|
|
402
|
-
case "markdown": return encodeMarkdownText(buildMarkdownText(pkg.content));
|
|
403
|
-
case "xlsx": throw new Error("'xlsx' cannot be built from a DocumentPackage directly -- documents.js does not re-export a ContentDocument-to-xlsx builder; convert to 'ods' here, then run 'ods-to-xlsx' on the result instead");
|
|
404
|
-
case "odf": throw new Error("'odf' (a standalone formula document) cannot be built from a DocumentPackage -- there is no ContentDocument-to-odf builder");
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
365
|
async function runFromPackage(input, output, options) {
|
|
408
366
|
const command = "from-package";
|
|
409
367
|
if (output !== void 0 && options.out !== void 0 && output !== options.out) {
|
|
@@ -432,7 +390,7 @@ async function runFromPackage(input, output, options) {
|
|
|
432
390
|
process.stderr.write(`[${command}] '${input}' is a ${result.kind}, not a DocumentPackage -- only a file written by --dump-package can be read back by this command\n`);
|
|
433
391
|
return 2;
|
|
434
392
|
}
|
|
435
|
-
const bytes =
|
|
393
|
+
const bytes = buildDocumentBytes(result.value, target.format);
|
|
436
394
|
await writeOutput(resolvedOutput, bytes);
|
|
437
395
|
createDiagnosticReporter({
|
|
438
396
|
json: options.json,
|
|
@@ -467,20 +425,6 @@ function registerFromPackageCommand(program) {
|
|
|
467
425
|
}
|
|
468
426
|
//#endregion
|
|
469
427
|
//#region src/commands/metadata.ts
|
|
470
|
-
function readMetadataForFormat(format, bytes, signal) {
|
|
471
|
-
switch (format) {
|
|
472
|
-
case "docx": return readDocxContent(decodePackage(bytes)).metadata;
|
|
473
|
-
case "pptx": return readPptxContent(decodePackage(bytes)).metadata;
|
|
474
|
-
case "odt": return readOdtContent(decodePackage$1(bytes)).metadata;
|
|
475
|
-
case "odp": return readOdpContent(decodePackage$1(bytes)).metadata;
|
|
476
|
-
case "ods": return readOdsContent(decodePackage$1(bytes)).metadata;
|
|
477
|
-
case "odg": return readOdgContent(decodePackage$1(bytes)).metadata;
|
|
478
|
-
case "odf": return readOdfFormulaContent(decodePackage$1(bytes)).metadata;
|
|
479
|
-
case "markdown": return readMarkdownContent(decodeMarkdownText(bytes)).metadata;
|
|
480
|
-
case "pdf": return readPdf(bytes, { signal }).metadata;
|
|
481
|
-
case "xlsx": return readPdf(xlsxToPdf(bytes, { signal }), { signal }).metadata;
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
428
|
async function runMetadata(input, options) {
|
|
485
429
|
const command = "metadata";
|
|
486
430
|
const source = inferFormatFromExtension(input);
|
|
@@ -491,7 +435,7 @@ async function runMetadata(input, options) {
|
|
|
491
435
|
const { signal, getAbortReason } = createRuntimeSignal({});
|
|
492
436
|
try {
|
|
493
437
|
const inputBytes = await readInput(input, { signal });
|
|
494
|
-
const metadata =
|
|
438
|
+
const metadata = readDocumentMetadata(source, new Uint8Array(inputBytes), { signal });
|
|
495
439
|
if (options.json) {
|
|
496
440
|
process.stdout.write(`${JSON.stringify(metadata)}\n`);
|
|
497
441
|
return 0;
|
|
@@ -739,32 +683,6 @@ const ODB_REPORT_TARGET_FORMATS = {
|
|
|
739
683
|
function isOdbReportTargetFormat(format) {
|
|
740
684
|
return format in ODB_REPORT_TARGET_FORMATS;
|
|
741
685
|
}
|
|
742
|
-
function renderOdbReportBytes(content, target, options) {
|
|
743
|
-
if (target === "docx") return encodePackage(buildDocxPackage(content));
|
|
744
|
-
if (target === "odt") return encodePackage$1(buildOdtPackage(content));
|
|
745
|
-
if (content.kind !== "wordprocessing") throw new Error("readOdbReportContent returned a non-wordprocessing ContentDocument");
|
|
746
|
-
const fonts = createFontRegistry({
|
|
747
|
-
fonts: options.fonts,
|
|
748
|
-
onSubstitution: (substitution) => {
|
|
749
|
-
if (options.reportFontSubstitution !== void 0) {
|
|
750
|
-
options.reportFontSubstitution(substitution);
|
|
751
|
-
return;
|
|
752
|
-
}
|
|
753
|
-
options.onDiagnosticCounted();
|
|
754
|
-
options.reporter.report(fontSubstitutionToDiagnostic(substitution));
|
|
755
|
-
}
|
|
756
|
-
});
|
|
757
|
-
const { document: layout, formulas } = convertWordprocessingToLayout(content, { measurer: createFontMeasurer(fonts) });
|
|
758
|
-
return writePdf(layout, {
|
|
759
|
-
signal: options.signal,
|
|
760
|
-
onSubstitution: (substitution, context) => {
|
|
761
|
-
options.onDiagnosticCounted();
|
|
762
|
-
options.reporter.report(substitutionToDiagnostic(substitution, context.pageIndex));
|
|
763
|
-
},
|
|
764
|
-
formulas,
|
|
765
|
-
fonts
|
|
766
|
-
});
|
|
767
|
-
}
|
|
768
686
|
async function runOdbRenderReport(input, output, options) {
|
|
769
687
|
const command = "odb-render-report";
|
|
770
688
|
if (output !== void 0 && options.out !== void 0 && output !== options.out) {
|
|
@@ -798,13 +716,21 @@ async function runOdbRenderReport(input, output, options) {
|
|
|
798
716
|
const inputBytes = await readInput(input, { signal });
|
|
799
717
|
const fonts = await loadProvidedFonts(options.fontFile ?? [], { signal });
|
|
800
718
|
const pkg = decodePackage$1(new Uint8Array(inputBytes));
|
|
801
|
-
const
|
|
802
|
-
|
|
719
|
+
const content = readOdbReportContent(pkg, { report: options.report });
|
|
720
|
+
const bytes = targetFormat === "docx" ? odbReportToDocx(content) : targetFormat === "odt" ? odbReportToOdt(content) : odbReportToPdf(content, {
|
|
803
721
|
signal,
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
722
|
+
fonts,
|
|
723
|
+
onFontSubstitution: (substitution) => {
|
|
724
|
+
if (reportFontSubstitution !== void 0) {
|
|
725
|
+
reportFontSubstitution(substitution);
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
diagnosticCount += 1;
|
|
729
|
+
reporter.report(fontSubstitutionToDiagnostic(substitution));
|
|
730
|
+
},
|
|
731
|
+
onSubstitution: (substitution, context) => {
|
|
807
732
|
diagnosticCount += 1;
|
|
733
|
+
reporter.report(substitutionToDiagnostic(substitution, context.pageIndex));
|
|
808
734
|
}
|
|
809
735
|
});
|
|
810
736
|
await writeOutput(resolvedOutput, bytes);
|
|
@@ -1047,63 +973,9 @@ function registerPdfInspectCommand(program) {
|
|
|
1047
973
|
}
|
|
1048
974
|
//#endregion
|
|
1049
975
|
//#region src/commands/set-metadata.ts
|
|
1050
|
-
const REBUILD_FORMATS = {
|
|
1051
|
-
docx: true,
|
|
1052
|
-
pptx: true,
|
|
1053
|
-
odt: true,
|
|
1054
|
-
odp: true,
|
|
1055
|
-
ods: true,
|
|
1056
|
-
odg: true,
|
|
1057
|
-
markdown: true
|
|
1058
|
-
};
|
|
1059
|
-
function isRebuildFormat(format) {
|
|
1060
|
-
return format in REBUILD_FORMATS;
|
|
1061
|
-
}
|
|
1062
|
-
function readContentForFormat(format, bytes) {
|
|
1063
|
-
switch (format) {
|
|
1064
|
-
case "docx": return readDocxContent(decodePackage(bytes));
|
|
1065
|
-
case "pptx": return readPptxContent(decodePackage(bytes));
|
|
1066
|
-
case "odt": return readOdtContent(decodePackage$1(bytes));
|
|
1067
|
-
case "odp": return readOdpContent(decodePackage$1(bytes));
|
|
1068
|
-
case "ods": return readOdsContent(decodePackage$1(bytes));
|
|
1069
|
-
case "odg": return readOdgContent(decodePackage$1(bytes));
|
|
1070
|
-
case "markdown": return readMarkdownContent(decodeMarkdownText(bytes));
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
function buildBytesForRebuildFormat(format, content) {
|
|
1074
|
-
switch (format) {
|
|
1075
|
-
case "docx": return encodePackage(buildDocxPackage(content));
|
|
1076
|
-
case "pptx": return encodePackage(buildPptxPackage(content));
|
|
1077
|
-
case "odt": return encodePackage$1(buildOdtPackage(content));
|
|
1078
|
-
case "odp": return encodePackage$1(buildOdpPackage(content));
|
|
1079
|
-
case "ods": return encodePackage$1(buildOdsPackage(content));
|
|
1080
|
-
case "odg": return encodePackage$1(buildOdgPackage(content));
|
|
1081
|
-
case "markdown": return encodeMarkdownText(buildMarkdownText(content));
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
function mergeMetadata(current, overrides) {
|
|
1085
|
-
return {
|
|
1086
|
-
...current,
|
|
1087
|
-
...overrides.title !== void 0 ? { title: overrides.title } : {},
|
|
1088
|
-
...overrides.author !== void 0 ? { author: overrides.author } : {},
|
|
1089
|
-
...overrides.subject !== void 0 ? { subject: overrides.subject } : {},
|
|
1090
|
-
...overrides.keywords !== void 0 ? { keywords: overrides.keywords } : {}
|
|
1091
|
-
};
|
|
1092
|
-
}
|
|
1093
976
|
function parseKeywords(csv) {
|
|
1094
977
|
return csv.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
1095
978
|
}
|
|
1096
|
-
function classifyWritePath(source, target) {
|
|
1097
|
-
if (source === "pdf" && target === "pdf") return { kind: "pdf" };
|
|
1098
|
-
if (target === "xlsx" || source === "xlsx") return { errorMessage: "'xlsx' is not a supported set-metadata source or target -- documents.js does not re-export a ContentDocument-to-xlsx builder or a readXlsxContent from its own public surface (see that package's own README, Architecture section); convert with 'xlsx-to-ods'/'ods-to-xlsx' first, then set metadata on the ods" };
|
|
1099
|
-
if (target === "odf" || source === "odf") return { errorMessage: "'odf' (a standalone formula document) is not a supported set-metadata source or target -- it has no write path back out at all" };
|
|
1100
|
-
if (!isRebuildFormat(source) || !isRebuildFormat(target)) return { errorMessage: `set-metadata only patches metadata in place; it does not convert format -- source ('${source}') and target ('${target}') must be the same format (or both 'pdf'). Run 'convert'/'from-package' first if you need a different target format.` };
|
|
1101
|
-
if (source !== target) return { errorMessage: `set-metadata only patches metadata in place; it does not convert format -- source ('${source}') and target ('${target}') must be the same format. Run 'convert'/'from-package' first if you need a different target format.` };
|
|
1102
|
-
return {
|
|
1103
|
-
kind: "rebuild",
|
|
1104
|
-
format: source
|
|
1105
|
-
};
|
|
1106
|
-
}
|
|
1107
979
|
async function runSetMetadata(input, output, options) {
|
|
1108
980
|
const command = "set-metadata";
|
|
1109
981
|
if (output !== void 0 && options.out !== void 0 && output !== options.out) {
|
|
@@ -1120,11 +992,6 @@ async function runSetMetadata(input, output, options) {
|
|
|
1120
992
|
process.stderr.write(`[${command}] cannot infer a source format from '${input}'; rename the file with a recognised extension (${KNOWN_DOCUMENT_FORMATS})\n`);
|
|
1121
993
|
return 2;
|
|
1122
994
|
}
|
|
1123
|
-
const writePath = classifyWritePath(source, target.format);
|
|
1124
|
-
if ("errorMessage" in writePath) {
|
|
1125
|
-
process.stderr.write(`[${command}] ${writePath.errorMessage}\n`);
|
|
1126
|
-
return 2;
|
|
1127
|
-
}
|
|
1128
995
|
const overrides = {
|
|
1129
996
|
title: options.setTitle,
|
|
1130
997
|
author: options.setAuthor,
|
|
@@ -1135,21 +1002,7 @@ async function runSetMetadata(input, output, options) {
|
|
|
1135
1002
|
const { signal, getAbortReason } = createRuntimeSignal({ timeoutMs: options.timeout });
|
|
1136
1003
|
try {
|
|
1137
1004
|
const inputBytes = await readInput(input, { signal });
|
|
1138
|
-
const bytes =
|
|
1139
|
-
const layout = readPdf(new Uint8Array(inputBytes), { signal });
|
|
1140
|
-
const patched = {
|
|
1141
|
-
...layout,
|
|
1142
|
-
metadata: mergeMetadata(layout.metadata, overrides)
|
|
1143
|
-
};
|
|
1144
|
-
return writePdf(patched, { signal });
|
|
1145
|
-
})() : (() => {
|
|
1146
|
-
const content = readContentForFormat(writePath.format, new Uint8Array(inputBytes));
|
|
1147
|
-
const nextContent = {
|
|
1148
|
-
...content,
|
|
1149
|
-
metadata: mergeMetadata(content.metadata, overrides)
|
|
1150
|
-
};
|
|
1151
|
-
return buildBytesForRebuildFormat(writePath.format, nextContent);
|
|
1152
|
-
})();
|
|
1005
|
+
const bytes = setDocumentMetadata(source, target.format, new Uint8Array(inputBytes), overrides, { signal });
|
|
1153
1006
|
await writeOutput(resolvedOutput, bytes);
|
|
1154
1007
|
createDiagnosticReporter({
|
|
1155
1008
|
json: options.json,
|
|
@@ -1194,7 +1047,7 @@ function registerSetMetadataCommand(program) {
|
|
|
1194
1047
|
}
|
|
1195
1048
|
//#endregion
|
|
1196
1049
|
//#region package.json
|
|
1197
|
-
var version = "1.
|
|
1050
|
+
var version = "1.11.1";
|
|
1198
1051
|
//#endregion
|
|
1199
1052
|
//#region src/program.ts
|
|
1200
1053
|
function createProgram() {
|
|
@@ -1221,7 +1074,7 @@ function createProgram() {
|
|
|
1221
1074
|
//#region src/cli.ts
|
|
1222
1075
|
async function launchTui(startPath, signal) {
|
|
1223
1076
|
try {
|
|
1224
|
-
const { runTui } = await import("./tui-
|
|
1077
|
+
const { runTui } = await import("./tui-Bw_z7xq6.js");
|
|
1225
1078
|
await runTui({
|
|
1226
1079
|
startPath,
|
|
1227
1080
|
signal
|