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/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
- return this._transport.getBytes(`/datasets/${this.id}/export`, { format });
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.1.0"
315
+ "User-Agent": "flexorch-sdk-js/0.3.1"
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,27 @@ 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
+ /** Set from `dataset_summary.dataset_id` on a completed dataset_build job's response. */
409
+ datasetId;
369
410
  /**
370
411
  * True when the underlying pipeline execution completed but one or more
371
412
  * non-critical steps failed (e.g. structured extraction couldn't find a
@@ -384,21 +425,37 @@ var Job = class _Job {
384
425
  this.qualityGrade = data.qualityGrade;
385
426
  this.qualityScore = data.qualityScore;
386
427
  this.documentId = data.documentId;
428
+ this.executionId = data.executionId;
387
429
  this.hasDataset = data.hasDataset;
430
+ this.datasetId = data.datasetId;
388
431
  this.degraded = data.degraded;
389
432
  this.failureReason = data.failureReason;
390
433
  this._transport = data._transport;
391
434
  }
392
435
  static fromDict(data, transport) {
393
- const quality = data["quality"] ?? {};
394
436
  const executionSummary = data["execution_summary"];
437
+ const processingSummary = data["processing_summary"];
438
+ const datasetSummary = data["dataset_summary"];
439
+ let quality = data["quality"];
440
+ if (!quality && processingSummary) {
441
+ quality = processingSummary["quality"];
442
+ }
443
+ quality = quality ?? {};
444
+ const executionId = executionSummary?.["execution_id"] ?? processingSummary?.["execution_id"] ?? data["execution_id"] ?? null;
395
445
  return new _Job({
396
446
  id: String(data["job_id"] ?? data["id"] ?? ""),
397
447
  status: String(data["status"] ?? ""),
398
448
  qualityGrade: quality["grade"] ?? null,
399
449
  qualityScore: quality["score"] ?? null,
400
450
  documentId: data["document_id"] ?? null,
401
- hasDataset: Boolean(data["has_dataset"] ?? false),
451
+ executionId,
452
+ // dataset_summary is only present on a completed dataset_build job's
453
+ // response — neither has_dataset nor processing_summary is ever set
454
+ // for that job type, so without this .dataset() always returned null
455
+ // for the job.buildDataset().wait().dataset() chain even though the
456
+ // dataset had been built successfully.
457
+ hasDataset: Boolean(data["has_dataset"] ?? processingSummary?.["has_dataset"] ?? Boolean(datasetSummary) ?? false),
458
+ datasetId: datasetSummary?.["dataset_id"] ?? null,
402
459
  degraded: Boolean(executionSummary?.["degraded"] ?? false),
403
460
  failureReason: data["failure_reason"] ?? null,
404
461
  _transport: transport
@@ -426,15 +483,56 @@ var Job = class _Job {
426
483
  throw new JobTimeoutError(this.id, timeout);
427
484
  }
428
485
  async dataset() {
486
+ const { Dataset: Dataset2 } = await Promise.resolve().then(() => (init_dataset(), dataset_exports));
487
+ if (this.datasetId !== null) {
488
+ const data2 = await this._transport.get(`/datasets/${this.datasetId}`);
489
+ return Dataset2.fromDict(data2, this._transport);
490
+ }
429
491
  if (!this.hasDataset) return null;
430
492
  const data = await this._transport.get("/datasets", {
431
493
  job_id: this.id
432
494
  });
433
495
  const items = data["items"] ?? [];
434
496
  if (items.length === 0) return null;
435
- const { Dataset: Dataset2 } = await Promise.resolve().then(() => (init_dataset(), dataset_exports));
436
497
  return Dataset2.fromDict(items[0], this._transport);
437
498
  }
499
+ /**
500
+ * Build a dataset from this job's execution.
501
+ *
502
+ * A completed data_process job does not have a dataset yet — building one
503
+ * is a separate, explicit step (`POST
504
+ * /datasets/build-from-execution/{executionId}`). Call this after
505
+ * `.wait()`, then `.wait()` again on the returned dataset_build Job before
506
+ * calling `.dataset()`:
507
+ *
508
+ * ```ts
509
+ * const job = await client.process("invoice.pdf");
510
+ * const done = await job.wait();
511
+ * const dataset = await (await done.buildDataset()).wait().then(j => j.dataset());
512
+ * ```
513
+ *
514
+ * @throws {Error} If this job has no executionId to build a dataset from
515
+ * (e.g. it failed, or is itself a dataset_build job).
516
+ */
517
+ async buildDataset(opts = {}) {
518
+ if (!this.executionId) {
519
+ throw new Error(
520
+ `Job ${this.id} has no executionId to build a dataset from (job must be a completed data_process job).`
521
+ );
522
+ }
523
+ const body = {
524
+ force_rebuild: opts.forceRebuild ?? false,
525
+ replace_existing: opts.replaceExisting ?? false
526
+ };
527
+ if (opts.name !== void 0) body["name"] = opts.name;
528
+ if (opts.description !== void 0) body["description"] = opts.description;
529
+ if (opts.slug !== void 0) body["slug"] = opts.slug;
530
+ const data = await this._transport.post(
531
+ `/datasets/build-from-execution/${this.executionId}`,
532
+ body
533
+ );
534
+ return _Job.fromDict(data, this._transport);
535
+ }
438
536
  toString() {
439
537
  return `Job(id=${this.id}, status=${this.status}, grade=${this.qualityGrade})`;
440
538
  }
