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.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.
|
|
126
|
+
"User-Agent": "flexorch-sdk-js/0.3.0"
|
|
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,35 @@ 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
|
+
/**
|
|
220
|
+
* True when the underlying pipeline execution completed but one or more
|
|
221
|
+
* non-critical steps failed (e.g. structured extraction couldn't find a
|
|
222
|
+
* table in the document). The job still succeeds — PII detection and
|
|
223
|
+
* quality scoring results are still meaningful — but `records`/columns
|
|
224
|
+
* may be empty. Read from `execution_summary.degraded`; false for jobs
|
|
225
|
+
* with no execution (e.g. dataset_build). wait() does not throw for a
|
|
226
|
+
* degraded completion.
|
|
227
|
+
*/
|
|
228
|
+
degraded;
|
|
201
229
|
failureReason;
|
|
202
230
|
_transport;
|
|
203
231
|
constructor(data) {
|
|
@@ -206,19 +234,30 @@ var Job = class _Job {
|
|
|
206
234
|
this.qualityGrade = data.qualityGrade;
|
|
207
235
|
this.qualityScore = data.qualityScore;
|
|
208
236
|
this.documentId = data.documentId;
|
|
237
|
+
this.executionId = data.executionId;
|
|
209
238
|
this.hasDataset = data.hasDataset;
|
|
239
|
+
this.degraded = data.degraded;
|
|
210
240
|
this.failureReason = data.failureReason;
|
|
211
241
|
this._transport = data._transport;
|
|
212
242
|
}
|
|
213
243
|
static fromDict(data, transport) {
|
|
214
|
-
const
|
|
244
|
+
const executionSummary = data["execution_summary"];
|
|
245
|
+
const processingSummary = data["processing_summary"];
|
|
246
|
+
let quality = data["quality"];
|
|
247
|
+
if (!quality && processingSummary) {
|
|
248
|
+
quality = processingSummary["quality"];
|
|
249
|
+
}
|
|
250
|
+
quality = quality ?? {};
|
|
251
|
+
const executionId = executionSummary?.["execution_id"] ?? processingSummary?.["execution_id"] ?? data["execution_id"] ?? null;
|
|
215
252
|
return new _Job({
|
|
216
253
|
id: String(data["job_id"] ?? data["id"] ?? ""),
|
|
217
254
|
status: String(data["status"] ?? ""),
|
|
218
255
|
qualityGrade: quality["grade"] ?? null,
|
|
219
256
|
qualityScore: quality["score"] ?? null,
|
|
220
257
|
documentId: data["document_id"] ?? null,
|
|
221
|
-
|
|
258
|
+
executionId,
|
|
259
|
+
hasDataset: Boolean(data["has_dataset"] ?? processingSummary?.["has_dataset"] ?? false),
|
|
260
|
+
degraded: Boolean(executionSummary?.["degraded"] ?? false),
|
|
222
261
|
failureReason: data["failure_reason"] ?? null,
|
|
223
262
|
_transport: transport
|
|
224
263
|
});
|
|
@@ -251,9 +290,46 @@ var Job = class _Job {
|
|
|
251
290
|
});
|
|
252
291
|
const items = data["items"] ?? [];
|
|
253
292
|
if (items.length === 0) return null;
|
|
254
|
-
const { Dataset: Dataset2 } = await import("./dataset-
|
|
293
|
+
const { Dataset: Dataset2 } = await import("./dataset-E7EXJETI.js");
|
|
255
294
|
return Dataset2.fromDict(items[0], this._transport);
|
|
256
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Build a dataset from this job's execution.
|
|
298
|
+
*
|
|
299
|
+
* A completed data_process job does not have a dataset yet — building one
|
|
300
|
+
* is a separate, explicit step (`POST
|
|
301
|
+
* /datasets/build-from-execution/{executionId}`). Call this after
|
|
302
|
+
* `.wait()`, then `.wait()` again on the returned dataset_build Job before
|
|
303
|
+
* calling `.dataset()`:
|
|
304
|
+
*
|
|
305
|
+
* ```ts
|
|
306
|
+
* const job = await client.process("invoice.pdf");
|
|
307
|
+
* const done = await job.wait();
|
|
308
|
+
* const dataset = await (await done.buildDataset()).wait().then(j => j.dataset());
|
|
309
|
+
* ```
|
|
310
|
+
*
|
|
311
|
+
* @throws {Error} If this job has no executionId to build a dataset from
|
|
312
|
+
* (e.g. it failed, or is itself a dataset_build job).
|
|
313
|
+
*/
|
|
314
|
+
async buildDataset(opts = {}) {
|
|
315
|
+
if (!this.executionId) {
|
|
316
|
+
throw new Error(
|
|
317
|
+
`Job ${this.id} has no executionId to build a dataset from (job must be a completed data_process job).`
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
const body = {
|
|
321
|
+
force_rebuild: opts.forceRebuild ?? false,
|
|
322
|
+
replace_existing: opts.replaceExisting ?? false
|
|
323
|
+
};
|
|
324
|
+
if (opts.name !== void 0) body["name"] = opts.name;
|
|
325
|
+
if (opts.description !== void 0) body["description"] = opts.description;
|
|
326
|
+
if (opts.slug !== void 0) body["slug"] = opts.slug;
|
|
327
|
+
const data = await this._transport.post(
|
|
328
|
+
`/datasets/build-from-execution/${this.executionId}`,
|
|
329
|
+
body
|
|
330
|
+
);
|
|
331
|
+
return _Job.fromDict(data, this._transport);
|
|
332
|
+
}
|
|
257
333
|
toString() {
|
|
258
334
|
return `Job(id=${this.id}, status=${this.status}, grade=${this.qualityGrade})`;
|
|
259
335
|
}
|
|
@@ -297,6 +373,15 @@ var SearchResult = class _SearchResult {
|
|
|
297
373
|
};
|
|
298
374
|
|
|
299
375
|
// src/resources/jobs.ts
|
|
376
|
+
var VALID_RATINGS = /* @__PURE__ */ new Set(["up", "down"]);
|
|
377
|
+
var VALID_ISSUES = /* @__PURE__ */ new Set([
|
|
378
|
+
"wrong_doc_type",
|
|
379
|
+
"missing_fields",
|
|
380
|
+
"wrong_values",
|
|
381
|
+
"pii_missed",
|
|
382
|
+
"pii_over_masked",
|
|
383
|
+
"other"
|
|
384
|
+
]);
|
|
300
385
|
var JobsResource = class {
|
|
301
386
|
constructor(_t) {
|
|
302
387
|
this._t = _t;
|
|
@@ -314,6 +399,34 @@ var JobsResource = class {
|
|
|
314
399
|
const items = data["items"] ?? [];
|
|
315
400
|
return items.map((item) => Job.fromDict(item, this._t));
|
|
316
401
|
}
|
|
402
|
+
/**
|
|
403
|
+
* Submit user feedback for a completed job. Upsert — a second call for the
|
|
404
|
+
* same job replaces the previous feedback.
|
|
405
|
+
*
|
|
406
|
+
* @param rating "up" or "down".
|
|
407
|
+
* @param opts.issue When rating="down": "wrong_doc_type" | "missing_fields" |
|
|
408
|
+
* "wrong_values" | "pii_missed" | "pii_over_masked" | "other".
|
|
409
|
+
*/
|
|
410
|
+
async submitFeedback(jobId, rating, opts = {}) {
|
|
411
|
+
if (!VALID_RATINGS.has(rating)) {
|
|
412
|
+
throw new Error(`Invalid rating "${rating}". Valid: ${[...VALID_RATINGS].join(", ")}`);
|
|
413
|
+
}
|
|
414
|
+
if (opts.issue !== void 0 && !VALID_ISSUES.has(opts.issue)) {
|
|
415
|
+
throw new Error(`Invalid issue "${opts.issue}". Valid: ${[...VALID_ISSUES].join(", ")}`);
|
|
416
|
+
}
|
|
417
|
+
const data = await this._t.post(`/jobs/${jobId}/feedback`, {
|
|
418
|
+
rating,
|
|
419
|
+
issue: opts.issue ?? null,
|
|
420
|
+
notes: opts.notes ?? null
|
|
421
|
+
});
|
|
422
|
+
return jobFeedbackFromDict(data);
|
|
423
|
+
}
|
|
424
|
+
/** Existing feedback for a job, or null if none was submitted. */
|
|
425
|
+
async getFeedback(jobId) {
|
|
426
|
+
const data = await this._t.get(`/jobs/${jobId}/feedback`);
|
|
427
|
+
if (!data) return null;
|
|
428
|
+
return jobFeedbackFromDict(data);
|
|
429
|
+
}
|
|
317
430
|
};
|
|
318
431
|
|
|
319
432
|
// src/resources/datasets.ts
|
|
@@ -330,10 +443,121 @@ var DatasetsResource = class {
|
|
|
330
443
|
const params = {};
|
|
331
444
|
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
332
445
|
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
446
|
+
if (opts.status !== void 0) params["status"] = opts.status;
|
|
447
|
+
if (opts.sourceExecutionId !== void 0) params["source_execution_id"] = String(opts.sourceExecutionId);
|
|
448
|
+
if (opts.sourceDocumentId !== void 0) params["source_document_id"] = String(opts.sourceDocumentId);
|
|
449
|
+
if (opts.q !== void 0) params["q"] = opts.q;
|
|
333
450
|
const data = await this._t.get("/datasets", params);
|
|
334
451
|
const items = data["items"] ?? [];
|
|
335
452
|
return items.map((item) => Dataset.fromDict(item, this._t));
|
|
336
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Build a dataset from a completed execution.
|
|
456
|
+
*
|
|
457
|
+
* Prefer `Job.buildDataset()` when you already have a Job object — this is
|
|
458
|
+
* the lower-level call for when you only have an executionId (e.g. from
|
|
459
|
+
* `Document.latestExecution`).
|
|
460
|
+
*
|
|
461
|
+
* @returns A dataset_build Job — call `.wait()` then `.dataset()`.
|
|
462
|
+
*/
|
|
463
|
+
async buildFromExecution(executionId, opts = {}) {
|
|
464
|
+
const body = {
|
|
465
|
+
force_rebuild: opts.forceRebuild ?? false,
|
|
466
|
+
replace_existing: opts.replaceExisting ?? false
|
|
467
|
+
};
|
|
468
|
+
if (opts.name !== void 0) body["name"] = opts.name;
|
|
469
|
+
if (opts.description !== void 0) body["description"] = opts.description;
|
|
470
|
+
if (opts.slug !== void 0) body["slug"] = opts.slug;
|
|
471
|
+
const data = await this._t.post(
|
|
472
|
+
`/datasets/build-from-execution/${executionId}`,
|
|
473
|
+
body
|
|
474
|
+
);
|
|
475
|
+
return Job.fromDict(data, this._t);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
// src/models/document.ts
|
|
480
|
+
var Document = class _Document {
|
|
481
|
+
id;
|
|
482
|
+
filename;
|
|
483
|
+
fileExt;
|
|
484
|
+
status;
|
|
485
|
+
storagePath;
|
|
486
|
+
createdAt;
|
|
487
|
+
processingCount;
|
|
488
|
+
latestExecution;
|
|
489
|
+
dataset;
|
|
490
|
+
processingHistory;
|
|
491
|
+
relatedDatasets;
|
|
492
|
+
_transport;
|
|
493
|
+
constructor(data) {
|
|
494
|
+
this.id = data.id;
|
|
495
|
+
this.filename = data.filename;
|
|
496
|
+
this.fileExt = data.fileExt;
|
|
497
|
+
this.status = data.status;
|
|
498
|
+
this.storagePath = data.storagePath;
|
|
499
|
+
this.createdAt = data.createdAt;
|
|
500
|
+
this.processingCount = data.processingCount;
|
|
501
|
+
this.latestExecution = data.latestExecution;
|
|
502
|
+
this.dataset = data.dataset;
|
|
503
|
+
this.processingHistory = data.processingHistory;
|
|
504
|
+
this.relatedDatasets = data.relatedDatasets;
|
|
505
|
+
this._transport = data._transport;
|
|
506
|
+
}
|
|
507
|
+
static fromDict(data, transport) {
|
|
508
|
+
return new _Document({
|
|
509
|
+
id: String(data["id"] ?? ""),
|
|
510
|
+
filename: String(data["filename"] ?? ""),
|
|
511
|
+
fileExt: String(data["file_ext"] ?? ""),
|
|
512
|
+
status: String(data["status"] ?? ""),
|
|
513
|
+
storagePath: String(data["storage_path"] ?? ""),
|
|
514
|
+
createdAt: String(data["created_at"] ?? ""),
|
|
515
|
+
processingCount: Number(data["processing_count"] ?? 0),
|
|
516
|
+
latestExecution: data["latest_execution"] ?? null,
|
|
517
|
+
dataset: data["dataset"] ?? null,
|
|
518
|
+
processingHistory: data["processing_history"] ?? [],
|
|
519
|
+
relatedDatasets: data["related_datasets"] ?? [],
|
|
520
|
+
_transport: transport
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Re-queue this document through the processing pipeline.
|
|
525
|
+
*
|
|
526
|
+
* Raises (via the API): 400 DOCUMENT_FILE_NOT_AVAILABLE if the source file
|
|
527
|
+
* is no longer on disk, or 400 REPROCESS_NOT_SUPPORTED for
|
|
528
|
+
* connector-sourced (e.g. S3) documents.
|
|
529
|
+
*/
|
|
530
|
+
async reprocess(pipelineConfig) {
|
|
531
|
+
const body = {};
|
|
532
|
+
if (pipelineConfig) body["pipeline_config"] = pipelineConfig;
|
|
533
|
+
const data = await this._transport.post(`/documents/${this.id}/reprocess`, body);
|
|
534
|
+
return Job.fromDict(data, this._transport);
|
|
535
|
+
}
|
|
536
|
+
toString() {
|
|
537
|
+
return `Document(id=${this.id}, filename=${this.filename}, status=${this.status})`;
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
// src/resources/documents.ts
|
|
542
|
+
var DocumentsResource = class {
|
|
543
|
+
constructor(_t) {
|
|
544
|
+
this._t = _t;
|
|
545
|
+
}
|
|
546
|
+
_t;
|
|
547
|
+
/** Fetch a single document, including processingHistory and relatedDatasets. */
|
|
548
|
+
async get(documentId) {
|
|
549
|
+
const data = await this._t.get(`/documents/${documentId}`);
|
|
550
|
+
return Document.fromDict(data, this._t);
|
|
551
|
+
}
|
|
552
|
+
/** List documents for the current tenant, newest first. */
|
|
553
|
+
async list(opts = {}) {
|
|
554
|
+
const params = {};
|
|
555
|
+
if (opts.page !== void 0) params["page"] = String(opts.page);
|
|
556
|
+
if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
|
|
557
|
+
const data = await this._t.get("/documents", params);
|
|
558
|
+
const items = data["items"] ?? [];
|
|
559
|
+
return items.map((item) => Document.fromDict(item, this._t));
|
|
560
|
+
}
|
|
337
561
|
};
|
|
338
562
|
|
|
339
563
|
// src/resources/usage.ts
|
|
@@ -343,15 +567,51 @@ var UsageResource = class {
|
|
|
343
567
|
}
|
|
344
568
|
_t;
|
|
345
569
|
async current() {
|
|
346
|
-
const data = await this._t.get("/usage
|
|
570
|
+
const data = await this._t.get("/usage") ?? {};
|
|
571
|
+
const trial = data["trial"] ?? {};
|
|
572
|
+
const usage = data["usage"] ?? {};
|
|
573
|
+
const credits = usage["credits"] ?? {};
|
|
347
574
|
return {
|
|
348
575
|
plan: String(data["plan"] ?? ""),
|
|
349
|
-
creditsUsed: Number(
|
|
350
|
-
creditsLimit:
|
|
351
|
-
creditsRemaining:
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
576
|
+
creditsUsed: Number(credits["used"] ?? 0),
|
|
577
|
+
creditsLimit: credits["limit"] ?? null,
|
|
578
|
+
creditsRemaining: credits["remaining"] ?? null,
|
|
579
|
+
isTrial: Boolean(trial["is_trial"] ?? false),
|
|
580
|
+
trialEndsAt: trial["trial_ends_at"] ?? null,
|
|
581
|
+
trialDaysRemaining: trial["trial_days_remaining"] ?? null
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
/** @param period "7d" | "30d" | "90d". Default: "30d". */
|
|
585
|
+
async history(period = "30d") {
|
|
586
|
+
const data = await this._t.get("/usage/history", { period });
|
|
587
|
+
return (data ?? []).map((item) => ({
|
|
588
|
+
date: String(item["date"] ?? ""),
|
|
589
|
+
creditsUsed: Number(item["credits_used"] ?? 0),
|
|
590
|
+
jobsCount: Number(item["jobs_count"] ?? 0)
|
|
591
|
+
}));
|
|
592
|
+
}
|
|
593
|
+
/** @param period "7d" | "30d" | "90d". Default: "30d". */
|
|
594
|
+
async qualityTrend(period = "30d") {
|
|
595
|
+
const data = await this._t.get("/usage/quality-trend", { period });
|
|
596
|
+
return (data ?? []).map((item) => ({
|
|
597
|
+
date: String(item["date"] ?? ""),
|
|
598
|
+
avgQualityScore: Number(item["avg_quality_score"] ?? 0),
|
|
599
|
+
gradeDistribution: item["grade_distribution"] ?? {},
|
|
600
|
+
avgFieldFillRate: item["avg_field_fill_rate"] ?? null,
|
|
601
|
+
jobCount: Number(item["job_count"] ?? 0)
|
|
602
|
+
}));
|
|
603
|
+
}
|
|
604
|
+
/** Current rate limit configuration and window usage. Does not consume a request slot. */
|
|
605
|
+
async rateLimits() {
|
|
606
|
+
const data = await this._t.get("/usage/rate-limits") ?? {};
|
|
607
|
+
return {
|
|
608
|
+
plan: String(data["plan"] ?? ""),
|
|
609
|
+
unlimited: Boolean(data["unlimited"] ?? false),
|
|
610
|
+
limit: data["limit"] ?? null,
|
|
611
|
+
used: data["used"] ?? null,
|
|
612
|
+
remaining: data["remaining"] ?? null,
|
|
613
|
+
windowSeconds: Number(data["window_seconds"] ?? 0),
|
|
614
|
+
resetInSeconds: data["reset_in_seconds"] ?? null
|
|
355
615
|
};
|
|
356
616
|
}
|
|
357
617
|
};
|
|
@@ -423,6 +683,32 @@ var Connector = class _Connector {
|
|
|
423
683
|
return `Connector(id=${this.id}, name=${this.name}, type=${this.type})`;
|
|
424
684
|
}
|
|
425
685
|
};
|
|
686
|
+
function syncScheduleFromDict(data) {
|
|
687
|
+
return {
|
|
688
|
+
id: String(data["id"] ?? ""),
|
|
689
|
+
connectorId: String(data["connector_id"] ?? ""),
|
|
690
|
+
cronExpression: String(data["cron_expression"] ?? ""),
|
|
691
|
+
prefixFilter: data["prefix_filter"] ?? null,
|
|
692
|
+
isActive: Boolean(data["is_active"] ?? true),
|
|
693
|
+
lastRunAt: data["last_run_at"] ?? null,
|
|
694
|
+
nextRunAt: data["next_run_at"] ?? null,
|
|
695
|
+
createdAt: String(data["created_at"] ?? "")
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
function syncLogFromDict(data) {
|
|
699
|
+
return {
|
|
700
|
+
id: String(data["id"] ?? ""),
|
|
701
|
+
scheduleId: String(data["schedule_id"] ?? ""),
|
|
702
|
+
startedAt: String(data["started_at"] ?? ""),
|
|
703
|
+
completedAt: data["completed_at"] ?? null,
|
|
704
|
+
filesFound: Number(data["files_found"] ?? 0),
|
|
705
|
+
filesNew: Number(data["files_new"] ?? 0),
|
|
706
|
+
filesSkipped: Number(data["files_skipped"] ?? 0),
|
|
707
|
+
filesFailed: Number(data["files_failed"] ?? 0),
|
|
708
|
+
status: String(data["status"] ?? ""),
|
|
709
|
+
errorMessage: data["error_message"] ?? null
|
|
710
|
+
};
|
|
711
|
+
}
|
|
426
712
|
|
|
427
713
|
// src/resources/connectors.ts
|
|
428
714
|
var VALID_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -466,13 +752,54 @@ var ConnectorsResource = class {
|
|
|
466
752
|
message: String(data["message"] ?? "")
|
|
467
753
|
};
|
|
468
754
|
}
|
|
755
|
+
/** Define a scheduled sync for a connector (Pro+ required). */
|
|
756
|
+
async createSchedule(connectorId, cronExpression, prefixFilter = null) {
|
|
757
|
+
const data = await this._t.post(`/connectors/${connectorId}/schedules`, {
|
|
758
|
+
cron_expression: cronExpression,
|
|
759
|
+
prefix_filter: prefixFilter
|
|
760
|
+
});
|
|
761
|
+
return syncScheduleFromDict(data);
|
|
762
|
+
}
|
|
763
|
+
/** Active schedules for a connector. */
|
|
764
|
+
async listSchedules(connectorId) {
|
|
765
|
+
const data = await this._t.get(`/connectors/${connectorId}/schedules`);
|
|
766
|
+
return (data ?? []).map(syncScheduleFromDict);
|
|
767
|
+
}
|
|
768
|
+
/** Delete a scheduled sync. */
|
|
769
|
+
async deleteSchedule(connectorId, scheduleId) {
|
|
770
|
+
await this._t.delete(`/connectors/${connectorId}/schedules/${scheduleId}`);
|
|
771
|
+
}
|
|
772
|
+
/** Run a schedule immediately instead of waiting for its cron time. */
|
|
773
|
+
async triggerSchedule(connectorId, scheduleId) {
|
|
774
|
+
const data = await this._t.post(
|
|
775
|
+
`/connectors/${connectorId}/schedules/${scheduleId}/trigger`
|
|
776
|
+
);
|
|
777
|
+
return syncLogFromDict(data);
|
|
778
|
+
}
|
|
779
|
+
/** Recent sync run logs for a schedule. */
|
|
780
|
+
async scheduleLogs(connectorId, scheduleId) {
|
|
781
|
+
const data = await this._t.get(
|
|
782
|
+
`/connectors/${connectorId}/schedules/${scheduleId}/logs`
|
|
783
|
+
);
|
|
784
|
+
return (data ?? []).map(syncLogFromDict);
|
|
785
|
+
}
|
|
469
786
|
};
|
|
470
787
|
|
|
471
788
|
// src/client.ts
|
|
472
789
|
var DEFAULT_BASE_URL = "https://api.flexorch.com/v1";
|
|
790
|
+
function firstJobOrThrow(uploadResponse, filename, transport) {
|
|
791
|
+
const jobs = uploadResponse["jobs"] ?? [];
|
|
792
|
+
if (jobs.length > 0) {
|
|
793
|
+
return Job.fromDict(jobs[0], transport);
|
|
794
|
+
}
|
|
795
|
+
const rejected = uploadResponse["rejected"] ?? [];
|
|
796
|
+
const reason = rejected.length > 0 ? String(rejected[0]["error"]) : "unknown error";
|
|
797
|
+
throw new ValidationError(`${filename} was rejected: ${reason}`);
|
|
798
|
+
}
|
|
473
799
|
var FlexOrchClient = class {
|
|
474
800
|
jobs;
|
|
475
801
|
datasets;
|
|
802
|
+
documents;
|
|
476
803
|
usage;
|
|
477
804
|
webhooks;
|
|
478
805
|
connectors;
|
|
@@ -494,6 +821,7 @@ var FlexOrchClient = class {
|
|
|
494
821
|
);
|
|
495
822
|
this.jobs = new JobsResource(this._transport);
|
|
496
823
|
this.datasets = new DatasetsResource(this._transport);
|
|
824
|
+
this.documents = new DocumentsResource(this._transport);
|
|
497
825
|
this.usage = new UsageResource(this._transport);
|
|
498
826
|
this.webhooks = new WebhooksResource(this._transport);
|
|
499
827
|
this.connectors = new ConnectorsResource(this._transport);
|
|
@@ -511,13 +839,13 @@ var FlexOrchClient = class {
|
|
|
511
839
|
chunks.push(chunk);
|
|
512
840
|
}
|
|
513
841
|
const blob = new Blob([Buffer.concat(chunks)], { type: "application/octet-stream" });
|
|
514
|
-
form.append("
|
|
842
|
+
form.append("files", blob, basename(filePath));
|
|
515
843
|
form.append("locale", opts.locale ?? "und");
|
|
516
844
|
if (opts.pipelineConfig) {
|
|
517
845
|
form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
|
|
518
846
|
}
|
|
519
847
|
const data = await this._transport.postForm("/data-process/async", form);
|
|
520
|
-
return
|
|
848
|
+
return firstJobOrThrow(data, basename(filePath), this._transport);
|
|
521
849
|
}
|
|
522
850
|
async processMany(filePaths, opts = {}) {
|
|
523
851
|
const jobs = [];
|
|
@@ -536,7 +864,7 @@ var FlexOrchClient = class {
|
|
|
536
864
|
form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
|
|
537
865
|
}
|
|
538
866
|
const data = await this._transport.postForm("/data-process/async", form);
|
|
539
|
-
jobs.push(
|
|
867
|
+
jobs.push(firstJobOrThrow(data, key, this._transport));
|
|
540
868
|
}
|
|
541
869
|
return jobs;
|
|
542
870
|
}
|
|
@@ -740,11 +1068,12 @@ var FlexOrchReader = class {
|
|
|
740
1068
|
};
|
|
741
1069
|
|
|
742
1070
|
// src/index.ts
|
|
743
|
-
var version = "0.
|
|
1071
|
+
var version = "0.3.0";
|
|
744
1072
|
export {
|
|
745
1073
|
AuthError,
|
|
746
1074
|
Connector,
|
|
747
1075
|
Dataset,
|
|
1076
|
+
Document,
|
|
748
1077
|
FlexOrchClient,
|
|
749
1078
|
FlexOrchError,
|
|
750
1079
|
FlexOrchReader,
|