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.cjs
ADDED
|
@@ -0,0 +1,722 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
|
|
33
|
+
// src/models/dataset.ts
|
|
34
|
+
var dataset_exports = {};
|
|
35
|
+
__export(dataset_exports, {
|
|
36
|
+
Dataset: () => Dataset
|
|
37
|
+
});
|
|
38
|
+
var SUPPORTED_FORMATS, Dataset;
|
|
39
|
+
var init_dataset = __esm({
|
|
40
|
+
"src/models/dataset.ts"() {
|
|
41
|
+
"use strict";
|
|
42
|
+
SUPPORTED_FORMATS = /* @__PURE__ */ new Set([
|
|
43
|
+
"json",
|
|
44
|
+
"jsonl",
|
|
45
|
+
"csv",
|
|
46
|
+
"parquet",
|
|
47
|
+
"md",
|
|
48
|
+
"xml",
|
|
49
|
+
"xlsx",
|
|
50
|
+
"rag"
|
|
51
|
+
]);
|
|
52
|
+
Dataset = class _Dataset {
|
|
53
|
+
id;
|
|
54
|
+
name;
|
|
55
|
+
slug;
|
|
56
|
+
status;
|
|
57
|
+
rowCount;
|
|
58
|
+
createdAt;
|
|
59
|
+
availableFormats;
|
|
60
|
+
_transport;
|
|
61
|
+
constructor(data) {
|
|
62
|
+
this.id = data.id;
|
|
63
|
+
this.name = data.name;
|
|
64
|
+
this.slug = data.slug;
|
|
65
|
+
this.status = data.status;
|
|
66
|
+
this.rowCount = data.rowCount;
|
|
67
|
+
this.createdAt = data.createdAt;
|
|
68
|
+
this.availableFormats = data.availableFormats;
|
|
69
|
+
this._transport = data._transport;
|
|
70
|
+
}
|
|
71
|
+
static fromDict(data, transport) {
|
|
72
|
+
const fmt = data["format_summary"] ?? {};
|
|
73
|
+
const files = fmt["files"] ?? {};
|
|
74
|
+
return new _Dataset({
|
|
75
|
+
id: String(data["id"] ?? ""),
|
|
76
|
+
name: String(data["name"] ?? ""),
|
|
77
|
+
slug: String(data["slug"] ?? ""),
|
|
78
|
+
status: String(data["status"] ?? ""),
|
|
79
|
+
rowCount: Number(data["row_count"] ?? 0),
|
|
80
|
+
createdAt: String(data["created_at"] ?? ""),
|
|
81
|
+
availableFormats: Object.keys(files),
|
|
82
|
+
_transport: transport
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async export(format) {
|
|
86
|
+
if (!SUPPORTED_FORMATS.has(format)) {
|
|
87
|
+
throw new Error(`Unsupported format "${format}". Choose from: ${[...SUPPORTED_FORMATS].sort().join(", ")}`);
|
|
88
|
+
}
|
|
89
|
+
return this._transport.getBytes(`/datasets/${this.id}/export`, { format });
|
|
90
|
+
}
|
|
91
|
+
async exportToS3(connectorId, format, prefix = "") {
|
|
92
|
+
if (!SUPPORTED_FORMATS.has(format)) {
|
|
93
|
+
throw new Error(`Unsupported format "${format}". Choose from: ${[...SUPPORTED_FORMATS].sort().join(", ")}`);
|
|
94
|
+
}
|
|
95
|
+
const data = await this._transport.post(`/datasets/${this.id}/export-s3`, {
|
|
96
|
+
format,
|
|
97
|
+
connector_id: connectorId,
|
|
98
|
+
prefix
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
s3Key: String(data["s3_key"] ?? ""),
|
|
102
|
+
sizeBytes: Number(data["size_bytes"] ?? 0)
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
async index() {
|
|
106
|
+
const data = await this._transport.post(`/datasets/${this.id}/index`) ?? {};
|
|
107
|
+
return {
|
|
108
|
+
status: String(data["status"] ?? ""),
|
|
109
|
+
message: String(data["message"] ?? "")
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
async indexStatus() {
|
|
113
|
+
const data = await this._transport.get(`/datasets/${this.id}/index/status`) ?? {};
|
|
114
|
+
return {
|
|
115
|
+
status: String(data["status"] ?? "not_indexed"),
|
|
116
|
+
chunksIndexed: Number(data["chunks_indexed"] ?? 0),
|
|
117
|
+
totalChunks: Number(data["total_chunks"] ?? 0)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
toString() {
|
|
121
|
+
return `Dataset(id=${this.id}, name=${this.name}, rows=${this.rowCount}, status=${this.status})`;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// src/index.ts
|
|
128
|
+
var index_exports = {};
|
|
129
|
+
__export(index_exports, {
|
|
130
|
+
AuthError: () => AuthError,
|
|
131
|
+
Connector: () => Connector,
|
|
132
|
+
Dataset: () => Dataset,
|
|
133
|
+
FlexOrchClient: () => FlexOrchClient,
|
|
134
|
+
FlexOrchError: () => FlexOrchError,
|
|
135
|
+
Job: () => Job,
|
|
136
|
+
JobFailedError: () => JobFailedError,
|
|
137
|
+
JobTimeoutError: () => JobTimeoutError,
|
|
138
|
+
NotFoundError: () => NotFoundError,
|
|
139
|
+
QuotaError: () => QuotaError,
|
|
140
|
+
RateLimitError: () => RateLimitError,
|
|
141
|
+
SearchResult: () => SearchResult,
|
|
142
|
+
ServerError: () => ServerError,
|
|
143
|
+
ValidationError: () => ValidationError,
|
|
144
|
+
version: () => version
|
|
145
|
+
});
|
|
146
|
+
module.exports = __toCommonJS(index_exports);
|
|
147
|
+
|
|
148
|
+
// src/errors.ts
|
|
149
|
+
var FlexOrchError = class extends Error {
|
|
150
|
+
statusCode;
|
|
151
|
+
errorCode;
|
|
152
|
+
constructor(message, statusCode, errorCode) {
|
|
153
|
+
super(message);
|
|
154
|
+
this.name = "FlexOrchError";
|
|
155
|
+
this.statusCode = statusCode;
|
|
156
|
+
this.errorCode = errorCode;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
var AuthError = class extends FlexOrchError {
|
|
160
|
+
constructor(message, statusCode = 401, errorCode) {
|
|
161
|
+
super(message, statusCode, errorCode);
|
|
162
|
+
this.name = "AuthError";
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
var QuotaError = class extends FlexOrchError {
|
|
166
|
+
remainingCredits;
|
|
167
|
+
resetAt;
|
|
168
|
+
constructor(message, statusCode = 402, errorCode, remainingCredits, resetAt) {
|
|
169
|
+
super(message, statusCode, errorCode);
|
|
170
|
+
this.name = "QuotaError";
|
|
171
|
+
this.remainingCredits = remainingCredits;
|
|
172
|
+
this.resetAt = resetAt;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
var RateLimitError = class extends FlexOrchError {
|
|
176
|
+
retryAfter;
|
|
177
|
+
constructor(message, retryAfter = 60) {
|
|
178
|
+
super(message, 429, "RATE_LIMIT_EXCEEDED");
|
|
179
|
+
this.name = "RateLimitError";
|
|
180
|
+
this.retryAfter = retryAfter;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
var NotFoundError = class extends FlexOrchError {
|
|
184
|
+
constructor(message, errorCode) {
|
|
185
|
+
super(message, 404, errorCode);
|
|
186
|
+
this.name = "NotFoundError";
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
var ValidationError = class extends FlexOrchError {
|
|
190
|
+
constructor(message, errorCode) {
|
|
191
|
+
super(message, 422, errorCode);
|
|
192
|
+
this.name = "ValidationError";
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
var ServerError = class extends FlexOrchError {
|
|
196
|
+
constructor(message, statusCode = 500, errorCode) {
|
|
197
|
+
super(message, statusCode, errorCode);
|
|
198
|
+
this.name = "ServerError";
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
var JobFailedError = class extends FlexOrchError {
|
|
202
|
+
jobId;
|
|
203
|
+
failureReason;
|
|
204
|
+
constructor(jobId, failureReason) {
|
|
205
|
+
super(`Job ${jobId} failed: ${failureReason}`);
|
|
206
|
+
this.name = "JobFailedError";
|
|
207
|
+
this.jobId = jobId;
|
|
208
|
+
this.failureReason = failureReason;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
var JobTimeoutError = class extends FlexOrchError {
|
|
212
|
+
jobId;
|
|
213
|
+
timeout;
|
|
214
|
+
constructor(jobId, timeout) {
|
|
215
|
+
super(`Job ${jobId} did not complete within ${timeout}s`);
|
|
216
|
+
this.name = "JobTimeoutError";
|
|
217
|
+
this.jobId = jobId;
|
|
218
|
+
this.timeout = timeout;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// src/transport.ts
|
|
223
|
+
var RETRY_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
224
|
+
async function parseError(res) {
|
|
225
|
+
const status = res.status;
|
|
226
|
+
let message = `HTTP ${status}`;
|
|
227
|
+
let code = "";
|
|
228
|
+
try {
|
|
229
|
+
const body = await res.json();
|
|
230
|
+
const err = body["error"] ?? {};
|
|
231
|
+
code = String(err["code"] ?? "");
|
|
232
|
+
message = String(err["message"] ?? body["detail"] ?? message);
|
|
233
|
+
} catch {
|
|
234
|
+
message = await res.text().catch(() => message) || message;
|
|
235
|
+
}
|
|
236
|
+
if (status === 401) return new AuthError(message, status, code);
|
|
237
|
+
if (status === 402) return new QuotaError(message, status, code);
|
|
238
|
+
if (status === 404) return new NotFoundError(message, code);
|
|
239
|
+
if (status === 422) return new ValidationError(message, code);
|
|
240
|
+
if (status === 429) {
|
|
241
|
+
const retryAfter = parseInt(res.headers.get("Retry-After") ?? "60") || 60;
|
|
242
|
+
return new RateLimitError(message, retryAfter);
|
|
243
|
+
}
|
|
244
|
+
if (status >= 500) return new ServerError(message, status, code);
|
|
245
|
+
return new FlexOrchError(message, status, code);
|
|
246
|
+
}
|
|
247
|
+
function sleep(ms) {
|
|
248
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
249
|
+
}
|
|
250
|
+
var Transport = class {
|
|
251
|
+
baseUrl;
|
|
252
|
+
defaultHeaders;
|
|
253
|
+
timeout;
|
|
254
|
+
maxRetries;
|
|
255
|
+
fetchFn;
|
|
256
|
+
constructor(apiKey, baseUrl, timeout, maxRetries, fetchFn) {
|
|
257
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
258
|
+
this.timeout = timeout;
|
|
259
|
+
this.maxRetries = maxRetries;
|
|
260
|
+
this.fetchFn = fetchFn ?? globalThis.fetch.bind(globalThis);
|
|
261
|
+
this.defaultHeaders = {
|
|
262
|
+
"X-API-KEY": apiKey,
|
|
263
|
+
"User-Agent": "flexorch-sdk-js/0.1.0"
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
url(path, params) {
|
|
267
|
+
const base = `${this.baseUrl}/${path.replace(/^\//, "")}`;
|
|
268
|
+
if (!params) return base;
|
|
269
|
+
return `${base}?${new URLSearchParams(params)}`;
|
|
270
|
+
}
|
|
271
|
+
async doRequest(method, path, options = {}) {
|
|
272
|
+
const url = this.url(path, options.params);
|
|
273
|
+
const headers = { ...this.defaultHeaders };
|
|
274
|
+
let body;
|
|
275
|
+
if (options.json !== void 0) {
|
|
276
|
+
headers["Content-Type"] = "application/json";
|
|
277
|
+
body = JSON.stringify(options.json);
|
|
278
|
+
} else if (options.form) {
|
|
279
|
+
body = options.form;
|
|
280
|
+
}
|
|
281
|
+
let lastError;
|
|
282
|
+
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
|
283
|
+
const controller = new AbortController();
|
|
284
|
+
const timer = setTimeout(() => controller.abort(), this.timeout * 1e3);
|
|
285
|
+
try {
|
|
286
|
+
const res = await this.fetchFn(url, {
|
|
287
|
+
method,
|
|
288
|
+
headers,
|
|
289
|
+
body,
|
|
290
|
+
signal: controller.signal
|
|
291
|
+
});
|
|
292
|
+
clearTimeout(timer);
|
|
293
|
+
if (RETRY_STATUSES.has(res.status) && attempt < this.maxRetries - 1) {
|
|
294
|
+
const wait = parseInt(res.headers.get("Retry-After") ?? "") || 2 ** attempt;
|
|
295
|
+
await sleep(wait * 1e3);
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (!res.ok) throw await parseError(res);
|
|
299
|
+
if (res.status === 204) return null;
|
|
300
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
301
|
+
if (!ct.includes("application/json")) return null;
|
|
302
|
+
const text = await res.text();
|
|
303
|
+
if (!text.trim()) return null;
|
|
304
|
+
return JSON.parse(text);
|
|
305
|
+
} catch (err) {
|
|
306
|
+
clearTimeout(timer);
|
|
307
|
+
if (err instanceof FlexOrchError) throw err;
|
|
308
|
+
lastError = err;
|
|
309
|
+
if (attempt < this.maxRetries - 1) await sleep(2 ** attempt * 1e3);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
throw new FlexOrchError(
|
|
313
|
+
`Request failed after ${this.maxRetries} attempts: ${lastError?.message}`
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
async getBytes(path, params) {
|
|
317
|
+
const url = this.url(path, params);
|
|
318
|
+
const res = await this.fetchFn(url, { headers: this.defaultHeaders });
|
|
319
|
+
if (!res.ok) throw await parseError(res);
|
|
320
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
321
|
+
}
|
|
322
|
+
get(path, params) {
|
|
323
|
+
return params ? this.doRequest("GET", path, { params }) : this.doRequest("GET", path);
|
|
324
|
+
}
|
|
325
|
+
post(path, json) {
|
|
326
|
+
return this.doRequest("POST", path, { json });
|
|
327
|
+
}
|
|
328
|
+
postForm(path, form) {
|
|
329
|
+
return this.doRequest("POST", path, { form });
|
|
330
|
+
}
|
|
331
|
+
delete(path) {
|
|
332
|
+
return this.doRequest("DELETE", path);
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// src/models/job.ts
|
|
337
|
+
var Job = class _Job {
|
|
338
|
+
id;
|
|
339
|
+
status;
|
|
340
|
+
qualityGrade;
|
|
341
|
+
qualityScore;
|
|
342
|
+
documentId;
|
|
343
|
+
hasDataset;
|
|
344
|
+
failureReason;
|
|
345
|
+
_transport;
|
|
346
|
+
constructor(data) {
|
|
347
|
+
this.id = data.id;
|
|
348
|
+
this.status = data.status;
|
|
349
|
+
this.qualityGrade = data.qualityGrade;
|
|
350
|
+
this.qualityScore = data.qualityScore;
|
|
351
|
+
this.documentId = data.documentId;
|
|
352
|
+
this.hasDataset = data.hasDataset;
|
|
353
|
+
this.failureReason = data.failureReason;
|
|
354
|
+
this._transport = data._transport;
|
|
355
|
+
}
|
|
356
|
+
static fromDict(data, transport) {
|
|
357
|
+
const quality = data["quality"] ?? {};
|
|
358
|
+
return new _Job({
|
|
359
|
+
id: String(data["job_id"] ?? data["id"] ?? ""),
|
|
360
|
+
status: String(data["status"] ?? ""),
|
|
361
|
+
qualityGrade: quality["grade"] ?? null,
|
|
362
|
+
qualityScore: quality["score"] ?? null,
|
|
363
|
+
documentId: data["document_id"] ?? null,
|
|
364
|
+
hasDataset: Boolean(data["has_dataset"] ?? false),
|
|
365
|
+
failureReason: data["failure_reason"] ?? null,
|
|
366
|
+
_transport: transport
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
async wait(opts = {}) {
|
|
370
|
+
const timeout = opts.timeout ?? 300;
|
|
371
|
+
const pollInterval = opts.pollInterval ?? 2;
|
|
372
|
+
const deadline = Date.now() + timeout * 1e3;
|
|
373
|
+
if (this.status === "completed" || this.status === "failed") {
|
|
374
|
+
if (this.status === "failed") {
|
|
375
|
+
throw new JobFailedError(this.id, this.failureReason ?? "unknown");
|
|
376
|
+
}
|
|
377
|
+
return this;
|
|
378
|
+
}
|
|
379
|
+
while (Date.now() < deadline) {
|
|
380
|
+
await sleep2(pollInterval * 1e3);
|
|
381
|
+
const data = await this._transport.get(`/jobs/${this.id}`);
|
|
382
|
+
const updated = _Job.fromDict(data, this._transport);
|
|
383
|
+
if (updated.status === "completed") return updated;
|
|
384
|
+
if (updated.status === "failed") {
|
|
385
|
+
throw new JobFailedError(updated.id, updated.failureReason ?? "unknown");
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
throw new JobTimeoutError(this.id, timeout);
|
|
389
|
+
}
|
|
390
|
+
async dataset() {
|
|
391
|
+
if (!this.hasDataset) return null;
|
|
392
|
+
const data = await this._transport.get("/datasets", {
|
|
393
|
+
job_id: this.id
|
|
394
|
+
});
|
|
395
|
+
const items = data["items"] ?? [];
|
|
396
|
+
if (items.length === 0) return null;
|
|
397
|
+
const { Dataset: Dataset2 } = await Promise.resolve().then(() => (init_dataset(), dataset_exports));
|
|
398
|
+
return Dataset2.fromDict(items[0], this._transport);
|
|
399
|
+
}
|
|
400
|
+
toString() {
|
|
401
|
+
return `Job(id=${this.id}, status=${this.status}, grade=${this.qualityGrade})`;
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
function sleep2(ms) {
|
|
405
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// src/models/search.ts
|
|
409
|
+
var SearchResult = class _SearchResult {
|
|
410
|
+
chunkId;
|
|
411
|
+
text;
|
|
412
|
+
score;
|
|
413
|
+
datasetId;
|
|
414
|
+
chunkIndex;
|
|
415
|
+
tokenCount;
|
|
416
|
+
metadata;
|
|
417
|
+
constructor(data) {
|
|
418
|
+
this.chunkId = data.chunkId;
|
|
419
|
+
this.text = data.text;
|
|
420
|
+
this.score = data.score;
|
|
421
|
+
this.datasetId = data.datasetId;
|
|
422
|
+
this.chunkIndex = data.chunkIndex;
|
|
423
|
+
this.tokenCount = data.tokenCount;
|
|
424
|
+
this.metadata = data.metadata;
|
|
425
|
+
}
|
|
426
|
+
static fromDict(data) {
|
|
427
|
+
return new _SearchResult({
|
|
428
|
+
chunkId: String(data["chunk_id"] ?? ""),
|
|
429
|
+
text: String(data["text"] ?? ""),
|
|
430
|
+
score: Number(data["score"] ?? 0),
|
|
431
|
+
datasetId: String(data["dataset_id"] ?? ""),
|
|
432
|
+
chunkIndex: Number(data["chunk_index"] ?? 0),
|
|
433
|
+
tokenCount: Number(data["token_count"] ?? 0),
|
|
434
|
+
metadata: data["metadata"] ?? {}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
toString() {
|
|
438
|
+
return `SearchResult(score=${this.score.toFixed(3)}, datasetId=${this.datasetId}, chunkIndex=${this.chunkIndex})`;
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
// src/resources/jobs.ts
|
|
443
|
+
var JobsResource = class {
|
|
444
|
+
constructor(_t) {
|
|
445
|
+
this._t = _t;
|
|
446
|
+
}
|
|
447
|
+
_t;
|
|
448
|
+
async get(jobId) {
|
|
449
|
+
const data = await this._t.get(`/jobs/${jobId}`);
|
|
450
|
+
return Job.fromDict(data, this._t);
|
|
451
|
+
}
|
|
452
|
+
async list(opts = {}) {
|
|
453
|
+
const params = {};
|
|
454
|
+
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
455
|
+
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
456
|
+
const data = await this._t.get("/jobs", params);
|
|
457
|
+
const items = data["items"] ?? [];
|
|
458
|
+
return items.map((item) => Job.fromDict(item, this._t));
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
// src/resources/datasets.ts
|
|
463
|
+
init_dataset();
|
|
464
|
+
var DatasetsResource = class {
|
|
465
|
+
constructor(_t) {
|
|
466
|
+
this._t = _t;
|
|
467
|
+
}
|
|
468
|
+
_t;
|
|
469
|
+
async get(datasetId) {
|
|
470
|
+
const data = await this._t.get(`/datasets/${datasetId}`);
|
|
471
|
+
return Dataset.fromDict(data, this._t);
|
|
472
|
+
}
|
|
473
|
+
async list(opts = {}) {
|
|
474
|
+
const params = {};
|
|
475
|
+
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
476
|
+
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
477
|
+
const data = await this._t.get("/datasets", params);
|
|
478
|
+
const items = data["items"] ?? [];
|
|
479
|
+
return items.map((item) => Dataset.fromDict(item, this._t));
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
// src/resources/usage.ts
|
|
484
|
+
var UsageResource = class {
|
|
485
|
+
constructor(_t) {
|
|
486
|
+
this._t = _t;
|
|
487
|
+
}
|
|
488
|
+
_t;
|
|
489
|
+
async current() {
|
|
490
|
+
const data = await this._t.get("/usage/current");
|
|
491
|
+
return {
|
|
492
|
+
plan: String(data["plan"] ?? ""),
|
|
493
|
+
creditsUsed: Number(data["credits_used"] ?? 0),
|
|
494
|
+
creditsLimit: Number(data["credits_limit"] ?? 0),
|
|
495
|
+
creditsRemaining: Number(data["credits_remaining"] ?? 0),
|
|
496
|
+
resetAt: String(data["reset_at"] ?? ""),
|
|
497
|
+
periodStart: String(data["period_start"] ?? ""),
|
|
498
|
+
periodEnd: String(data["period_end"] ?? "")
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
// src/resources/webhooks.ts
|
|
504
|
+
var VALID_EVENTS = /* @__PURE__ */ new Set(["dataset.ready", "job.completed", "job.failed"]);
|
|
505
|
+
function webhookFromDict(data) {
|
|
506
|
+
return {
|
|
507
|
+
id: String(data["id"] ?? ""),
|
|
508
|
+
url: String(data["url"] ?? ""),
|
|
509
|
+
events: data["events"] ?? [],
|
|
510
|
+
active: Boolean(data["active"] ?? true),
|
|
511
|
+
createdAt: String(data["created_at"] ?? "")
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
var WebhooksResource = class {
|
|
515
|
+
constructor(_t) {
|
|
516
|
+
this._t = _t;
|
|
517
|
+
}
|
|
518
|
+
_t;
|
|
519
|
+
async register(url, events) {
|
|
520
|
+
const invalid = events.filter((e) => !VALID_EVENTS.has(e));
|
|
521
|
+
if (invalid.length > 0) {
|
|
522
|
+
throw new Error(`Unknown event types: ${invalid.join(", ")}. Valid: ${[...VALID_EVENTS].join(", ")}`);
|
|
523
|
+
}
|
|
524
|
+
const data = await this._t.post("/webhooks", { url, events });
|
|
525
|
+
return webhookFromDict(data);
|
|
526
|
+
}
|
|
527
|
+
async list() {
|
|
528
|
+
const data = await this._t.get("/webhooks");
|
|
529
|
+
const items = data["items"] ?? [];
|
|
530
|
+
return items.map(webhookFromDict);
|
|
531
|
+
}
|
|
532
|
+
async delete(webhookId) {
|
|
533
|
+
await this._t.delete(`/webhooks/${webhookId}`);
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
// src/models/connector.ts
|
|
538
|
+
var Connector = class _Connector {
|
|
539
|
+
id;
|
|
540
|
+
name;
|
|
541
|
+
type;
|
|
542
|
+
active;
|
|
543
|
+
lastTestedAt;
|
|
544
|
+
lastUsedAt;
|
|
545
|
+
createdAt;
|
|
546
|
+
constructor(data) {
|
|
547
|
+
this.id = data.id;
|
|
548
|
+
this.name = data.name;
|
|
549
|
+
this.type = data.type;
|
|
550
|
+
this.active = data.active;
|
|
551
|
+
this.lastTestedAt = data.lastTestedAt;
|
|
552
|
+
this.lastUsedAt = data.lastUsedAt;
|
|
553
|
+
this.createdAt = data.createdAt;
|
|
554
|
+
}
|
|
555
|
+
static fromDict(data) {
|
|
556
|
+
return new _Connector({
|
|
557
|
+
id: String(data["id"] ?? ""),
|
|
558
|
+
name: String(data["name"] ?? ""),
|
|
559
|
+
type: String(data["type"] ?? ""),
|
|
560
|
+
active: Boolean(data["active"] ?? true),
|
|
561
|
+
lastTestedAt: data["last_tested_at"] ?? null,
|
|
562
|
+
lastUsedAt: data["last_used_at"] ?? null,
|
|
563
|
+
createdAt: String(data["created_at"] ?? "")
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
toString() {
|
|
567
|
+
return `Connector(id=${this.id}, name=${this.name}, type=${this.type})`;
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
// src/resources/connectors.ts
|
|
572
|
+
var VALID_TYPES = /* @__PURE__ */ new Set(["s3", "gcs", "azure_blob"]);
|
|
573
|
+
var ConnectorsResource = class {
|
|
574
|
+
constructor(_t) {
|
|
575
|
+
this._t = _t;
|
|
576
|
+
}
|
|
577
|
+
_t;
|
|
578
|
+
async create(name, type, config) {
|
|
579
|
+
if (!VALID_TYPES.has(type)) {
|
|
580
|
+
throw new Error(`Unknown connector type "${type}". Valid: ${[...VALID_TYPES].join(", ")}`);
|
|
581
|
+
}
|
|
582
|
+
const data = await this._t.post("/connectors", { name, type, config });
|
|
583
|
+
return Connector.fromDict(data);
|
|
584
|
+
}
|
|
585
|
+
async list() {
|
|
586
|
+
const data = await this._t.get("/connectors");
|
|
587
|
+
const items = data["items"] ?? [];
|
|
588
|
+
return items.map(Connector.fromDict);
|
|
589
|
+
}
|
|
590
|
+
async get(connectorId) {
|
|
591
|
+
const data = await this._t.get(`/connectors/${connectorId}`);
|
|
592
|
+
return Connector.fromDict(data);
|
|
593
|
+
}
|
|
594
|
+
async delete(connectorId) {
|
|
595
|
+
await this._t.delete(`/connectors/${connectorId}`);
|
|
596
|
+
}
|
|
597
|
+
async test(connectorId) {
|
|
598
|
+
const data = await this._t.post(`/connectors/${connectorId}/test`) ?? {};
|
|
599
|
+
return {
|
|
600
|
+
success: Boolean(data["success"] ?? false),
|
|
601
|
+
latencyMs: data["latency_ms"] !== void 0 ? Number(data["latency_ms"]) : null,
|
|
602
|
+
message: String(data["message"] ?? "")
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
// src/client.ts
|
|
608
|
+
var DEFAULT_BASE_URL = "https://api.flexorch.com/v1";
|
|
609
|
+
var FlexOrchClient = class {
|
|
610
|
+
jobs;
|
|
611
|
+
datasets;
|
|
612
|
+
usage;
|
|
613
|
+
webhooks;
|
|
614
|
+
connectors;
|
|
615
|
+
_transport;
|
|
616
|
+
constructor(apiKeyOrOptions = {}) {
|
|
617
|
+
const opts = typeof apiKeyOrOptions === "string" ? { apiKey: apiKeyOrOptions } : apiKeyOrOptions;
|
|
618
|
+
const apiKey = opts.apiKey ?? process.env["FLEXORCH_API_KEY"] ?? "";
|
|
619
|
+
if (!apiKey) {
|
|
620
|
+
throw new Error(
|
|
621
|
+
"No API key provided. Pass apiKey or set the FLEXORCH_API_KEY environment variable."
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
this._transport = new Transport(
|
|
625
|
+
apiKey,
|
|
626
|
+
opts.baseUrl ?? DEFAULT_BASE_URL,
|
|
627
|
+
opts.timeout ?? 30,
|
|
628
|
+
opts.maxRetries ?? 3,
|
|
629
|
+
opts._fetch
|
|
630
|
+
);
|
|
631
|
+
this.jobs = new JobsResource(this._transport);
|
|
632
|
+
this.datasets = new DatasetsResource(this._transport);
|
|
633
|
+
this.usage = new UsageResource(this._transport);
|
|
634
|
+
this.webhooks = new WebhooksResource(this._transport);
|
|
635
|
+
this.connectors = new ConnectorsResource(this._transport);
|
|
636
|
+
}
|
|
637
|
+
async process(filePath, opts = {}) {
|
|
638
|
+
const { createReadStream, statSync } = await import("fs");
|
|
639
|
+
const { basename } = await import("path");
|
|
640
|
+
if (!statSync(filePath, { throwIfNoEntry: false })) {
|
|
641
|
+
throw new Error(`File not found: ${filePath}`);
|
|
642
|
+
}
|
|
643
|
+
const form = new FormData();
|
|
644
|
+
const stream = createReadStream(filePath);
|
|
645
|
+
const chunks = [];
|
|
646
|
+
for await (const chunk of stream) {
|
|
647
|
+
chunks.push(chunk);
|
|
648
|
+
}
|
|
649
|
+
const blob = new Blob([Buffer.concat(chunks)], { type: "application/octet-stream" });
|
|
650
|
+
form.append("file", blob, basename(filePath));
|
|
651
|
+
form.append("locale", opts.locale ?? "und");
|
|
652
|
+
if (opts.pipelineConfig) {
|
|
653
|
+
form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
|
|
654
|
+
}
|
|
655
|
+
const data = await this._transport.postForm("/data-process/async", form);
|
|
656
|
+
return Job.fromDict(data, this._transport);
|
|
657
|
+
}
|
|
658
|
+
async processMany(filePaths, opts = {}) {
|
|
659
|
+
const jobs = [];
|
|
660
|
+
for (const fp of filePaths) {
|
|
661
|
+
jobs.push(await this.process(fp, opts));
|
|
662
|
+
}
|
|
663
|
+
return jobs;
|
|
664
|
+
}
|
|
665
|
+
async processFromS3(connectorId, keys, opts = {}) {
|
|
666
|
+
const jobs = [];
|
|
667
|
+
for (const key of keys) {
|
|
668
|
+
const form = new FormData();
|
|
669
|
+
form.append("locale", opts.locale ?? "und");
|
|
670
|
+
form.append("source", JSON.stringify({ connector_id: connectorId, keys: [key] }));
|
|
671
|
+
if (opts.pipelineConfig) {
|
|
672
|
+
form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
|
|
673
|
+
}
|
|
674
|
+
const data = await this._transport.postForm("/data-process/async", form);
|
|
675
|
+
jobs.push(Job.fromDict(data, this._transport));
|
|
676
|
+
}
|
|
677
|
+
return jobs;
|
|
678
|
+
}
|
|
679
|
+
async search(query, opts = {}) {
|
|
680
|
+
const body = {
|
|
681
|
+
query,
|
|
682
|
+
top_k: opts.topK ?? 10
|
|
683
|
+
};
|
|
684
|
+
if (opts.filters) {
|
|
685
|
+
const f = opts.filters;
|
|
686
|
+
const mapped = {};
|
|
687
|
+
if (f.documentType !== void 0) mapped["document_type"] = f.documentType;
|
|
688
|
+
if (f.language !== void 0) mapped["language"] = f.language;
|
|
689
|
+
if (f.piiMasked !== void 0) mapped["pii_masked"] = f.piiMasked;
|
|
690
|
+
if (f.qualityGrade !== void 0) mapped["quality_grade"] = f.qualityGrade;
|
|
691
|
+
body["filters"] = mapped;
|
|
692
|
+
}
|
|
693
|
+
const data = await this._transport.post("/search", body) ?? {};
|
|
694
|
+
const results = data["results"] ?? [];
|
|
695
|
+
return results.map(SearchResult.fromDict);
|
|
696
|
+
}
|
|
697
|
+
toString() {
|
|
698
|
+
return `FlexOrchClient(baseUrl=${DEFAULT_BASE_URL})`;
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
// src/index.ts
|
|
703
|
+
init_dataset();
|
|
704
|
+
var version = "0.1.0";
|
|
705
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
706
|
+
0 && (module.exports = {
|
|
707
|
+
AuthError,
|
|
708
|
+
Connector,
|
|
709
|
+
Dataset,
|
|
710
|
+
FlexOrchClient,
|
|
711
|
+
FlexOrchError,
|
|
712
|
+
Job,
|
|
713
|
+
JobFailedError,
|
|
714
|
+
JobTimeoutError,
|
|
715
|
+
NotFoundError,
|
|
716
|
+
QuotaError,
|
|
717
|
+
RateLimitError,
|
|
718
|
+
SearchResult,
|
|
719
|
+
ServerError,
|
|
720
|
+
ValidationError,
|
|
721
|
+
version
|
|
722
|
+
});
|