@anyformat/sdk 0.2.2 → 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 +66 -7
- package/dist/index.cjs +232 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +491 -126
- package/dist/index.d.ts +491 -126
- package/dist/index.js +225 -38
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,3 +1,46 @@
|
|
|
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";
|
|
@@ -62,10 +105,14 @@ var Result = class {
|
|
|
62
105
|
* Convenience accessor for a top-level scalar field on the first
|
|
63
106
|
* extraction (linear workflows). Returns `undefined` for missing fields
|
|
64
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`.
|
|
65
111
|
*/
|
|
66
112
|
field(name) {
|
|
67
113
|
const value = this.extractions[0]?.fields?.[name];
|
|
68
|
-
|
|
114
|
+
if (value === void 0 || Array.isArray(value)) return void 0;
|
|
115
|
+
return value;
|
|
69
116
|
}
|
|
70
117
|
};
|
|
71
118
|
|
|
@@ -82,35 +129,41 @@ var APIError = class extends AnyformatError {
|
|
|
82
129
|
status;
|
|
83
130
|
body;
|
|
84
131
|
};
|
|
85
|
-
var
|
|
132
|
+
var BadRequestError = class extends APIError {
|
|
86
133
|
};
|
|
87
|
-
var
|
|
134
|
+
var UnauthorizedError = class extends APIError {
|
|
88
135
|
};
|
|
89
|
-
var
|
|
136
|
+
var ForbiddenError = class extends APIError {
|
|
90
137
|
};
|
|
91
|
-
var
|
|
138
|
+
var NotFoundError = class extends APIError {
|
|
92
139
|
};
|
|
93
|
-
var
|
|
140
|
+
var RateLimitedError = class extends APIError {
|
|
94
141
|
};
|
|
95
142
|
var ServerError = class extends APIError {
|
|
96
143
|
};
|
|
97
|
-
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 {
|
|
98
150
|
};
|
|
151
|
+
var SDKTimeout = SDKTimeoutError;
|
|
99
152
|
var WorkflowBuilderError = class extends AnyformatError {
|
|
100
153
|
};
|
|
101
154
|
function toApiError(status, body) {
|
|
102
155
|
const message = `AnyFormat API error (${status})`;
|
|
103
156
|
switch (status) {
|
|
104
157
|
case 400:
|
|
105
|
-
return new
|
|
158
|
+
return new BadRequestError(status, message, body);
|
|
106
159
|
case 401:
|
|
107
|
-
return new
|
|
160
|
+
return new UnauthorizedError(status, message, body);
|
|
108
161
|
case 403:
|
|
109
|
-
return new
|
|
162
|
+
return new ForbiddenError(status, message, body);
|
|
110
163
|
case 404:
|
|
111
|
-
return new
|
|
164
|
+
return new NotFoundError(status, message, body);
|
|
112
165
|
case 429:
|
|
113
|
-
return new
|
|
166
|
+
return new RateLimitedError(status, message, body);
|
|
114
167
|
default:
|
|
115
168
|
return status >= 500 ? new ServerError(status, message, body) : new APIError(status, message, body);
|
|
116
169
|
}
|
|
@@ -927,9 +980,24 @@ var createClient = (config = {}) => {
|
|
|
927
980
|
};
|
|
928
981
|
|
|
929
982
|
// src/sdk/client.gen.ts
|
|
930
|
-
var client = createClient(createConfig({ baseUrl: "https://api
|
|
983
|
+
var client = createClient(createConfig({ baseUrl: "https://api.anyformat.dev" }));
|
|
931
984
|
|
|
932
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
|
+
});
|
|
933
1001
|
var v2ListWorkflows = (options) => (options?.client ?? client).get({
|
|
934
1002
|
security: [{ scheme: "bearer", type: "http" }],
|
|
935
1003
|
url: "/v2/workflows/",
|
|
@@ -963,6 +1031,11 @@ var v2GetFileResults = (options) => (options.client ?? client).get({
|
|
|
963
1031
|
url: "/v2/workflows/{workflow_id}/files/{collection_id}/results/",
|
|
964
1032
|
...options
|
|
965
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
|
+
});
|
|
966
1039
|
var v2RunWorkflow = (options) => (options.client ?? client).post({
|
|
967
1040
|
...formDataBodySerializer,
|
|
968
1041
|
security: [{ scheme: "bearer", type: "http" }],
|
|
@@ -973,6 +1046,16 @@ var v2RunWorkflow = (options) => (options.client ?? client).post({
|
|
|
973
1046
|
...options.headers
|
|
974
1047
|
}
|
|
975
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
|
+
});
|
|
976
1059
|
|
|
977
1060
|
// src/run.ts
|
|
978
1061
|
var Run = class {
|
|
@@ -1000,11 +1083,49 @@ var Run = class {
|
|
|
1000
1083
|
}
|
|
1001
1084
|
await new Promise((resolve) => setTimeout(resolve, pollMs));
|
|
1002
1085
|
}
|
|
1003
|
-
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);
|
|
1004
1114
|
}
|
|
1005
1115
|
};
|
|
1006
1116
|
|
|
1007
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
|
+
}
|
|
1008
1129
|
var Workflow = class {
|
|
1009
1130
|
/** @internal */
|
|
1010
1131
|
constructor(client2, id, name) {
|
|
@@ -1016,29 +1137,36 @@ var Workflow = class {
|
|
|
1016
1137
|
id;
|
|
1017
1138
|
name;
|
|
1018
1139
|
/** Submit a document against this workflow and return a pending `Run`. */
|
|
1019
|
-
async run(file = null
|
|
1020
|
-
|
|
1021
|
-
throw new WorkflowBuilderError("run() requires a document \u2014 pass a file or non-empty opts.text");
|
|
1022
|
-
}
|
|
1023
|
-
if (file !== null && opts.text !== void 0) {
|
|
1024
|
-
throw new WorkflowBuilderError("run() accepts either a file or text, not both");
|
|
1025
|
-
}
|
|
1026
|
-
if (file !== null) {
|
|
1027
|
-
const filename = file.name;
|
|
1028
|
-
if (typeof filename !== "string" || filename.length === 0) {
|
|
1029
|
-
throw new WorkflowBuilderError(
|
|
1030
|
-
'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'
|
|
1031
|
-
);
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1140
|
+
async run(file = null) {
|
|
1141
|
+
validateDocument(file, "run");
|
|
1034
1142
|
const submitted = await v2RunWorkflow({
|
|
1035
1143
|
client: this.client,
|
|
1036
1144
|
path: { workflow_id: this.id },
|
|
1037
|
-
body: { file
|
|
1145
|
+
body: { file }
|
|
1038
1146
|
});
|
|
1039
1147
|
if (submitted.error) throw toApiError(submitted.response?.status ?? 500, submitted.error);
|
|
1040
1148
|
return new Run(this.client, this.id, submitted.data.id);
|
|
1041
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);
|
|
1169
|
+
}
|
|
1042
1170
|
};
|
|
1043
1171
|
|
|
1044
1172
|
// src/builder.ts
|
|
@@ -1067,13 +1195,21 @@ var WorkflowBuilder = class {
|
|
|
1067
1195
|
}
|
|
1068
1196
|
parse(opts = {}) {
|
|
1069
1197
|
this.require(this.parseNode === null, "parse() can only be called once");
|
|
1198
|
+
const o = opts;
|
|
1070
1199
|
this.parseNode = {
|
|
1071
1200
|
type: "parse",
|
|
1072
|
-
id:
|
|
1073
|
-
mode:
|
|
1074
|
-
...
|
|
1075
|
-
figure_enhancement:
|
|
1076
|
-
cache:
|
|
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 } : {}
|
|
1077
1213
|
};
|
|
1078
1214
|
return this;
|
|
1079
1215
|
}
|
|
@@ -1120,9 +1256,12 @@ var WorkflowBuilder = class {
|
|
|
1120
1256
|
const node = {
|
|
1121
1257
|
type: "extract",
|
|
1122
1258
|
id: opts.id ?? this.nextId("extract"),
|
|
1259
|
+
...opts.mode !== void 0 ? { mode: opts.mode } : {},
|
|
1123
1260
|
extraction_schema: { fields },
|
|
1124
1261
|
...lookupFileUploads.length > 0 ? { lookup_file_uploads: lookupFileUploads } : {},
|
|
1125
|
-
...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 } : {}
|
|
1126
1265
|
};
|
|
1127
1266
|
this.extracts.push([node, branchId]);
|
|
1128
1267
|
return this;
|
|
@@ -1219,6 +1358,7 @@ var WorkflowBuilder = class {
|
|
|
1219
1358
|
};
|
|
1220
1359
|
|
|
1221
1360
|
// src/client.ts
|
|
1361
|
+
var SDK_USER_AGENT = `anyformat-typescript-sdk-${package_default.version}`;
|
|
1222
1362
|
var Anyformat = class {
|
|
1223
1363
|
/** @internal */
|
|
1224
1364
|
_client;
|
|
@@ -1228,8 +1368,12 @@ var Anyformat = class {
|
|
|
1228
1368
|
baseUrl: opts.baseUrl ?? "https://api.anyformat.ai",
|
|
1229
1369
|
auth: opts.apiKey,
|
|
1230
1370
|
// Identifies the caller in our logs (Datadog facet). Plain HTTP callers
|
|
1231
|
-
// send no such header and are logged as origin "api".
|
|
1232
|
-
|
|
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
|
+
}
|
|
1233
1377
|
})
|
|
1234
1378
|
);
|
|
1235
1379
|
}
|
|
@@ -1252,6 +1396,42 @@ var Anyformat = class {
|
|
|
1252
1396
|
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1253
1397
|
return workflowId;
|
|
1254
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
|
+
}
|
|
1255
1435
|
};
|
|
1256
1436
|
|
|
1257
1437
|
// src/schema.ts
|
|
@@ -1276,16 +1456,23 @@ export {
|
|
|
1276
1456
|
Anyformat,
|
|
1277
1457
|
AnyformatError,
|
|
1278
1458
|
BadRequest,
|
|
1459
|
+
BadRequestError,
|
|
1279
1460
|
Forbidden,
|
|
1461
|
+
ForbiddenError,
|
|
1280
1462
|
NotFound,
|
|
1463
|
+
NotFoundError,
|
|
1281
1464
|
ParseView,
|
|
1282
1465
|
RateLimited,
|
|
1466
|
+
RateLimitedError,
|
|
1283
1467
|
Result,
|
|
1284
1468
|
Run,
|
|
1285
1469
|
SDKTimeout,
|
|
1470
|
+
SDKTimeoutError,
|
|
1286
1471
|
Schema,
|
|
1287
1472
|
ServerError,
|
|
1288
1473
|
Unauthorized,
|
|
1474
|
+
UnauthorizedError,
|
|
1475
|
+
Upload,
|
|
1289
1476
|
Workflow,
|
|
1290
1477
|
WorkflowBuilder,
|
|
1291
1478
|
WorkflowBuilderError
|