@@ -478,6 +576,15 @@ var SearchResult = class _SearchResult {
478
576
  };
479
577
 
480
578
  // src/resources/jobs.ts
579
+ var VALID_RATINGS = /* @__PURE__ */ new Set(["up", "down"]);
580
+ var VALID_ISSUES = /* @__PURE__ */ new Set([
581
+ "wrong_doc_type",
582
+ "missing_fields",
583
+ "wrong_values",
584
+ "pii_missed",
585
+ "pii_over_masked",
586
+ "other"
587
+ ]);
481
588
  var JobsResource = class {
482
589
  constructor(_t) {
483
590
  this._t = _t;
@@ -495,6 +602,34 @@ var JobsResource = class {
495
602
  const items = data["items"] ?? [];
496
603
  return items.map((item) => Job.fromDict(item, this._t));
497
604
  }
605
+ /**
606
+ * Submit user feedback for a completed job. Upsert — a second call for the
607
+ * same job replaces the previous feedback.
608
+ *
609
+ * @param rating "up" or "down".
610
+ * @param opts.issue When rating="down": "wrong_doc_type" | "missing_fields" |
611
+ * "wrong_values" | "pii_missed" | "pii_over_masked" | "other".
612
+ */
613
+ async submitFeedback(jobId, rating, opts = {}) {
614
+ if (!VALID_RATINGS.has(rating)) {
615
+ throw new Error(`Invalid rating "${rating}". Valid: ${[...VALID_RATINGS].join(", ")}`);
616
+ }
617
+ if (opts.issue !== void 0 && !VALID_ISSUES.has(opts.issue)) {
618
+ throw new Error(`Invalid issue "${opts.issue}". Valid: ${[...VALID_ISSUES].join(", ")}`);
619
+ }
620
+ const data = await this._t.post(`/jobs/${jobId}/feedback`, {
621
+ rating,
622
+ issue: opts.issue ?? null,
623
+ notes: opts.notes ?? null
624
+ });
625
+ return jobFeedbackFromDict(data);
626
+ }
627
+ /** Existing feedback for a job, or null if none was submitted. */
628
+ async getFeedback(jobId) {
629
+ const data = await this._t.get(`/jobs/${jobId}/feedback`);
630
+ if (!data) return null;
631
+ return jobFeedbackFromDict(data);
632
+ }
498
633
  };
499
634
 
500
635
  // src/resources/datasets.ts
@@ -512,10 +647,121 @@ var DatasetsResource = class {
512
647
  const params = {};
513
648
  if (opts.page !== void 0) params["page"] = String(opts.page);
514
649
  if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
650
+ if (opts.status !== void 0) params["status"] = opts.status;
651
+ if (opts.sourceExecutionId !== void 0) params["source_execution_id"] = String(opts.sourceExecutionId);
652
+ if (opts.sourceDocumentId !== void 0) params["source_document_id"] = String(opts.sourceDocumentId);
653
+ if (opts.q !== void 0) params["q"] = opts.q;
515
654
  const data = await this._t.get("/datasets", params);
516
655
  const items = data["items"] ?? [];
517
656
  return items.map((item) => Dataset.fromDict(item, this._t));
518
657
  }
658
+ /**
659
+ * Build a dataset from a completed execution.
660
+ *
661
+ * Prefer `Job.buildDataset()` when you already have a Job object — this is
662
+ * the lower-level call for when you only have an executionId (e.g. from
663
+ * `Document.latestExecution`).
664
+ *
665
+ * @returns A dataset_build Job — call `.wait()` then `.dataset()`.
666
+ */
667
+ async buildFromExecution(executionId, opts = {}) {
668
+ const body = {
669
+ force_rebuild: opts.forceRebuild ?? false,
670
+ replace_existing: opts.replaceExisting ?? false
671
+ };
672
+ if (opts.name !== void 0) body["name"] = opts.name;
673
+ if (opts.description !== void 0) body["description"] = opts.description;
674
+ if (opts.slug !== void 0) body["slug"] = opts.slug;
675
+ const data = await this._t.post(
676
+ `/datasets/build-from-execution/${executionId}`,
677
+ body
678
+ );
679
+ return Job.fromDict(data, this._t);
680
+ }
681
+ };
682
+
683
+ // src/models/document.ts
684
+ var Document = class _Document {
685
+ id;
686
+ filename;
687
+ fileExt;
688
+ status;
689
+ storagePath;
690
+ createdAt;
691
+ processingCount;
692
+ latestExecution;
693
+ dataset;
694
+ processingHistory;
695
+ relatedDatasets;
696
+ _transport;
697
+ constructor(data) {
698
+ this.id = data.id;
699
+ this.filename = data.filename;
700
+ this.fileExt = data.fileExt;
701
+ this.status = data.status;
702
+ this.storagePath = data.storagePath;
703
+ this.createdAt = data.createdAt;
704
+ this.processingCount = data.processingCount;
705
+ this.latestExecution = data.latestExecution;
706
+ this.dataset = data.dataset;
707
+ this.processingHistory = data.processingHistory;
708
+ this.relatedDatasets = data.relatedDatasets;
709
+ this._transport = data._transport;
710
+ }
711
+ static fromDict(data, transport) {
712
+ return new _Document({
713
+ id: String(data["id"] ?? ""),
714
+ filename: String(data["filename"] ?? ""),
715
+ fileExt: String(data["file_ext"] ?? ""),
716
+ status: String(data["status"] ?? ""),
717
+ storagePath: String(data["storage_path"] ?? ""),
718
+ createdAt: String(data["created_at"] ?? ""),
719
+ processingCount: Number(data["processing_count"] ?? 0),
720
+ latestExecution: data["latest_execution"] ?? null,
721
+ dataset: data["dataset"] ?? null,
722
+ processingHistory: data["processing_history"] ?? [],
723
+ relatedDatasets: data["related_datasets"] ?? [],
724
+ _transport: transport
725
+ });
726
+ }
727
+ /**
728
+ * Re-queue this document through the processing pipeline.
729
+ *
730
+ * Raises (via the API): 400 DOCUMENT_FILE_NOT_AVAILABLE if the source file
731
+ * is no longer on disk, or 400 REPROCESS_NOT_SUPPORTED for
732
+ * connector-sourced (e.g. S3) documents.
733
+ */
734
+ async reprocess(pipelineConfig) {
735
+ const body = {};
736
+ if (pipelineConfig) body["pipeline_config"] = pipelineConfig;
737
+ const data = await this._transport.post(`/documents/${this.id}/reprocess`, body);
738
+ return Job.fromDict(data, this._transport);
739
+ }
740
+ toString() {
741
+ return `Document(id=${this.id}, filename=${this.filename}, status=${this.status})`;
742
+ }
743
+ };
744
+
745
+ // src/resources/documents.ts
746
+ var DocumentsResource = class {
747
+ constructor(_t) {
748
+ this._t = _t;
749
+ }
750
+ _t;
751
+ /** Fetch a single document, including processingHistory and relatedDatasets. */
752
+ async get(documentId) {
753
+ const data = await this._t.get(`/documents/${documentId}`);
754
+ return Document.fromDict(data, this._t);
755
+ }
756
+ /** List documents for the current tenant, newest first. */
757
+ async list(opts = {}) {
758
+ const params = {};
759
+ if (opts.page !== void 0) params["page"] = String(opts.page);
760
+ if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
761
+ const data = await this._t.get("/documents", params);
762
+ const items = data["items"] ?? [];
763
+ return items.map((item) => Document.fromDict(item, this._t));
764
+ }
519
765
  };
