@docmana/sdk 0.2.1 → 0.3.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/CHANGELOG.md +11 -0
- package/dist/cli.mjs +365 -59
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.cts +237 -12
- package/dist/index.d.ts +237 -12
- package/dist/index.js +162 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +162 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
- Relocated mapper logic and tests to `src/mappers/`.
|
|
5
|
+
- Renamed SDK models to `DocmanaX` and API models to `DocmanaApiX` to distinguish raw backend types from clean public SDK types.
|
|
6
|
+
- Pluralized `classification` results into a `classifications` key-value record on document results.
|
|
7
|
+
- Nested dynamic extraction fields inside a dedicated `data` record on node results to prevent property name collisions.
|
|
8
|
+
- Restructured node result interfaces to remove `score` and `feedback` from `DocmanaExtractionResult` and `DocmanaMetadataExtractionResult` (via new `DocmanaScoreNodeResult` interface).
|
|
9
|
+
- Excluded internal fields `result` and `documentType` from mapped SDK results.
|
|
10
|
+
|
|
11
|
+
## 0.2.2
|
|
12
|
+
- Fix `package-lock.json`.
|
|
13
|
+
|
|
3
14
|
## 0.2.1
|
|
4
15
|
- 400 responses now throw `DocmanaRequestError` (was `DocmanaAuthError`); add `Incompleted` to `ExecutionStatus`.
|
|
5
16
|
|
package/dist/cli.mjs
CHANGED
|
@@ -44,9 +44,11 @@ var DocmanaRequestError = class extends DocmanaError {
|
|
|
44
44
|
};
|
|
45
45
|
var DocmanaExecutionError = class extends DocmanaError {
|
|
46
46
|
errors;
|
|
47
|
-
|
|
47
|
+
result;
|
|
48
|
+
constructor(message, errors = [], result) {
|
|
48
49
|
super(message, { code: "execution_failed" });
|
|
49
50
|
this.errors = errors;
|
|
51
|
+
this.result = result;
|
|
50
52
|
}
|
|
51
53
|
};
|
|
52
54
|
var DocmanaTimeoutError = class extends DocmanaError {
|
|
@@ -356,6 +358,156 @@ async function pollUntilTerminal(opts) {
|
|
|
356
358
|
}
|
|
357
359
|
}
|
|
358
360
|
|
|
361
|
+
// src/mappers/mapper.ts
|
|
362
|
+
function extractNodeFields(rawNode, targetLanguage) {
|
|
363
|
+
const metadataFields = /* @__PURE__ */ new Set([
|
|
364
|
+
"node_id",
|
|
365
|
+
"node_name",
|
|
366
|
+
"node_type",
|
|
367
|
+
"feature_name",
|
|
368
|
+
"running_time",
|
|
369
|
+
"status",
|
|
370
|
+
"score",
|
|
371
|
+
"feedback",
|
|
372
|
+
"translations",
|
|
373
|
+
"tokens",
|
|
374
|
+
"input_tokens",
|
|
375
|
+
"output_tokens",
|
|
376
|
+
"errors",
|
|
377
|
+
"mana",
|
|
378
|
+
"model",
|
|
379
|
+
"tool_calls",
|
|
380
|
+
"prompt_id",
|
|
381
|
+
"prompt",
|
|
382
|
+
"prompt_name",
|
|
383
|
+
"label",
|
|
384
|
+
"scoreDescription",
|
|
385
|
+
"score_description",
|
|
386
|
+
"result",
|
|
387
|
+
"documentType"
|
|
388
|
+
]);
|
|
389
|
+
let sourceObj = rawNode;
|
|
390
|
+
if (targetLanguage) {
|
|
391
|
+
const translations = rawNode.translations;
|
|
392
|
+
if (!translations || !translations[targetLanguage]) {
|
|
393
|
+
throw new DocmanaError(
|
|
394
|
+
`Translation for language '${targetLanguage}' is missing on node '${rawNode.node_name || rawNode.node_id}'`,
|
|
395
|
+
{ code: "translation_missing", status: 400 }
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
sourceObj = translations[targetLanguage];
|
|
399
|
+
}
|
|
400
|
+
const dynamicFields = {};
|
|
401
|
+
for (const [key, value] of Object.entries(sourceObj)) {
|
|
402
|
+
if (!metadataFields.has(key)) {
|
|
403
|
+
dynamicFields[key] = value;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
const sdkNode = {
|
|
407
|
+
status: rawNode.status || "Unknown"
|
|
408
|
+
};
|
|
409
|
+
if (rawNode.errors && rawNode.errors.length > 0) {
|
|
410
|
+
sdkNode.errors = rawNode.errors;
|
|
411
|
+
}
|
|
412
|
+
const nodeType = rawNode.node_type || "";
|
|
413
|
+
const isScoreNode = /^(Validation|Classification|CrossValidation|Conclusion)$/i.test(nodeType);
|
|
414
|
+
if (isScoreNode) {
|
|
415
|
+
if (rawNode.score !== void 0 && rawNode.score !== null) {
|
|
416
|
+
sdkNode.score = rawNode.score;
|
|
417
|
+
}
|
|
418
|
+
if (rawNode.feedback !== void 0 && rawNode.feedback !== null) {
|
|
419
|
+
sdkNode.feedback = rawNode.feedback;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (Object.keys(dynamicFields).length > 0) {
|
|
423
|
+
sdkNode.data = dynamicFields;
|
|
424
|
+
}
|
|
425
|
+
return sdkNode;
|
|
426
|
+
}
|
|
427
|
+
function mapExecutionResult(raw, targetLanguage) {
|
|
428
|
+
const sdkResult = {
|
|
429
|
+
status: raw.status || "Unknown",
|
|
430
|
+
executionId: String(raw.execution_id || raw.executionResultId || raw.execution_result_id || ""),
|
|
431
|
+
documents: {
|
|
432
|
+
mappings: []
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
if (raw.errors && raw.errors.length > 0) {
|
|
436
|
+
sdkResult.errors = raw.errors;
|
|
437
|
+
}
|
|
438
|
+
const results = raw.results || [];
|
|
439
|
+
for (const item of results) {
|
|
440
|
+
const isDocSpecific = !!item.document;
|
|
441
|
+
if (isDocSpecific && item.document) {
|
|
442
|
+
const docReq = item.document;
|
|
443
|
+
const docKey = docReq.doc_key || "unknown_doc";
|
|
444
|
+
const docName = docReq.name || "";
|
|
445
|
+
sdkResult.documents.mappings.push({
|
|
446
|
+
name: docName,
|
|
447
|
+
reference: docKey
|
|
448
|
+
});
|
|
449
|
+
const docResult = {
|
|
450
|
+
status: item.status || docReq.status || "Unknown",
|
|
451
|
+
extractions: {},
|
|
452
|
+
validations: {}
|
|
453
|
+
};
|
|
454
|
+
const nodeResults = item.node_results || [];
|
|
455
|
+
for (const node of nodeResults) {
|
|
456
|
+
const nodeType = node.node_type || "";
|
|
457
|
+
const nodeName = node.node_name || node.node_id || "unknown_node";
|
|
458
|
+
if (/^Classification$/i.test(nodeType)) {
|
|
459
|
+
const mappedNode = extractNodeFields(node, targetLanguage);
|
|
460
|
+
if (!docResult.classifications) {
|
|
461
|
+
docResult.classifications = {};
|
|
462
|
+
}
|
|
463
|
+
docResult.classifications[nodeName] = mappedNode;
|
|
464
|
+
} else if (/^MetadataExtraction$/i.test(nodeType)) {
|
|
465
|
+
docResult.metadataExtraction = extractNodeFields(node, targetLanguage);
|
|
466
|
+
} else if (/^Extraction$/i.test(nodeType)) {
|
|
467
|
+
if (docResult.extractions) {
|
|
468
|
+
docResult.extractions[nodeName] = extractNodeFields(node, targetLanguage);
|
|
469
|
+
}
|
|
470
|
+
} else if (/^Validation$/i.test(nodeType)) {
|
|
471
|
+
if (docResult.validations) {
|
|
472
|
+
docResult.validations[nodeName] = extractNodeFields(node, targetLanguage);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
if (docResult.extractions && Object.keys(docResult.extractions).length === 0) {
|
|
477
|
+
delete docResult.extractions;
|
|
478
|
+
}
|
|
479
|
+
if (docResult.validations && Object.keys(docResult.validations).length === 0) {
|
|
480
|
+
delete docResult.validations;
|
|
481
|
+
}
|
|
482
|
+
sdkResult.documents[docKey] = docResult;
|
|
483
|
+
} else {
|
|
484
|
+
const nodeResults = item.node_results || [];
|
|
485
|
+
for (const node of nodeResults) {
|
|
486
|
+
const nodeType = node.node_type || "";
|
|
487
|
+
const nodeName = node.node_name || node.node_id || "unknown_node";
|
|
488
|
+
if (/^CrossValidation$/i.test(nodeType)) {
|
|
489
|
+
if (!sdkResult.crossValidations) {
|
|
490
|
+
sdkResult.crossValidations = {};
|
|
491
|
+
}
|
|
492
|
+
sdkResult.crossValidations[nodeName] = extractNodeFields(
|
|
493
|
+
node,
|
|
494
|
+
targetLanguage
|
|
495
|
+
);
|
|
496
|
+
} else if (/^(Conclusion|Finish)$/i.test(nodeType)) {
|
|
497
|
+
if (!sdkResult.conclusions) {
|
|
498
|
+
sdkResult.conclusions = {};
|
|
499
|
+
}
|
|
500
|
+
sdkResult.conclusions[nodeName] = extractNodeFields(
|
|
501
|
+
node,
|
|
502
|
+
targetLanguage
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return sdkResult;
|
|
509
|
+
}
|
|
510
|
+
|
|
359
511
|
// src/client.ts
|
|
360
512
|
var Docmana = class {
|
|
361
513
|
config;
|
|
@@ -392,8 +544,9 @@ var Docmana = class {
|
|
|
392
544
|
async getStatus(executionResultId, signal) {
|
|
393
545
|
return getStatus(this.http, executionResultId, signal);
|
|
394
546
|
}
|
|
395
|
-
async getResult(executionResultId, signal) {
|
|
396
|
-
|
|
547
|
+
async getResult(executionResultId, signal, language) {
|
|
548
|
+
const rawResult = await getResult(this.http, executionResultId, signal);
|
|
549
|
+
return mapExecutionResult(rawResult, language);
|
|
397
550
|
}
|
|
398
551
|
async runFlow(flowId, input) {
|
|
399
552
|
const { executionResultId } = await this.runFlowAsync(flowId, input);
|
|
@@ -403,9 +556,13 @@ var Docmana = class {
|
|
|
403
556
|
timeoutMs: input.timeoutMs ?? this.config.timeoutMs,
|
|
404
557
|
signal: input.signal
|
|
405
558
|
});
|
|
406
|
-
const result = await this.getResult(executionResultId, input.signal);
|
|
559
|
+
const result = await this.getResult(executionResultId, input.signal, input.language);
|
|
407
560
|
if (result.status === "Failed") {
|
|
408
|
-
throw new DocmanaExecutionError(
|
|
561
|
+
throw new DocmanaExecutionError(
|
|
562
|
+
`Flow ${flowId} execution failed`,
|
|
563
|
+
result.errors ?? [],
|
|
564
|
+
result
|
|
565
|
+
);
|
|
409
566
|
}
|
|
410
567
|
return result;
|
|
411
568
|
}
|
|
@@ -418,6 +575,15 @@ var CliUsageError = class extends Error {
|
|
|
418
575
|
this.name = "CliUsageError";
|
|
419
576
|
}
|
|
420
577
|
};
|
|
578
|
+
var CliSilentError = class extends Error {
|
|
579
|
+
exitCode;
|
|
580
|
+
constructor(exitCode = 1) {
|
|
581
|
+
super();
|
|
582
|
+
this.name = "CliSilentError";
|
|
583
|
+
this.exitCode = exitCode;
|
|
584
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
585
|
+
}
|
|
586
|
+
};
|
|
421
587
|
var HELP = {
|
|
422
588
|
root: "Run Docmana document-analysis flows.",
|
|
423
589
|
flow: "Manage and run Docmana flows.",
|
|
@@ -441,6 +607,9 @@ async function runCli(argv = process.argv.slice(2), env = process.env, io = {
|
|
|
441
607
|
await program.parseAsync(argv, { from: "user" });
|
|
442
608
|
return 0;
|
|
443
609
|
} catch (err) {
|
|
610
|
+
if (err instanceof CliSilentError) {
|
|
611
|
+
return err.exitCode;
|
|
612
|
+
}
|
|
444
613
|
if (err instanceof CliUsageError) {
|
|
445
614
|
io.stderr(`Error: ${err.message}
|
|
446
615
|
`);
|
|
@@ -467,7 +636,7 @@ function buildProgram(env, io, clientFactory, deps) {
|
|
|
467
636
|
const flow = program.command("flow").description(HELP.flow).action(() => {
|
|
468
637
|
io.stdout(flow.helpInformation());
|
|
469
638
|
});
|
|
470
|
-
flow.command("run").description(HELP.run).argument("<flow-id>", "Docmana flow id").requiredOption("--files <csv>", "Comma-separated file paths to upload").option("--client-id <id>", "OAuth2 client id; defaults to DOCMANA_CLIENT_ID").option("--client-secret <secret>", "OAuth2 client secret; defaults to DOCMANA_CLIENT_SECRET").option("--api-url <url>", "Docmana API base URL; defaults to DOCMANA_API_URL").option("--token-url <url>", "OAuth2 token endpoint; defaults to DOCMANA_TOKEN_URL").option("--scope <scope>", "OAuth2 scope; defaults to DOCMANA_SCOPE").option("--organisation <id>", "Docmana organisation id; defaults to DOCMANA_ORGANISATION").option("--config <path>", `Config file path; defaults to ./${DEFAULT_CONFIG_FILE}`).option("--token-cache <path>", `Token cache path; defaults to ./${DEFAULT_TOKEN_CACHE_FILE}`).option("--json", "Print the raw JSON result").action(async (flowId, options) => {
|
|
639
|
+
flow.command("run").description(HELP.run).argument("<flow-id>", "Docmana flow id").requiredOption("--files <csv>", "Comma-separated file paths to upload").option("--client-id <id>", "OAuth2 client id; defaults to DOCMANA_CLIENT_ID").option("--client-secret <secret>", "OAuth2 client secret; defaults to DOCMANA_CLIENT_SECRET").option("--api-url <url>", "Docmana API base URL; defaults to DOCMANA_API_URL").option("--token-url <url>", "OAuth2 token endpoint; defaults to DOCMANA_TOKEN_URL").option("--scope <scope>", "OAuth2 scope; defaults to DOCMANA_SCOPE").option("--organisation <id>", "Docmana organisation id; defaults to DOCMANA_ORGANISATION").option("--config <path>", `Config file path; defaults to ./${DEFAULT_CONFIG_FILE}`).option("--token-cache <path>", `Token cache path; defaults to ./${DEFAULT_TOKEN_CACHE_FILE}`).option("--json", "Print the raw JSON result").option("--language <lang>", "Translate output to specified language").action(async (flowId, options) => {
|
|
471
640
|
await runFlowCommand(flowId, options, env, io, clientFactory, deps);
|
|
472
641
|
});
|
|
473
642
|
const config = program.command("config").description(HELP.config).action(() => {
|
|
@@ -479,50 +648,77 @@ function buildProgram(env, io, clientFactory, deps) {
|
|
|
479
648
|
return program;
|
|
480
649
|
}
|
|
481
650
|
async function runFlowCommand(flowId, options, env, io, clientFactory, deps) {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
651
|
+
try {
|
|
652
|
+
const files = parseFiles(options.files);
|
|
653
|
+
const cliConfig = await loadCliConfig(options.config, getCwd(deps), Boolean(options.config));
|
|
654
|
+
const clientId = firstNonEmpty(options.clientId, env.DOCMANA_CLIENT_ID, cliConfig.clientId);
|
|
655
|
+
const clientSecret = firstNonEmpty(
|
|
656
|
+
options.clientSecret,
|
|
657
|
+
env.DOCMANA_CLIENT_SECRET,
|
|
658
|
+
cliConfig.clientSecret
|
|
659
|
+
);
|
|
660
|
+
const organisation = firstNonEmpty(
|
|
661
|
+
options.organisation,
|
|
662
|
+
env.DOCMANA_ORGANISATION,
|
|
663
|
+
cliConfig.organisation
|
|
664
|
+
);
|
|
665
|
+
const apiBaseUrl = firstNonEmpty(options.apiUrl, env.DOCMANA_API_URL, cliConfig.apiBaseUrl);
|
|
666
|
+
const tokenEndpoint = firstNonEmpty(
|
|
667
|
+
options.tokenUrl,
|
|
668
|
+
env.DOCMANA_TOKEN_URL,
|
|
669
|
+
cliConfig.tokenEndpoint
|
|
670
|
+
);
|
|
671
|
+
const scope = firstNonEmpty(options.scope, env.DOCMANA_SCOPE, cliConfig.scope);
|
|
672
|
+
if (!clientId)
|
|
673
|
+
throw new CliUsageError("Missing client id. Use --client-id or DOCMANA_CLIENT_ID.");
|
|
674
|
+
if (!clientSecret) {
|
|
675
|
+
throw new CliUsageError(
|
|
676
|
+
"Missing client secret. Use --client-secret or DOCMANA_CLIENT_SECRET."
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
if (!organisation) {
|
|
680
|
+
throw new CliUsageError("Missing organisation. Use --organisation or DOCMANA_ORGANISATION.");
|
|
681
|
+
}
|
|
682
|
+
const client = clientFactory({
|
|
683
|
+
clientId,
|
|
684
|
+
clientSecret,
|
|
685
|
+
apiBaseUrl,
|
|
686
|
+
tokenEndpoint,
|
|
687
|
+
scope,
|
|
688
|
+
headers: { "X-Selected-Organization": organisation },
|
|
689
|
+
tokenCache: createFileTokenCache(resolveTokenCachePath(options.tokenCache, getCwd(deps)))
|
|
690
|
+
});
|
|
691
|
+
const result = await client.runFlow(flowId, {
|
|
692
|
+
files: files.map((path) => ({ path })),
|
|
693
|
+
language: options.language
|
|
694
|
+
});
|
|
695
|
+
if (options.json) {
|
|
696
|
+
io.stdout(`${JSON.stringify(result, null, 2)}
|
|
697
|
+
`);
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
io.stdout(formatHumanResult(result));
|
|
701
|
+
} catch (err) {
|
|
702
|
+
if (options.json) {
|
|
703
|
+
if (err instanceof DocmanaExecutionError && err.result) {
|
|
704
|
+
io.stdout(`${JSON.stringify(err.result, null, 2)}
|
|
705
|
+
`);
|
|
706
|
+
} else {
|
|
707
|
+
const errorPayload = {
|
|
708
|
+
error: err instanceof Error ? err.message : String(err)
|
|
709
|
+
};
|
|
710
|
+
if (err instanceof DocmanaError) {
|
|
711
|
+
errorPayload.code = err.code;
|
|
712
|
+
if (err.status !== void 0) errorPayload.status = err.status;
|
|
713
|
+
if (err.requestId !== void 0) errorPayload.requestId = err.requestId;
|
|
714
|
+
}
|
|
715
|
+
io.stdout(`${JSON.stringify(errorPayload, null, 2)}
|
|
522
716
|
`);
|
|
523
|
-
|
|
717
|
+
}
|
|
718
|
+
throw new CliSilentError(err instanceof CliUsageError ? 2 : 1);
|
|
719
|
+
}
|
|
720
|
+
throw err;
|
|
524
721
|
}
|
|
525
|
-
io.stdout(formatHumanResult(result));
|
|
526
722
|
}
|
|
527
723
|
async function loginCommand(options, env, io, deps) {
|
|
528
724
|
const auth = await resolveAuthConfig(options, env, deps);
|
|
@@ -726,31 +922,141 @@ function firstNonEmpty(...values) {
|
|
|
726
922
|
}
|
|
727
923
|
function formatHumanResult(result) {
|
|
728
924
|
const lines = ["Docmana flow completed", `Status: ${String(result.status ?? "Unknown")}`];
|
|
729
|
-
const executionId = result.
|
|
925
|
+
const executionId = result.executionId;
|
|
730
926
|
if (executionId) lines.push(`Execution id: ${String(executionId)}`);
|
|
731
|
-
if (
|
|
732
|
-
|
|
733
|
-
|
|
927
|
+
if (result.documents && result.documents.mappings) {
|
|
928
|
+
lines.push(`Results: ${result.documents.mappings.length}`);
|
|
929
|
+
}
|
|
930
|
+
if (result.errors && result.errors.length > 0) {
|
|
931
|
+
lines.push(`Errors: ${result.errors.length}`);
|
|
932
|
+
}
|
|
933
|
+
const previewData = {};
|
|
934
|
+
if (result.documents && result.documents.mappings) {
|
|
935
|
+
for (const mapping of result.documents.mappings.slice(0, 3)) {
|
|
936
|
+
const docKey = mapping.reference;
|
|
937
|
+
previewData[mapping.name] = result.documents[docKey];
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
const preview = formatResultsPreview(previewData);
|
|
734
941
|
if (preview) lines.push("", "Result preview:", preview);
|
|
735
942
|
lines.push("", "Use --json to print the complete result payload.");
|
|
736
943
|
return `${lines.join("\n")}
|
|
737
944
|
`;
|
|
738
945
|
}
|
|
739
946
|
function formatResultsPreview(results) {
|
|
740
|
-
if (!
|
|
741
|
-
const preview = JSON.stringify(results
|
|
947
|
+
if (!results) return void 0;
|
|
948
|
+
const preview = JSON.stringify(results, null, 2);
|
|
742
949
|
if (!preview) return void 0;
|
|
743
950
|
return preview.length > 2e3 ? `${preview.slice(0, 2e3)}
|
|
744
951
|
...` : preview;
|
|
745
952
|
}
|
|
746
953
|
function formatRuntimeError(err) {
|
|
954
|
+
return formatHumanError(err);
|
|
955
|
+
}
|
|
956
|
+
function formatHumanError(err) {
|
|
747
957
|
if (err instanceof DocmanaExecutionError) {
|
|
748
|
-
const
|
|
749
|
-
|
|
958
|
+
const lines = [`Error: ${err.message}`];
|
|
959
|
+
if (err.errors && err.errors.length > 0) {
|
|
960
|
+
lines.push("Global errors:");
|
|
961
|
+
for (const e of err.errors) {
|
|
962
|
+
lines.push(` - ${formatSingleError(e)}`);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
const result = err.result;
|
|
966
|
+
if (result) {
|
|
967
|
+
if (result.documents && result.documents.mappings && result.documents.mappings.length > 0) {
|
|
968
|
+
lines.push("Document execution results:");
|
|
969
|
+
for (const mapping of result.documents.mappings) {
|
|
970
|
+
const docKey = mapping.reference;
|
|
971
|
+
const docName = mapping.name;
|
|
972
|
+
const docResult = result.documents[docKey];
|
|
973
|
+
if (docResult) {
|
|
974
|
+
const status = docResult.status || "Unknown";
|
|
975
|
+
const nodes = [];
|
|
976
|
+
if (docResult.classifications) nodes.push(...Object.values(docResult.classifications));
|
|
977
|
+
if (docResult.metadataExtraction) nodes.push(docResult.metadataExtraction);
|
|
978
|
+
if (docResult.extractions) nodes.push(...Object.values(docResult.extractions));
|
|
979
|
+
if (docResult.validations) nodes.push(...Object.values(docResult.validations));
|
|
980
|
+
const hasNodeFailures = nodes.some(
|
|
981
|
+
(n) => n.status === "Failed" || n.errors && n.errors.length > 0
|
|
982
|
+
);
|
|
983
|
+
if (docResult.status === "Failed" || hasNodeFailures) {
|
|
984
|
+
lines.push(` - Document: ${docName} (Status: ${status})`);
|
|
985
|
+
if (docResult.classifications) {
|
|
986
|
+
for (const [nodeName, node] of Object.entries(docResult.classifications)) {
|
|
987
|
+
if (node.errors && node.errors.length > 0) {
|
|
988
|
+
lines.push(` Classification: ${nodeName} (Status: ${node.status})`);
|
|
989
|
+
for (const nodeErr of node.errors) {
|
|
990
|
+
lines.push(` - ${nodeErr}`);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
if (docResult.metadataExtraction?.errors && docResult.metadataExtraction.errors.length > 0) {
|
|
996
|
+
lines.push(
|
|
997
|
+
` MetadataExtraction: (Status: ${docResult.metadataExtraction.status})`
|
|
998
|
+
);
|
|
999
|
+
for (const nodeErr of docResult.metadataExtraction.errors) {
|
|
1000
|
+
lines.push(` - ${nodeErr}`);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
if (docResult.extractions) {
|
|
1004
|
+
for (const [nodeName, node] of Object.entries(docResult.extractions)) {
|
|
1005
|
+
if (node.status === "Failed" || node.errors && node.errors.length > 0) {
|
|
1006
|
+
lines.push(` Extraction: ${nodeName} (Status: ${node.status})`);
|
|
1007
|
+
if (node.errors) {
|
|
1008
|
+
for (const nodeErr of node.errors) {
|
|
1009
|
+
lines.push(` - ${nodeErr}`);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
if (docResult.validations) {
|
|
1016
|
+
for (const [nodeName, node] of Object.entries(docResult.validations)) {
|
|
1017
|
+
if (node.status === "Failed" || node.errors && node.errors.length > 0) {
|
|
1018
|
+
lines.push(` Validation: ${nodeName} (Status: ${node.status})`);
|
|
1019
|
+
if (node.errors) {
|
|
1020
|
+
for (const nodeErr of node.errors) {
|
|
1021
|
+
lines.push(` - ${nodeErr}`);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
} else {
|
|
1028
|
+
lines.push(` - Document: ${docName} (Status: ${status})`);
|
|
1029
|
+
}
|
|
1030
|
+
} else {
|
|
1031
|
+
lines.push(` - Document: ${docName} (Status: Unknown)`);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
return lines.join("\n");
|
|
1037
|
+
}
|
|
1038
|
+
if (err instanceof DocmanaError) {
|
|
1039
|
+
return `Error: ${err.message} (Code: ${err.code})`;
|
|
1040
|
+
}
|
|
1041
|
+
if (err instanceof Error) {
|
|
1042
|
+
return `Error: ${err.message}`;
|
|
1043
|
+
}
|
|
1044
|
+
return `Error: ${String(err)}`;
|
|
1045
|
+
}
|
|
1046
|
+
function formatSingleError(e) {
|
|
1047
|
+
if (typeof e === "string") return e;
|
|
1048
|
+
if (e && typeof e === "object") {
|
|
1049
|
+
const obj = e;
|
|
1050
|
+
if (typeof obj.msg === "string") return obj.msg;
|
|
1051
|
+
if (typeof obj.message === "string") return obj.message;
|
|
1052
|
+
if (typeof obj.error === "string") return obj.error;
|
|
1053
|
+
try {
|
|
1054
|
+
return JSON.stringify(e);
|
|
1055
|
+
} catch {
|
|
1056
|
+
return String(e);
|
|
1057
|
+
}
|
|
750
1058
|
}
|
|
751
|
-
|
|
752
|
-
if (err instanceof Error) return err.message;
|
|
753
|
-
return "Unexpected error";
|
|
1059
|
+
return String(e);
|
|
754
1060
|
}
|
|
755
1061
|
function isDirectRun() {
|
|
756
1062
|
const entry = process.argv[1];
|