flexorch-sdk 0.2.2 → 0.3.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/README.md +93 -37
- package/dist/{chunk-35RGZSFP.js → chunk-4KCMMRD7.js} +22 -2
- package/dist/{dataset-PP755LIW.js → dataset-E7EXJETI.js} +1 -1
- package/dist/index.cjs +367 -17
- package/dist/index.d.cts +212 -8
- package/dist/index.d.ts +212 -8
- package/dist/index.js +346 -17
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -83,11 +83,12 @@ var init_dataset = __esm({
|
|
|
83
83
|
_transport: transport
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
async export(format) {
|
|
86
|
+
async export(format, opts = {}) {
|
|
87
87
|
if (!SUPPORTED_FORMATS.has(format)) {
|
|
88
88
|
throw new Error(`Unsupported format "${format}". Choose from: ${[...SUPPORTED_FORMATS].sort().join(", ")}`);
|
|
89
89
|
}
|
|
90
|
-
|
|
90
|
+
const params = opts.minQuality !== void 0 ? { min_quality: opts.minQuality } : void 0;
|
|
91
|
+
return this._transport.getBytes(`/datasets/${this.id}/export/${format}`, params);
|
|
91
92
|
}
|
|
92
93
|
async exportToS3(connectorId, format, prefix = "") {
|
|
93
94
|
if (!SUPPORTED_FORMATS.has(format)) {
|
|
@@ -139,6 +140,25 @@ var init_dataset = __esm({
|
|
|
139
140
|
totalChunks: Number(data["total_chunks"] ?? 0)
|
|
140
141
|
};
|
|
141
142
|
}
|
|
143
|
+
/** Preview dataset rows. */
|
|
144
|
+
async rows(opts = {}) {
|
|
145
|
+
const params = {};
|
|
146
|
+
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
147
|
+
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
148
|
+
if (opts.q !== void 0) params["q"] = opts.q;
|
|
149
|
+
return await this._transport.get(`/datasets/${this.id}/rows`, params) ?? {};
|
|
150
|
+
}
|
|
151
|
+
/** Quality/privacy profile — only available once status is "ready". */
|
|
152
|
+
async profile() {
|
|
153
|
+
return await this._transport.get(`/datasets/${this.id}/profile`) ?? {};
|
|
154
|
+
}
|
|
155
|
+
/** KVKK/GDPR processing transparency report (Pro+ required). */
|
|
156
|
+
async complianceReport(format = "json") {
|
|
157
|
+
if (format === "pdf") {
|
|
158
|
+
return this._transport.getBytes(`/datasets/${this.id}/compliance-report`, { format: "pdf" });
|
|
159
|
+
}
|
|
160
|
+
return await this._transport.get(`/datasets/${this.id}/compliance-report`, { format }) ?? {};
|
|
161
|
+
}
|
|
142
162
|
toString() {
|
|
143
163
|
return `Dataset(id=${this.id}, name=${this.name}, rows=${this.rowCount}, status=${this.status})`;
|
|
144
164
|
}
|
|
@@ -152,6 +172,7 @@ __export(index_exports, {
|
|
|
152
172
|
AuthError: () => AuthError,
|
|
153
173
|
Connector: () => Connector,
|
|
154
174
|
Dataset: () => Dataset,
|
|
175
|
+
Document: () => Document,
|
|
155
176
|
FlexOrchClient: () => FlexOrchClient,
|
|
156
177
|
FlexOrchError: () => FlexOrchError,
|
|
157
178
|
FlexOrchReader: () => FlexOrchReader,
|
|
@@ -272,6 +293,12 @@ async function parseError(res) {
|
|
|
272
293
|
function sleep(ms) {
|
|
273
294
|
return new Promise((r) => setTimeout(r, ms));
|
|
274
295
|
}
|
|
296
|
+
function unwrap(body) {
|
|
297
|
+
if (body !== null && typeof body === "object" && "data" in body && "error" in body && typeof body["status"] === "string") {
|
|
298
|
+
return body["data"];
|
|
299
|
+
}
|
|
300
|
+
return body;
|
|
301
|
+
}
|
|
275
302
|
var Transport = class {
|
|
276
303
|
baseUrl;
|
|
277
304
|
defaultHeaders;
|
|
@@ -285,7 +312,7 @@ var Transport = class {
|
|
|
285
312
|
this.fetchFn = fetchFn ?? globalThis.fetch.bind(globalThis);
|
|
286
313
|
this.defaultHeaders = {
|
|
287
314
|
"X-API-KEY": apiKey,
|
|
288
|
-
"User-Agent": "flexorch-sdk-js/0.
|
|
315
|
+
"User-Agent": "flexorch-sdk-js/0.3.0"
|
|
289
316
|
};
|
|
290
317
|
}
|
|
291
318
|
url(path, params) {
|
|
@@ -326,7 +353,7 @@ var Transport = class {
|
|
|
326
353
|
if (!ct.includes("application/json")) return null;
|
|
327
354
|
const text = await res.text();
|
|
328
355
|
if (!text.trim()) return null;
|
|
329
|
-
return JSON.parse(text);
|
|
356
|
+
return unwrap(JSON.parse(text));
|
|
330
357
|
} catch (err) {
|
|
331
358
|
clearTimeout(timer);
|
|
332
359
|
if (err instanceof FlexOrchError) throw err;
|
|
@@ -359,13 +386,35 @@ var Transport = class {
|
|
|
359
386
|
};
|
|
360
387
|
|
|
361
388
|
// src/models/job.ts
|
|
389
|
+
function jobFeedbackFromDict(data) {
|
|
390
|
+
return {
|
|
391
|
+
id: String(data["id"] ?? ""),
|
|
392
|
+
jobId: String(data["job_id"] ?? ""),
|
|
393
|
+
rating: String(data["rating"] ?? ""),
|
|
394
|
+
issue: data["issue"] ?? null,
|
|
395
|
+
notes: data["notes"] ?? null,
|
|
396
|
+
createdAt: String(data["created_at"] ?? "")
|
|
397
|
+
};
|
|
398
|
+
}
|
|
362
399
|
var Job = class _Job {
|
|
363
400
|
id;
|
|
364
401
|
status;
|
|
365
402
|
qualityGrade;
|
|
366
403
|
qualityScore;
|
|
367
404
|
documentId;
|
|
405
|
+
/** Needed by buildDataset() — POST /datasets/build-from-execution/{executionId}. */
|
|
406
|
+
executionId;
|
|
368
407
|
hasDataset;
|
|
408
|
+
/**
|
|
409
|
+
* True when the underlying pipeline execution completed but one or more
|
|
410
|
+
* non-critical steps failed (e.g. structured extraction couldn't find a
|
|
411
|
+
* table in the document). The job still succeeds — PII detection and
|
|
412
|
+
* quality scoring results are still meaningful — but `records`/columns
|
|
413
|
+
* may be empty. Read from `execution_summary.degraded`; false for jobs
|
|
414
|
+
* with no execution (e.g. dataset_build). wait() does not throw for a
|
|
415
|
+
* degraded completion.
|
|
416
|
+
*/
|
|
417
|
+
degraded;
|
|
369
418
|
failureReason;
|
|
370
419
|
_transport;
|
|
371
420
|
constructor(data) {
|
|
@@ -374,19 +423,30 @@ var Job = class _Job {
|
|
|
374
423
|
this.qualityGrade = data.qualityGrade;
|
|
375
424
|
this.qualityScore = data.qualityScore;
|
|
376
425
|
this.documentId = data.documentId;
|
|
426
|
+
this.executionId = data.executionId;
|
|
377
427
|
this.hasDataset = data.hasDataset;
|
|
428
|
+
this.degraded = data.degraded;
|
|
378
429
|
this.failureReason = data.failureReason;
|
|
379
430
|
this._transport = data._transport;
|
|
380
431
|
}
|
|
381
432
|
static fromDict(data, transport) {
|
|
382
|
-
const
|
|
433
|
+
const executionSummary = data["execution_summary"];
|
|
434
|
+
const processingSummary = data["processing_summary"];
|
|
435
|
+
let quality = data["quality"];
|
|
436
|
+
if (!quality && processingSummary) {
|
|
437
|
+
quality = processingSummary["quality"];
|
|
438
|
+
}
|
|
439
|
+
quality = quality ?? {};
|
|
440
|
+
const executionId = executionSummary?.["execution_id"] ?? processingSummary?.["execution_id"] ?? data["execution_id"] ?? null;
|
|
383
441
|
return new _Job({
|
|
384
442
|
id: String(data["job_id"] ?? data["id"] ?? ""),
|
|
385
443
|
status: String(data["status"] ?? ""),
|
|
386
444
|
qualityGrade: quality["grade"] ?? null,
|
|
387
445
|
qualityScore: quality["score"] ?? null,
|
|
388
446
|
documentId: data["document_id"] ?? null,
|
|
389
|
-
|
|
447
|
+
executionId,
|
|
448
|
+
hasDataset: Boolean(data["has_dataset"] ?? processingSummary?.["has_dataset"] ?? false),
|
|
449
|
+
degraded: Boolean(executionSummary?.["degraded"] ?? false),
|
|
390
450
|
failureReason: data["failure_reason"] ?? null,
|
|
391
451
|
_transport: transport
|
|
392
452
|
});
|
|
@@ -422,6 +482,43 @@ var Job = class _Job {
|
|
|
422
482
|
const { Dataset: Dataset2 } = await Promise.resolve().then(() => (init_dataset(), dataset_exports));
|
|
423
483
|
return Dataset2.fromDict(items[0], this._transport);
|
|
424
484
|
}
|
|
485
|
+
/**
|
|
486
|
+
* Build a dataset from this job's execution.
|
|
487
|
+
*
|
|
488
|
+
* A completed data_process job does not have a dataset yet — building one
|
|
489
|
+
* is a separate, explicit step (`POST
|
|
490
|
+
* /datasets/build-from-execution/{executionId}`). Call this after
|
|
491
|
+
* `.wait()`, then `.wait()` again on the returned dataset_build Job before
|
|
492
|
+
* calling `.dataset()`:
|
|
493
|
+
*
|
|
494
|
+
* ```ts
|
|
495
|
+
* const job = await client.process("invoice.pdf");
|
|
496
|
+
* const done = await job.wait();
|
|
497
|
+
* const dataset = await (await done.buildDataset()).wait().then(j => j.dataset());
|
|
498
|
+
* ```
|
|
499
|
+
*
|
|
500
|
+
* @throws {Error} If this job has no executionId to build a dataset from
|
|
501
|
+
* (e.g. it failed, or is itself a dataset_build job).
|
|
502
|
+
*/
|
|
503
|
+
async buildDataset(opts = {}) {
|
|
504
|
+
if (!this.executionId) {
|
|
505
|
+
throw new Error(
|
|
506
|
+
`Job ${this.id} has no executionId to build a dataset from (job must be a completed data_process job).`
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
const body = {
|
|
510
|
+
force_rebuild: opts.forceRebuild ?? false,
|
|
511
|
+
replace_existing: opts.replaceExisting ?? false
|
|
512
|
+
};
|
|
513
|
+
if (opts.name !== void 0) body["name"] = opts.name;
|
|
514
|
+
if (opts.description !== void 0) body["description"] = opts.description;
|
|
515
|
+
if (opts.slug !== void 0) body["slug"] = opts.slug;
|
|
516
|
+
const data = await this._transport.post(
|
|
517
|
+
`/datasets/build-from-execution/${this.executionId}`,
|
|
518
|
+
body
|
|
519
|
+
);
|
|
520
|
+
return _Job.fromDict(data, this._transport);
|
|
521
|
+
}
|
|
425
522
|
toString() {
|
|
426
523
|
return `Job(id=${this.id}, status=${this.status}, grade=${this.qualityGrade})`;
|
|
427
524
|
}
|
|
@@ -465,6 +562,15 @@ var SearchResult = class _SearchResult {
|
|
|
465
562
|
};
|
|
466
563
|
|
|
467
564
|
// src/resources/jobs.ts
|
|
565
|
+
var VALID_RATINGS = /* @__PURE__ */ new Set(["up", "down"]);
|
|
566
|
+
var VALID_ISSUES = /* @__PURE__ */ new Set([
|
|
567
|
+
"wrong_doc_type",
|
|
568
|
+
"missing_fields",
|
|
569
|
+
"wrong_values",
|
|
570
|
+
"pii_missed",
|
|
571
|
+
"pii_over_masked",
|
|
572
|
+
"other"
|
|
573
|
+
]);
|
|
468
574
|
var JobsResource = class {
|
|
469
575
|
constructor(_t) {
|
|
470
576
|
this._t = _t;
|
|
@@ -482,6 +588,34 @@ var JobsResource = class {
|
|
|
482
588
|
const items = data["items"] ?? [];
|
|
483
589
|
return items.map((item) => Job.fromDict(item, this._t));
|
|
484
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* Submit user feedback for a completed job. Upsert — a second call for the
|
|
593
|
+
* same job replaces the previous feedback.
|
|
594
|
+
*
|
|
595
|
+
* @param rating "up" or "down".
|
|
596
|
+
* @param opts.issue When rating="down": "wrong_doc_type" | "missing_fields" |
|
|
597
|
+
* "wrong_values" | "pii_missed" | "pii_over_masked" | "other".
|
|
598
|
+
*/
|
|
599
|
+
async submitFeedback(jobId, rating, opts = {}) {
|
|
600
|
+
if (!VALID_RATINGS.has(rating)) {
|
|
601
|
+
throw new Error(`Invalid rating "${rating}". Valid: ${[...VALID_RATINGS].join(", ")}`);
|
|
602
|
+
}
|
|
603
|
+
if (opts.issue !== void 0 && !VALID_ISSUES.has(opts.issue)) {
|
|
604
|
+
throw new Error(`Invalid issue "${opts.issue}". Valid: ${[...VALID_ISSUES].join(", ")}`);
|
|
605
|
+
}
|
|
606
|
+
const data = await this._t.post(`/jobs/${jobId}/feedback`, {
|
|
607
|
+
rating,
|
|
608
|
+
issue: opts.issue ?? null,
|
|
609
|
+
notes: opts.notes ?? null
|
|
610
|
+
});
|
|
611
|
+
return jobFeedbackFromDict(data);
|
|
612
|
+
}
|
|
613
|
+
/** Existing feedback for a job, or null if none was submitted. */
|
|
614
|
+
async getFeedback(jobId) {
|
|
615
|
+
const data = await this._t.get(`/jobs/${jobId}/feedback`);
|
|
616
|
+
if (!data) return null;
|
|
617
|
+
return jobFeedbackFromDict(data);
|
|
618
|
+
}
|
|
485
619
|
};
|
|
486
620
|
|
|
487
621
|
// src/resources/datasets.ts
|
|
@@ -499,10 +633,121 @@ var DatasetsResource = class {
|
|
|
499
633
|
const params = {};
|
|
500
634
|
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
501
635
|
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
636
|
+
if (opts.status !== void 0) params["status"] = opts.status;
|
|
637
|
+
if (opts.sourceExecutionId !== void 0) params["source_execution_id"] = String(opts.sourceExecutionId);
|
|
638
|
+
if (opts.sourceDocumentId !== void 0) params["source_document_id"] = String(opts.sourceDocumentId);
|
|
639
|
+
if (opts.q !== void 0) params["q"] = opts.q;
|
|
502
640
|
const data = await this._t.get("/datasets", params);
|
|
503
641
|
const items = data["items"] ?? [];
|
|
504
642
|
return items.map((item) => Dataset.fromDict(item, this._t));
|
|
505
643
|
}
|
|
644
|
+
/**
|
|
645
|
+
* Build a dataset from a completed execution.
|
|
646
|
+
*
|
|
647
|
+
* Prefer `Job.buildDataset()` when you already have a Job object — this is
|
|
648
|
+
* the lower-level call for when you only have an executionId (e.g. from
|
|
649
|
+
* `Document.latestExecution`).
|
|
650
|
+
*
|
|
651
|
+
* @returns A dataset_build Job — call `.wait()` then `.dataset()`.
|
|
652
|
+
*/
|
|
653
|
+
async buildFromExecution(executionId, opts = {}) {
|
|
654
|
+
const body = {
|
|
655
|
+
force_rebuild: opts.forceRebuild ?? false,
|
|
656
|
+
replace_existing: opts.replaceExisting ?? false
|
|
657
|
+
};
|
|
658
|
+
if (opts.name !== void 0) body["name"] = opts.name;
|
|
659
|
+
if (opts.description !== void 0) body["description"] = opts.description;
|
|
660
|
+
if (opts.slug !== void 0) body["slug"] = opts.slug;
|
|
661
|
+
const data = await this._t.post(
|
|
662
|
+
`/datasets/build-from-execution/${executionId}`,
|
|
663
|
+
body
|
|
664
|
+
);
|
|
665
|
+
return Job.fromDict(data, this._t);
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
// src/models/document.ts
|
|
670
|
+
var Document = class _Document {
|
|
671
|
+
id;
|
|
672
|
+
filename;
|
|
673
|
+
fileExt;
|
|
674
|
+
status;
|
|
675
|
+
storagePath;
|
|
676
|
+
createdAt;
|
|
677
|
+
processingCount;
|
|
678
|
+
latestExecution;
|
|
679
|
+
dataset;
|
|
680
|
+
processingHistory;
|
|
681
|
+
relatedDatasets;
|
|
682
|
+
_transport;
|
|
683
|
+
constructor(data) {
|
|
684
|
+
this.id = data.id;
|
|
685
|
+
this.filename = data.filename;
|
|
686
|
+
this.fileExt = data.fileExt;
|
|
687
|
+
this.status = data.status;
|
|
688
|
+
this.storagePath = data.storagePath;
|
|
689
|
+
this.createdAt = data.createdAt;
|
|
690
|
+
this.processingCount = data.processingCount;
|
|
691
|
+
this.latestExecution = data.latestExecution;
|
|
692
|
+
this.dataset = data.dataset;
|
|
693
|
+
this.processingHistory = data.processingHistory;
|
|
694
|
+
this.relatedDatasets = data.relatedDatasets;
|
|
695
|
+
this._transport = data._transport;
|
|
696
|
+
}
|
|
697
|
+
static fromDict(data, transport) {
|
|
698
|
+
return new _Document({
|
|
699
|
+
id: String(data["id"] ?? ""),
|
|
700
|
+
filename: String(data["filename"] ?? ""),
|
|
701
|
+
fileExt: String(data["file_ext"] ?? ""),
|
|
702
|
+
status: String(data["status"] ?? ""),
|
|
703
|
+
storagePath: String(data["storage_path"] ?? ""),
|
|
704
|
+
createdAt: String(data["created_at"] ?? ""),
|
|
705
|
+
processingCount: Number(data["processing_count"] ?? 0),
|
|
706
|
+
latestExecution: data["latest_execution"] ?? null,
|
|
707
|
+
dataset: data["dataset"] ?? null,
|
|
708
|
+
processingHistory: data["processing_history"] ?? [],
|
|
709
|
+
relatedDatasets: data["related_datasets"] ?? [],
|
|
710
|
+
_transport: transport
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Re-queue this document through the processing pipeline.
|
|
715
|
+
*
|
|
716
|
+
* Raises (via the API): 400 DOCUMENT_FILE_NOT_AVAILABLE if the source file
|
|
717
|
+
* is no longer on disk, or 400 REPROCESS_NOT_SUPPORTED for
|
|
718
|
+
* connector-sourced (e.g. S3) documents.
|
|
719
|
+
*/
|
|
720
|
+
async reprocess(pipelineConfig) {
|
|
721
|
+
const body = {};
|
|
722
|
+
if (pipelineConfig) body["pipeline_config"] = pipelineConfig;
|
|
723
|
+
const data = await this._transport.post(`/documents/${this.id}/reprocess`, body);
|
|
724
|
+
return Job.fromDict(data, this._transport);
|
|
725
|
+
}
|
|
726
|
+
toString() {
|
|
727
|
+
return `Document(id=${this.id}, filename=${this.filename}, status=${this.status})`;
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
// src/resources/documents.ts
|
|
732
|
+
var DocumentsResource = class {
|
|
733
|
+
constructor(_t) {
|
|
734
|
+
this._t = _t;
|
|
735
|
+
}
|
|
736
|
+
_t;
|
|
737
|
+
/** Fetch a single document, including processingHistory and relatedDatasets. */
|
|
738
|
+
async get(documentId) {
|
|
739
|
+
const data = await this._t.get(`/documents/${documentId}`);
|
|
740
|
+
return Document.fromDict(data, this._t);
|
|
741
|
+
}
|
|
742
|
+
/** List documents for the current tenant, newest first. */
|
|
743
|
+
async list(opts = {}) {
|
|
744
|
+
const params = {};
|
|
745
|
+
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
746
|
+
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
747
|
+
const data = await this._t.get("/documents", params);
|
|
748
|
+
const items = data["items"] ?? [];
|
|
749
|
+
return items.map((item) => Document.fromDict(item, this._t));
|
|
750
|
+
}
|
|
506
751
|
};
|
|
507
752
|
|
|
508
753
|
// src/resources/usage.ts
|
|
@@ -512,15 +757,51 @@ var UsageResource = class {
|
|
|
512
757
|
}
|
|
513
758
|
_t;
|
|
514
759
|
async current() {
|
|
515
|
-
const data = await this._t.get("/usage
|
|
760
|
+
const data = await this._t.get("/usage") ?? {};
|
|
761
|
+
const trial = data["trial"] ?? {};
|
|
762
|
+
const usage = data["usage"] ?? {};
|
|
763
|
+
const credits = usage["credits"] ?? {};
|
|
764
|
+
return {
|
|
765
|
+
plan: String(data["plan"] ?? ""),
|
|
766
|
+
creditsUsed: Number(credits["used"] ?? 0),
|
|
767
|
+
creditsLimit: credits["limit"] ?? null,
|
|
768
|
+
creditsRemaining: credits["remaining"] ?? null,
|
|
769
|
+
isTrial: Boolean(trial["is_trial"] ?? false),
|
|
770
|
+
trialEndsAt: trial["trial_ends_at"] ?? null,
|
|
771
|
+
trialDaysRemaining: trial["trial_days_remaining"] ?? null
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
/** @param period "7d" | "30d" | "90d". Default: "30d". */
|
|
775
|
+
async history(period = "30d") {
|
|
776
|
+
const data = await this._t.get("/usage/history", { period });
|
|
777
|
+
return (data ?? []).map((item) => ({
|
|
778
|
+
date: String(item["date"] ?? ""),
|
|
779
|
+
creditsUsed: Number(item["credits_used"] ?? 0),
|
|
780
|
+
jobsCount: Number(item["jobs_count"] ?? 0)
|
|
781
|
+
}));
|
|
782
|
+
}
|
|
783
|
+
/** @param period "7d" | "30d" | "90d". Default: "30d". */
|
|
784
|
+
async qualityTrend(period = "30d") {
|
|
785
|
+
const data = await this._t.get("/usage/quality-trend", { period });
|
|
786
|
+
return (data ?? []).map((item) => ({
|
|
787
|
+
date: String(item["date"] ?? ""),
|
|
788
|
+
avgQualityScore: Number(item["avg_quality_score"] ?? 0),
|
|
789
|
+
gradeDistribution: item["grade_distribution"] ?? {},
|
|
790
|
+
avgFieldFillRate: item["avg_field_fill_rate"] ?? null,
|
|
791
|
+
jobCount: Number(item["job_count"] ?? 0)
|
|
792
|
+
}));
|
|
793
|
+
}
|
|
794
|
+
/** Current rate limit configuration and window usage. Does not consume a request slot. */
|
|
795
|
+
async rateLimits() {
|
|
796
|
+
const data = await this._t.get("/usage/rate-limits") ?? {};
|
|
516
797
|
return {
|
|
517
798
|
plan: String(data["plan"] ?? ""),
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
799
|
+
unlimited: Boolean(data["unlimited"] ?? false),
|
|
800
|
+
limit: data["limit"] ?? null,
|
|
801
|
+
used: data["used"] ?? null,
|
|
802
|
+
remaining: data["remaining"] ?? null,
|
|
803
|
+
windowSeconds: Number(data["window_seconds"] ?? 0),
|
|
804
|
+
resetInSeconds: data["reset_in_seconds"] ?? null
|
|
524
805
|
};
|
|
525
806
|
}
|
|
526
807
|
};
|
|
@@ -592,6 +873,32 @@ var Connector = class _Connector {
|
|
|
592
873
|
return `Connector(id=${this.id}, name=${this.name}, type=${this.type})`;
|
|
593
874
|
}
|
|
594
875
|
};
|
|
876
|
+
function syncScheduleFromDict(data) {
|
|
877
|
+
return {
|
|
878
|
+
id: String(data["id"] ?? ""),
|
|
879
|
+
connectorId: String(data["connector_id"] ?? ""),
|
|
880
|
+
cronExpression: String(data["cron_expression"] ?? ""),
|
|
881
|
+
prefixFilter: data["prefix_filter"] ?? null,
|
|
882
|
+
isActive: Boolean(data["is_active"] ?? true),
|
|
883
|
+
lastRunAt: data["last_run_at"] ?? null,
|
|
884
|
+
nextRunAt: data["next_run_at"] ?? null,
|
|
885
|
+
createdAt: String(data["created_at"] ?? "")
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
function syncLogFromDict(data) {
|
|
889
|
+
return {
|
|
890
|
+
id: String(data["id"] ?? ""),
|
|
891
|
+
scheduleId: String(data["schedule_id"] ?? ""),
|
|
892
|
+
startedAt: String(data["started_at"] ?? ""),
|
|
893
|
+
completedAt: data["completed_at"] ?? null,
|
|
894
|
+
filesFound: Number(data["files_found"] ?? 0),
|
|
895
|
+
filesNew: Number(data["files_new"] ?? 0),
|
|
896
|
+
filesSkipped: Number(data["files_skipped"] ?? 0),
|
|
897
|
+
filesFailed: Number(data["files_failed"] ?? 0),
|
|
898
|
+
status: String(data["status"] ?? ""),
|
|
899
|
+
errorMessage: data["error_message"] ?? null
|
|
900
|
+
};
|
|
901
|
+
}
|
|
595
902
|
|
|
596
903
|
// src/resources/connectors.ts
|
|
597
904
|
var VALID_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -635,13 +942,54 @@ var ConnectorsResource = class {
|
|
|
635
942
|
message: String(data["message"] ?? "")
|
|
636
943
|
};
|
|
637
944
|
}
|
|
945
|
+
/** Define a scheduled sync for a connector (Pro+ required). */
|
|
946
|
+
async createSchedule(connectorId, cronExpression, prefixFilter = null) {
|
|
947
|
+
const data = await this._t.post(`/connectors/${connectorId}/schedules`, {
|
|
948
|
+
cron_expression: cronExpression,
|
|
949
|
+
prefix_filter: prefixFilter
|
|
950
|
+
});
|
|
951
|
+
return syncScheduleFromDict(data);
|
|
952
|
+
}
|
|
953
|
+
/** Active schedules for a connector. */
|
|
954
|
+
async listSchedules(connectorId) {
|
|
955
|
+
const data = await this._t.get(`/connectors/${connectorId}/schedules`);
|
|
956
|
+
return (data ?? []).map(syncScheduleFromDict);
|
|
957
|
+
}
|
|
958
|
+
/** Delete a scheduled sync. */
|
|
959
|
+
async deleteSchedule(connectorId, scheduleId) {
|
|
960
|
+
await this._t.delete(`/connectors/${connectorId}/schedules/${scheduleId}`);
|
|
961
|
+
}
|
|
962
|
+
/** Run a schedule immediately instead of waiting for its cron time. */
|
|
963
|
+
async triggerSchedule(connectorId, scheduleId) {
|
|
964
|
+
const data = await this._t.post(
|
|
965
|
+
`/connectors/${connectorId}/schedules/${scheduleId}/trigger`
|
|
966
|
+
);
|
|
967
|
+
return syncLogFromDict(data);
|
|
968
|
+
}
|
|
969
|
+
/** Recent sync run logs for a schedule. */
|
|
970
|
+
async scheduleLogs(connectorId, scheduleId) {
|
|
971
|
+
const data = await this._t.get(
|
|
972
|
+
`/connectors/${connectorId}/schedules/${scheduleId}/logs`
|
|
973
|
+
);
|
|
974
|
+
return (data ?? []).map(syncLogFromDict);
|
|
975
|
+
}
|
|
638
976
|
};
|
|
639
977
|
|
|
640
978
|
// src/client.ts
|
|
641
979
|
var DEFAULT_BASE_URL = "https://api.flexorch.com/v1";
|
|
980
|
+
function firstJobOrThrow(uploadResponse, filename, transport) {
|
|
981
|
+
const jobs = uploadResponse["jobs"] ?? [];
|
|
982
|
+
if (jobs.length > 0) {
|
|
983
|
+
return Job.fromDict(jobs[0], transport);
|
|
984
|
+
}
|
|
985
|
+
const rejected = uploadResponse["rejected"] ?? [];
|
|
986
|
+
const reason = rejected.length > 0 ? String(rejected[0]["error"]) : "unknown error";
|
|
987
|
+
throw new ValidationError(`${filename} was rejected: ${reason}`);
|
|
988
|
+
}
|
|
642
989
|
var FlexOrchClient = class {
|
|
643
990
|
jobs;
|
|
644
991
|
datasets;
|
|
992
|
+
documents;
|
|
645
993
|
usage;
|
|
646
994
|
webhooks;
|
|
647
995
|
connectors;
|
|
@@ -663,6 +1011,7 @@ var FlexOrchClient = class {
|
|
|
663
1011
|
);
|
|
664
1012
|
this.jobs = new JobsResource(this._transport);
|
|
665
1013
|
this.datasets = new DatasetsResource(this._transport);
|
|
1014
|
+
this.documents = new DocumentsResource(this._transport);
|
|
666
1015
|
this.usage = new UsageResource(this._transport);
|
|
667
1016
|
this.webhooks = new WebhooksResource(this._transport);
|
|
668
1017
|
this.connectors = new ConnectorsResource(this._transport);
|
|
@@ -680,13 +1029,13 @@ var FlexOrchClient = class {
|
|
|
680
1029
|
chunks.push(chunk);
|
|
681
1030
|
}
|
|
682
1031
|
const blob = new Blob([Buffer.concat(chunks)], { type: "application/octet-stream" });
|
|
683
|
-
form.append("
|
|
1032
|
+
form.append("files", blob, basename(filePath));
|
|
684
1033
|
form.append("locale", opts.locale ?? "und");
|
|
685
1034
|
if (opts.pipelineConfig) {
|
|
686
1035
|
form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
|
|
687
1036
|
}
|
|
688
1037
|
const data = await this._transport.postForm("/data-process/async", form);
|
|
689
|
-
return
|
|
1038
|
+
return firstJobOrThrow(data, basename(filePath), this._transport);
|
|
690
1039
|
}
|
|
691
1040
|
async processMany(filePaths, opts = {}) {
|
|
692
1041
|
const jobs = [];
|
|
@@ -705,7 +1054,7 @@ var FlexOrchClient = class {
|
|
|
705
1054
|
form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
|
|
706
1055
|
}
|
|
707
1056
|
const data = await this._transport.postForm("/data-process/async", form);
|
|
708
|
-
jobs.push(
|
|
1057
|
+
jobs.push(firstJobOrThrow(data, key, this._transport));
|
|
709
1058
|
}
|
|
710
1059
|
return jobs;
|
|
711
1060
|
}
|
|
@@ -912,12 +1261,13 @@ var FlexOrchReader = class {
|
|
|
912
1261
|
};
|
|
913
1262
|
|
|
914
1263
|
// src/index.ts
|
|
915
|
-
var version = "0.
|
|
1264
|
+
var version = "0.3.0";
|
|
916
1265
|
// Annotate the CommonJS export names for ESM import in node:
|
|
917
1266
|
0 && (module.exports = {
|
|
918
1267
|
AuthError,
|
|
919
1268
|
Connector,
|
|
920
1269
|
Dataset,
|
|
1270
|
+
Document,
|
|
921
1271
|
FlexOrchClient,
|
|
922
1272
|
FlexOrchError,
|
|
923
1273
|
FlexOrchReader,
|