520
766
 
521
767
  // src/resources/usage.ts
@@ -525,15 +771,51 @@ var UsageResource = class {
525
771
  }
526
772
  _t;
527
773
  async current() {
528
- const data = await this._t.get("/usage/current");
774
+ const data = await this._t.get("/usage") ?? {};
775
+ const trial = data["trial"] ?? {};
776
+ const usage = data["usage"] ?? {};
777
+ const credits = usage["credits"] ?? {};
778
+ return {
779
+ plan: String(data["plan"] ?? ""),
780
+ creditsUsed: Number(credits["used"] ?? 0),
781
+ creditsLimit: credits["limit"] ?? null,
782
+ creditsRemaining: credits["remaining"] ?? null,
783
+ isTrial: Boolean(trial["is_trial"] ?? false),
784
+ trialEndsAt: trial["trial_ends_at"] ?? null,
785
+ trialDaysRemaining: trial["trial_days_remaining"] ?? null
786
+ };
787
+ }
788
+ /** @param period "7d" | "30d" | "90d". Default: "30d". */
789
+ async history(period = "30d") {
790
+ const data = await this._t.get("/usage/history", { period });
791
+ return (data ?? []).map((item) => ({
792
+ date: String(item["date"] ?? ""),
793
+ creditsUsed: Number(item["credits_used"] ?? 0),
794
+ jobsCount: Number(item["jobs_count"] ?? 0)
795
+ }));
796
+ }
797
+ /** @param period "7d" | "30d" | "90d". Default: "30d". */
798
+ async qualityTrend(period = "30d") {
799
+ const data = await this._t.get("/usage/quality-trend", { period });
800
+ return (data ?? []).map((item) => ({
801
+ date: String(item["date"] ?? ""),
802
+ avgQualityScore: Number(item["avg_quality_score"] ?? 0),
803
+ gradeDistribution: item["grade_distribution"] ?? {},
804
+ avgFieldFillRate: item["avg_field_fill_rate"] ?? null,
805
+ jobCount: Number(item["job_count"] ?? 0)
806
+ }));
807
+ }
808
+ /** Current rate limit configuration and window usage. Does not consume a request slot. */
809
+ async rateLimits() {
810
+ const data = await this._t.get("/usage/rate-limits") ?? {};
529
811
  return {
530
812
  plan: String(data["plan"] ?? ""),
531
- creditsUsed: Number(data["credits_used"] ?? 0),
532
- creditsLimit: Number(data["credits_limit"] ?? 0),
533
- creditsRemaining: Number(data["credits_remaining"] ?? 0),
534
- resetAt: String(data["reset_at"] ?? ""),
535
- periodStart: String(data["period_start"] ?? ""),
536
- periodEnd: String(data["period_end"] ?? "")
813
+ unlimited: Boolean(data["unlimited"] ?? false),
814
+ limit: data["limit"] ?? null,
815
+ used: data["used"] ?? null,
816
+ remaining: data["remaining"] ?? null,
817
+ windowSeconds: Number(data["window_seconds"] ?? 0),
818
+ resetInSeconds: data["reset_in_seconds"] ?? null
537
819
  };
538
820
  }
