document-cli 1.2.11 → 1.4.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/dist/cli.js +284 -11
- package/dist/index.cjs +335 -4
- package/dist/index.js +340 -9
- package/dist/{odb-structure-CX_0zL8_.js → odb-structure-DkfNyHGR.js} +59 -1
- package/dist/{tui-DD4bQp39.js → tui-CQCLalYe.js} +223 -6
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as odbFormSummary, c as
|
|
2
|
+
import { a as odbFormSummary, c as resolveDefaultOutputPath, f as inferFormatFromExtension, i as formatOdbReportLines, l as writeOutput, n as describeOdbReport, o as formatDocxExtrasLines, p as isDocumentFormat, r as formatOdbFormLines, s as readInput, t as describeOdbForm, u as loadProvidedFonts } from "./odb-structure-DkfNyHGR.js";
|
|
3
3
|
import { Command, CommanderError, InvalidArgumentError } from "commander";
|
|
4
4
|
import { writeFile } from "node:fs/promises";
|
|
5
|
-
import { OdbNoEmbeddedDataSourceError, OdbTableNotFoundError, OdbTableNotSpecifiedError, OdbUnsupportedFormatError, OdmUnresolvedSectionError, PdfEncryptedError, PdfParseError, UnrecognizedDocumentSchemaError, buildDocxPackage, buildMarkdownText, buildOdgPackage, buildOdpPackage, buildOdsPackage, buildOdtPackage, buildPptxPackage, createLocalDocumentConverter, documentFromJson, documentPackageWithSchema, encodeMarkdownText, encodePackage, odbToCsv, odbToXlsx, odmToPdf, readOdbForms, readOdbReports, readOdbTables, readPdf, writePdf } from "documents.js";
|
|
5
|
+
import { HsqldbSqlEvaluationError, HsqldbSqlParseError, HsqldbSqlUnsupportedError, OdbNoEmbeddedDataSourceError, OdbReportNotSpecifiedError, OdbTableNotFoundError, OdbTableNotSpecifiedError, OdbUnsupportedFormatError, OdmUnresolvedSectionError, PdfEncryptedError, PdfParseError, UnrecognizedDocumentSchemaError, buildDocxPackage, buildMarkdownText, buildOdgPackage, buildOdpPackage, buildOdsPackage, buildOdtPackage, buildPptxPackage, convertWordprocessingToLayout, createFontMeasurer, createFontRegistry, createLocalDocumentConverter, decodePackage, documentFromJson, documentPackageWithSchema, encodeMarkdownText, encodePackage, evaluateSelect, extractSourceFonts, hsqldbCellDisplayText, layoutDocumentWithSchema, odbToCsv, odbToXlsx, odmToPdf, parseSelect, readDocxExtras, readOdbForms, readOdbInventory, readOdbReportContent, readOdbReports, readOdbTables, readPdf, writePdf } from "documents.js";
|
|
6
6
|
import { basename, dirname, extname, join } from "node:path";
|
|
7
|
-
import { decodePackage, encodePackage as encodePackage$1 } from "odf.js";
|
|
7
|
+
import { decodePackage as decodePackage$1, encodePackage as encodePackage$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) {
|
|
@@ -114,7 +114,8 @@ function pdfDiagnosticToDiagnostic(diagnostic) {
|
|
|
114
114
|
function mapErrorToExit(error, abortReason) {
|
|
115
115
|
if (abortReason === "interrupt") return 130;
|
|
116
116
|
if (abortReason === "timeout") return 124;
|
|
117
|
-
if (error instanceof OdmUnresolvedSectionError || error instanceof OdbTableNotSpecifiedError || error instanceof OdbTableNotFoundError || error instanceof OdbNoEmbeddedDataSourceError || error instanceof OdbUnsupportedFormatError) return 3;
|
|
117
|
+
if (error instanceof OdmUnresolvedSectionError || error instanceof OdbTableNotSpecifiedError || error instanceof OdbTableNotFoundError || error instanceof OdbNoEmbeddedDataSourceError || error instanceof OdbUnsupportedFormatError || error instanceof OdbReportNotSpecifiedError) return 3;
|
|
118
|
+
if (error instanceof HsqldbSqlUnsupportedError || error instanceof HsqldbSqlParseError || error instanceof HsqldbSqlEvaluationError) return 1;
|
|
118
119
|
if (error instanceof PdfEncryptedError || error instanceof PdfParseError) return 1;
|
|
119
120
|
return 1;
|
|
120
121
|
}
|
|
@@ -279,8 +280,100 @@ function registerConversionCommands(program) {
|
|
|
279
280
|
});
|
|
280
281
|
}
|
|
281
282
|
//#endregion
|
|
283
|
+
//#region src/commands/docx-extras.ts
|
|
284
|
+
async function runDocxExtras(input, options) {
|
|
285
|
+
const command = "docx-extras";
|
|
286
|
+
const { signal, getAbortReason } = createRuntimeSignal({});
|
|
287
|
+
try {
|
|
288
|
+
const inputBytes = await readInput(input, { signal });
|
|
289
|
+
const pkg = decodePackage(new Uint8Array(inputBytes));
|
|
290
|
+
const extras = readDocxExtras(pkg);
|
|
291
|
+
if (options.json) {
|
|
292
|
+
process.stdout.write(`${JSON.stringify(extras)}\n`);
|
|
293
|
+
return 0;
|
|
294
|
+
}
|
|
295
|
+
for (const line of formatDocxExtrasLines(extras)) process.stdout.write(`${line}\n`);
|
|
296
|
+
return 0;
|
|
297
|
+
} catch (error) {
|
|
298
|
+
process.stderr.write(`[${command}] ${formatError(error, false)}\n`);
|
|
299
|
+
return mapErrorToExit(error, getAbortReason());
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
function registerDocxExtrasCommand(program) {
|
|
303
|
+
program.command("docx-extras <input>").description("print a docx's own comments, footnotes, headers, footers, and numbering definitions -- data readDocxContent's ContentDocument cannot carry").option("--json", "emit the raw DocxExtras object as JSON instead of a human-readable report", false).action(async (input, options) => {
|
|
304
|
+
process.exitCode = await runDocxExtras(input, options);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
//#endregion
|
|
308
|
+
//#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
|
+
async function runFonts(input, options) {
|
|
331
|
+
const command = "fonts";
|
|
332
|
+
const { signal, getAbortReason } = createRuntimeSignal({});
|
|
333
|
+
try {
|
|
334
|
+
const format = inferFormatFromExtension(input);
|
|
335
|
+
if (format === void 0) {
|
|
336
|
+
process.stderr.write(`[${command}] cannot infer a document format from '${input}'; expected one of docx, pptx, odt, odp, ods, odg\n`);
|
|
337
|
+
return 2;
|
|
338
|
+
}
|
|
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
|
+
const inputBytes = await readInput(input, { signal });
|
|
344
|
+
const source = resolveFontSourcePackage(format, new Uint8Array(inputBytes));
|
|
345
|
+
const summaries = extractSourceFonts(source).map((face) => ({
|
|
346
|
+
family: face.family,
|
|
347
|
+
bold: face.bold,
|
|
348
|
+
italic: face.italic,
|
|
349
|
+
byteLength: face.bytes.length
|
|
350
|
+
}));
|
|
351
|
+
if (options.json) {
|
|
352
|
+
process.stdout.write(`${JSON.stringify(summaries)}\n`);
|
|
353
|
+
return 0;
|
|
354
|
+
}
|
|
355
|
+
if (summaries.length === 0) {
|
|
356
|
+
process.stdout.write("This document embeds no source fonts.\n");
|
|
357
|
+
return 0;
|
|
358
|
+
}
|
|
359
|
+
for (const face of summaries) {
|
|
360
|
+
const style = [face.bold ? "bold" : void 0, face.italic ? "italic" : void 0].filter((value) => value !== void 0).join(" ");
|
|
361
|
+
process.stdout.write(`${face.family}${style === "" ? "" : ` (${style})`} -- ${face.byteLength} bytes\n`);
|
|
362
|
+
}
|
|
363
|
+
return 0;
|
|
364
|
+
} catch (error) {
|
|
365
|
+
process.stderr.write(`${formatError(error, false)}\n`);
|
|
366
|
+
return mapErrorToExit(error, getAbortReason());
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
function registerFontsCommand(program) {
|
|
370
|
+
program.command("fonts <input>").description("list every source-embedded font face a docx/pptx/odt/odp/ods/odg document carries (family, weight/style, byte length)").option("--json", "emit the face list as a JSON array instead of a human-readable report", false).action(async (input, options) => {
|
|
371
|
+
process.exitCode = await runFonts(input, options);
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
//#endregion
|
|
282
375
|
//#region src/commands/formats.ts
|
|
283
|
-
const COMMANDS_NOT_LISTED = "odm-to-pdf, odb-to-csv, odb-to-xlsx, odb-tables, odb-forms, odb-reports, pdf-inspect, from-package";
|
|
376
|
+
const COMMANDS_NOT_LISTED = "odm-to-pdf, odb-to-csv, odb-to-xlsx, odb-tables, odb-forms, odb-reports, pdf-inspect, from-package, fonts, docx-extras";
|
|
284
377
|
function registerFormatsCommand(program) {
|
|
285
378
|
program.command("formats").description("list every source -> target conversion this CLI supports via a <source>-to-<target> command").option("--json", "emit the conversion list as a JSON array instead of a human-readable table", false).action((options) => {
|
|
286
379
|
const { conversions } = createLocalDocumentConverter();
|
|
@@ -373,6 +466,27 @@ function registerFromPackageCommand(program) {
|
|
|
373
466
|
});
|
|
374
467
|
}
|
|
375
468
|
//#endregion
|
|
469
|
+
//#region src/sql-result-format.ts
|
|
470
|
+
const COLUMN_GAP = " ";
|
|
471
|
+
function columnWidths(columns, cells) {
|
|
472
|
+
return columns.map((column, index) => {
|
|
473
|
+
const cellWidths = cells.map((row) => row[index]?.length ?? 0);
|
|
474
|
+
return Math.max(column.length, ...cellWidths);
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
function formatRow(values, widths) {
|
|
478
|
+
return values.map((value, index) => value.padEnd(widths[index] ?? value.length)).join(COLUMN_GAP).trimEnd();
|
|
479
|
+
}
|
|
480
|
+
function formatSqlResultSetTable(result) {
|
|
481
|
+
const { columns, rows } = result;
|
|
482
|
+
const cells = rows.map((row) => row.map((value) => hsqldbCellDisplayText(value)));
|
|
483
|
+
const widths = columnWidths(columns, cells);
|
|
484
|
+
const lines = [formatRow(columns, widths), formatRow(widths.map((width) => "-".repeat(width)), widths)];
|
|
485
|
+
for (const row of cells) lines.push(formatRow(row, widths));
|
|
486
|
+
lines.push(`${rows.length} row${rows.length === 1 ? "" : "s"}`);
|
|
487
|
+
return lines;
|
|
488
|
+
}
|
|
489
|
+
//#endregion
|
|
376
490
|
//#region src/commands/odb.ts
|
|
377
491
|
function reportOdbError(command, error, verbose, abortReason) {
|
|
378
492
|
if (error instanceof OdbNoEmbeddedDataSourceError || error instanceof OdbUnsupportedFormatError) {
|
|
@@ -389,6 +503,13 @@ function reportOdbCsvError(command, error, verbose, abortReason) {
|
|
|
389
503
|
}
|
|
390
504
|
return reportOdbError(command, error, verbose, abortReason);
|
|
391
505
|
}
|
|
506
|
+
function reportOdbReportError(command, error, verbose, abortReason) {
|
|
507
|
+
if (error instanceof OdbReportNotSpecifiedError) {
|
|
508
|
+
process.stderr.write(`[${command}] ${error.message}\nrun 'odb-reports' first to see the available reports\n`);
|
|
509
|
+
return mapErrorToExit(error, abortReason);
|
|
510
|
+
}
|
|
511
|
+
return reportOdbError(command, error, verbose, abortReason);
|
|
512
|
+
}
|
|
392
513
|
function resolveDefaultCsvOutputPath(inputPath) {
|
|
393
514
|
const directory = dirname(inputPath);
|
|
394
515
|
const stem = basename(inputPath, extname(inputPath));
|
|
@@ -454,7 +575,7 @@ async function runOdbTables(input, options) {
|
|
|
454
575
|
const { signal, getAbortReason } = createRuntimeSignal({});
|
|
455
576
|
try {
|
|
456
577
|
const inputBytes = await readInput(input, { signal });
|
|
457
|
-
const pkg = decodePackage(new Uint8Array(inputBytes));
|
|
578
|
+
const pkg = decodePackage$1(new Uint8Array(inputBytes));
|
|
458
579
|
const tables = readOdbTables(pkg);
|
|
459
580
|
if (options.json) {
|
|
460
581
|
const summary = tables.map((table) => ({
|
|
@@ -474,12 +595,54 @@ async function runOdbTables(input, options) {
|
|
|
474
595
|
return reportOdbError(command, error, false, getAbortReason());
|
|
475
596
|
}
|
|
476
597
|
}
|
|
598
|
+
function resolveQuerySql(pkg, options) {
|
|
599
|
+
if (options.sql !== void 0) return { sql: options.sql };
|
|
600
|
+
const queryName = options.query;
|
|
601
|
+
if (queryName === void 0) return { errorMessage: "pass --sql <text> or --query <savedName>" };
|
|
602
|
+
const inventory = readOdbInventory(pkg);
|
|
603
|
+
const saved = inventory.queries.find((candidate) => candidate.name === queryName);
|
|
604
|
+
if (saved === void 0) {
|
|
605
|
+
const available = inventory.queries.map((candidate) => candidate.name);
|
|
606
|
+
return { errorMessage: `this .odb declares no saved query named '${queryName}'${available.length === 0 ? "" : ` -- available: ${available.join(", ")}`}` };
|
|
607
|
+
}
|
|
608
|
+
return { sql: saved.command };
|
|
609
|
+
}
|
|
610
|
+
async function runOdbQuery(input, options) {
|
|
611
|
+
const command = "odb-query";
|
|
612
|
+
if (options.sql !== void 0 && options.query !== void 0) {
|
|
613
|
+
process.stderr.write(`[${command}] pass --sql or --query, not both\n`);
|
|
614
|
+
return 2;
|
|
615
|
+
}
|
|
616
|
+
if (options.sql === void 0 && options.query === void 0) {
|
|
617
|
+
process.stderr.write(`[${command}] pass --sql <text> or --query <savedName>\n`);
|
|
618
|
+
return 2;
|
|
619
|
+
}
|
|
620
|
+
const { signal, getAbortReason } = createRuntimeSignal({});
|
|
621
|
+
try {
|
|
622
|
+
const inputBytes = await readInput(input, { signal });
|
|
623
|
+
const pkg = decodePackage$1(new Uint8Array(inputBytes));
|
|
624
|
+
const resolved = resolveQuerySql(pkg, options);
|
|
625
|
+
if ("errorMessage" in resolved) {
|
|
626
|
+
process.stderr.write(`[${command}] ${resolved.errorMessage}\n`);
|
|
627
|
+
return 2;
|
|
628
|
+
}
|
|
629
|
+
const result = evaluateSelect(parseSelect(resolved.sql), readOdbTables(pkg));
|
|
630
|
+
if (options.json) {
|
|
631
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
632
|
+
return 0;
|
|
633
|
+
}
|
|
634
|
+
for (const line of formatSqlResultSetTable(result)) process.stdout.write(`${line}\n`);
|
|
635
|
+
return 0;
|
|
636
|
+
} catch (error) {
|
|
637
|
+
return reportOdbError(command, error, false, getAbortReason());
|
|
638
|
+
}
|
|
639
|
+
}
|
|
477
640
|
async function runOdbForms(input, options) {
|
|
478
641
|
const command = "odb-forms";
|
|
479
642
|
const { signal, getAbortReason } = createRuntimeSignal({});
|
|
480
643
|
try {
|
|
481
644
|
const inputBytes = await readInput(input, { signal });
|
|
482
|
-
const forms = readOdbForms(decodePackage(new Uint8Array(inputBytes)));
|
|
645
|
+
const forms = readOdbForms(decodePackage$1(new Uint8Array(inputBytes)));
|
|
483
646
|
if (options.json) {
|
|
484
647
|
process.stdout.write(`${JSON.stringify(forms.map((form) => odbFormSummary(form)))}\n`);
|
|
485
648
|
return 0;
|
|
@@ -502,7 +665,7 @@ async function runOdbReports(input, options) {
|
|
|
502
665
|
const { signal, getAbortReason } = createRuntimeSignal({});
|
|
503
666
|
try {
|
|
504
667
|
const inputBytes = await readInput(input, { signal });
|
|
505
|
-
const reports = readOdbReports(decodePackage(new Uint8Array(inputBytes)));
|
|
668
|
+
const reports = readOdbReports(decodePackage$1(new Uint8Array(inputBytes)));
|
|
506
669
|
if (options.json) {
|
|
507
670
|
process.stdout.write(`${JSON.stringify(reports)}\n`);
|
|
508
671
|
return 0;
|
|
@@ -520,6 +683,93 @@ async function runOdbReports(input, options) {
|
|
|
520
683
|
return reportOdbError(command, error, false, getAbortReason());
|
|
521
684
|
}
|
|
522
685
|
}
|
|
686
|
+
const ODB_REPORT_TARGET_FORMATS = {
|
|
687
|
+
docx: true,
|
|
688
|
+
odt: true,
|
|
689
|
+
pdf: true
|
|
690
|
+
};
|
|
691
|
+
function isOdbReportTargetFormat(format) {
|
|
692
|
+
return format in ODB_REPORT_TARGET_FORMATS;
|
|
693
|
+
}
|
|
694
|
+
function renderOdbReportBytes(content, target, options) {
|
|
695
|
+
if (target === "docx") return encodePackage(buildDocxPackage(content));
|
|
696
|
+
if (target === "odt") return encodePackage$1(buildOdtPackage(content));
|
|
697
|
+
if (content.kind !== "wordprocessing") throw new Error("readOdbReportContent returned a non-wordprocessing ContentDocument");
|
|
698
|
+
const fonts = createFontRegistry({
|
|
699
|
+
fonts: options.fonts,
|
|
700
|
+
onSubstitution: (substitution) => {
|
|
701
|
+
if (options.reportFontSubstitution !== void 0) {
|
|
702
|
+
options.reportFontSubstitution(substitution);
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
options.onDiagnosticCounted();
|
|
706
|
+
options.reporter.report(fontSubstitutionToDiagnostic(substitution));
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
const { document: layout, formulas } = convertWordprocessingToLayout(content, { measurer: createFontMeasurer(fonts) });
|
|
710
|
+
return writePdf(layout, {
|
|
711
|
+
signal: options.signal,
|
|
712
|
+
onSubstitution: (substitution, context) => {
|
|
713
|
+
options.onDiagnosticCounted();
|
|
714
|
+
options.reporter.report(substitutionToDiagnostic(substitution, context.pageIndex));
|
|
715
|
+
},
|
|
716
|
+
formulas,
|
|
717
|
+
fonts
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
async function runOdbRenderReport(input, output, options) {
|
|
721
|
+
const command = "odb-render-report";
|
|
722
|
+
if (output !== void 0 && options.out !== void 0 && output !== options.out) {
|
|
723
|
+
process.stderr.write(`[${command}] conflicting output destinations: positional '${output}' and --out '${options.out}'\n`);
|
|
724
|
+
return 2;
|
|
725
|
+
}
|
|
726
|
+
const target = resolveTargetFormat(output, options.out, options.to);
|
|
727
|
+
if ("errorMessage" in target) {
|
|
728
|
+
process.stderr.write(`[${command}] ${target.errorMessage}\n`);
|
|
729
|
+
return 2;
|
|
730
|
+
}
|
|
731
|
+
if (!isOdbReportTargetFormat(target.format)) {
|
|
732
|
+
process.stderr.write(`[${command}] '${target.format}' is not a supported report render target; expected one of docx, odt, pdf\n`);
|
|
733
|
+
return 2;
|
|
734
|
+
}
|
|
735
|
+
const targetFormat = target.format;
|
|
736
|
+
const resolvedOutput = output ?? options.out ?? (input === "-" ? "-" : resolveDefaultOutputPath(input, targetFormat));
|
|
737
|
+
const { signal, getAbortReason } = createRuntimeSignal({ timeoutMs: options.timeout });
|
|
738
|
+
const reporter = createDiagnosticReporter({
|
|
739
|
+
json: options.json,
|
|
740
|
+
quiet: options.quiet,
|
|
741
|
+
command
|
|
742
|
+
});
|
|
743
|
+
let diagnosticCount = 0;
|
|
744
|
+
const reportFontSubstitution = options.reportFontSubstitutions === true ? createFontSubstitutionReporter({
|
|
745
|
+
json: options.json,
|
|
746
|
+
quiet: options.quiet,
|
|
747
|
+
command
|
|
748
|
+
}) : void 0;
|
|
749
|
+
try {
|
|
750
|
+
const inputBytes = await readInput(input, { signal });
|
|
751
|
+
const fonts = await loadProvidedFonts(options.fontFile ?? [], { signal });
|
|
752
|
+
const pkg = decodePackage$1(new Uint8Array(inputBytes));
|
|
753
|
+
const bytes = renderOdbReportBytes(readOdbReportContent(pkg, { report: options.report }), targetFormat, {
|
|
754
|
+
fonts,
|
|
755
|
+
signal,
|
|
756
|
+
reporter,
|
|
757
|
+
reportFontSubstitution,
|
|
758
|
+
onDiagnosticCounted: () => {
|
|
759
|
+
diagnosticCount += 1;
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
await writeOutput(resolvedOutput, bytes);
|
|
763
|
+
reporter.summarize({
|
|
764
|
+
output: resolvedOutput,
|
|
765
|
+
bytes: bytes.byteLength,
|
|
766
|
+
diagnosticCount
|
|
767
|
+
});
|
|
768
|
+
return 0;
|
|
769
|
+
} catch (error) {
|
|
770
|
+
return reportOdbReportError(command, error, options.verbose, getAbortReason());
|
|
771
|
+
}
|
|
772
|
+
}
|
|
523
773
|
function registerOdbToXlsxCommand(program) {
|
|
524
774
|
const command = program.command("odb-to-xlsx <input> [output]").description("extract every table an embedded .odb database declares into one xlsx workbook, one sheet per table");
|
|
525
775
|
addOutOption(command);
|
|
@@ -558,12 +808,33 @@ function registerOdbReportsCommand(program) {
|
|
|
558
808
|
process.exitCode = await runOdbReports(input, options);
|
|
559
809
|
});
|
|
560
810
|
}
|
|
811
|
+
function registerOdbQueryCommand(program) {
|
|
812
|
+
program.command("odb-query <input>").description("run a bounded SELECT over an embedded .odb database's own extracted tables, given directly or by naming one of its saved queries").option("--sql <text>", "the SELECT statement to run -- mutually exclusive with --query").option("--query <savedName>", "the name of one of the .odb's own saved queries to run -- mutually exclusive with --sql").option("--json", "emit the result set as JSON ({ columns, rows }) instead of a plain-text table", false).action(async (input, options) => {
|
|
813
|
+
process.exitCode = await runOdbQuery(input, options);
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
function registerOdbRenderReportCommand(program) {
|
|
817
|
+
const command = program.command("odb-render-report <input> [output]").description("render one of an .odb's own reports -- its query resolved, its rpt: formulas evaluated, its bands laid out -- to docx, odt, or pdf");
|
|
818
|
+
addOutOption(command);
|
|
819
|
+
addTimeoutOption(command);
|
|
820
|
+
addJsonOption(command);
|
|
821
|
+
addQuietOption(command);
|
|
822
|
+
addVerboseOption(command);
|
|
823
|
+
addFontOptions(command);
|
|
824
|
+
command.option("--report <name>", "the report to render -- required only when the .odb declares more than one report");
|
|
825
|
+
command.option("--to <format>", "target format when it cannot be inferred from the output path (docx, odt, pdf)");
|
|
826
|
+
command.action(async (input, output, options) => {
|
|
827
|
+
process.exitCode = await runOdbRenderReport(input, output, options);
|
|
828
|
+
});
|
|
829
|
+
}
|
|
561
830
|
function registerOdbCommands(program) {
|
|
562
831
|
registerOdbToXlsxCommand(program);
|
|
563
832
|
registerOdbToCsvCommand(program);
|
|
564
833
|
registerOdbTablesCommand(program);
|
|
565
834
|
registerOdbFormsCommand(program);
|
|
566
835
|
registerOdbReportsCommand(program);
|
|
836
|
+
registerOdbQueryCommand(program);
|
|
837
|
+
registerOdbRenderReportCommand(program);
|
|
567
838
|
}
|
|
568
839
|
//#endregion
|
|
569
840
|
//#region src/commands/odm.ts
|
|
@@ -689,7 +960,7 @@ async function runPdfInspect(input, options) {
|
|
|
689
960
|
}
|
|
690
961
|
});
|
|
691
962
|
if (options.full) {
|
|
692
|
-
process.stdout.write(`${JSON.stringify(layout, void 0, 2)}\n`);
|
|
963
|
+
process.stdout.write(`${JSON.stringify(layoutDocumentWithSchema(layout), void 0, 2)}\n`);
|
|
693
964
|
return 0;
|
|
694
965
|
}
|
|
695
966
|
const imagesByFormat = countImagesByFormat(layout.images);
|
|
@@ -744,7 +1015,7 @@ function registerPdfInspectCommand(program) {
|
|
|
744
1015
|
}
|
|
745
1016
|
//#endregion
|
|
746
1017
|
//#region package.json
|
|
747
|
-
var version = "1.
|
|
1018
|
+
var version = "1.4.0";
|
|
748
1019
|
//#endregion
|
|
749
1020
|
//#region src/program.ts
|
|
750
1021
|
function createProgram() {
|
|
@@ -761,13 +1032,15 @@ function createProgram() {
|
|
|
761
1032
|
registerOdmCommand(program);
|
|
762
1033
|
registerOdbCommands(program);
|
|
763
1034
|
registerPdfInspectCommand(program);
|
|
1035
|
+
registerFontsCommand(program);
|
|
1036
|
+
registerDocxExtrasCommand(program);
|
|
764
1037
|
return program;
|
|
765
1038
|
}
|
|
766
1039
|
//#endregion
|
|
767
1040
|
//#region src/cli.ts
|
|
768
1041
|
async function launchTui(startPath, signal) {
|
|
769
1042
|
try {
|
|
770
|
-
const { runTui } = await import("./tui-
|
|
1043
|
+
const { runTui } = await import("./tui-CQCLalYe.js");
|
|
771
1044
|
await runTui({
|
|
772
1045
|
startPath,
|
|
773
1046
|
signal
|