@stack0/sdk 0.2.8 → 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/dist/index.mjs CHANGED
@@ -381,6 +381,874 @@ var CDN = class {
381
381
  }
382
382
  return folder;
383
383
  }
384
+ // ============================================================================
385
+ // Video Transcoding Methods
386
+ // ============================================================================
387
+ /**
388
+ * Start a video transcoding job
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * const job = await cdn.transcode({
393
+ * projectSlug: 'my-project',
394
+ * assetId: 'video-asset-id',
395
+ * outputFormat: 'hls',
396
+ * variants: [
397
+ * { quality: '720p', codec: 'h264' },
398
+ * { quality: '1080p', codec: 'h264' },
399
+ * ],
400
+ * webhookUrl: 'https://your-app.com/webhook',
401
+ * });
402
+ * console.log(`Job started: ${job.id}`);
403
+ * ```
404
+ */
405
+ async transcode(request) {
406
+ const response = await this.http.post("/cdn/video/transcode", request);
407
+ return this.convertJobDates(response);
408
+ }
409
+ /**
410
+ * Get a transcoding job by ID
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * const job = await cdn.getJob('job-id');
415
+ * console.log(`Status: ${job.status}, Progress: ${job.progress}%`);
416
+ * ```
417
+ */
418
+ async getJob(jobId) {
419
+ const response = await this.http.get(`/cdn/video/jobs/${jobId}`);
420
+ return this.convertJobDates(response);
421
+ }
422
+ /**
423
+ * List transcoding jobs with filters
424
+ *
425
+ * @example
426
+ * ```typescript
427
+ * const { jobs, total } = await cdn.listJobs({
428
+ * projectSlug: 'my-project',
429
+ * status: 'processing',
430
+ * limit: 20,
431
+ * });
432
+ * ```
433
+ */
434
+ async listJobs(request) {
435
+ const params = new URLSearchParams();
436
+ params.set("projectSlug", request.projectSlug);
437
+ if (request.assetId) params.set("assetId", request.assetId);
438
+ if (request.status) params.set("status", request.status);
439
+ if (request.limit) params.set("limit", request.limit.toString());
440
+ if (request.offset) params.set("offset", request.offset.toString());
441
+ const response = await this.http.get(`/cdn/video/jobs?${params.toString()}`);
442
+ return {
443
+ ...response,
444
+ jobs: response.jobs.map((job) => this.convertJobDates(job))
445
+ };
446
+ }
447
+ /**
448
+ * Cancel a pending or processing transcoding job
449
+ *
450
+ * @example
451
+ * ```typescript
452
+ * await cdn.cancelJob('job-id');
453
+ * ```
454
+ */
455
+ async cancelJob(jobId) {
456
+ return this.http.post(`/cdn/video/jobs/${jobId}/cancel`, {});
457
+ }
458
+ /**
459
+ * Get streaming URLs for a transcoded video
460
+ *
461
+ * @example
462
+ * ```typescript
463
+ * const urls = await cdn.getStreamingUrls('asset-id');
464
+ * console.log(`HLS URL: ${urls.hlsUrl}`);
465
+ * console.log(`MP4 720p: ${urls.mp4Urls.find(u => u.quality === '720p')?.url}`);
466
+ * ```
467
+ */
468
+ async getStreamingUrls(assetId) {
469
+ return this.http.get(`/cdn/video/stream/${assetId}`);
470
+ }
471
+ /**
472
+ * Generate a thumbnail from a video at a specific timestamp
473
+ *
474
+ * @example
475
+ * ```typescript
476
+ * const thumbnail = await cdn.getThumbnail({
477
+ * assetId: 'video-asset-id',
478
+ * timestamp: 10.5, // 10.5 seconds into the video
479
+ * width: 320,
480
+ * format: 'webp',
481
+ * });
482
+ * console.log(`Thumbnail URL: ${thumbnail.url}`);
483
+ * ```
484
+ */
485
+ async getThumbnail(request) {
486
+ const params = new URLSearchParams();
487
+ params.set("timestamp", request.timestamp.toString());
488
+ if (request.width) params.set("width", request.width.toString());
489
+ if (request.format) params.set("format", request.format);
490
+ return this.http.get(
491
+ `/cdn/video/thumbnail/${request.assetId}?${params.toString()}`
492
+ );
493
+ }
494
+ /**
495
+ * Extract audio from a video file
496
+ *
497
+ * @example
498
+ * ```typescript
499
+ * const { jobId } = await cdn.extractAudio({
500
+ * projectSlug: 'my-project',
501
+ * assetId: 'video-asset-id',
502
+ * format: 'mp3',
503
+ * bitrate: 192,
504
+ * });
505
+ * ```
506
+ */
507
+ async extractAudio(request) {
508
+ return this.http.post("/cdn/video/extract-audio", request);
509
+ }
510
+ convertJobDates(job) {
511
+ if (typeof job.createdAt === "string") {
512
+ job.createdAt = new Date(job.createdAt);
513
+ }
514
+ if (job.startedAt && typeof job.startedAt === "string") {
515
+ job.startedAt = new Date(job.startedAt);
516
+ }
517
+ if (job.completedAt && typeof job.completedAt === "string") {
518
+ job.completedAt = new Date(job.completedAt);
519
+ }
520
+ return job;
521
+ }
522
+ };
523
+
524
+ // src/screenshots/client.ts
525
+ var Screenshots = class {
526
+ http;
527
+ constructor(config) {
528
+ this.http = new HttpClient(config);
529
+ }
530
+ // ==========================================================================
531
+ // SCREENSHOTS
532
+ // ==========================================================================
533
+ /**
534
+ * Capture a screenshot of a URL
535
+ *
536
+ * @example
537
+ * ```typescript
538
+ * const { id, status } = await screenshots.capture({
539
+ * url: 'https://example.com',
540
+ * format: 'png',
541
+ * fullPage: true,
542
+ * deviceType: 'desktop',
543
+ * });
544
+ *
545
+ * // Poll for completion
546
+ * const screenshot = await screenshots.get({ id });
547
+ * console.log(screenshot.imageUrl);
548
+ * ```
549
+ */
550
+ async capture(request) {
551
+ return this.http.post("/webdata/screenshots", request);
552
+ }
553
+ /**
554
+ * Get a screenshot by ID
555
+ *
556
+ * @example
557
+ * ```typescript
558
+ * const screenshot = await screenshots.get({ id: 'screenshot-id' });
559
+ * if (screenshot.status === 'completed') {
560
+ * console.log(screenshot.imageUrl);
561
+ * }
562
+ * ```
563
+ */
564
+ async get(request) {
565
+ const params = new URLSearchParams();
566
+ if (request.environment) params.set("environment", request.environment);
567
+ if (request.projectId) params.set("projectId", request.projectId);
568
+ const query = params.toString();
569
+ const path = `/webdata/screenshots/${request.id}${query ? `?${query}` : ""}`;
570
+ const response = await this.http.get(path);
571
+ return this.convertDates(response);
572
+ }
573
+ /**
574
+ * List screenshots with pagination and filters
575
+ *
576
+ * @example
577
+ * ```typescript
578
+ * const { items, nextCursor } = await screenshots.list({
579
+ * status: 'completed',
580
+ * limit: 20,
581
+ * });
582
+ * ```
583
+ */
584
+ async list(request = {}) {
585
+ const params = new URLSearchParams();
586
+ if (request.environment) params.set("environment", request.environment);
587
+ if (request.projectId) params.set("projectId", request.projectId);
588
+ if (request.status) params.set("status", request.status);
589
+ if (request.url) params.set("url", request.url);
590
+ if (request.limit) params.set("limit", request.limit.toString());
591
+ if (request.cursor) params.set("cursor", request.cursor);
592
+ const query = params.toString();
593
+ const response = await this.http.get(
594
+ `/webdata/screenshots${query ? `?${query}` : ""}`
595
+ );
596
+ return {
597
+ ...response,
598
+ items: response.items.map((item) => this.convertDates(item))
599
+ };
600
+ }
601
+ /**
602
+ * Delete a screenshot
603
+ *
604
+ * @example
605
+ * ```typescript
606
+ * await screenshots.delete({ id: 'screenshot-id' });
607
+ * ```
608
+ */
609
+ async delete(request) {
610
+ const params = new URLSearchParams();
611
+ if (request.environment) params.set("environment", request.environment);
612
+ if (request.projectId) params.set("projectId", request.projectId);
613
+ const query = params.toString();
614
+ return this.http.delete(
615
+ `/webdata/screenshots/${request.id}${query ? `?${query}` : ""}`
616
+ );
617
+ }
618
+ /**
619
+ * Capture a screenshot and wait for completion
620
+ *
621
+ * @example
622
+ * ```typescript
623
+ * const screenshot = await screenshots.captureAndWait({
624
+ * url: 'https://example.com',
625
+ * format: 'png',
626
+ * });
627
+ * console.log(screenshot.imageUrl);
628
+ * ```
629
+ */
630
+ async captureAndWait(request, options = {}) {
631
+ const { pollInterval = 1e3, timeout = 6e4 } = options;
632
+ const startTime = Date.now();
633
+ const { id } = await this.capture(request);
634
+ while (Date.now() - startTime < timeout) {
635
+ const screenshot = await this.get({
636
+ id,
637
+ environment: request.environment,
638
+ projectId: request.projectId
639
+ });
640
+ if (screenshot.status === "completed" || screenshot.status === "failed") {
641
+ if (screenshot.status === "failed") {
642
+ throw new Error(screenshot.error || "Screenshot failed");
643
+ }
644
+ return screenshot;
645
+ }
646
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
647
+ }
648
+ throw new Error("Screenshot timed out");
649
+ }
650
+ // ==========================================================================
651
+ // BATCH JOBS
652
+ // ==========================================================================
653
+ /**
654
+ * Create a batch screenshot job for multiple URLs
655
+ *
656
+ * @example
657
+ * ```typescript
658
+ * const { id, totalUrls } = await screenshots.batch({
659
+ * urls: [
660
+ * 'https://example.com',
661
+ * 'https://example.org',
662
+ * ],
663
+ * config: { format: 'png', fullPage: true },
664
+ * });
665
+ *
666
+ * // Poll for completion
667
+ * const job = await screenshots.getBatchJob({ id });
668
+ * console.log(`Progress: ${job.processedUrls}/${job.totalUrls}`);
669
+ * ```
670
+ */
671
+ async batch(request) {
672
+ return this.http.post("/webdata/batch/screenshots", request);
673
+ }
674
+ /**
675
+ * Get a batch job by ID
676
+ */
677
+ async getBatchJob(request) {
678
+ const params = new URLSearchParams();
679
+ if (request.environment) params.set("environment", request.environment);
680
+ if (request.projectId) params.set("projectId", request.projectId);
681
+ const query = params.toString();
682
+ const path = `/webdata/batch/${request.id}${query ? `?${query}` : ""}`;
683
+ const response = await this.http.get(path);
684
+ return this.convertBatchJobDates(response);
685
+ }
686
+ /**
687
+ * List batch jobs with pagination and filters
688
+ */
689
+ async listBatchJobs(request = {}) {
690
+ const params = new URLSearchParams();
691
+ if (request.environment) params.set("environment", request.environment);
692
+ if (request.projectId) params.set("projectId", request.projectId);
693
+ if (request.status) params.set("status", request.status);
694
+ params.set("type", "screenshot");
695
+ if (request.limit) params.set("limit", request.limit.toString());
696
+ if (request.cursor) params.set("cursor", request.cursor);
697
+ const query = params.toString();
698
+ const response = await this.http.get(
699
+ `/webdata/batch${query ? `?${query}` : ""}`
700
+ );
701
+ return {
702
+ ...response,
703
+ items: response.items.map((item) => this.convertBatchJobDates(item))
704
+ };
705
+ }
706
+ /**
707
+ * Cancel a batch job
708
+ */
709
+ async cancelBatchJob(request) {
710
+ const params = new URLSearchParams();
711
+ if (request.environment) params.set("environment", request.environment);
712
+ if (request.projectId) params.set("projectId", request.projectId);
713
+ const query = params.toString();
714
+ return this.http.post(
715
+ `/webdata/batch/${request.id}/cancel${query ? `?${query}` : ""}`,
716
+ {}
717
+ );
718
+ }
719
+ /**
720
+ * Create a batch screenshot job and wait for completion
721
+ */
722
+ async batchAndWait(request, options = {}) {
723
+ const { pollInterval = 2e3, timeout = 3e5 } = options;
724
+ const startTime = Date.now();
725
+ const { id } = await this.batch(request);
726
+ while (Date.now() - startTime < timeout) {
727
+ const job = await this.getBatchJob({
728
+ id,
729
+ environment: request.environment,
730
+ projectId: request.projectId
731
+ });
732
+ if (job.status === "completed" || job.status === "failed" || job.status === "cancelled") {
733
+ return job;
734
+ }
735
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
736
+ }
737
+ throw new Error("Batch job timed out");
738
+ }
739
+ // ==========================================================================
740
+ // SCHEDULES
741
+ // ==========================================================================
742
+ /**
743
+ * Create a scheduled screenshot job
744
+ *
745
+ * @example
746
+ * ```typescript
747
+ * const { id } = await screenshots.createSchedule({
748
+ * name: 'Daily homepage screenshot',
749
+ * url: 'https://example.com',
750
+ * frequency: 'daily',
751
+ * config: { format: 'png', fullPage: true },
752
+ * });
753
+ * ```
754
+ */
755
+ async createSchedule(request) {
756
+ return this.http.post("/webdata/schedules", {
757
+ ...request,
758
+ type: "screenshot"
759
+ });
760
+ }
761
+ /**
762
+ * Update a schedule
763
+ */
764
+ async updateSchedule(request) {
765
+ const { id, environment, projectId, ...data } = request;
766
+ const params = new URLSearchParams();
767
+ if (environment) params.set("environment", environment);
768
+ if (projectId) params.set("projectId", projectId);
769
+ const query = params.toString();
770
+ return this.http.post(
771
+ `/webdata/schedules/${id}${query ? `?${query}` : ""}`,
772
+ data
773
+ );
774
+ }
775
+ /**
776
+ * Get a schedule by ID
777
+ */
778
+ async getSchedule(request) {
779
+ const params = new URLSearchParams();
780
+ if (request.environment) params.set("environment", request.environment);
781
+ if (request.projectId) params.set("projectId", request.projectId);
782
+ const query = params.toString();
783
+ const path = `/webdata/schedules/${request.id}${query ? `?${query}` : ""}`;
784
+ const response = await this.http.get(path);
785
+ return this.convertScheduleDates(response);
786
+ }
787
+ /**
788
+ * List schedules with pagination and filters
789
+ */
790
+ async listSchedules(request = {}) {
791
+ const params = new URLSearchParams();
792
+ if (request.environment) params.set("environment", request.environment);
793
+ if (request.projectId) params.set("projectId", request.projectId);
794
+ params.set("type", "screenshot");
795
+ if (request.isActive !== void 0) params.set("isActive", request.isActive.toString());
796
+ if (request.limit) params.set("limit", request.limit.toString());
797
+ if (request.cursor) params.set("cursor", request.cursor);
798
+ const query = params.toString();
799
+ const response = await this.http.get(
800
+ `/webdata/schedules${query ? `?${query}` : ""}`
801
+ );
802
+ return {
803
+ ...response,
804
+ items: response.items.map((item) => this.convertScheduleDates(item))
805
+ };
806
+ }
807
+ /**
808
+ * Delete a schedule
809
+ */
810
+ async deleteSchedule(request) {
811
+ const params = new URLSearchParams();
812
+ if (request.environment) params.set("environment", request.environment);
813
+ if (request.projectId) params.set("projectId", request.projectId);
814
+ const query = params.toString();
815
+ return this.http.delete(
816
+ `/webdata/schedules/${request.id}${query ? `?${query}` : ""}`
817
+ );
818
+ }
819
+ /**
820
+ * Toggle a schedule on or off
821
+ */
822
+ async toggleSchedule(request) {
823
+ const params = new URLSearchParams();
824
+ if (request.environment) params.set("environment", request.environment);
825
+ if (request.projectId) params.set("projectId", request.projectId);
826
+ const query = params.toString();
827
+ return this.http.post(
828
+ `/webdata/schedules/${request.id}/toggle${query ? `?${query}` : ""}`,
829
+ {}
830
+ );
831
+ }
832
+ // ==========================================================================
833
+ // HELPERS
834
+ // ==========================================================================
835
+ convertDates(screenshot) {
836
+ if (typeof screenshot.createdAt === "string") {
837
+ screenshot.createdAt = new Date(screenshot.createdAt);
838
+ }
839
+ if (screenshot.completedAt && typeof screenshot.completedAt === "string") {
840
+ screenshot.completedAt = new Date(screenshot.completedAt);
841
+ }
842
+ return screenshot;
843
+ }
844
+ convertBatchJobDates(job) {
845
+ if (typeof job.createdAt === "string") {
846
+ job.createdAt = new Date(job.createdAt);
847
+ }
848
+ if (job.startedAt && typeof job.startedAt === "string") {
849
+ job.startedAt = new Date(job.startedAt);
850
+ }
851
+ if (job.completedAt && typeof job.completedAt === "string") {
852
+ job.completedAt = new Date(job.completedAt);
853
+ }
854
+ return job;
855
+ }
856
+ convertScheduleDates(schedule) {
857
+ if (typeof schedule.createdAt === "string") {
858
+ schedule.createdAt = new Date(schedule.createdAt);
859
+ }
860
+ if (typeof schedule.updatedAt === "string") {
861
+ schedule.updatedAt = new Date(schedule.updatedAt);
862
+ }
863
+ if (schedule.lastRunAt && typeof schedule.lastRunAt === "string") {
864
+ schedule.lastRunAt = new Date(schedule.lastRunAt);
865
+ }
866
+ if (schedule.nextRunAt && typeof schedule.nextRunAt === "string") {
867
+ schedule.nextRunAt = new Date(schedule.nextRunAt);
868
+ }
869
+ return schedule;
870
+ }
871
+ };
872
+
873
+ // src/extraction/client.ts
874
+ var Extraction = class {
875
+ http;
876
+ constructor(config) {
877
+ this.http = new HttpClient(config);
878
+ }
879
+ // ==========================================================================
880
+ // EXTRACTIONS
881
+ // ==========================================================================
882
+ /**
883
+ * Extract content from a URL
884
+ *
885
+ * @example
886
+ * ```typescript
887
+ * const { id, status } = await extraction.extract({
888
+ * url: 'https://example.com/article',
889
+ * mode: 'markdown',
890
+ * includeMetadata: true,
891
+ * });
892
+ *
893
+ * // Poll for completion
894
+ * const result = await extraction.get({ id });
895
+ * console.log(result.markdown);
896
+ * ```
897
+ */
898
+ async extract(request) {
899
+ return this.http.post("/webdata/extractions", request);
900
+ }
901
+ /**
902
+ * Get an extraction by ID
903
+ *
904
+ * @example
905
+ * ```typescript
906
+ * const extraction = await extraction.get({ id: 'extraction-id' });
907
+ * if (extraction.status === 'completed') {
908
+ * console.log(extraction.markdown);
909
+ * console.log(extraction.pageMetadata);
910
+ * }
911
+ * ```
912
+ */
913
+ async get(request) {
914
+ const params = new URLSearchParams();
915
+ if (request.environment) params.set("environment", request.environment);
916
+ if (request.projectId) params.set("projectId", request.projectId);
917
+ const query = params.toString();
918
+ const path = `/webdata/extractions/${request.id}${query ? `?${query}` : ""}`;
919
+ const response = await this.http.get(path);
920
+ return this.convertDates(response);
921
+ }
922
+ /**
923
+ * List extractions with pagination and filters
924
+ *
925
+ * @example
926
+ * ```typescript
927
+ * const { items, nextCursor } = await extraction.list({
928
+ * status: 'completed',
929
+ * limit: 20,
930
+ * });
931
+ * ```
932
+ */
933
+ async list(request = {}) {
934
+ const params = new URLSearchParams();
935
+ if (request.environment) params.set("environment", request.environment);
936
+ if (request.projectId) params.set("projectId", request.projectId);
937
+ if (request.status) params.set("status", request.status);
938
+ if (request.url) params.set("url", request.url);
939
+ if (request.limit) params.set("limit", request.limit.toString());
940
+ if (request.cursor) params.set("cursor", request.cursor);
941
+ const query = params.toString();
942
+ const response = await this.http.get(
943
+ `/webdata/extractions${query ? `?${query}` : ""}`
944
+ );
945
+ return {
946
+ ...response,
947
+ items: response.items.map((item) => this.convertDates(item))
948
+ };
949
+ }
950
+ /**
951
+ * Delete an extraction
952
+ *
953
+ * @example
954
+ * ```typescript
955
+ * await extraction.delete({ id: 'extraction-id' });
956
+ * ```
957
+ */
958
+ async delete(request) {
959
+ const params = new URLSearchParams();
960
+ if (request.environment) params.set("environment", request.environment);
961
+ if (request.projectId) params.set("projectId", request.projectId);
962
+ const query = params.toString();
963
+ return this.http.delete(
964
+ `/webdata/extractions/${request.id}${query ? `?${query}` : ""}`
965
+ );
966
+ }
967
+ /**
968
+ * Extract content and wait for completion
969
+ *
970
+ * @example
971
+ * ```typescript
972
+ * const extraction = await extraction.extractAndWait({
973
+ * url: 'https://example.com/article',
974
+ * mode: 'markdown',
975
+ * });
976
+ * console.log(extraction.markdown);
977
+ * ```
978
+ */
979
+ async extractAndWait(request, options = {}) {
980
+ const { pollInterval = 1e3, timeout = 6e4 } = options;
981
+ const startTime = Date.now();
982
+ const { id } = await this.extract(request);
983
+ while (Date.now() - startTime < timeout) {
984
+ const extraction = await this.get({
985
+ id,
986
+ environment: request.environment,
987
+ projectId: request.projectId
988
+ });
989
+ if (extraction.status === "completed" || extraction.status === "failed") {
990
+ if (extraction.status === "failed") {
991
+ throw new Error(extraction.error || "Extraction failed");
992
+ }
993
+ return extraction;
994
+ }
995
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
996
+ }
997
+ throw new Error("Extraction timed out");
998
+ }
999
+ // ==========================================================================
1000
+ // BATCH JOBS
1001
+ // ==========================================================================
1002
+ /**
1003
+ * Create a batch extraction job for multiple URLs
1004
+ *
1005
+ * @example
1006
+ * ```typescript
1007
+ * const { id, totalUrls } = await extraction.batch({
1008
+ * urls: [
1009
+ * 'https://example.com/article1',
1010
+ * 'https://example.com/article2',
1011
+ * ],
1012
+ * config: { mode: 'markdown' },
1013
+ * });
1014
+ * ```
1015
+ */
1016
+ async batch(request) {
1017
+ return this.http.post("/webdata/batch/extractions", request);
1018
+ }
1019
+ /**
1020
+ * Get a batch job by ID
1021
+ */
1022
+ async getBatchJob(request) {
1023
+ const params = new URLSearchParams();
1024
+ if (request.environment) params.set("environment", request.environment);
1025
+ if (request.projectId) params.set("projectId", request.projectId);
1026
+ const query = params.toString();
1027
+ const path = `/webdata/batch/${request.id}${query ? `?${query}` : ""}`;
1028
+ const response = await this.http.get(path);
1029
+ return this.convertBatchJobDates(response);
1030
+ }
1031
+ /**
1032
+ * List batch jobs with pagination and filters
1033
+ */
1034
+ async listBatchJobs(request = {}) {
1035
+ const params = new URLSearchParams();
1036
+ if (request.environment) params.set("environment", request.environment);
1037
+ if (request.projectId) params.set("projectId", request.projectId);
1038
+ if (request.status) params.set("status", request.status);
1039
+ params.set("type", "extraction");
1040
+ if (request.limit) params.set("limit", request.limit.toString());
1041
+ if (request.cursor) params.set("cursor", request.cursor);
1042
+ const query = params.toString();
1043
+ const response = await this.http.get(
1044
+ `/webdata/batch${query ? `?${query}` : ""}`
1045
+ );
1046
+ return {
1047
+ ...response,
1048
+ items: response.items.map((item) => this.convertBatchJobDates(item))
1049
+ };
1050
+ }
1051
+ /**
1052
+ * Cancel a batch job
1053
+ */
1054
+ async cancelBatchJob(request) {
1055
+ const params = new URLSearchParams();
1056
+ if (request.environment) params.set("environment", request.environment);
1057
+ if (request.projectId) params.set("projectId", request.projectId);
1058
+ const query = params.toString();
1059
+ return this.http.post(
1060
+ `/webdata/batch/${request.id}/cancel${query ? `?${query}` : ""}`,
1061
+ {}
1062
+ );
1063
+ }
1064
+ /**
1065
+ * Create a batch extraction job and wait for completion
1066
+ */
1067
+ async batchAndWait(request, options = {}) {
1068
+ const { pollInterval = 2e3, timeout = 3e5 } = options;
1069
+ const startTime = Date.now();
1070
+ const { id } = await this.batch(request);
1071
+ while (Date.now() - startTime < timeout) {
1072
+ const job = await this.getBatchJob({
1073
+ id,
1074
+ environment: request.environment,
1075
+ projectId: request.projectId
1076
+ });
1077
+ if (job.status === "completed" || job.status === "failed" || job.status === "cancelled") {
1078
+ return job;
1079
+ }
1080
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
1081
+ }
1082
+ throw new Error("Batch job timed out");
1083
+ }
1084
+ // ==========================================================================
1085
+ // SCHEDULES
1086
+ // ==========================================================================
1087
+ /**
1088
+ * Create a scheduled extraction job
1089
+ *
1090
+ * @example
1091
+ * ```typescript
1092
+ * const { id } = await extraction.createSchedule({
1093
+ * name: 'Daily price monitoring',
1094
+ * url: 'https://competitor.com/pricing',
1095
+ * frequency: 'daily',
1096
+ * config: { mode: 'schema', schema: { ... } },
1097
+ * });
1098
+ * ```
1099
+ */
1100
+ async createSchedule(request) {
1101
+ return this.http.post("/webdata/schedules", {
1102
+ ...request,
1103
+ type: "extraction"
1104
+ });
1105
+ }
1106
+ /**
1107
+ * Update a schedule
1108
+ */
1109
+ async updateSchedule(request) {
1110
+ const { id, environment, projectId, ...data } = request;
1111
+ const params = new URLSearchParams();
1112
+ if (environment) params.set("environment", environment);
1113
+ if (projectId) params.set("projectId", projectId);
1114
+ const query = params.toString();
1115
+ return this.http.post(
1116
+ `/webdata/schedules/${id}${query ? `?${query}` : ""}`,
1117
+ data
1118
+ );
1119
+ }
1120
+ /**
1121
+ * Get a schedule by ID
1122
+ */
1123
+ async getSchedule(request) {
1124
+ const params = new URLSearchParams();
1125
+ if (request.environment) params.set("environment", request.environment);
1126
+ if (request.projectId) params.set("projectId", request.projectId);
1127
+ const query = params.toString();
1128
+ const path = `/webdata/schedules/${request.id}${query ? `?${query}` : ""}`;
1129
+ const response = await this.http.get(path);
1130
+ return this.convertScheduleDates(response);
1131
+ }
1132
+ /**
1133
+ * List schedules with pagination and filters
1134
+ */
1135
+ async listSchedules(request = {}) {
1136
+ const params = new URLSearchParams();
1137
+ if (request.environment) params.set("environment", request.environment);
1138
+ if (request.projectId) params.set("projectId", request.projectId);
1139
+ params.set("type", "extraction");
1140
+ if (request.isActive !== void 0) params.set("isActive", request.isActive.toString());
1141
+ if (request.limit) params.set("limit", request.limit.toString());
1142
+ if (request.cursor) params.set("cursor", request.cursor);
1143
+ const query = params.toString();
1144
+ const response = await this.http.get(
1145
+ `/webdata/schedules${query ? `?${query}` : ""}`
1146
+ );
1147
+ return {
1148
+ ...response,
1149
+ items: response.items.map((item) => this.convertScheduleDates(item))
1150
+ };
1151
+ }
1152
+ /**
1153
+ * Delete a schedule
1154
+ */
1155
+ async deleteSchedule(request) {
1156
+ const params = new URLSearchParams();
1157
+ if (request.environment) params.set("environment", request.environment);
1158
+ if (request.projectId) params.set("projectId", request.projectId);
1159
+ const query = params.toString();
1160
+ return this.http.delete(
1161
+ `/webdata/schedules/${request.id}${query ? `?${query}` : ""}`
1162
+ );
1163
+ }
1164
+ /**
1165
+ * Toggle a schedule on or off
1166
+ */
1167
+ async toggleSchedule(request) {
1168
+ const params = new URLSearchParams();
1169
+ if (request.environment) params.set("environment", request.environment);
1170
+ if (request.projectId) params.set("projectId", request.projectId);
1171
+ const query = params.toString();
1172
+ return this.http.post(
1173
+ `/webdata/schedules/${request.id}/toggle${query ? `?${query}` : ""}`,
1174
+ {}
1175
+ );
1176
+ }
1177
+ // ==========================================================================
1178
+ // USAGE
1179
+ // ==========================================================================
1180
+ /**
1181
+ * Get usage statistics
1182
+ *
1183
+ * @example
1184
+ * ```typescript
1185
+ * const usage = await extraction.getUsage({
1186
+ * periodStart: '2024-01-01T00:00:00Z',
1187
+ * periodEnd: '2024-01-31T23:59:59Z',
1188
+ * });
1189
+ * console.log(`Extractions: ${usage.extractionsTotal}`);
1190
+ * console.log(`Tokens used: ${usage.extractionTokensUsed}`);
1191
+ * ```
1192
+ */
1193
+ async getUsage(request = {}) {
1194
+ const params = new URLSearchParams();
1195
+ if (request.environment) params.set("environment", request.environment);
1196
+ if (request.periodStart) params.set("periodStart", request.periodStart);
1197
+ if (request.periodEnd) params.set("periodEnd", request.periodEnd);
1198
+ const query = params.toString();
1199
+ const response = await this.http.get(
1200
+ `/webdata/usage${query ? `?${query}` : ""}`
1201
+ );
1202
+ return this.convertUsageDates(response);
1203
+ }
1204
+ // ==========================================================================
1205
+ // HELPERS
1206
+ // ==========================================================================
1207
+ convertDates(extraction) {
1208
+ if (typeof extraction.createdAt === "string") {
1209
+ extraction.createdAt = new Date(extraction.createdAt);
1210
+ }
1211
+ if (extraction.completedAt && typeof extraction.completedAt === "string") {
1212
+ extraction.completedAt = new Date(extraction.completedAt);
1213
+ }
1214
+ return extraction;
1215
+ }
1216
+ convertBatchJobDates(job) {
1217
+ if (typeof job.createdAt === "string") {
1218
+ job.createdAt = new Date(job.createdAt);
1219
+ }
1220
+ if (job.startedAt && typeof job.startedAt === "string") {
1221
+ job.startedAt = new Date(job.startedAt);
1222
+ }
1223
+ if (job.completedAt && typeof job.completedAt === "string") {
1224
+ job.completedAt = new Date(job.completedAt);
1225
+ }
1226
+ return job;
1227
+ }
1228
+ convertScheduleDates(schedule) {
1229
+ if (typeof schedule.createdAt === "string") {
1230
+ schedule.createdAt = new Date(schedule.createdAt);
1231
+ }
1232
+ if (typeof schedule.updatedAt === "string") {
1233
+ schedule.updatedAt = new Date(schedule.updatedAt);
1234
+ }
1235
+ if (schedule.lastRunAt && typeof schedule.lastRunAt === "string") {
1236
+ schedule.lastRunAt = new Date(schedule.lastRunAt);
1237
+ }
1238
+ if (schedule.nextRunAt && typeof schedule.nextRunAt === "string") {
1239
+ schedule.nextRunAt = new Date(schedule.nextRunAt);
1240
+ }
1241
+ return schedule;
1242
+ }
1243
+ convertUsageDates(usage) {
1244
+ if (typeof usage.periodStart === "string") {
1245
+ usage.periodStart = new Date(usage.periodStart);
1246
+ }
1247
+ if (typeof usage.periodEnd === "string") {
1248
+ usage.periodEnd = new Date(usage.periodEnd);
1249
+ }
1250
+ return usage;
1251
+ }
384
1252
  };