539
821
  };
@@ -605,6 +887,32 @@ var Connector = class _Connector {
605
887
  return `Connector(id=${this.id}, name=${this.name}, type=${this.type})`;
606
888
  }
607
889
  };
890
+ function syncScheduleFromDict(data) {
891
+ return {
892
+ id: String(data["id"] ?? ""),
893
+ connectorId: String(data["connector_id"] ?? ""),
894
+ cronExpression: String(data["cron_expression"] ?? ""),
895
+ prefixFilter: data["prefix_filter"] ?? null,
896
+ isActive: Boolean(data["is_active"] ?? true),
897
+ lastRunAt: data["last_run_at"] ?? null,
898
+ nextRunAt: data["next_run_at"] ?? null,
899
+ createdAt: String(data["created_at"] ?? "")
900
+ };
901
+ }
902
+ function syncLogFromDict(data) {
903
+ return {
904
+ id: String(data["id"] ?? ""),
905
+ scheduleId: String(data["schedule_id"] ?? ""),
906
+ startedAt: String(data["started_at"] ?? ""),
907
+ completedAt: data["completed_at"] ?? null,
908
+ filesFound: Number(data["files_found"] ?? 0),
909
+ filesNew: Number(data["files_new"] ?? 0),
910
+ filesSkipped: Number(data["files_skipped"] ?? 0),
911
+ filesFailed: Number(data["files_failed"] ?? 0),
912
+ status: String(data["status"] ?? ""),
913
+ errorMessage: data["error_message"] ?? null
914
+ };
915
+ }
608
916
 
609
917
  // src/resources/connectors.ts
