@anyformat/sdk 0.2.1 → 0.2.3
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 +75 -7
- package/dist/index.cjs +354 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +578 -143
- package/dist/index.d.ts +578 -143
- package/dist/index.js +345 -67
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1,27 +1,118 @@
|
|
|
1
|
+
// package.json
|
|
2
|
+
var package_default = {
|
|
3
|
+
name: "@anyformat/sdk",
|
|
4
|
+
version: "0.2.3",
|
|
5
|
+
description: "TypeScript SDK for the AnyFormat API",
|
|
6
|
+
license: "MIT",
|
|
7
|
+
author: "Anyformat <info@anyformat.ai>",
|
|
8
|
+
type: "module",
|
|
9
|
+
main: "./dist/index.cjs",
|
|
10
|
+
module: "./dist/index.js",
|
|
11
|
+
types: "./dist/index.d.ts",
|
|
12
|
+
exports: {
|
|
13
|
+
".": {
|
|
14
|
+
types: "./dist/index.d.ts",
|
|
15
|
+
import: "./dist/index.js",
|
|
16
|
+
require: "./dist/index.cjs"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
files: [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
engines: {
|
|
23
|
+
node: ">=18"
|
|
24
|
+
},
|
|
25
|
+
scripts: {
|
|
26
|
+
"gen:spec": 'ROOT=$(unset GIT_DIR && git rev-parse --show-toplevel) && cd "$ROOT/anyformat/services/api" && uv run python "$ROOT/anyformat/libs/public/sdk-js/scripts/dump_openapi.py" "$ROOT/anyformat/libs/public/sdk-js/openapi/v2.json"',
|
|
27
|
+
"gen:client": "openapi-ts",
|
|
28
|
+
gen: "bun run gen:spec && bun run gen:client",
|
|
29
|
+
"gen:check": "bun run gen && git diff --exit-code -- openapi/v2.json src/sdk",
|
|
30
|
+
build: "tsup",
|
|
31
|
+
typecheck: "tsc --noEmit",
|
|
32
|
+
test: "vitest run",
|
|
33
|
+
prepublishOnly: "bun run build"
|
|
34
|
+
},
|
|
35
|
+
devDependencies: {
|
|
36
|
+
"@hey-api/openapi-ts": "^0.99.0",
|
|
37
|
+
"@types/node": "^25.9.1",
|
|
38
|
+
tsup: "^8.3.0",
|
|
39
|
+
typescript: "^5.6.0",
|
|
40
|
+
vitest: "^4.1.7"
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
1
44
|
// src/builder.ts
|
|
2
45
|
import { readFileSync } from "fs";
|
|
3
46
|
import { basename } from "path";
|
|
4
47
|
|
|
48
|
+
// src/parse-view.ts
|
|
49
|
+
var ParseView = class {
|
|
50
|
+
/** @internal */
|
|
51
|
+
constructor(parse) {
|
|
52
|
+
this.parse = parse;
|
|
53
|
+
}
|
|
54
|
+
parse;
|
|
55
|
+
get markdown() {
|
|
56
|
+
return this.parse.markdown ?? null;
|
|
57
|
+
}
|
|
58
|
+
get text() {
|
|
59
|
+
return this.parse.text ?? null;
|
|
60
|
+
}
|
|
61
|
+
get blocks() {
|
|
62
|
+
return this.parse.blocks ?? [];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Document-level confidence (0-100) in the parsed content. May be `null` for
|
|
66
|
+
* some parse modes — fall back to `layoutConfidence`.
|
|
67
|
+
*/
|
|
68
|
+
get parseConfidence() {
|
|
69
|
+
return this.parse.parse_confidence ?? null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Document-level confidence (0-100) in the page layout (block positions).
|
|
73
|
+
* `null` when not available.
|
|
74
|
+
*/
|
|
75
|
+
get layoutConfidence() {
|
|
76
|
+
return this.parse.layout_confidence ?? null;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
5
80
|
// src/result.ts
|
|
6
81
|
var Result = class {
|
|
7
82
|
constructor(raw) {
|
|
8
83
|
this.raw = raw;
|
|
9
84
|
}
|
|
10
85
|
raw;
|
|
86
|
+
_parse;
|
|
11
87
|
get collectionId() {
|
|
12
88
|
return this.raw.collection_id;
|
|
13
89
|
}
|
|
14
90
|
get extractions() {
|
|
15
91
|
return this.raw.extractions ?? [];
|
|
16
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Typed view over the parse node's output, or `null` when the workflow has
|
|
95
|
+
* no parse node. Cached so repeated access doesn't re-wrap.
|
|
96
|
+
*/
|
|
97
|
+
get parse() {
|
|
98
|
+
if (this._parse === void 0) {
|
|
99
|
+
const raw = this.raw.parse;
|
|
100
|
+
this._parse = raw ? new ParseView(raw) : null;
|
|
101
|
+
}
|
|
102
|
+
return this._parse;
|
|
103
|
+
}
|
|
17
104
|
/**
|
|
18
105
|
* Convenience accessor for a top-level scalar field on the first
|
|
19
106
|
* extraction (linear workflows). Returns `undefined` for missing fields
|
|
20
107
|
* or list-valued fields — read `extractions` directly for those.
|
|
108
|
+
*
|
|
109
|
+
* Parameterise with the declared schema type to type `.value`:
|
|
110
|
+
* `result.field<number>("total").value` is `number | null`.
|
|
21
111
|
*/
|
|
22
112
|
field(name) {
|
|
23
113
|
const value = this.extractions[0]?.fields?.[name];
|
|
24
|
-
|
|
114
|
+
if (value === void 0 || Array.isArray(value)) return void 0;
|
|
115
|
+
return value;
|
|
25
116
|
}
|
|
26
117
|
};
|
|
27
118
|
|
|
@@ -38,35 +129,41 @@ var APIError = class extends AnyformatError {
|
|
|
38
129
|
status;
|
|
39
130
|
body;
|
|
40
131
|
};
|
|
41
|
-
var
|
|
132
|
+
var BadRequestError = class extends APIError {
|
|
42
133
|
};
|
|
43
|
-
var
|
|
134
|
+
var UnauthorizedError = class extends APIError {
|
|
44
135
|
};
|
|
45
|
-
var
|
|
136
|
+
var ForbiddenError = class extends APIError {
|
|
46
137
|
};
|
|
47
|
-
var
|
|
138
|
+
var NotFoundError = class extends APIError {
|
|
48
139
|
};
|
|
49
|
-
var
|
|
140
|
+
var RateLimitedError = class extends APIError {
|
|
50
141
|
};
|
|
51
142
|
var ServerError = class extends APIError {
|
|
52
143
|
};
|
|
53
|
-
var
|
|
144
|
+
var BadRequest = BadRequestError;
|
|
145
|
+
var Unauthorized = UnauthorizedError;
|
|
146
|
+
var Forbidden = ForbiddenError;
|
|
147
|
+
var NotFound = NotFoundError;
|
|
148
|
+
var RateLimited = RateLimitedError;
|
|
149
|
+
var SDKTimeoutError = class extends AnyformatError {
|
|
54
150
|
};
|
|
151
|
+
var SDKTimeout = SDKTimeoutError;
|
|
55
152
|
var WorkflowBuilderError = class extends AnyformatError {
|
|
56
153
|
};
|
|
57
154
|
function toApiError(status, body) {
|
|
58
155
|
const message = `AnyFormat API error (${status})`;
|
|
59
156
|
switch (status) {
|
|
60
157
|
case 400:
|
|
61
|
-
return new
|
|
158
|
+
return new BadRequestError(status, message, body);
|
|
62
159
|
case 401:
|
|
63
|
-
return new
|
|
160
|
+
return new UnauthorizedError(status, message, body);
|
|
64
161
|
case 403:
|
|
65
|
-
return new
|
|
162
|
+
return new ForbiddenError(status, message, body);
|
|
66
163
|
case 404:
|
|
67
|
-
return new
|
|
164
|
+
return new NotFoundError(status, message, body);
|
|
68
165
|
case 429:
|
|
69
|
-
return new
|
|
166
|
+
return new RateLimitedError(status, message, body);
|
|
70
167
|
default:
|
|
71
168
|
return status >= 500 ? new ServerError(status, message, body) : new APIError(status, message, body);
|
|
72
169
|
}
|
|
@@ -883,9 +980,29 @@ var createClient = (config = {}) => {
|
|
|
883
980
|
};
|
|
884
981
|
|
|
885
982
|
// src/sdk/client.gen.ts
|
|
886
|
-
var client = createClient(createConfig({ baseUrl: "https://api
|
|
983
|
+
var client = createClient(createConfig({ baseUrl: "https://api.anyformat.dev" }));
|
|
887
984
|
|
|
888
985
|
// src/sdk/sdk.gen.ts
|
|
986
|
+
var v2Parse = (options) => (options.client ?? client).post({
|
|
987
|
+
...formDataBodySerializer,
|
|
988
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
989
|
+
url: "/v2/operations/parse",
|
|
990
|
+
...options,
|
|
991
|
+
headers: {
|
|
992
|
+
"Content-Type": null,
|
|
993
|
+
...options.headers
|
|
994
|
+
}
|
|
995
|
+
});
|
|
996
|
+
var v2ParseResult = (options) => (options.client ?? client).get({
|
|
997
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
998
|
+
url: "/v2/operations/parse/{job_id}",
|
|
999
|
+
...options
|
|
1000
|
+
});
|
|
1001
|
+
var v2ListWorkflows = (options) => (options?.client ?? client).get({
|
|
1002
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1003
|
+
url: "/v2/workflows/",
|
|
1004
|
+
...options
|
|
1005
|
+
});
|
|
889
1006
|
var v2CreateWorkflow = (options) => (options.client ?? client).post({
|
|
890
1007
|
security: [{ scheme: "bearer", type: "http" }],
|
|
891
1008
|
url: "/v2/workflows/",
|
|
@@ -895,11 +1012,30 @@ var v2CreateWorkflow = (options) => (options.client ?? client).post({
|
|
|
895
1012
|
...options.headers
|
|
896
1013
|
}
|
|
897
1014
|
});
|
|
1015
|
+
var v2DeleteWorkflow = (options) => (options.client ?? client).delete({
|
|
1016
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1017
|
+
url: "/v2/workflows/{workflow_id}/",
|
|
1018
|
+
...options
|
|
1019
|
+
});
|
|
1020
|
+
var v2UpdateWorkflow = (options) => (options.client ?? client).put({
|
|
1021
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1022
|
+
url: "/v2/workflows/{workflow_id}/",
|
|
1023
|
+
...options,
|
|
1024
|
+
headers: {
|
|
1025
|
+
"Content-Type": "application/json",
|
|
1026
|
+
...options.headers
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
898
1029
|
var v2GetFileResults = (options) => (options.client ?? client).get({
|
|
899
1030
|
security: [{ scheme: "bearer", type: "http" }],
|
|
900
1031
|
url: "/v2/workflows/{workflow_id}/files/{collection_id}/results/",
|
|
901
1032
|
...options
|
|
902
1033
|
});
|
|
1034
|
+
var v2RunFile = (options) => (options.client ?? client).post({
|
|
1035
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1036
|
+
url: "/v2/workflows/{workflow_id}/files/{file_id}/run/",
|
|
1037
|
+
...options
|
|
1038
|
+
});
|
|
903
1039
|
var v2RunWorkflow = (options) => (options.client ?? client).post({
|
|
904
1040
|
...formDataBodySerializer,
|
|
905
1041
|
security: [{ scheme: "bearer", type: "http" }],
|
|
@@ -910,48 +1046,36 @@ var v2RunWorkflow = (options) => (options.client ?? client).post({
|
|
|
910
1046
|
...options.headers
|
|
911
1047
|
}
|
|
912
1048
|
});
|
|
1049
|
+
var v2UploadFile = (options) => (options.client ?? client).post({
|
|
1050
|
+
...formDataBodySerializer,
|
|
1051
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1052
|
+
url: "/v2/workflows/{workflow_id}/upload/",
|
|
1053
|
+
...options,
|
|
1054
|
+
headers: {
|
|
1055
|
+
"Content-Type": null,
|
|
1056
|
+
...options.headers
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
913
1059
|
|
|
914
1060
|
// src/run.ts
|
|
915
1061
|
var Run = class {
|
|
916
|
-
|
|
1062
|
+
/** @internal */
|
|
1063
|
+
constructor(client2, workflowId, id) {
|
|
917
1064
|
this.client = client2;
|
|
918
|
-
this.
|
|
919
|
-
this.
|
|
920
|
-
this.text = text;
|
|
1065
|
+
this.workflowId = workflowId;
|
|
1066
|
+
this.id = id;
|
|
921
1067
|
}
|
|
922
1068
|
client;
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
text;
|
|
926
|
-
workflowId = null;
|
|
927
|
-
collectionId = null;
|
|
928
|
-
/**
|
|
929
|
-
* Create the workflow and submit the document — exactly once per `Run`.
|
|
930
|
-
* Memoized so that retrying `wait()` after an `SDKTimeout` resumes polling
|
|
931
|
-
* the in-flight run instead of creating a duplicate workflow + submission.
|
|
932
|
-
*/
|
|
933
|
-
async submit() {
|
|
934
|
-
if (this.collectionId !== null) return;
|
|
935
|
-
const created = await v2CreateWorkflow({ client: this.client, body: this.request });
|
|
936
|
-
if (created.error) throw toApiError(created.response?.status ?? 500, created.error);
|
|
937
|
-
this.workflowId = created.data.id;
|
|
938
|
-
const submitted = await v2RunWorkflow({
|
|
939
|
-
client: this.client,
|
|
940
|
-
path: { workflow_id: this.workflowId },
|
|
941
|
-
body: { file: this.file, text: this.text }
|
|
942
|
-
});
|
|
943
|
-
if (submitted.error) throw toApiError(submitted.response?.status ?? 500, submitted.error);
|
|
944
|
-
this.collectionId = submitted.data.id;
|
|
945
|
-
}
|
|
1069
|
+
workflowId;
|
|
1070
|
+
id;
|
|
946
1071
|
async wait(opts = {}) {
|
|
947
|
-
const timeoutMs = opts.timeoutMs ??
|
|
948
|
-
const pollMs = opts.pollMs ??
|
|
949
|
-
await this.submit();
|
|
1072
|
+
const timeoutMs = opts.timeoutMs ?? 3e5;
|
|
1073
|
+
const pollMs = opts.pollMs ?? 3e3;
|
|
950
1074
|
const deadline = Date.now() + timeoutMs;
|
|
951
1075
|
while (Date.now() < deadline) {
|
|
952
1076
|
const results = await v2GetFileResults({
|
|
953
1077
|
client: this.client,
|
|
954
|
-
path: { workflow_id: this.workflowId, collection_id: this.
|
|
1078
|
+
path: { workflow_id: this.workflowId, collection_id: this.id }
|
|
955
1079
|
});
|
|
956
1080
|
if (!results.error) return new Result(results.data);
|
|
957
1081
|
if (results.response?.status !== 412) {
|
|
@@ -959,7 +1083,89 @@ var Run = class {
|
|
|
959
1083
|
}
|
|
960
1084
|
await new Promise((resolve) => setTimeout(resolve, pollMs));
|
|
961
1085
|
}
|
|
962
|
-
throw new
|
|
1086
|
+
throw new SDKTimeoutError(`Extraction did not complete within ${timeoutMs}ms`);
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
|
|
1090
|
+
// src/upload.ts
|
|
1091
|
+
var Upload = class {
|
|
1092
|
+
/** @internal */
|
|
1093
|
+
constructor(client2, workflowId, collectionId, fileId) {
|
|
1094
|
+
this.client = client2;
|
|
1095
|
+
this.workflowId = workflowId;
|
|
1096
|
+
this.collectionId = collectionId;
|
|
1097
|
+
this.fileId = fileId;
|
|
1098
|
+
}
|
|
1099
|
+
client;
|
|
1100
|
+
workflowId;
|
|
1101
|
+
collectionId;
|
|
1102
|
+
fileId;
|
|
1103
|
+
/** Trigger extraction on the staged file and return a pending `Run`. */
|
|
1104
|
+
async run() {
|
|
1105
|
+
if (!this.fileId) {
|
|
1106
|
+
throw new WorkflowBuilderError("This upload has no file_id \u2014 cannot run it");
|
|
1107
|
+
}
|
|
1108
|
+
const res = await v2RunFile({
|
|
1109
|
+
client: this.client,
|
|
1110
|
+
path: { workflow_id: this.workflowId, file_id: this.fileId }
|
|
1111
|
+
});
|
|
1112
|
+
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1113
|
+
return new Run(this.client, this.workflowId, res.data.id ?? this.collectionId);
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
|
|
1117
|
+
// src/workflow.ts
|
|
1118
|
+
function validateDocument(file, op) {
|
|
1119
|
+
if (file === null) {
|
|
1120
|
+
throw new WorkflowBuilderError(`${op}() requires a named file`);
|
|
1121
|
+
}
|
|
1122
|
+
const filename = file.name;
|
|
1123
|
+
if (typeof filename !== "string" || filename.length === 0) {
|
|
1124
|
+
throw new WorkflowBuilderError(
|
|
1125
|
+
`${op}() needs a named file so the server can detect its type \u2014 pass a File, e.g. new File([bytes], "invoice.pdf"), not a bare Blob`
|
|
1126
|
+
);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
var Workflow = class {
|
|
1130
|
+
/** @internal */
|
|
1131
|
+
constructor(client2, id, name) {
|
|
1132
|
+
this.client = client2;
|
|
1133
|
+
this.id = id;
|
|
1134
|
+
this.name = name;
|
|
1135
|
+
}
|
|
1136
|
+
client;
|
|
1137
|
+
id;
|
|
1138
|
+
name;
|
|
1139
|
+
/** Submit a document against this workflow and return a pending `Run`. */
|
|
1140
|
+
async run(file = null) {
|
|
1141
|
+
validateDocument(file, "run");
|
|
1142
|
+
const submitted = await v2RunWorkflow({
|
|
1143
|
+
client: this.client,
|
|
1144
|
+
path: { workflow_id: this.id },
|
|
1145
|
+
body: { file }
|
|
1146
|
+
});
|
|
1147
|
+
if (submitted.error) throw toApiError(submitted.response?.status ?? 500, submitted.error);
|
|
1148
|
+
return new Run(this.client, this.id, submitted.data.id);
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Stage a document in this workflow WITHOUT running it (no credits spent).
|
|
1152
|
+
* Returns an `Upload`; call `.run()` on it to start extraction.
|
|
1153
|
+
*/
|
|
1154
|
+
async upload(file = null) {
|
|
1155
|
+
validateDocument(file, "upload");
|
|
1156
|
+
const staged = await v2UploadFile({
|
|
1157
|
+
client: this.client,
|
|
1158
|
+
path: { workflow_id: this.id },
|
|
1159
|
+
body: { file }
|
|
1160
|
+
});
|
|
1161
|
+
if (staged.error) throw toApiError(staged.response?.status ?? 500, staged.error);
|
|
1162
|
+
const collectionId = staged.data.file_collection_id;
|
|
1163
|
+
if (!collectionId) {
|
|
1164
|
+
throw new WorkflowBuilderError(
|
|
1165
|
+
"Upload succeeded but the server did not return a file_collection_id \u2014 cannot build an Upload handle"
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
return new Upload(this.client, this.id, collectionId, staged.data.file_id ?? null);
|
|
963
1169
|
}
|
|
964
1170
|
};
|
|
965
1171
|
|
|
@@ -989,12 +1195,21 @@ var WorkflowBuilder = class {
|
|
|
989
1195
|
}
|
|
990
1196
|
parse(opts = {}) {
|
|
991
1197
|
this.require(this.parseNode === null, "parse() can only be called once");
|
|
1198
|
+
const o = opts;
|
|
992
1199
|
this.parseNode = {
|
|
993
1200
|
type: "parse",
|
|
994
|
-
id:
|
|
995
|
-
mode:
|
|
996
|
-
...
|
|
997
|
-
figure_enhancement:
|
|
1201
|
+
id: o.id ?? this.nextId("parse"),
|
|
1202
|
+
mode: o.mode ?? "standard",
|
|
1203
|
+
...o.promptHint !== void 0 ? { prompt_hint: o.promptHint } : {},
|
|
1204
|
+
figure_enhancement: o.figureEnhancement ?? false,
|
|
1205
|
+
cache: o.cache ?? true,
|
|
1206
|
+
...o.effort !== void 0 ? { effort: o.effort } : {},
|
|
1207
|
+
...o.ocrEffort !== void 0 ? { ocr_effort: o.ocrEffort } : {},
|
|
1208
|
+
...o.region !== void 0 ? { region: o.region } : {},
|
|
1209
|
+
...o.skipRoutingReview !== void 0 ? { skip_routing_review: o.skipRoutingReview } : {},
|
|
1210
|
+
...o.figures !== void 0 ? { figures: o.figures } : {},
|
|
1211
|
+
...o.textFormatting !== void 0 ? { text_formatting: o.textFormatting } : {},
|
|
1212
|
+
...o.routingEffort !== void 0 ? { routing_effort: o.routingEffort } : {}
|
|
998
1213
|
};
|
|
999
1214
|
return this;
|
|
1000
1215
|
}
|
|
@@ -1041,9 +1256,12 @@ var WorkflowBuilder = class {
|
|
|
1041
1256
|
const node = {
|
|
1042
1257
|
type: "extract",
|
|
1043
1258
|
id: opts.id ?? this.nextId("extract"),
|
|
1259
|
+
...opts.mode !== void 0 ? { mode: opts.mode } : {},
|
|
1044
1260
|
extraction_schema: { fields },
|
|
1045
1261
|
...lookupFileUploads.length > 0 ? { lookup_file_uploads: lookupFileUploads } : {},
|
|
1046
|
-
...opts.lookupSuggestion !== void 0 ? { lookup_suggestion: opts.lookupSuggestion } : {}
|
|
1262
|
+
...opts.lookupSuggestion !== void 0 ? { lookup_suggestion: opts.lookupSuggestion } : {},
|
|
1263
|
+
...opts.lookupReasoningEffort !== void 0 ? { lookup_reasoning_effort: opts.lookupReasoningEffort } : {},
|
|
1264
|
+
...opts.useImages !== void 0 ? { use_images: opts.useImages } : {}
|
|
1047
1265
|
};
|
|
1048
1266
|
this.extracts.push([node, branchId]);
|
|
1049
1267
|
return this;
|
|
@@ -1125,30 +1343,22 @@ var WorkflowBuilder = class {
|
|
|
1125
1343
|
}
|
|
1126
1344
|
return { name: this.name, description: this.description, nodes, edges };
|
|
1127
1345
|
}
|
|
1128
|
-
/** Persist the workflow and return
|
|
1346
|
+
/** Persist the workflow and return a handle you can `.run(file)` on. */
|
|
1129
1347
|
async create() {
|
|
1130
1348
|
const res = await v2CreateWorkflow({ client: this.client, body: this.build() });
|
|
1131
1349
|
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1132
|
-
return res.data.id;
|
|
1350
|
+
return new Workflow(this.client, res.data.id, res.data.name);
|
|
1133
1351
|
}
|
|
1134
|
-
/**
|
|
1135
|
-
|
|
1136
|
-
this.
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
);
|
|
1140
|
-
if (file !== null) {
|
|
1141
|
-
const filename = file.name;
|
|
1142
|
-
this.require(
|
|
1143
|
-
typeof filename === "string" && filename.length > 0,
|
|
1144
|
-
'run() needs a named file so the server can detect its type \u2014 pass a File, e.g. new File([bytes], "invoice.pdf"), not a bare Blob'
|
|
1145
|
-
);
|
|
1146
|
-
}
|
|
1147
|
-
return new Run(this.client, this.build(), file, opts.text ?? null);
|
|
1352
|
+
/** Replace an existing workflow's definition and return a handle you can `.run(file)` on. */
|
|
1353
|
+
async update(workflowId) {
|
|
1354
|
+
const res = await v2UpdateWorkflow({ client: this.client, path: { workflow_id: workflowId }, body: this.build() });
|
|
1355
|
+
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1356
|
+
return new Workflow(this.client, res.data.id, res.data.name);
|
|
1148
1357
|
}
|
|
1149
1358
|
};
|
|
1150
1359
|
|
|
1151
1360
|
// src/client.ts
|
|
1361
|
+
var SDK_USER_AGENT = `anyformat-typescript-sdk-${package_default.version}`;
|
|
1152
1362
|
var Anyformat = class {
|
|
1153
1363
|
/** @internal */
|
|
1154
1364
|
_client;
|
|
@@ -1156,13 +1366,72 @@ var Anyformat = class {
|
|
|
1156
1366
|
this._client = createClient(
|
|
1157
1367
|
createConfig({
|
|
1158
1368
|
baseUrl: opts.baseUrl ?? "https://api.anyformat.ai",
|
|
1159
|
-
auth: opts.apiKey
|
|
1369
|
+
auth: opts.apiKey,
|
|
1370
|
+
// Identifies the caller in our logs (Datadog facet). Plain HTTP callers
|
|
1371
|
+
// send no such header and are logged as origin "api". User-Agent is
|
|
1372
|
+
// ignored by browsers (forbidden header) but used by Node fetch.
|
|
1373
|
+
headers: {
|
|
1374
|
+
"x-anyformat-origin": "js-sdk",
|
|
1375
|
+
"User-Agent": SDK_USER_AGENT
|
|
1376
|
+
}
|
|
1160
1377
|
})
|
|
1161
1378
|
);
|
|
1162
1379
|
}
|
|
1163
1380
|
workflow(name, description) {
|
|
1164
1381
|
return new WorkflowBuilder(this._client, name, description);
|
|
1165
1382
|
}
|
|
1383
|
+
async listWorkflows(opts) {
|
|
1384
|
+
const res = await v2ListWorkflows({
|
|
1385
|
+
client: this._client,
|
|
1386
|
+
query: { page: opts?.page, page_size: opts?.pageSize, status: opts?.status }
|
|
1387
|
+
});
|
|
1388
|
+
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1389
|
+
return res.data.results.map((r) => new Workflow(this._client, r.id, r.name ?? ""));
|
|
1390
|
+
}
|
|
1391
|
+
async deleteWorkflow(workflowId) {
|
|
1392
|
+
const res = await v2DeleteWorkflow({
|
|
1393
|
+
client: this._client,
|
|
1394
|
+
path: { workflow_id: workflowId }
|
|
1395
|
+
});
|
|
1396
|
+
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1397
|
+
return workflowId;
|
|
1398
|
+
}
|
|
1399
|
+
/** Stage a document in a workflow without running it. Returns an `Upload`. */
|
|
1400
|
+
upload(workflowId, file = null) {
|
|
1401
|
+
return new Workflow(this._client, workflowId, "").upload(file);
|
|
1402
|
+
}
|
|
1403
|
+
/** Trigger extraction on already-uploaded files. Returns a pending `Run` per file_id. */
|
|
1404
|
+
async runWorkflow(workflowId, fileIds) {
|
|
1405
|
+
const runs = [];
|
|
1406
|
+
for (const fileId of fileIds) {
|
|
1407
|
+
const res = await v2RunFile({
|
|
1408
|
+
client: this._client,
|
|
1409
|
+
path: { workflow_id: workflowId, file_id: fileId }
|
|
1410
|
+
});
|
|
1411
|
+
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1412
|
+
runs.push(new Run(this._client, workflowId, res.data.id ?? fileId));
|
|
1413
|
+
}
|
|
1414
|
+
return runs;
|
|
1415
|
+
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Parse a document with the platform's atomic `/parse` operation (fast lite
|
|
1418
|
+
* parse). Returns an opaque `jobId`; poll `getParseMarkdown(jobId)` for the
|
|
1419
|
+
* parsed markdown.
|
|
1420
|
+
*/
|
|
1421
|
+
async parse(file) {
|
|
1422
|
+
const res = await v2Parse({ client: this._client, body: { file } });
|
|
1423
|
+
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1424
|
+
return res.data.job_id;
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Poll a parse job. Returns the parsed markdown once the job is done, or
|
|
1428
|
+
* `null` while it is still processing.
|
|
1429
|
+
*/
|
|
1430
|
+
async getParseMarkdown(jobId) {
|
|
1431
|
+
const res = await v2ParseResult({ client: this._client, path: { job_id: jobId } });
|
|
1432
|
+
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1433
|
+
return res.data.status === "done" ? res.data.markdown ?? "" : null;
|
|
1434
|
+
}
|
|
1166
1435
|
};
|
|
1167
1436
|
|
|
1168
1437
|
// src/schema.ts
|
|
@@ -1187,15 +1456,24 @@ export {
|
|
|
1187
1456
|
Anyformat,
|
|
1188
1457
|
AnyformatError,
|
|
1189
1458
|
BadRequest,
|
|
1459
|
+
BadRequestError,
|
|
1190
1460
|
Forbidden,
|
|
1461
|
+
ForbiddenError,
|
|
1191
1462
|
NotFound,
|
|
1463
|
+
NotFoundError,
|
|
1464
|
+
ParseView,
|
|
1192
1465
|
RateLimited,
|
|
1466
|
+
RateLimitedError,
|
|
1193
1467
|
Result,
|
|
1194
1468
|
Run,
|
|
1195
1469
|
SDKTimeout,
|
|
1470
|
+
SDKTimeoutError,
|
|
1196
1471
|
Schema,
|
|
1197
1472
|
ServerError,
|
|
1198
1473
|
Unauthorized,
|
|
1474
|
+
UnauthorizedError,
|
|
1475
|
+
Upload,
|
|
1476
|
+
Workflow,
|
|
1199
1477
|
WorkflowBuilder,
|
|
1200
1478
|
WorkflowBuilderError
|
|
1201
1479
|
};
|