385
1253
 
386
1254
  // src/webdata/client.ts
@@ -983,10 +1851,324 @@ var Webdata = class {
983
1851
  }
984
1852
  };
985
1853
 
1854
+ // src/integrations/client.ts
1855
+ var CRM = class {
1856
+ http;
1857
+ constructor(http) {
1858
+ this.http = http;
1859
+ }
1860
+ // Contacts
1861
+ async listContacts(connectionId, options) {
1862
+ const params = new URLSearchParams({ connectionId });
1863
+ if (options?.cursor) params.set("cursor", options.cursor);
1864
+ if (options?.limit) params.set("limit", String(options.limit));
1865
+ if (options?.sortBy) params.set("sortBy", options.sortBy);
1866
+ if (options?.sortOrder) params.set("sortOrder", options.sortOrder);
1867
+ return this.http.get(`/integrations/crm/contacts?${params}`);
1868
+ }
1869
+ async getContact(connectionId, id) {
1870
+ return this.http.get(`/integrations/crm/contacts/${id}?connectionId=${connectionId}`);
1871
+ }
1872
+ async createContact(connectionId, data) {
1873
+ return this.http.post("/integrations/crm/contacts", { connectionId, data });
1874
+ }
1875
+ async updateContact(connectionId, id, data) {
1876
+ return this.http.patch(`/integrations/crm/contacts/${id}`, { connectionId, data });
1877
+ }
1878
+ async deleteContact(connectionId, id) {
1879
+ return this.http.delete(`/integrations/crm/contacts/${id}?connectionId=${connectionId}`);
1880
+ }
1881
+ // Companies
1882
+ async listCompanies(connectionId, options) {
1883
+ const params = new URLSearchParams({ connectionId });
1884
+ if (options?.cursor) params.set("cursor", options.cursor);
1885
+ if (options?.limit) params.set("limit", String(options.limit));
1886
+ if (options?.sortBy) params.set("sortBy", options.sortBy);
1887
+ if (options?.sortOrder) params.set("sortOrder", options.sortOrder);
1888
+ return this.http.get(`/integrations/crm/companies?${params}`);
1889
+ }
1890
+ async getCompany(connectionId, id) {
1891
+ return this.http.get(`/integrations/crm/companies/${id}?connectionId=${connectionId}`);
1892
+ }
1893
+ async createCompany(connectionId, data) {
1894
+ return this.http.post("/integrations/crm/companies", { connectionId, data });
1895
+ }
1896
+ async updateCompany(connectionId, id, data) {
1897
+ return this.http.patch(`/integrations/crm/companies/${id}`, { connectionId, data });
1898
+ }
1899
+ async deleteCompany(connectionId, id) {
1900
+ return this.http.delete(`/integrations/crm/companies/${id}?connectionId=${connectionId}`);
1901
+ }
1902
+ // Deals
1903
+ async listDeals(connectionId, options) {
1904
+ const params = new URLSearchParams({ connectionId });
1905
+ if (options?.cursor) params.set("cursor", options.cursor);
1906
+ if (options?.limit) params.set("limit", String(options.limit));
1907
+ if (options?.sortBy) params.set("sortBy", options.sortBy);
1908
+ if (options?.sortOrder) params.set("sortOrder", options.sortOrder);
1909
+ return this.http.get(`/integrations/crm/deals?${params}`);
1910
+ }
1911
+ async getDeal(connectionId, id) {
1912
+ return this.http.get(`/integrations/crm/deals/${id}?connectionId=${connectionId}`);
1913
+ }
1914
+ async createDeal(connectionId, data) {
1915
+ return this.http.post("/integrations/crm/deals", { connectionId, data });
1916
+ }
1917
+ async updateDeal(connectionId, id, data) {
1918
+ return this.http.patch(`/integrations/crm/deals/${id}`, { connectionId, data });
1919
+ }
1920
+ async deleteDeal(connectionId, id) {
1921
+ return this.http.delete(`/integrations/crm/deals/${id}?connectionId=${connectionId}`);
1922
+ }
1923
+ };
1924
+ var Storage = class {
1925
+ http;
1926
+ constructor(http) {
1927
+ this.http = http;
1928
+ }
1929
+ // Files
1930
+ async listFiles(connectionId, folderId, options) {
1931
+ const params = new URLSearchParams({ connectionId });
1932
+ if (folderId) params.set("folderId", folderId);
1933
+ if (options?.cursor) params.set("cursor", options.cursor);
1934
+ if (options?.limit) params.set("limit", String(options.limit));
1935
+ return this.http.get(`/integrations/storage/files?${params}`);
1936
+ }
1937
+ async getFile(connectionId, id) {
1938
+ return this.http.get(`/integrations/storage/files/${id}?connectionId=${connectionId}`);
1939
+ }
1940
+ async uploadFile(connectionId, input) {
1941
+ const base64Data = input.data instanceof ArrayBuffer ? btoa(String.fromCharCode(...new Uint8Array(input.data))) : btoa(String.fromCharCode(...input.data));
1942
+ return this.http.post("/integrations/storage/files", {
1943
+ connectionId,
1944
+ name: input.name,
1945
+ mimeType: input.mimeType,
1946
+ data: base64Data,
1947
+ folderId: input.folderId
1948
+ });
1949
+ }
1950
+ async deleteFile(connectionId, id) {
1951
+ return this.http.delete(`/integrations/storage/files/${id}?connectionId=${connectionId}`);
1952
+ }
1953
+ async downloadFile(connectionId, id) {
1954
+ const response = await this.http.get(
1955
+ `/integrations/storage/files/${id}/download?connectionId=${connectionId}`
1956
+ );
1957
+ const binaryString = atob(response.data);
1958
+ const bytes = new Uint8Array(binaryString.length);
1959
+ for (let i = 0; i < binaryString.length; i++) {
1960
+ bytes[i] = binaryString.charCodeAt(i);
1961
+ }
1962
+ return {
1963
+ data: bytes.buffer,
1964
+ mimeType: response.mimeType,
1965
+ filename: response.filename
1966
+ };
1967
+ }
1968
+ // Folders
1969
+ async listFolders(connectionId, parentId, options) {
1970
+ const params = new URLSearchParams({ connectionId });
1971
+ if (parentId) params.set("parentId", parentId);
1972
+ if (options?.cursor) params.set("cursor", options.cursor);
1973
+ if (options?.limit) params.set("limit", String(options.limit));
1974
+ return this.http.get(`/integrations/storage/folders?${params}`);
1975
+ }
1976
+ async getFolder(connectionId, id) {
1977
+ return this.http.get(`/integrations/storage/folders/${id}?connectionId=${connectionId}`);
1978
+ }
1979
+ async createFolder(connectionId, data) {
1980
+ return this.http.post("/integrations/storage/folders", { connectionId, ...data });
1981
+ }
1982
+ async deleteFolder(connectionId, id) {
1983
+ return this.http.delete(`/integrations/storage/folders/${id}?connectionId=${connectionId}`);
1984
+ }
1985
+ };
1986
+ var Communication = class {
1987
+ http;
1988
+ constructor(http) {
1989
+ this.http = http;
1990
+ }
1991
+ // Channels
1992
+ async listChannels(connectionId, options) {
1993
+ const params = new URLSearchParams({ connectionId });
1994
+ if (options?.cursor) params.set("cursor", options.cursor);
1995
+ if (options?.limit) params.set("limit", String(options.limit));
1996
+ return this.http.get(`/integrations/communication/channels?${params}`);
1997
+ }
1998
+ async getChannel(connectionId, id) {
1999
+ return this.http.get(`/integrations/communication/channels/${id}?connectionId=${connectionId}`);
2000
+ }
2001
+ // Messages
2002
+ async listMessages(connectionId, channelId, options) {
2003
+ const params = new URLSearchParams({ connectionId, channelId });
2004
+ if (options?.cursor) params.set("cursor", options.cursor);
2005
+ if (options?.limit) params.set("limit", String(options.limit));
2006
+ return this.http.get(`/integrations/communication/messages?${params}`);
2007
+ }
2008
+ async sendMessage(connectionId, input) {
2009
+ return this.http.post("/integrations/communication/messages", { connectionId, ...input });
2010
+ }
2011
+ // Users
2012
+ async listUsers(connectionId, options) {
2013
+ const params = new URLSearchParams({ connectionId });
2014
+ if (options?.cursor) params.set("cursor", options.cursor);
2015
+ if (options?.limit) params.set("limit", String(options.limit));
2016
+ return this.http.get(`/integrations/communication/users?${params}`);
2017
+ }
2018
+ };
2019
+ var Productivity = class {
2020
+ http;
2021
+ constructor(http) {
2022
+ this.http = http;
2023
+ }
2024
+ // Documents
2025
+ async listDocuments(connectionId, parentId, options) {
2026
+ const params = new URLSearchParams({ connectionId });
2027
+ if (parentId) params.set("parentId", parentId);
2028
+ if (options?.cursor) params.set("cursor", options.cursor);
2029
+ if (options?.limit) params.set("limit", String(options.limit));
2030
+ return this.http.get(`/integrations/productivity/documents?${params}`);
2031
+ }
2032
+ async getDocument(connectionId, id) {
2033
+ return this.http.get(`/integrations/productivity/documents/${id}?connectionId=${connectionId}`);
2034
+ }
2035
+ async createDocument(connectionId, data) {
2036
+ return this.http.post("/integrations/productivity/documents", { connectionId, ...data });
2037
+ }
2038
+ async updateDocument(connectionId, id, data) {
2039
+ return this.http.patch(`/integrations/productivity/documents/${id}`, { connectionId, ...data });
2040
+ }
2041
+ // Tables
2042
+ async listTables(connectionId, options) {
2043
+ const params = new URLSearchParams({ connectionId });
2044
+ if (options?.cursor) params.set("cursor", options.cursor);
2045
+ if (options?.limit) params.set("limit", String(options.limit));
2046
+ return this.http.get(`/integrations/productivity/tables?${params}`);
2047
+ }
2048
+ async getTable(connectionId, id) {
2049
+ return this.http.get(`/integrations/productivity/tables/${id}?connectionId=${connectionId}`);
2050
+ }
2051
+ // Table Rows
2052
+ async listTableRows(connectionId, tableId, options) {
2053
+ const params = new URLSearchParams({ connectionId });
2054
+ if (options?.cursor) params.set("cursor", options.cursor);
2055
+ if (options?.limit) params.set("limit", String(options.limit));
2056
+ return this.http.get(`/integrations/productivity/tables/${tableId}/rows?${params}`);
2057
+ }
2058
+ async getTableRow(connectionId, tableId, rowId) {
2059
+ return this.http.get(
2060
+ `/integrations/productivity/tables/${tableId}/rows/${rowId}?connectionId=${connectionId}`
2061
+ );
2062
+ }
2063
+ async createTableRow(connectionId, tableId, data) {
2064
+ return this.http.post(`/integrations/productivity/tables/${tableId}/rows`, {
2065
+ connectionId,
2066
+ ...data
2067
+ });
2068
+ }
2069
+ async updateTableRow(connectionId, tableId, rowId, data) {
2070
+ return this.http.patch(`/integrations/productivity/tables/${tableId}/rows/${rowId}`, {
2071
+ connectionId,
2072
+ ...data
2073
+ });
2074
+ }
2075
+ async deleteTableRow(connectionId, tableId, rowId) {
2076
+ return this.http.delete(
2077
+ `/integrations/productivity/tables/${tableId}/rows/${rowId}?connectionId=${connectionId}`
2078
+ );
2079
+ }
2080
+ };
2081
+ var Integrations = class {
2082
+ http;
2083
+ crm;
2084
+ storage;
2085
+ communication;
2086
+ productivity;
2087
+ constructor(config) {
2088
+ this.http = new HttpClient(config);
2089
+ this.crm = new CRM(this.http);
2090
+ this.storage = new Storage(this.http);
2091
+ this.communication = new Communication(this.http);
2092
+ this.productivity = new Productivity(this.http);
2093
+ }
2094
+ // ============================================================================
2095
+ // CONNECTORS
2096
+ // ============================================================================
2097
+ /**
2098
+ * List all available connectors
2099
+ */
2100
+ async listConnectors(category) {
2101
+ const params = category ? `?category=${category}` : "";
2102
+ return this.http.get(`/integrations/connectors${params}`);
2103
+ }
2104
+ /**
2105
+ * Get a specific connector
2106
+ */
2107
+ async getConnector(slug) {
2108
+ return this.http.get(`/integrations/connectors/${slug}`);
2109
+ }
2110
+ // ============================================================================
2111
+ // CONNECTIONS
2112
+ // ============================================================================
2113
+ /**
2114
+ * List all connections
2115
+ */
2116
+ async listConnections(options) {
2117
+ const params = new URLSearchParams();
2118
+ if (options?.connectorId) params.set("connectorId", options.connectorId);
2119
+ if (options?.status) params.set("status", options.status);
2120
+ const queryString = params.toString();
2121
+ return this.http.get(`/integrations/connections${queryString ? `?${queryString}` : ""}`);
2122
+ }
2123
+ /**
2124
+ * Get a specific connection
2125
+ */
2126
+ async getConnection(id) {
2127
+ return this.http.get(`/integrations/connections/${id}`);
2128
+ }
2129
+ /**
2130
+ * Create a new connection (initiates OAuth flow)
2131
+ * Returns the OAuth authorization URL to redirect the user to
2132
+ */
2133
+ async createConnection(connectorSlug, options) {
2134
+ return this.http.post("/integrations/connections", {
2135
+ connectorSlug,
2136
+ ...options
2137
+ });
2138
+ }
2139
+ /**
2140
+ * Delete a connection
2141
+ */
2142
+ async deleteConnection(id) {
2143
+ return this.http.delete(`/integrations/connections/${id}`);
2144
+ }
2145
+ /**
2146
+ * Test a connection's credentials
2147
+ */
2148
+ async testConnection(id) {
2149
+ return this.http.post(`/integrations/connections/${id}/test`, {});
2150
+ }
2151
+ // ============================================================================
2152
+ // PASSTHROUGH
2153
+ // ============================================================================
2154
+ /**
2155
+ * Make a raw passthrough request to the provider API
2156
+ */
2157
+ async passthrough(request) {
2158
+ return this.http.post("/integrations/passthrough", request);
2159
+ }
2160
+ };
2161
+
986
2162
  // src/index.ts