610
918
  var VALID_TYPES = /* @__PURE__ */ new Set([
@@ -648,13 +956,54 @@ var ConnectorsResource = class {
648
956
  message: String(data["message"] ?? "")
649
957
  };
650
958
  }
959
+ /** Define a scheduled sync for a connector (Pro+ required). */
960
+ async createSchedule(connectorId, cronExpression, prefixFilter = null) {
961
+ const data = await this._t.post(`/connectors/${connectorId}/schedules`, {
962
+ cron_expression: cronExpression,
963
+ prefix_filter: prefixFilter
964
+ });
965
+ return syncScheduleFromDict(data);
966
+ }
967
+ /** Active schedules for a connector. */
968
+ async listSchedules(connectorId) {
969
+ const data = await this._t.get(`/connectors/${connectorId}/schedules`);
970
+ return (data ?? []).map(syncScheduleFromDict);
971
+ }
972
+ /** Delete a scheduled sync. */
973
+ async deleteSchedule(connectorId, scheduleId) {
974
+ await this._t.delete(`/connectors/${connectorId}/schedules/${scheduleId}`);
975
+ }
976
+ /** Run a schedule immediately instead of waiting for its cron time. */
977
+ async triggerSchedule(connectorId, scheduleId) {
978
+ const data = await this._t.post(
979
+ `/connectors/${connectorId}/schedules/${scheduleId}/trigger`
980
+ );
981
+ return syncLogFromDict(data);
982
+ }
983
+ /** Recent sync run logs for a schedule. */
984
+ async scheduleLogs(connectorId, scheduleId) {
985
+ const data = await this._t.get(
986
+ `/connectors/${connectorId}/schedules/${scheduleId}/logs`
987
+ );
988
+ return (data ?? []).map(syncLogFromDict);
989
+ }
651
990
  };
652
991
 
653
992
  // src/client.ts
654
993
  var DEFAULT_BASE_URL = "https://api.flexorch.com/v1";
994
+ function firstJobOrThrow(uploadResponse, filename, transport) {
995
+ const jobs = uploadResponse["jobs"] ?? [];
996
+ if (jobs.length > 0) {
997
+ return Job.fromDict(jobs[0], transport);
998
+ }
999
+ const rejected = uploadResponse["rejected"] ?? [];
1000
+ const reason = rejected.length > 0 ? String(rejected[0]["error"]) : "unknown error";
1001
+ throw new ValidationError(`${filename} was rejected: ${reason}`);
1002
+ }
655
1003
  var FlexOrchClient = class {
656
1004
  jobs;
657
1005
  datasets;
1006
+ documents;
658
1007
  usage;
659
1008
  webhooks;
660
1009
  connectors;
@@ -676,6 +1025,7 @@ var FlexOrchClient = class {
676
1025
  );
677
1026
  this.jobs = new JobsResource(this._transport);
678
1027
  this.datasets = new DatasetsResource(this._transport);
1028
+ this.documents = new DocumentsResource(this._transport);
679
1029
  this.usage = new UsageResource(this._transport);
680
1030
  this.webhooks = new WebhooksResource(this._transport);
681
1031
  this.connectors = new ConnectorsResource(this._transport);
@@ -693,13 +1043,13 @@ var FlexOrchClient = class {
693
1043
  chunks.push(chunk);
694
1044
  }
695
1045
  const blob = new Blob([Buffer.concat(chunks)], { type: "application/octet-stream" });
696
- form.append("file", blob, basename(filePath));
1046
+ form.append("files", blob, basename(filePath));
697
1047
  form.append("locale", opts.locale ?? "und");
698
1048
  if (opts.pipelineConfig) {
699
1049
  form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
700
1050
  }
701
1051
  const data = await this._transport.postForm("/data-process/async", form);
702
- return Job.fromDict(data, this._transport);
1052
+ return firstJobOrThrow(data, basename(filePath), this._transport);
703
1053
  }
704
1054
  async processMany(filePaths, opts = {}) {
705
1055
  const jobs = [];
@@ -718,7 +1068,7 @@ var FlexOrchClient = class {
718
1068
  form.append("pipeline_config", JSON.stringify(opts.pipelineConfig));
719
1069
  }
720
1070
  const data = await this._transport.postForm("/data-process/async", form);
721
- jobs.push(Job.fromDict(data, this._transport));
1071
+ jobs.push(firstJobOrThrow(data, key, this._transport));
722
1072
  }
723
1073
  return jobs;
724
1074
  }
@@ -925,12 +1275,13 @@ var FlexOrchReader = class {
925
1275
  };
926
1276
 
927
1277
  // src/index.ts
928
- var version = "0.2.3";
1278
+ var version = "0.3.1";
929
1279
  // Annotate the CommonJS export names for ESM import in node:
930
1280
  0 && (module.exports = {
931
1281
  AuthError,
932
1282
  Connector,
933
1283
  Dataset,
1284
+ Document,
934
1285
  FlexOrchClient,
935
1286
  FlexOrchError,
936
1287
  FlexOrchReader,