flexorch-sdk 0.1.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/LICENSE +21 -0
- package/README.md +265 -0
- package/dist/chunk-7JBTDKMH.js +87 -0
- package/dist/dataset-IS63EK2G.js +6 -0
- package/dist/index.cjs +722 -0
- package/dist/index.d.cts +279 -0
- package/dist/index.d.ts +279 -0
- package/dist/index.js +576 -0
- package/package.json +54 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Dataset
|
|
3
|
+
} from "./chunk-7JBTDKMH.js";
|
|
4
|
+
|
|
5
|
+
// src/errors.ts
|
|
6
|
+
var FlexOrchError = class extends Error {
|
|
7
|
+
statusCode;
|
|
8
|
+
errorCode;
|
|
9
|
+
constructor(message, statusCode, errorCode) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "FlexOrchError";
|
|
12
|
+
this.statusCode = statusCode;
|
|
13
|
+
this.errorCode = errorCode;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var AuthError = class extends FlexOrchError {
|
|
17
|
+
constructor(message, statusCode = 401, errorCode) {
|
|
18
|
+
super(message, statusCode, errorCode);
|
|
19
|
+
this.name = "AuthError";
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var QuotaError = class extends FlexOrchError {
|
|
23
|
+
remainingCredits;
|
|
24
|
+
resetAt;
|
|
25
|
+
constructor(message, statusCode = 402, errorCode, remainingCredits, resetAt) {
|
|
26
|
+
super(message, statusCode, errorCode);
|
|
27
|
+
this.name = "QuotaError";
|
|
28
|
+
this.remainingCredits = remainingCredits;
|
|
29
|
+
this.resetAt = resetAt;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var RateLimitError = class extends FlexOrchError {
|
|
33
|
+
retryAfter;
|
|
34
|
+
constructor(message, retryAfter = 60) {
|
|
35
|
+
super(message, 429, "RATE_LIMIT_EXCEEDED");
|
|
36
|
+
this.name = "RateLimitError";
|
|
37
|
+
this.retryAfter = retryAfter;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var NotFoundError = class extends FlexOrchError {
|
|
41
|
+
constructor(message, errorCode) {
|
|
42
|
+
super(message, 404, errorCode);
|
|
43
|
+
this.name = "NotFoundError";
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var ValidationError = class extends FlexOrchError {
|
|
47
|
+
constructor(message, errorCode) {
|
|
48
|
+
super(message, 422, errorCode);
|
|
49
|
+
this.name = "ValidationError";
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var ServerError = class extends FlexOrchError {
|
|
53
|
+
constructor(message, statusCode = 500, errorCode) {
|
|
54
|
+
super(message, statusCode, errorCode);
|
|
55
|
+
this.name = "ServerError";
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var JobFailedError = class extends FlexOrchError {
|
|
59
|
+
jobId;
|
|
60
|
+
failureReason;
|
|
61
|
+
constructor(jobId, failureReason) {
|
|
62
|
+
super(`Job ${jobId} failed: ${failureReason}`);
|
|
63
|
+
this.name = "JobFailedError";
|
|
64
|
+
this.jobId = jobId;
|
|
65
|
+
this.failureReason = failureReason;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var JobTimeoutError = class extends FlexOrchError {
|
|
69
|
+
jobId;
|
|
70
|
+
timeout;
|
|
71
|
+
constructor(jobId, timeout) {
|
|
72
|
+
super(`Job ${jobId} did not complete within ${timeout}s`);
|
|
73
|
+
this.name = "JobTimeoutError";
|
|
74
|
+
this.jobId = jobId;
|
|
75
|
+
this.timeout = timeout;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// src/transport.ts
|
|
80
|
+
var RETRY_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
81
|
+
async function parseError(res) {
|
|
82
|
+
const status = res.status;
|
|
83
|
+
let message = `HTTP ${status}`;
|
|
84
|
+
let code = "";
|
|
85
|
+
try {
|
|
86
|
+
const body = await res.json();
|
|
87
|
+
const err = body["error"] ?? {};
|
|
88
|
+
code = String(err["code"] ?? "");
|
|
89
|
+
message = String(err["message"] ?? body["detail"] ?? message);
|
|
90
|
+
} catch {
|
|
91
|
+
message = await res.text().catch(() => message) || message;
|
|
92
|
+
}
|
|
93
|
+
if (status === 401) return new AuthError(message, status, code);
|
|
94
|
+
if (status === 402) return new QuotaError(message, status, code);
|
|
95
|
+
if (status === 404) return new NotFoundError(message, code);
|
|
96
|
+
if (status === 422) return new ValidationError(message, code);
|
|
97
|
+
if (status === 429) {
|
|
98
|
+
const retryAfter = parseInt(res.headers.get("Retry-After") ?? "60") || 60;
|
|
99
|
+
return new RateLimitError(message, retryAfter);
|
|
100
|
+
}
|
|
101
|
+
if (status >= 500) return new ServerError(message, status, code);
|
|
102
|
+
return new FlexOrchError(message, status, code);
|
|
103
|
+
}
|
|
104
|
+
function sleep(ms) {
|
|
105
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
106
|
+
}
|
|
107
|
+
var Transport = class {
|
|
108
|
+
baseUrl;
|
|
109
|
+
defaultHeaders;
|
|
110
|
+
timeout;
|
|
111
|
+
maxRetries;
|
|
112
|
+
fetchFn;
|
|
113
|
+
constructor(apiKey, baseUrl, timeout, maxRetries, fetchFn) {
|
|
114
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
115
|
+
this.timeout = timeout;
|
|
116
|
+
this.maxRetries = maxRetries;
|
|
117
|
+
this.fetchFn = fetchFn ?? globalThis.fetch.bind(globalThis);
|
|
118
|
+
this.defaultHeaders = {
|
|
119
|
+
"X-API-KEY": apiKey,
|
|
120
|
+
"User-Agent": "flexorch-sdk-js/0.1.0"
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
url(path, params) {
|
|
124
|
+
const base = `${this.baseUrl}/${path.replace(/^\//, "")}`;
|
|
125
|
+
if (!params) return base;
|
|
126
|
+
return `${base}?${new URLSearchParams(params)}`;
|
|
127
|
+
}
|
|
128
|
+
async doRequest(method, path, options = {}) {
|
|
129
|
+
const url = this.url(path, options.params);
|
|
130
|
+
const headers = { ...this.defaultHeaders };
|
|
131
|
+
let body;
|
|
132
|
+
if (options.json !== void 0) {
|
|
133
|
+
headers["Content-Type"] = "application/json";
|
|
134
|
+
body = JSON.stringify(options.json);
|
|
135
|
+
} else if (options.form) {
|
|
136
|
+
body = options.form;
|
|
137
|
+
}
|
|
138
|
+
let lastError;
|
|
139
|
+
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
|
140
|
+
const controller = new AbortController();
|
|
141
|
+
const timer = setTimeout(() => controller.abort(), this.timeout * 1e3);
|
|
142
|
+
try {
|
|
143
|
+
const res = await this.fetchFn(url, {
|
|
144
|
+
method,
|
|
145
|
+
headers,
|
|
146
|
+
body,
|
|
147
|
+
signal: controller.signal
|
|
148
|
+
});
|
|
149
|
+
clearTimeout(timer);
|
|
150
|
+
if (RETRY_STATUSES.has(res.status) && attempt < this.maxRetries - 1) {
|
|
151
|
+
const wait = parseInt(res.headers.get("Retry-After") ?? "") || 2 ** attempt;
|
|
152
|
+
await sleep(wait * 1e3);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (!res.ok) throw await parseError(res);
|
|
156
|
+
if (res.status === 204) return null;
|
|
157
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
158
|
+
if (!ct.includes("application/json")) return null;
|
|
159
|
+
const text = await res.text();
|
|
160
|
+
if (!text.trim()) return null;
|
|
161
|
+
return JSON.parse(text);
|
|
162
|
+
} catch (err) {
|
|
163
|
+
clearTimeout(timer);
|
|
164
|
+
if (err instanceof FlexOrchError) throw err;
|
|
165
|
+
lastError = err;
|
|
166
|
+
if (attempt < this.maxRetries - 1) await sleep(2 ** attempt * 1e3);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
throw new FlexOrchError(
|
|
170
|
+
`Request failed after ${this.maxRetries} attempts: ${lastError?.message}`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
async getBytes(path, params) {
|
|
174
|
+
const url = this.url(path, params);
|
|
175
|
+
const res = await this.fetchFn(url, { headers: this.defaultHeaders });
|
|
176
|
+
if (!res.ok) throw await parseError(res);
|
|
177
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
178
|
+
}
|
|
179
|
+
get(path, params) {
|
|
180
|
+
return params ? this.doRequest("GET", path, { params }) : this.doRequest("GET", path);
|
|
181
|
+
}
|
|
182
|
+
post(path, json) {
|
|
183
|
+
return this.doRequest("POST", path, { json });
|
|
184
|
+
}
|
|
185
|
+
postForm(path, form) {
|
|
186
|
+
return this.doRequest("POST", path, { form });
|
|
187
|
+
}
|
|
188
|
+
delete(path) {
|
|
189
|
+
return this.doRequest("DELETE", path);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// src/models/job.ts
|
|
194
|
+
var Job = class _Job {
|
|
195
|
+
id;
|
|
196
|
+
status;
|
|
197
|
+
qualityGrade;
|
|
198
|
+
qualityScore;
|
|
199
|
+
documentId;
|
|
200
|
+
hasDataset;
|
|
201
|
+
failureReason;
|
|
202
|
+
_transport;
|
|
203
|
+
constructor(data) {
|
|
204
|
+
this.id = data.id;
|
|
205
|
+
this.status = data.status;
|
|
206
|
+
this.qualityGrade = data.qualityGrade;
|
|
207
|
+
this.qualityScore = data.qualityScore;
|
|
208
|
+
this.documentId = data.documentId;
|
|
209
|
+
this.hasDataset = data.hasDataset;
|
|
210
|
+
this.failureReason = data.failureReason;
|
|
211
|
+
this._transport = data._transport;
|
|
212
|
+
}
|
|
213
|
+
static fromDict(data, transport) {
|
|
214
|
+
const quality = data["quality"] ?? {};
|
|
215
|
+
return new _Job({
|
|
216
|
+
id: String(data["job_id"] ?? data["id"] ?? ""),
|
|
217
|
+
status: String(data["status"] ?? ""),
|
|
218
|
+
qualityGrade: quality["grade"] ?? null,
|
|
219
|
+
qualityScore: quality["score"] ?? null,
|
|
220
|
+
documentId: data["document_id"] ?? null,
|
|
221
|
+
hasDataset: Boolean(data["has_dataset"] ?? false),
|
|
222
|
+
failureReason: data["failure_reason"] ?? null,
|
|
223
|
+
_transport: transport
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
async wait(opts = {}) {
|
|
227
|
+
const timeout = opts.timeout ?? 300;
|
|
228
|
+
const pollInterval = opts.pollInterval ?? 2;
|
|
229
|
+
const deadline = Date.now() + timeout * 1e3;
|
|
230
|
+
if (this.status === "completed" || this.status === "failed") {
|
|
231
|
+
if (this.status === "failed") {
|
|
232
|
+
throw new JobFailedError(this.id, this.failureReason ?? "unknown");
|
|
233
|
+
}
|
|
234
|
+
return this;
|
|
235
|
+
}
|
|
236
|
+
while (Date.now() < deadline) {
|
|
237
|
+
await sleep2(pollInterval * 1e3);
|
|
238
|
+
const data = await this._transport.get(`/jobs/${this.id}`);
|
|
239
|
+
const updated = _Job.fromDict(data, this._transport);
|
|
240
|
+
if (updated.status === "completed") return updated;
|
|
241
|
+
if (updated.status === "failed") {
|
|
242
|
+
throw new JobFailedError(updated.id, updated.failureReason ?? "unknown");
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
throw new JobTimeoutError(this.id, timeout);
|
|
246
|
+
}
|
|
247
|
+
async dataset() {
|
|
248
|
+
if (!this.hasDataset) return null;
|
|
249
|
+
const data = await this._transport.get("/datasets", {
|
|
250
|
+
job_id: this.id
|
|
251
|
+
});
|
|
252
|
+
const items = data["items"] ?? [];
|
|
253
|
+
if (items.length === 0) return null;
|
|
254
|
+
const { Dataset: Dataset2 } = await import("./dataset-IS63EK2G.js");
|
|
255
|
+
return Dataset2.fromDict(items[0], this._transport);
|
|
256
|
+
}
|
|
257
|
+
toString() {
|
|
258
|
+
return `Job(id=${this.id}, status=${this.status}, grade=${this.qualityGrade})`;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
function sleep2(ms) {
|
|
262
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// src/models/search.ts
|
|
266
|
+
var SearchResult = class _SearchResult {
|
|
267
|
+
chunkId;
|
|
268
|
+
text;
|
|
269
|
+
score;
|
|
270
|
+
datasetId;
|
|
271
|
+
chunkIndex;
|
|
272
|
+
tokenCount;
|
|
273
|
+
metadata;
|
|
274
|
+
constructor(data) {
|
|
275
|
+
this.chunkId = data.chunkId;
|
|
276
|
+
this.text = data.text;
|
|
277
|
+
this.score = data.score;
|
|
278
|
+
this.datasetId = data.datasetId;
|
|
279
|
+
this.chunkIndex = data.chunkIndex;
|
|
280
|
+
this.tokenCount = data.tokenCount;
|
|
281
|
+
this.metadata = data.metadata;
|
|
282
|
+
}
|
|
283
|
+
static fromDict(data) {
|
|
284
|
+
return new _SearchResult({
|
|
285
|
+
chunkId: String(data["chunk_id"] ?? ""),
|
|
286
|
+
text: String(data["text"] ?? ""),
|
|
287
|
+
score: Number(data["score"] ?? 0),
|
|
288
|
+
datasetId: String(data["dataset_id"] ?? ""),
|
|
289
|
+
chunkIndex: Number(data["chunk_index"] ?? 0),
|
|
290
|
+
tokenCount: Number(data["token_count"] ?? 0),
|
|
291
|
+
metadata: data["metadata"] ?? {}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
toString() {
|
|
295
|
+
return `SearchResult(score=${this.score.toFixed(3)}, datasetId=${this.datasetId}, chunkIndex=${this.chunkIndex})`;
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// src/resources/jobs.ts
|
|
300
|
+
var JobsResource = class {
|
|
301
|
+
constructor(_t) {
|
|
302
|
+
this._t = _t;
|
|
303
|
+
}
|
|
304
|
+
_t;
|
|
305
|
+
async get(jobId) {
|
|
306
|
+
const data = await this._t.get(`/jobs/${jobId}`);
|
|
307
|
+
return Job.fromDict(data, this._t);
|
|
308
|
+
}
|
|
309
|
+
async list(opts = {}) {
|
|
310
|
+
const params = {};
|
|
311
|
+
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
312
|
+
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
313
|
+
const data = await this._t.get("/jobs", params);
|
|
314
|
+
const items = data["items"] ?? [];
|
|
315
|
+
return items.map((item) => Job.fromDict(item, this._t));
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// src/resources/datasets.ts
|
|
320
|
+
var DatasetsResource = class {
|
|
321
|
+
constructor(_t) {
|
|
322
|
+
this._t = _t;
|
|
323
|
+
}
|
|
324
|
+
_t;
|
|
325
|
+
async get(datasetId) {
|
|
326
|
+
const data = await this._t.get(`/datasets/${datasetId}`);
|
|
327
|
+
return Dataset.fromDict(data, this._t);
|
|
328
|
+
}
|
|
329
|
+
async list(opts = {}) {
|
|
330
|
+
const params = {};
|
|
331
|
+
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
332
|
+
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
333
|
+
const data = await this._t.get("/datasets", params);
|
|
334
|
+
const items = data["items"] ?? [];
|
|
335
|
+
return items.map((item) => Dataset.fromDict(item, this._t));
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
// src/resources/usage.ts
|
|
340
|
+
var UsageResource = class {
|
|
341
|
+
constructor(_t) {
|
|
342
|
+
this._t = _t;
|
|
343
|
+
}
|
|
344
|
+
_t;
|
|
345
|
+
async current() {
|
|
346
|
+
const data = await this._t.get("/usage/current");
|
|
347
|
+
return {
|
|
348
|
+
plan: String(data["plan"] ?? ""),
|
|
349
|
+
creditsUsed: Number(data["credits_used"] ?? 0),
|
|
350
|
+
creditsLimit: Number(data["credits_limit"] ?? 0),
|
|
351
|
+
creditsRemaining: Number(data["credits_remaining"] ?? 0),
|
|
352
|
+
resetAt: String(data["reset_at"] ?? ""),
|
|
353
|
+
periodStart: String(data["period_start"] ?? ""),
|
|
354
|
+
periodEnd: String(data["period_end"] ?? "")
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
// src/resources/webhooks.ts
|
|
360
|
+
var VALID_EVENTS = /* @__PURE__ */ new Set(["dataset.ready", "job.completed", "job.failed"]);
|
|
361
|
+
function webhookFromDict(data) {
|
|
362
|
+
return {
|
|
363
|
+
id: String(data["id"] ?? ""),
|
|
364
|
+
url: String(data["url"] ?? ""),
|
|
365
|
+
events: data["events"] ?? [],
|
|
366
|
+
active: Boolean(data["active"] ?? true),
|
|
367
|
+
createdAt: String(data["created_at"] ?? "")
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
var WebhooksResource = class {
|
|
371
|
+
constructor(_t) {
|
|
372
|
+
this._t = _t;
|
|
373
|
+
}
|
|
374
|
+
_t;
|
|
375
|
+
async register(url, events) {
|
|
376
|
+
const invalid = events.filter((e) => !VALID_EVENTS.has(e));
|
|
377
|
+
if (invalid.length > 0) {
|
|
378
|
+
throw new Error(`Unknown event types: ${invalid.join(", ")}. Valid: ${[...VALID_EVENTS].join(", ")}`);
|
|
379
|
+
}
|
|
380
|
+
const data = await this._t.post("/webhooks", { url, events });
|
|
381
|
+
return webhookFromDict(data);
|
|
382
|
+
}
|
|
383
|
+
async list() {
|
|
384
|
+
const data = await this._t.get("/webhooks");
|
|
385
|
+
const items = data["items"] ?? [];
|
|
386
|
+
return items.map(webhookFromDict);
|
|
387
|
+
}
|
|
388
|
+
async delete(webhookId) {
|
|
389
|
+
await this._t.delete(`/webhooks/${webhookId}`);
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
// src/models/connector.ts
|
|
394
|
+
var Connector = class _Connector {
|
|
395
|
+
id;
|
|
396
|
+
name;
|
|
397
|
+
type;
|
|
398
|
+
active;
|
|
399
|
+
lastTestedAt;
|
|
400
|
+
lastUsedAt;
|
|
401
|
+
createdAt;
|
|
402
|
+
constructor(data) {
|
|
403
|
+
this.id = data.id;
|
|
404
|
+
this.name = data.name;
|
|
405
|
+
this.type = data.type;
|
|
406
|
+
this.active = data.active;
|
|
407
|
+
this.lastTestedAt = data.lastTestedAt;
|
|
408
|
+
this.lastUsedAt = data.lastUsedAt;
|
|
409
|
+
this.createdAt = data.createdAt;
|
|
410
|
+
}
|
|
411
|
+
static fromDict(data) {
|
|
412
|
+
return new _Connector({
|
|
413
|
+
id: String(data["id"] ?? ""),
|
|
414
|
+
name: String(data["name"] ?? ""),
|
|
415
|
+
type: String(data["type"] ?? ""),
|
|
416
|
+
active: Boolean(data["active"] ?? true),
|
|
417
|
+
lastTestedAt: data["last_tested_at"] ?? null,
|
|
418
|
+
lastUsedAt: data["last_used_at"] ?? null,
|
|
419
|
+
createdAt: String(data["created_at"] ?? "")
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
toString() {
|
|
423
|
+
return `Connector(id=${this.id}, name=${this.name}, type=${this.type})`;
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
// src/resources/connectors.ts
|
|
428
|
+
var VALID_TYPES = /* @__PURE__ */ new Set(["s3", "gcs", "azure_blob"]);
|
|
429
|
+
var ConnectorsResource = class {
|
|
430
|
+
constructor(_t) {
|
|
431
|
+
this._t = _t;
|
|
432
|
+
}
|
|
433
|
+
_t;
|
|
434
|
+
async create(name, type, config) {
|
|
435
|
+
if (!VALID_TYPES.has(type)) {
|
|
436
|
+
throw new Error(`Unknown connector type "${type}". Valid: ${[...VALID_TYPES].join(", ")}`);
|
|
437
|
+
}
|
|
438
|
+
const data = await this._t.post("/connectors", { name, type, config });
|
|
439
|
+
return Connector.fromDict(data);
|
|
440
|
+
}
|
|
441
|
+
async list() {
|
|
442
|
+
const data = await this._t.get("/connectors");
|
|
443
|
+
const items = data["items"] ?? [];
|
|
444
|
+
return items.map(Connector.fromDict);
|
|
445
|
+
}
|
|
446
|
+
async get(connectorId) {
|
|
447
|
+
const data = await this._t.get(`/connectors/${connectorId}`);
|
|
448
|
+
return Connector.fromDict(data);
|
|
449
|
+
}
|
|
450
|
+
async delete(connectorId) {
|
|
451
|
+
await this._t.delete(`/connectors/${connectorId}`);
|
|
452
|
+
}
|
|
453
|
+
async test(connectorId) {
|
|
454
|
+
const data = await this._t.post(`/connectors/${connectorId}/test`) ?? {};
|
|
455
|
+
return {
|
|
456
|
+
success: Boolean(data["success"] ?? false),
|
|
457
|
+
latencyMs: data["latency_ms"] !== void 0 ? Number(data["latency_ms"]) : null,
|
|
458
|
+
message: String(data["message"] ?? "")
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
// src/client.ts
|
|
464
|
+
var DEFAULT_BASE_URL = "https://api.flexorch.com/v1";
|
|
465
|
+
var FlexOrchClient = class {
|
|
466
|
+
jobs;
|
|
467
|
+
datasets;
|
|
468
|
+
usage;
|
|
469
|
+
webhooks;
|
|
470
|
+
connectors;
|
|
471
|
+
_transport;
|
|
472
|
+
constructor(apiKeyOrOptions = {}) {
|
|
473
|
+
const opts = typeof apiKeyOrOptions === "string" ? { apiKey: apiKeyOrOptions } : apiKeyOrOptions;
|
|
474
|
+
const apiKey = opts.apiKey ?? process.env["FLEXORCH_API_KEY"] ?? "";
|
|
475
|
+
if (!apiKey) {
|
|
476
|
+
throw new Error(
|
|
477
|
+
"No API key provided. Pass apiKey or set the FLEXORCH_API_KEY environment variable."
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
this._transport = new Transport(
|
|
481
|
+
apiKey,
|
|
482
|
+
opts.baseUrl ?? DEFAULT_BASE_URL,
|
|
483
|
+
opts.timeout ?? 30,
|
|
484
|
+
opts.maxRetries ?? 3,
|
|
485
|
+
opts._fetch
|
|
486
|
+
);
|
|
487
|
+
this.jobs = new JobsResource(this._transport);
|
|
488
|
+
this.datasets = new DatasetsResource(this._transport);
|
|
489
|
+
this.usage = new UsageResource(this._transport);
|
|
490
|
+
this.webhooks = new WebhooksResource(this._transport);
|
|
491
|
+
this.connectors = new ConnectorsResource(this._transport);
|
|
492
|
+
}
|
|
493
|
+
async process(filePath, opts = {}) {
|
|
494
|
+
const { createReadStream, statSync } = await import("fs");
|
|
495
|
+
const { basename } = await import("path");
|
|
496
|
+
if (!statSync(filePath, { throwIfNoEntry: false })) {
|
|
497
|
+
throw new Error(`File not found: ${filePath}`);
|
|
498
|
+
}
|
|
499
|
+
const form = new FormData();
|
|
500
|
+
const stream = createReadStream(filePath);
|
|
501
|
+
const chunks = [];
|
|
502
|
+
for await (const chunk of stream) {
|
|
503
|
+
chunks.push(chunk);
|
|
504
|
+
}
|
|
505
|
+
const blob = new Blob([Buffer.concat(chunks)], { type: "application/octet-stream" });
|
|
506
|
+
form.append("file", blob, basename(filePath));
|
|
507
|
+
form.append("locale", opts.locale ?? "und");
|
|
508
|
+
if (opts.pipelineConfig) {
|
|
509
|
+
form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
|
|
510
|
+
}
|
|
511
|
+
const data = await this._transport.postForm("/data-process/async", form);
|
|
512
|
+
return Job.fromDict(data, this._transport);
|
|
513
|
+
}
|
|
514
|
+
async processMany(filePaths, opts = {}) {
|
|
515
|
+
const jobs = [];
|
|
516
|
+
for (const fp of filePaths) {
|
|
517
|
+
jobs.push(await this.process(fp, opts));
|
|
518
|
+
}
|
|
519
|
+
return jobs;
|
|
520
|
+
}
|
|
521
|
+
async processFromS3(connectorId, keys, opts = {}) {
|
|
522
|
+
const jobs = [];
|
|
523
|
+
for (const key of keys) {
|
|
524
|
+
const form = new FormData();
|
|
525
|
+
form.append("locale", opts.locale ?? "und");
|
|
526
|
+
form.append("source", JSON.stringify({ connector_id: connectorId, keys: [key] }));
|
|
527
|
+
if (opts.pipelineConfig) {
|
|
528
|
+
form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
|
|
529
|
+
}
|
|
530
|
+
const data = await this._transport.postForm("/data-process/async", form);
|
|
531
|
+
jobs.push(Job.fromDict(data, this._transport));
|
|
532
|
+
}
|
|
533
|
+
return jobs;
|
|
534
|
+
}
|
|
535
|
+
async search(query, opts = {}) {
|
|
536
|
+
const body = {
|
|
537
|
+
query,
|
|
538
|
+
top_k: opts.topK ?? 10
|
|
539
|
+
};
|
|
540
|
+
if (opts.filters) {
|
|
541
|
+
const f = opts.filters;
|
|
542
|
+
const mapped = {};
|
|
543
|
+
if (f.documentType !== void 0) mapped["document_type"] = f.documentType;
|
|
544
|
+
if (f.language !== void 0) mapped["language"] = f.language;
|
|
545
|
+
if (f.piiMasked !== void 0) mapped["pii_masked"] = f.piiMasked;
|
|
546
|
+
if (f.qualityGrade !== void 0) mapped["quality_grade"] = f.qualityGrade;
|
|
547
|
+
body["filters"] = mapped;
|
|
548
|
+
}
|
|
549
|
+
const data = await this._transport.post("/search", body) ?? {};
|
|
550
|
+
const results = data["results"] ?? [];
|
|
551
|
+
return results.map(SearchResult.fromDict);
|
|
552
|
+
}
|
|
553
|
+
toString() {
|
|
554
|
+
return `FlexOrchClient(baseUrl=${DEFAULT_BASE_URL})`;
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
// src/index.ts
|
|
559
|
+
var version = "0.1.0";
|
|
560
|
+
export {
|
|
561
|
+
AuthError,
|
|
562
|
+
Connector,
|
|
563
|
+
Dataset,
|
|
564
|
+
FlexOrchClient,
|
|
565
|
+
FlexOrchError,
|
|
566
|
+
Job,
|
|
567
|
+
JobFailedError,
|
|
568
|
+
JobTimeoutError,
|
|
569
|
+
NotFoundError,
|
|
570
|
+
QuotaError,
|
|
571
|
+
RateLimitError,
|
|
572
|
+
SearchResult,
|
|
573
|
+
ServerError,
|
|
574
|
+
ValidationError,
|
|
575
|
+
version
|
|
576
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "flexorch-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript/JavaScript SDK for the FlexOrch API — process documents, build LLM-ready datasets",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup src/index.ts --format esm,cjs --dts --clean",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"prepublishOnly": "npm run build && npm test"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"llm",
|
|
28
|
+
"dataset",
|
|
29
|
+
"document",
|
|
30
|
+
"pipeline",
|
|
31
|
+
"flexorch",
|
|
32
|
+
"pii",
|
|
33
|
+
"rag"
|
|
34
|
+
],
|
|
35
|
+
"author": "Flexorch Technology",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"homepage": "https://flexorch.com",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/flexorch/flexorch-sdk-js"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/flexorch/flexorch-sdk-js/issues"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"tsup": "^8.3.0",
|
|
50
|
+
"typescript": "^5.4.0",
|
|
51
|
+
"@types/node": "^20.0.0",
|
|
52
|
+
"vitest": "^2.0.0"
|
|
53
|
+
}
|
|
54
|
+
}
|