flexorch-sdk 0.2.3 → 0.3.1
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 +90 -38
- package/dist/{chunk-35RGZSFP.js → chunk-4KCMMRD7.js} +22 -2
- package/dist/{dataset-PP755LIW.js → dataset-E7EXJETI.js} +1 -1
- package/dist/index.cjs +369 -18
- package/dist/index.d.cts +204 -8
- package/dist/index.d.ts +204 -8
- package/dist/index.js +347 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Dataset
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4KCMMRD7.js";
|
|
4
4
|
|
|
5
5
|
// src/errors.ts
|
|
6
6
|
var FlexOrchError = class extends Error {
|
|
@@ -104,6 +104,12 @@ async function parseError(res) {
|
|
|
104
104
|
function sleep(ms) {
|
|
105
105
|
return new Promise((r) => setTimeout(r, ms));
|
|
106
106
|
}
|
|
107
|
+
function unwrap(body) {
|
|
108
|
+
if (body !== null && typeof body === "object" && "data" in body && "error" in body && typeof body["status"] === "string") {
|
|
109
|
+
return body["data"];
|
|
110
|
+
}
|
|
111
|
+
return body;
|
|
112
|
+
}
|
|
107
113
|
var Transport = class {
|
|
108
114
|
baseUrl;
|
|
109
115
|
defaultHeaders;
|
|
@@ -117,7 +123,7 @@ var Transport = class {
|
|
|
117
123
|
this.fetchFn = fetchFn ?? globalThis.fetch.bind(globalThis);
|
|
118
124
|
this.defaultHeaders = {
|
|
119
125
|
"X-API-KEY": apiKey,
|
|
120
|
-
"User-Agent": "flexorch-sdk-js/0.1
|
|
126
|
+
"User-Agent": "flexorch-sdk-js/0.3.1"
|
|
121
127
|
};
|
|
122
128
|
}
|
|
123
129
|
url(path, params) {
|
|
@@ -158,7 +164,7 @@ var Transport = class {
|
|
|
158
164
|
if (!ct.includes("application/json")) return null;
|
|
159
165
|
const text = await res.text();
|
|
160
166
|
if (!text.trim()) return null;
|
|
161
|
-
return JSON.parse(text);
|
|
167
|
+
return unwrap(JSON.parse(text));
|
|
162
168
|
} catch (err) {
|
|
163
169
|
clearTimeout(timer);
|
|
164
170
|
if (err instanceof FlexOrchError) throw err;
|
|
@@ -191,13 +197,27 @@ var Transport = class {
|
|
|
191
197
|
};
|
|
192
198
|
|
|
193
199
|
// src/models/job.ts
|
|
200
|
+
function jobFeedbackFromDict(data) {
|
|
201
|
+
return {
|
|
202
|
+
id: String(data["id"] ?? ""),
|
|
203
|
+
jobId: String(data["job_id"] ?? ""),
|
|
204
|
+
rating: String(data["rating"] ?? ""),
|
|
205
|
+
issue: data["issue"] ?? null,
|
|
206
|
+
notes: data["notes"] ?? null,
|
|
207
|
+
createdAt: String(data["created_at"] ?? "")
|
|
208
|
+
};
|
|
209
|
+
}
|
|
194
210
|
var Job = class _Job {
|
|
195
211
|
id;
|
|
196
212
|
status;
|
|
197
213
|
qualityGrade;
|
|
198
214
|
qualityScore;
|
|
199
215
|
documentId;
|
|
216
|
+
/** Needed by buildDataset() — POST /datasets/build-from-execution/{executionId}. */
|
|
217
|
+
executionId;
|
|
200
218
|
hasDataset;
|
|
219
|
+
/** Set from `dataset_summary.dataset_id` on a completed dataset_build job's response. */
|
|
220
|
+
datasetId;
|
|
201
221
|
/**
|
|
202
222
|
* True when the underlying pipeline execution completed but one or more
|
|
203
223
|
* non-critical steps failed (e.g. structured extraction couldn't find a
|
|
@@ -216,21 +236,37 @@ var Job = class _Job {
|
|
|
216
236
|
this.qualityGrade = data.qualityGrade;
|
|
217
237
|
this.qualityScore = data.qualityScore;
|
|
218
238
|
this.documentId = data.documentId;
|
|
239
|
+
this.executionId = data.executionId;
|
|
219
240
|
this.hasDataset = data.hasDataset;
|
|
241
|
+
this.datasetId = data.datasetId;
|
|
220
242
|
this.degraded = data.degraded;
|
|
221
243
|
this.failureReason = data.failureReason;
|
|
222
244
|
this._transport = data._transport;
|
|
223
245
|
}
|
|
224
246
|
static fromDict(data, transport) {
|
|
225
|
-
const quality = data["quality"] ?? {};
|
|
226
247
|
const executionSummary = data["execution_summary"];
|
|
248
|
+
const processingSummary = data["processing_summary"];
|
|
249
|
+
const datasetSummary = data["dataset_summary"];
|
|
250
|
+
let quality = data["quality"];
|
|
251
|
+
if (!quality && processingSummary) {
|
|
252
|
+
quality = processingSummary["quality"];
|
|
253
|
+
}
|
|
254
|
+
quality = quality ?? {};
|
|
255
|
+
const executionId = executionSummary?.["execution_id"] ?? processingSummary?.["execution_id"] ?? data["execution_id"] ?? null;
|
|
227
256
|
return new _Job({
|
|
228
257
|
id: String(data["job_id"] ?? data["id"] ?? ""),
|
|
229
258
|
status: String(data["status"] ?? ""),
|
|
230
259
|
qualityGrade: quality["grade"] ?? null,
|
|
231
260
|
qualityScore: quality["score"] ?? null,
|
|
232
261
|
documentId: data["document_id"] ?? null,
|
|
233
|
-
|
|
262
|
+
executionId,
|
|
263
|
+
// dataset_summary is only present on a completed dataset_build job's
|
|
264
|
+
// response — neither has_dataset nor processing_summary is ever set
|
|
265
|
+
// for that job type, so without this .dataset() always returned null
|
|
266
|
+
// for the job.buildDataset().wait().dataset() chain even though the
|
|
267
|
+
// dataset had been built successfully.
|
|
268
|
+
hasDataset: Boolean(data["has_dataset"] ?? processingSummary?.["has_dataset"] ?? Boolean(datasetSummary) ?? false),
|
|
269
|
+
datasetId: datasetSummary?.["dataset_id"] ?? null,
|
|
234
270
|
degraded: Boolean(executionSummary?.["degraded"] ?? false),
|
|
235
271
|
failureReason: data["failure_reason"] ?? null,
|
|
236
272
|
_transport: transport
|
|
@@ -258,15 +294,56 @@ var Job = class _Job {
|
|
|
258
294
|
throw new JobTimeoutError(this.id, timeout);
|
|
259
295
|
}
|
|
260
296
|
async dataset() {
|
|
297
|
+
const { Dataset: Dataset2 } = await import("./dataset-E7EXJETI.js");
|
|
298
|
+
if (this.datasetId !== null) {
|
|
299
|
+
const data2 = await this._transport.get(`/datasets/${this.datasetId}`);
|
|
300
|
+
return Dataset2.fromDict(data2, this._transport);
|
|
301
|
+
}
|
|
261
302
|
if (!this.hasDataset) return null;
|
|
262
303
|
const data = await this._transport.get("/datasets", {
|
|
263
304
|
job_id: this.id
|
|
264
305
|
});
|
|
265
306
|
const items = data["items"] ?? [];
|
|
266
307
|
if (items.length === 0) return null;
|
|
267
|
-
const { Dataset: Dataset2 } = await import("./dataset-PP755LIW.js");
|
|
268
308
|
return Dataset2.fromDict(items[0], this._transport);
|
|
269
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* Build a dataset from this job's execution.
|
|
312
|
+
*
|
|
313
|
+
* A completed data_process job does not have a dataset yet — building one
|
|
314
|
+
* is a separate, explicit step (`POST
|
|
315
|
+
* /datasets/build-from-execution/{executionId}`). Call this after
|
|
316
|
+
* `.wait()`, then `.wait()` again on the returned dataset_build Job before
|
|
317
|
+
* calling `.dataset()`:
|
|
318
|
+
*
|
|
319
|
+
* ```ts
|
|
320
|
+
* const job = await client.process("invoice.pdf");
|
|
321
|
+
* const done = await job.wait();
|
|
322
|
+
* const dataset = await (await done.buildDataset()).wait().then(j => j.dataset());
|
|
323
|
+
* ```
|
|
324
|
+
*
|
|
325
|
+
* @throws {Error} If this job has no executionId to build a dataset from
|
|
326
|
+
* (e.g. it failed, or is itself a dataset_build job).
|
|
327
|
+
*/
|
|
328
|
+
async buildDataset(opts = {}) {
|
|
329
|
+
if (!this.executionId) {
|
|
330
|
+
throw new Error(
|
|
331
|
+
`Job ${this.id} has no executionId to build a dataset from (job must be a completed data_process job).`
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
const body = {
|
|
335
|
+
force_rebuild: opts.forceRebuild ?? false,
|
|
336
|
+
replace_existing: opts.replaceExisting ?? false
|
|
337
|
+
};
|
|
338
|
+
if (opts.name !== void 0) body["name"] = opts.name;
|
|
339
|
+
if (opts.description !== void 0) body["description"] = opts.description;
|
|
340
|
+
if (opts.slug !== void 0) body["slug"] = opts.slug;
|
|
341
|
+
const data = await this._transport.post(
|
|
342
|
+
`/datasets/build-from-execution/${this.executionId}`,
|
|
343
|
+
body
|
|
344
|
+
);
|
|
345
|
+
return _Job.fromDict(data, this._transport);
|
|
346
|
+
}
|
|
270
347
|
toString() {
|
|
271
348
|
return `Job(id=${this.id}, status=${this.status}, grade=${this.qualityGrade})`;
|
|
272
349
|
}
|
|
@@ -310,6 +387,15 @@ var SearchResult = class _SearchResult {
|
|
|
310
387
|
};
|
|
311
388
|
|
|
312
389
|
// src/resources/jobs.ts
|
|
390
|
+
var VALID_RATINGS = /* @__PURE__ */ new Set(["up", "down"]);
|
|
391
|
+
var VALID_ISSUES = /* @__PURE__ */ new Set([
|
|
392
|
+
"wrong_doc_type",
|
|
393
|
+
"missing_fields",
|
|
394
|
+
"wrong_values",
|
|
395
|
+
"pii_missed",
|
|
396
|
+
"pii_over_masked",
|
|
397
|
+
"other"
|
|
398
|
+
]);
|
|
313
399
|
var JobsResource = class {
|
|
314
400
|
constructor(_t) {
|
|
315
401
|
this._t = _t;
|
|
@@ -327,6 +413,34 @@ var JobsResource = class {
|
|
|
327
413
|
const items = data["items"] ?? [];
|
|
328
414
|
return items.map((item) => Job.fromDict(item, this._t));
|
|
329
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* Submit user feedback for a completed job. Upsert — a second call for the
|
|
418
|
+
* same job replaces the previous feedback.
|
|
419
|
+
*
|
|
420
|
+
* @param rating "up" or "down".
|
|
421
|
+
* @param opts.issue When rating="down": "wrong_doc_type" | "missing_fields" |
|
|
422
|
+
* "wrong_values" | "pii_missed" | "pii_over_masked" | "other".
|
|
423
|
+
*/
|
|
424
|
+
async submitFeedback(jobId, rating, opts = {}) {
|
|
425
|
+
if (!VALID_RATINGS.has(rating)) {
|
|
426
|
+
throw new Error(`Invalid rating "${rating}". Valid: ${[...VALID_RATINGS].join(", ")}`);
|
|
427
|
+
}
|
|
428
|
+
if (opts.issue !== void 0 && !VALID_ISSUES.has(opts.issue)) {
|
|
429
|
+
throw new Error(`Invalid issue "${opts.issue}". Valid: ${[...VALID_ISSUES].join(", ")}`);
|
|
430
|
+
}
|
|
431
|
+
const data = await this._t.post(`/jobs/${jobId}/feedback`, {
|
|
432
|
+
rating,
|
|
433
|
+
issue: opts.issue ?? null,
|
|
434
|
+
notes: opts.notes ?? null
|
|
435
|
+
});
|
|
436
|
+
return jobFeedbackFromDict(data);
|
|
437
|
+
}
|
|
438
|
+
/** Existing feedback for a job, or null if none was submitted. */
|
|
439
|
+
async getFeedback(jobId) {
|
|
440
|
+
const data = await this._t.get(`/jobs/${jobId}/feedback`);
|
|
441
|
+
if (!data) return null;
|
|
442
|
+
return jobFeedbackFromDict(data);
|
|
443
|
+
}
|
|
330
444
|
};
|
|
331
445
|
|
|
332
446
|
// src/resources/datasets.ts
|
|
@@ -343,10 +457,121 @@ var DatasetsResource = class {
|
|
|
343
457
|
const params = {};
|
|
344
458
|
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
345
459
|
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
460
|
+
if (opts.status !== void 0) params["status"] = opts.status;
|
|
461
|
+
if (opts.sourceExecutionId !== void 0) params["source_execution_id"] = String(opts.sourceExecutionId);
|
|
462
|
+
if (opts.sourceDocumentId !== void 0) params["source_document_id"] = String(opts.sourceDocumentId);
|
|
463
|
+
if (opts.q !== void 0) params["q"] = opts.q;
|
|
346
464
|
const data = await this._t.get("/datasets", params);
|
|
347
465
|
const items = data["items"] ?? [];
|
|
348
466
|
return items.map((item) => Dataset.fromDict(item, this._t));
|
|
349
467
|
}
|
|
468
|
+
/**
|
|
469
|
+
* Build a dataset from a completed execution.
|
|
470
|
+
*
|
|
471
|
+
* Prefer `Job.buildDataset()` when you already have a Job object — this is
|
|
472
|
+
* the lower-level call for when you only have an executionId (e.g. from
|
|
473
|
+
* `Document.latestExecution`).
|
|
474
|
+
*
|
|
475
|
+
* @returns A dataset_build Job — call `.wait()` then `.dataset()`.
|
|
476
|
+
*/
|
|
477
|
+
async buildFromExecution(executionId, opts = {}) {
|
|
478
|
+
const body = {
|
|
479
|
+
force_rebuild: opts.forceRebuild ?? false,
|
|
480
|
+
replace_existing: opts.replaceExisting ?? false
|
|
481
|
+
};
|
|
482
|
+
if (opts.name !== void 0) body["name"] = opts.name;
|
|
483
|
+
if (opts.description !== void 0) body["description"] = opts.description;
|
|
484
|
+
if (opts.slug !== void 0) body["slug"] = opts.slug;
|
|
485
|
+
const data = await this._t.post(
|
|
486
|
+
`/datasets/build-from-execution/${executionId}`,
|
|
487
|
+
body
|
|
488
|
+
);
|
|
489
|
+
return Job.fromDict(data, this._t);
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
// src/models/document.ts
|
|
494
|
+
var Document = class _Document {
|
|
495
|
+
id;
|
|
496
|
+
filename;
|
|
497
|
+
fileExt;
|
|
498
|
+
status;
|
|
499
|
+
storagePath;
|
|
500
|
+
createdAt;
|
|
501
|
+
processingCount;
|
|
502
|
+
latestExecution;
|
|
503
|
+
dataset;
|
|
504
|
+
processingHistory;
|
|
505
|
+
relatedDatasets;
|
|
506
|
+
_transport;
|
|
507
|
+
constructor(data) {
|
|
508
|
+
this.id = data.id;
|
|
509
|
+
this.filename = data.filename;
|
|
510
|
+
this.fileExt = data.fileExt;
|
|
511
|
+
this.status = data.status;
|
|
512
|
+
this.storagePath = data.storagePath;
|
|
513
|
+
this.createdAt = data.createdAt;
|
|
514
|
+
this.processingCount = data.processingCount;
|
|
515
|
+
this.latestExecution = data.latestExecution;
|
|
516
|
+
this.dataset = data.dataset;
|
|
517
|
+
this.processingHistory = data.processingHistory;
|
|
518
|
+
this.relatedDatasets = data.relatedDatasets;
|
|
519
|
+
this._transport = data._transport;
|
|
520
|
+
}
|
|
521
|
+
static fromDict(data, transport) {
|
|
522
|
+
return new _Document({
|
|
523
|
+
id: String(data["id"] ?? ""),
|
|
524
|
+
filename: String(data["filename"] ?? ""),
|
|
525
|
+
fileExt: String(data["file_ext"] ?? ""),
|
|
526
|
+
status: String(data["status"] ?? ""),
|
|
527
|
+
storagePath: String(data["storage_path"] ?? ""),
|
|
528
|
+
createdAt: String(data["created_at"] ?? ""),
|
|
529
|
+
processingCount: Number(data["processing_count"] ?? 0),
|
|
530
|
+
latestExecution: data["latest_execution"] ?? null,
|
|
531
|
+
dataset: data["dataset"] ?? null,
|
|
532
|
+
processingHistory: data["processing_history"] ?? [],
|
|
533
|
+
relatedDatasets: data["related_datasets"] ?? [],
|
|
534
|
+
_transport: transport
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Re-queue this document through the processing pipeline.
|
|
539
|
+
*
|
|
540
|
+
* Raises (via the API): 400 DOCUMENT_FILE_NOT_AVAILABLE if the source file
|
|
541
|
+
* is no longer on disk, or 400 REPROCESS_NOT_SUPPORTED for
|
|
542
|
+
* connector-sourced (e.g. S3) documents.
|
|
543
|
+
*/
|
|
544
|
+
async reprocess(pipelineConfig) {
|
|
545
|
+
const body = {};
|
|
546
|
+
if (pipelineConfig) body["pipeline_config"] = pipelineConfig;
|
|
547
|
+
const data = await this._transport.post(`/documents/${this.id}/reprocess`, body);
|
|
548
|
+
return Job.fromDict(data, this._transport);
|
|
549
|
+
}
|
|
550
|
+
toString() {
|
|
551
|
+
return `Document(id=${this.id}, filename=${this.filename}, status=${this.status})`;
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
// src/resources/documents.ts
|
|
556
|
+
var DocumentsResource = class {
|
|
557
|
+
constructor(_t) {
|
|
558
|
+
this._t = _t;
|
|
559
|
+
}
|
|
560
|
+
_t;
|
|
561
|
+
/** Fetch a single document, including processingHistory and relatedDatasets. */
|
|
562
|
+
async get(documentId) {
|
|
563
|
+
const data = await this._t.get(`/documents/${documentId}`);
|
|
564
|
+
return Document.fromDict(data, this._t);
|
|
565
|
+
}
|
|
566
|
+
/** List documents for the current tenant, newest first. */
|
|
567
|
+
async list(opts = {}) {
|
|
568
|
+
const params = {};
|
|
569
|
+
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
570
|
+
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
571
|
+
const data = await this._t.get("/documents", params);
|
|
572
|
+
const items = data["items"] ?? [];
|
|
573
|
+
return items.map((item) => Document.fromDict(item, this._t));
|
|
574
|
+
}
|
|
350
575
|
};
|
|
351
576
|
|
|
352
577
|
// src/resources/usage.ts
|
|
@@ -356,15 +581,51 @@ var UsageResource = class {
|
|
|
356
581
|
}
|
|
357
582
|
_t;
|
|
358
583
|
async current() {
|
|
359
|
-
const data = await this._t.get("/usage
|
|
584
|
+
const data = await this._t.get("/usage") ?? {};
|
|
585
|
+
const trial = data["trial"] ?? {};
|
|
586
|
+
const usage = data["usage"] ?? {};
|
|
587
|
+
const credits = usage["credits"] ?? {};
|
|
588
|
+
return {
|
|
589
|
+
plan: String(data["plan"] ?? ""),
|
|
590
|
+
creditsUsed: Number(credits["used"] ?? 0),
|
|
591
|
+
creditsLimit: credits["limit"] ?? null,
|
|
592
|
+
creditsRemaining: credits["remaining"] ?? null,
|
|
593
|
+
isTrial: Boolean(trial["is_trial"] ?? false),
|
|
594
|
+
trialEndsAt: trial["trial_ends_at"] ?? null,
|
|
595
|
+
trialDaysRemaining: trial["trial_days_remaining"] ?? null
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
/** @param period "7d" | "30d" | "90d". Default: "30d". */
|
|
599
|
+
async history(period = "30d") {
|
|
600
|
+
const data = await this._t.get("/usage/history", { period });
|
|
601
|
+
return (data ?? []).map((item) => ({
|
|
602
|
+
date: String(item["date"] ?? ""),
|
|
603
|
+
creditsUsed: Number(item["credits_used"] ?? 0),
|
|
604
|
+
jobsCount: Number(item["jobs_count"] ?? 0)
|
|
605
|
+
}));
|
|
606
|
+
}
|
|
607
|
+
/** @param period "7d" | "30d" | "90d". Default: "30d". */
|
|
608
|
+
async qualityTrend(period = "30d") {
|
|
609
|
+
const data = await this._t.get("/usage/quality-trend", { period });
|
|
610
|
+
return (data ?? []).map((item) => ({
|
|
611
|
+
date: String(item["date"] ?? ""),
|
|
612
|
+
avgQualityScore: Number(item["avg_quality_score"] ?? 0),
|
|
613
|
+
gradeDistribution: item["grade_distribution"] ?? {},
|
|
614
|
+
avgFieldFillRate: item["avg_field_fill_rate"] ?? null,
|
|
615
|
+
jobCount: Number(item["job_count"] ?? 0)
|
|
616
|
+
}));
|
|
617
|
+
}
|
|
618
|
+
/** Current rate limit configuration and window usage. Does not consume a request slot. */
|
|
619
|
+
async rateLimits() {
|
|
620
|
+
const data = await this._t.get("/usage/rate-limits") ?? {};
|
|
360
621
|
return {
|
|
361
622
|
plan: String(data["plan"] ?? ""),
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
623
|
+
unlimited: Boolean(data["unlimited"] ?? false),
|
|
624
|
+
limit: data["limit"] ?? null,
|
|
625
|
+
used: data["used"] ?? null,
|
|
626
|
+
remaining: data["remaining"] ?? null,
|
|
627
|
+
windowSeconds: Number(data["window_seconds"] ?? 0),
|
|
628
|
+
resetInSeconds: data["reset_in_seconds"] ?? null
|
|
368
629
|
};
|
|
369
630
|
}
|
|
370
631
|
};
|
|
@@ -436,6 +697,32 @@ var Connector = class _Connector {
|
|
|
436
697
|
return `Connector(id=${this.id}, name=${this.name}, type=${this.type})`;
|
|
437
698
|
}
|
|
438
699
|
};
|
|
700
|
+
function syncScheduleFromDict(data) {
|
|
701
|
+
return {
|
|
702
|
+
id: String(data["id"] ?? ""),
|
|
703
|
+
connectorId: String(data["connector_id"] ?? ""),
|
|
704
|
+
cronExpression: String(data["cron_expression"] ?? ""),
|
|
705
|
+
prefixFilter: data["prefix_filter"] ?? null,
|
|
706
|
+
isActive: Boolean(data["is_active"] ?? true),
|
|
707
|
+
lastRunAt: data["last_run_at"] ?? null,
|
|
708
|
+
nextRunAt: data["next_run_at"] ?? null,
|
|
709
|
+
createdAt: String(data["created_at"] ?? "")
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
function syncLogFromDict(data) {
|
|
713
|
+
return {
|
|
714
|
+
id: String(data["id"] ?? ""),
|
|
715
|
+
scheduleId: String(data["schedule_id"] ?? ""),
|
|
716
|
+
startedAt: String(data["started_at"] ?? ""),
|
|
717
|
+
completedAt: data["completed_at"] ?? null,
|
|
718
|
+
filesFound: Number(data["files_found"] ?? 0),
|
|
719
|
+
filesNew: Number(data["files_new"] ?? 0),
|
|
720
|
+
filesSkipped: Number(data["files_skipped"] ?? 0),
|
|
721
|
+
filesFailed: Number(data["files_failed"] ?? 0),
|
|
722
|
+
status: String(data["status"] ?? ""),
|
|
723
|
+
errorMessage: data["error_message"] ?? null
|
|
724
|
+
};
|
|
725
|
+
}
|
|
439
726
|
|
|
440
727
|
// src/resources/connectors.ts
|
|
441
728
|
var VALID_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -479,13 +766,54 @@ var ConnectorsResource = class {
|
|
|
479
766
|
message: String(data["message"] ?? "")
|
|
480
767
|
};
|
|
481
768
|
}
|
|
769
|
+
/** Define a scheduled sync for a connector (Pro+ required). */
|
|
770
|
+
async createSchedule(connectorId, cronExpression, prefixFilter = null) {
|
|
771
|
+
const data = await this._t.post(`/connectors/${connectorId}/schedules`, {
|
|
772
|
+
cron_expression: cronExpression,
|
|
773
|
+
prefix_filter: prefixFilter
|
|
774
|
+
});
|
|
775
|
+
return syncScheduleFromDict(data);
|
|
776
|
+
}
|
|
777
|
+
/** Active schedules for a connector. */
|
|
778
|
+
async listSchedules(connectorId) {
|
|
779
|
+
const data = await this._t.get(`/connectors/${connectorId}/schedules`);
|
|
780
|
+
return (data ?? []).map(syncScheduleFromDict);
|
|
781
|
+
}
|
|
782
|
+
/** Delete a scheduled sync. */
|
|
783
|
+
async deleteSchedule(connectorId, scheduleId) {
|
|
784
|
+
await this._t.delete(`/connectors/${connectorId}/schedules/${scheduleId}`);
|
|
785
|
+
}
|
|
786
|
+
/** Run a schedule immediately instead of waiting for its cron time. */
|
|
787
|
+
async triggerSchedule(connectorId, scheduleId) {
|
|
788
|
+
const data = await this._t.post(
|
|
789
|
+
`/connectors/${connectorId}/schedules/${scheduleId}/trigger`
|
|
790
|
+
);
|
|
791
|
+
return syncLogFromDict(data);
|
|
792
|
+
}
|
|
793
|
+
/** Recent sync run logs for a schedule. */
|
|
794
|
+
async scheduleLogs(connectorId, scheduleId) {
|
|
795
|
+
const data = await this._t.get(
|
|
796
|
+
`/connectors/${connectorId}/schedules/${scheduleId}/logs`
|
|
797
|
+
);
|
|
798
|
+
return (data ?? []).map(syncLogFromDict);
|
|
799
|
+
}
|
|
482
800
|
};
|
|
483
801
|
|
|
484
802
|
// src/client.ts
|
|
485
803
|
var DEFAULT_BASE_URL = "https://api.flexorch.com/v1";
|
|
804
|
+
function firstJobOrThrow(uploadResponse, filename, transport) {
|
|
805
|
+
const jobs = uploadResponse["jobs"] ?? [];
|
|
806
|
+
if (jobs.length > 0) {
|
|
807
|
+
return Job.fromDict(jobs[0], transport);
|
|
808
|
+
}
|
|
809
|
+
const rejected = uploadResponse["rejected"] ?? [];
|
|
810
|
+
const reason = rejected.length > 0 ? String(rejected[0]["error"]) : "unknown error";
|
|
811
|
+
throw new ValidationError(`${filename} was rejected: ${reason}`);
|
|
812
|
+
}
|
|
486
813
|
var FlexOrchClient = class {
|
|
487
814
|
jobs;
|
|
488
815
|
datasets;
|
|
816
|
+
documents;
|
|
489
817
|
usage;
|
|
490
818
|
webhooks;
|
|
491
819
|
connectors;
|
|
@@ -507,6 +835,7 @@ var FlexOrchClient = class {
|
|
|
507
835
|
);
|
|
508
836
|
this.jobs = new JobsResource(this._transport);
|
|
509
837
|
this.datasets = new DatasetsResource(this._transport);
|
|
838
|
+
this.documents = new DocumentsResource(this._transport);
|
|
510
839
|
this.usage = new UsageResource(this._transport);
|
|
511
840
|
this.webhooks = new WebhooksResource(this._transport);
|
|
512
841
|
this.connectors = new ConnectorsResource(this._transport);
|
|
@@ -524,13 +853,13 @@ var FlexOrchClient = class {
|
|
|
524
853
|
chunks.push(chunk);
|
|
525
854
|
}
|
|
526
855
|
const blob = new Blob([Buffer.concat(chunks)], { type: "application/octet-stream" });
|
|
527
|
-
form.append("
|
|
856
|
+
form.append("files", blob, basename(filePath));
|
|
528
857
|
form.append("locale", opts.locale ?? "und");
|
|
529
858
|
if (opts.pipelineConfig) {
|
|
530
859
|
form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
|
|
531
860
|
}
|
|
532
861
|
const data = await this._transport.postForm("/data-process/async", form);
|
|
533
|
-
return
|
|
862
|
+
return firstJobOrThrow(data, basename(filePath), this._transport);
|
|
534
863
|
}
|
|
535
864
|
async processMany(filePaths, opts = {}) {
|
|
536
865
|
const jobs = [];
|
|
@@ -549,7 +878,7 @@ var FlexOrchClient = class {
|
|
|
549
878
|
form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
|
|
550
879
|
}
|
|
551
880
|
const data = await this._transport.postForm("/data-process/async", form);
|
|
552
|
-
jobs.push(
|
|
881
|
+
jobs.push(firstJobOrThrow(data, key, this._transport));
|
|
553
882
|
}
|
|
554
883
|
return jobs;
|
|
555
884
|
}
|
|
@@ -753,11 +1082,12 @@ var FlexOrchReader = class {
|
|
|
753
1082
|
};
|
|
754
1083
|
|
|
755
1084
|
// src/index.ts
|
|
756
|
-
var version = "0.
|
|
1085
|
+
var version = "0.3.1";
|
|
757
1086
|
export {
|
|
758
1087
|
AuthError,
|
|
759
1088
|
Connector,
|
|
760
1089
|
Dataset,
|
|
1090
|
+
Document,
|
|
761
1091
|
FlexOrchClient,
|
|
762
1092
|
FlexOrchError,
|
|
763
1093
|
FlexOrchReader,
|