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