987
2163
  var Stack0 = class {
988
2164
  mail;
989
2165
  cdn;
2166
+ screenshots;
2167
+ extraction;
2168
+ integrations;
2169
+ /**
2170
+ * @deprecated Use `screenshots` and `extraction` instead. Will be removed in a future version.
2171
+ */
990
2172
  webdata;
991
2173
  constructor(config) {
992
2174
  const clientConfig = {
@@ -995,11 +2177,14 @@ var Stack0 = class {
995
2177
  };
996
2178
  this.mail = new Mail(clientConfig);
997
2179
  this.cdn = new CDN(clientConfig);
2180
+ this.screenshots = new Screenshots(clientConfig);
2181
+ this.extraction = new Extraction(clientConfig);
2182
+ this.integrations = new Integrations(clientConfig);
998
2183
  this.webdata = new Webdata(clientConfig);
999
2184
  }
1000
2185
  };
1001
2186
  var src_default = Stack0;
1002
2187
 
1003
- export { CDN, Mail, Stack0, Webdata, src_default as default };
2188
+ export { CDN, Extraction, Integrations, Mail, Screenshots, Stack0, Webdata, src_default as default };
1004
2189
  //# sourceMappingURL=index.mjs.map
1005
2190
  //# sourceMappingURL=index.mjs.map