@docmana/sdk 0.9.1 → 0.11.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/README.md +4 -4
- package/dist/api/flow-definition.d.ts +1 -1
- package/dist/api/flow-metadata.d.ts +1 -1
- package/dist/api/list-flows.d.ts +1 -1
- package/dist/api/run-flow.d.ts +1 -1
- package/dist/cli.mjs +56 -26
- package/dist/cli.mjs.map +1 -1
- package/dist/client.d.ts +9 -3
- package/dist/index.js +52 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +52 -22
- package/dist/index.mjs.map +1 -1
- package/dist/models/execution-status.enum.d.ts +1 -1
- package/dist/status.d.ts +3 -0
- package/dist/types.d.ts +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.10.0
|
|
4
|
+
- Add an optional `organization` to flow selection, emitted as a
|
|
5
|
+
`?organization=<org>` query param on the request to
|
|
6
|
+
`docmana-consumer-edge-api`. Purely additive — existing calls are unchanged.
|
|
7
|
+
- `listFlows({ organization })`, `getFlowMetadata(flowId, { organization })`,
|
|
8
|
+
and `getFlowDefinition(flowId, { organization })` accept the option.
|
|
9
|
+
- `RunFlowParams` (and therefore `runFlow` / `runFlowAsync`) gains
|
|
10
|
+
`organization`, threaded onto the `execute-async` request URL.
|
|
11
|
+
- Expose `organization` on `FlowListItem`: when the consumer-edge tags a flow
|
|
12
|
+
with its organization, `listFlows()` now carries it through on each item.
|
|
13
|
+
|
|
3
14
|
## 0.8.1
|
|
4
15
|
- Rename the multipart wire fields sent to `docmana-consumer-edge-api` from
|
|
5
16
|
`json_context` / `callback_url` to `jsonContext` / `callbackUrl`, matching the
|
package/README.md
CHANGED
|
@@ -121,7 +121,7 @@ use `RunFlowParams` for request data:
|
|
|
121
121
|
`GET /v1/executions/:executionResultId/result`.
|
|
122
122
|
- `runFlow(flowId, params, options?)` starts async execution, polls status, fetches the
|
|
123
123
|
result, respects `X-Poll-After` and `429 Retry-After` while polling, and throws
|
|
124
|
-
`DocmanaExecutionError` if the result status is `
|
|
124
|
+
`DocmanaExecutionError` if the result status is `FAILED`.
|
|
125
125
|
|
|
126
126
|
Consumer is the polling authority. When `GET /status` returns `X-Poll-After`,
|
|
127
127
|
the SDK waits that many milliseconds before the next status call. If the header
|
|
@@ -159,8 +159,8 @@ const { executionResultId } = await docmana.runFlowAsync("<flow-id>", {
|
|
|
159
159
|
files: ["./contract.pdf"],
|
|
160
160
|
});
|
|
161
161
|
|
|
162
|
-
let status = "
|
|
163
|
-
while (status !== "
|
|
162
|
+
let status = "PENDING";
|
|
163
|
+
while (status !== "COMPLETED" && status !== "FAILED") {
|
|
164
164
|
await new Promise((r) => setTimeout(r, 2000));
|
|
165
165
|
({ status } = await docmana.getStatus(executionResultId));
|
|
166
166
|
}
|
|
@@ -264,7 +264,7 @@ optional `.requestId` when available.
|
|
|
264
264
|
| `DocmanaAuthError` | `401` rejected or expired Bearer token. |
|
|
265
265
|
| `DocmanaPermissionError` | `403` missing permission. |
|
|
266
266
|
| `DocmanaNotFoundError` | `404` flow or execution not found. |
|
|
267
|
-
| `DocmanaExecutionError` | The flow finished with status `"
|
|
267
|
+
| `DocmanaExecutionError` | The flow finished with status `"FAILED"`. Carries `.errors` and `.result`. |
|
|
268
268
|
| `DocmanaTimeoutError` | Polling exceeded `timeoutMs`. |
|
|
269
269
|
| `DocmanaAbortError` | The provided `AbortSignal` fired. |
|
|
270
270
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { HttpClient } from "../http/http-client.js";
|
|
2
2
|
import type { FlowDefinition } from "../types.js";
|
|
3
|
-
export declare function getFlowDefinition(http: HttpClient, flowId: string): Promise<FlowDefinition>;
|
|
3
|
+
export declare function getFlowDefinition(http: HttpClient, flowId: string, organization?: string): Promise<FlowDefinition>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { HttpClient } from "../http/http-client.js";
|
|
2
2
|
import type { FlowMetadata } from "../types.js";
|
|
3
|
-
export declare function getFlowMetadata(http: HttpClient, flowId: string): Promise<FlowMetadata>;
|
|
3
|
+
export declare function getFlowMetadata(http: HttpClient, flowId: string, organization?: string): Promise<FlowMetadata>;
|
package/dist/api/list-flows.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { HttpClient } from "../http/http-client.js";
|
|
2
2
|
import type { FlowListItem } from "../types.js";
|
|
3
|
-
export declare function listFlows(http: HttpClient): Promise<FlowListItem[]>;
|
|
3
|
+
export declare function listFlows(http: HttpClient, organization?: string): Promise<FlowListItem[]>;
|
package/dist/api/run-flow.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ResolvedPart } from "../files/resolve-input.js";
|
|
2
2
|
import type { HttpClient } from "../http/http-client.js";
|
|
3
|
-
export declare function runFlow(http: HttpClient, flowId: string, parts: ResolvedPart[], signal?: AbortSignal, useDraftVersion?: boolean, context?: Record<string, unknown>, callbackUrl?: string, language?: string): Promise<{
|
|
3
|
+
export declare function runFlow(http: HttpClient, flowId: string, parts: ResolvedPart[], signal?: AbortSignal, useDraftVersion?: boolean, context?: Record<string, unknown>, callbackUrl?: string, language?: string, organization?: string): Promise<{
|
|
4
4
|
executionResultId: string;
|
|
5
5
|
fileIds: string[];
|
|
6
6
|
}>;
|
package/dist/cli.mjs
CHANGED
|
@@ -265,7 +265,7 @@ async function resolveInputs(input) {
|
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
// src/sdk/api/run-flow.ts
|
|
268
|
-
async function runFlow(http, flowId, parts, signal, useDraftVersion = false, context, callbackUrl, language) {
|
|
268
|
+
async function runFlow(http, flowId, parts, signal, useDraftVersion = false, context, callbackUrl, language, organization) {
|
|
269
269
|
const form = new FormData();
|
|
270
270
|
for (const part of parts) {
|
|
271
271
|
form.append("files", new File([part.data], part.filename, { type: part.contentType }));
|
|
@@ -274,20 +274,37 @@ async function runFlow(http, flowId, parts, signal, useDraftVersion = false, con
|
|
|
274
274
|
if (callbackUrl !== void 0) form.append("callbackUrl", callbackUrl);
|
|
275
275
|
if (language !== void 0) form.append("language", language);
|
|
276
276
|
if (useDraftVersion) form.append("useDraftVersion", "true");
|
|
277
|
+
const path = `/flows/${flowId}/execute-async`;
|
|
277
278
|
return http.requestJson(
|
|
278
279
|
"POST",
|
|
279
|
-
|
|
280
|
+
organization ? `${path}?organization=${encodeURIComponent(organization)}` : path,
|
|
280
281
|
{ body: form, signal }
|
|
281
282
|
);
|
|
282
283
|
}
|
|
283
284
|
|
|
285
|
+
// src/sdk/status.ts
|
|
286
|
+
function normalizeStatus(status, fallback = "UNKNOWN") {
|
|
287
|
+
if (typeof status !== "string") return fallback;
|
|
288
|
+
const trimmed = status.trim();
|
|
289
|
+
if (!trimmed) return fallback;
|
|
290
|
+
return trimmed.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").toUpperCase();
|
|
291
|
+
}
|
|
292
|
+
function isFailedStatus(status) {
|
|
293
|
+
return normalizeStatus(status) === "FAILED";
|
|
294
|
+
}
|
|
295
|
+
function isTerminalStatus(status) {
|
|
296
|
+
const normalized = normalizeStatus(status);
|
|
297
|
+
return normalized === "COMPLETED" || normalized === "FAILED";
|
|
298
|
+
}
|
|
299
|
+
|
|
284
300
|
// src/sdk/api/execution-status.ts
|
|
285
301
|
async function getStatus(http, executionResultId, signal) {
|
|
286
302
|
const res = await http.requestRaw("GET", `/executions/${executionResultId}/status`, { signal });
|
|
287
303
|
const text = await res.text();
|
|
288
304
|
const body = text ? JSON.parse(text) : { status: "" };
|
|
305
|
+
const normalizedBody = { ...body, status: normalizeStatus(body.status) };
|
|
289
306
|
const pollAfterMs = parsePositiveInt(res.headers.get("x-poll-after"));
|
|
290
|
-
return pollAfterMs === void 0 ?
|
|
307
|
+
return pollAfterMs === void 0 ? normalizedBody : { ...normalizedBody, pollAfterMs };
|
|
291
308
|
}
|
|
292
309
|
function parsePositiveInt(value) {
|
|
293
310
|
if (!value) return void 0;
|
|
@@ -304,17 +321,22 @@ async function getResult(http, executionResultId, signal, language) {
|
|
|
304
321
|
}
|
|
305
322
|
|
|
306
323
|
// src/sdk/api/list-flows.ts
|
|
307
|
-
async function listFlows(http) {
|
|
308
|
-
const
|
|
324
|
+
async function listFlows(http, organization) {
|
|
325
|
+
const path = organization ? `/flows?organization=${encodeURIComponent(organization)}` : "/flows";
|
|
326
|
+
const flows = await http.requestJson("GET", path);
|
|
309
327
|
return Array.isArray(flows) ? flows.map(toFlowListItem) : [];
|
|
310
328
|
}
|
|
311
329
|
function toFlowListItem(flow) {
|
|
312
330
|
const value = flow && typeof flow === "object" ? flow : {};
|
|
313
|
-
|
|
331
|
+
const item = {
|
|
314
332
|
id: toStringValue(value.id),
|
|
315
333
|
name: toStringValue(value.name),
|
|
316
334
|
state: toStateValue(value.state)
|
|
317
335
|
};
|
|
336
|
+
if (typeof value.organization === "string") {
|
|
337
|
+
item.organization = value.organization;
|
|
338
|
+
}
|
|
339
|
+
return item;
|
|
318
340
|
}
|
|
319
341
|
function toStringValue(value) {
|
|
320
342
|
return typeof value === "string" ? value : "";
|
|
@@ -346,13 +368,21 @@ function toStringValue2(value) {
|
|
|
346
368
|
}
|
|
347
369
|
|
|
348
370
|
// src/sdk/api/flow-metadata.ts
|
|
349
|
-
async function getFlowMetadata(http, flowId) {
|
|
350
|
-
|
|
371
|
+
async function getFlowMetadata(http, flowId, organization) {
|
|
372
|
+
const path = `/flows/${encodeURIComponent(flowId)}/metadata`;
|
|
373
|
+
return http.requestJson(
|
|
374
|
+
"GET",
|
|
375
|
+
organization ? `${path}?organization=${encodeURIComponent(organization)}` : path
|
|
376
|
+
);
|
|
351
377
|
}
|
|
352
378
|
|
|
353
379
|
// src/sdk/api/flow-definition.ts
|
|
354
|
-
async function getFlowDefinition(http, flowId) {
|
|
355
|
-
|
|
380
|
+
async function getFlowDefinition(http, flowId, organization) {
|
|
381
|
+
const path = `/flows/${encodeURIComponent(flowId)}/definition`;
|
|
382
|
+
return http.requestJson(
|
|
383
|
+
"GET",
|
|
384
|
+
organization ? `${path}?organization=${encodeURIComponent(organization)}` : path
|
|
385
|
+
);
|
|
356
386
|
}
|
|
357
387
|
|
|
358
388
|
// src/sdk/api/organization-documents.ts
|
|
@@ -416,7 +446,6 @@ function toNumberValue(value) {
|
|
|
416
446
|
}
|
|
417
447
|
|
|
418
448
|
// src/sdk/polling/poll.ts
|
|
419
|
-
var TERMINAL = /* @__PURE__ */ new Set(["Completed", "Failed"]);
|
|
420
449
|
var defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
421
450
|
async function pollUntilTerminal(opts) {
|
|
422
451
|
const sleep = opts.sleep ?? defaultSleep;
|
|
@@ -437,8 +466,8 @@ async function pollUntilTerminal(opts) {
|
|
|
437
466
|
await sleep(err.retryAfterMs ?? opts.intervalMs);
|
|
438
467
|
continue;
|
|
439
468
|
}
|
|
440
|
-
const
|
|
441
|
-
if (
|
|
469
|
+
const status = normalizeStatus(result.status);
|
|
470
|
+
if (isTerminalStatus(status)) return status;
|
|
442
471
|
if (elapsed() >= opts.timeoutMs) {
|
|
443
472
|
throw new DocmanaTimeoutError(`Execution did not finish within ${opts.timeoutMs}ms`);
|
|
444
473
|
}
|
|
@@ -484,7 +513,8 @@ var Docmana = class {
|
|
|
484
513
|
params.useDraftVersion ?? false,
|
|
485
514
|
params.context,
|
|
486
515
|
params.callbackUrl,
|
|
487
|
-
params.language
|
|
516
|
+
params.language,
|
|
517
|
+
params.organization
|
|
488
518
|
);
|
|
489
519
|
}
|
|
490
520
|
async getStatus(executionResultId, signal) {
|
|
@@ -532,7 +562,7 @@ var Docmana = class {
|
|
|
532
562
|
signal: options.signal
|
|
533
563
|
});
|
|
534
564
|
const result = await this.getResult(executionResultId, options.signal, params.language);
|
|
535
|
-
if (result.status
|
|
565
|
+
if (isFailedStatus(result.status)) {
|
|
536
566
|
throw new DocmanaExecutionError(
|
|
537
567
|
`Flow ${flowId} execution failed`,
|
|
538
568
|
result.errors ?? [],
|
|
@@ -541,17 +571,17 @@ var Docmana = class {
|
|
|
541
571
|
}
|
|
542
572
|
return result;
|
|
543
573
|
}
|
|
544
|
-
async listFlows() {
|
|
545
|
-
return listFlows(this.http);
|
|
574
|
+
async listFlows(options = {}) {
|
|
575
|
+
return listFlows(this.http, options.organization);
|
|
546
576
|
}
|
|
547
577
|
async listOrganizations() {
|
|
548
578
|
return listOrganizations(this.http);
|
|
549
579
|
}
|
|
550
|
-
async getFlowMetadata(flowId) {
|
|
551
|
-
return getFlowMetadata(this.http, flowId);
|
|
580
|
+
async getFlowMetadata(flowId, options = {}) {
|
|
581
|
+
return getFlowMetadata(this.http, flowId, options.organization);
|
|
552
582
|
}
|
|
553
|
-
async getFlowDefinition(flowId) {
|
|
554
|
-
return getFlowDefinition(this.http, flowId);
|
|
583
|
+
async getFlowDefinition(flowId, options = {}) {
|
|
584
|
+
return getFlowDefinition(this.http, flowId, options.organization);
|
|
555
585
|
}
|
|
556
586
|
async listOrganizationDocuments(options = {}) {
|
|
557
587
|
return listOrganizationDocuments(this.http, options);
|
|
@@ -563,7 +593,7 @@ var Docmana = class {
|
|
|
563
593
|
return downloadOrganizationDocuments(this.http, paths);
|
|
564
594
|
}
|
|
565
595
|
isTerminalStatus(status) {
|
|
566
|
-
return status
|
|
596
|
+
return isTerminalStatus(status);
|
|
567
597
|
}
|
|
568
598
|
};
|
|
569
599
|
|
|
@@ -671,10 +701,10 @@ function formatHumanError(err) {
|
|
|
671
701
|
if (docResult.extractions) nodes.push(...Object.values(docResult.extractions));
|
|
672
702
|
if (docResult.validations) nodes.push(...Object.values(docResult.validations));
|
|
673
703
|
const hasNodeFailures = nodes.some(
|
|
674
|
-
(n) => n.status
|
|
704
|
+
(n) => isFailedStatus(n.status) || n.errors && n.errors.length > 0
|
|
675
705
|
);
|
|
676
706
|
lines.push(` - Document: ${docName} (Status: ${status})`);
|
|
677
|
-
if (docResult.status
|
|
707
|
+
if (!isFailedStatus(docResult.status) && !hasNodeFailures) continue;
|
|
678
708
|
if (docResult.classifications) {
|
|
679
709
|
for (const [nodeName, node] of Object.entries(docResult.classifications)) {
|
|
680
710
|
if (node.errors && node.errors.length > 0) {
|
|
@@ -691,7 +721,7 @@ function formatHumanError(err) {
|
|
|
691
721
|
}
|
|
692
722
|
if (docResult.extractions) {
|
|
693
723
|
for (const [nodeName, node] of Object.entries(docResult.extractions)) {
|
|
694
|
-
if (node.status
|
|
724
|
+
if (isFailedStatus(node.status) || node.errors && node.errors.length > 0) {
|
|
695
725
|
lines.push(` Extraction: ${nodeName} (Status: ${node.status})`);
|
|
696
726
|
if (node.errors) {
|
|
697
727
|
for (const nodeErr of node.errors) lines.push(` - ${nodeErr}`);
|
|
@@ -701,7 +731,7 @@ function formatHumanError(err) {
|
|
|
701
731
|
}
|
|
702
732
|
if (docResult.validations) {
|
|
703
733
|
for (const [nodeName, node] of Object.entries(docResult.validations)) {
|
|
704
|
-
if (node.status
|
|
734
|
+
if (isFailedStatus(node.status) || node.errors && node.errors.length > 0) {
|
|
705
735
|
lines.push(` Validation: ${nodeName} (Status: ${node.status})`);
|
|
706
736
|
if (node.errors) {
|
|
707
737
|
for (const nodeErr of node.errors) lines.push(` - ${nodeErr}`);
|