@stack0/sdk 0.5.7 → 0.5.9

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.
@@ -44,6 +44,15 @@ interface UploadUrlResponse {
44
44
  cdnUrl: string;
45
45
  expiresAt: Date;
46
46
  }
47
+ interface UploadFromUrlRequest {
48
+ projectSlug: string;
49
+ /** URL to fetch the file from */
50
+ sourceUrl: string;
51
+ filename: string;
52
+ mimeType: string;
53
+ folder?: string;
54
+ metadata?: Record<string, unknown>;
55
+ }
47
56
  interface ConfirmUploadRequest {
48
57
  assetId: string;
49
58
  }
@@ -216,6 +225,8 @@ interface ImageWatermarkConfig {
216
225
  tile?: boolean;
217
226
  /** Spacing between tiles when tile is true (pixels, default: 100) */
218
227
  tileSpacing?: number;
228
+ /** Corner radius in pixels (0-500, default: 0) */
229
+ borderRadius?: number;
219
230
  }
220
231
  interface TrimOptions {
221
232
  start: number;
@@ -306,6 +317,52 @@ interface ExtractAudioResponse {
306
317
  jobId: string;
307
318
  status: TranscodingStatus;
308
319
  }
320
+ type GifStatus = "pending" | "processing" | "completed" | "failed";
321
+ interface GenerateGifRequest {
322
+ /** Project slug */
323
+ projectSlug: string;
324
+ /** ID of the video asset to generate GIF from */
325
+ assetId: string;
326
+ /** Start time in seconds (default: 0) */
327
+ startTime?: number;
328
+ /** Duration in seconds (0.5-30, default: 5) */
329
+ duration?: number;
330
+ /** Output width in pixels (100-800, default: 480) */
331
+ width?: number;
332
+ /** Frames per second (5-30, default: 10) */
333
+ fps?: number;
334
+ /** Use two-pass palette optimization for smaller file size (default: true) */
335
+ optimizePalette?: boolean;
336
+ }
337
+ interface VideoGif {
338
+ id: string;
339
+ assetId: string;
340
+ /** Start time in seconds */
341
+ startTime: number;
342
+ /** Duration in seconds */
343
+ duration: number;
344
+ /** Frames per second */
345
+ fps: number;
346
+ /** CDN URL of the generated GIF (null if pending/processing) */
347
+ url: string | null;
348
+ /** Width in pixels */
349
+ width: number | null;
350
+ /** Height in pixels */
351
+ height: number | null;
352
+ /** File size in bytes */
353
+ sizeBytes: number | null;
354
+ /** Number of frames in the GIF */
355
+ frameCount: number | null;
356
+ /** Current status of the GIF generation */
357
+ status: GifStatus;
358
+ /** Error message if failed */
359
+ errorMessage: string | null;
360
+ createdAt: Date;
361
+ completedAt: Date | null;
362
+ }
363
+ interface ListGifsRequest {
364
+ assetId: string;
365
+ }
309
366
  type PrivateFileStatus = "pending" | "ready" | "failed" | "deleted";
310
367
  interface PrivateFile {
311
368
  id: string;
@@ -714,6 +771,177 @@ interface ListMergeJobsResponse {
714
771
  total: number;
715
772
  hasMore: boolean;
716
773
  }
774
+ type ImportJobStatus = "pending" | "validating" | "importing" | "completed" | "failed" | "cancelled";
775
+ type ImportAuthType = "iam_credentials" | "role_assumption";
776
+ type ImportPathMode = "preserve" | "flatten";
777
+ type ImportFileStatus = "pending" | "importing" | "completed" | "failed" | "skipped";
778
+ /**
779
+ * Error recorded during import
780
+ */
781
+ interface ImportError {
782
+ key: string;
783
+ error: string;
784
+ timestamp: string;
785
+ }
786
+ /**
787
+ * Request to create an S3 import job
788
+ */
789
+ interface CreateImportRequest {
790
+ projectSlug: string;
791
+ environment?: CdnEnvironment;
792
+ /** Source S3 bucket name */
793
+ sourceBucket: string;
794
+ /** AWS region of the source bucket */
795
+ sourceRegion: string;
796
+ /** Optional prefix to filter source files */
797
+ sourcePrefix?: string;
798
+ /** Authentication method */
799
+ authType: ImportAuthType;
800
+ /** AWS access key ID (required for iam_credentials auth) */
801
+ accessKeyId?: string;
802
+ /** AWS secret access key (required for iam_credentials auth) */
803
+ secretAccessKey?: string;
804
+ /** IAM role ARN (required for role_assumption auth) */
805
+ roleArn?: string;
806
+ /** External ID for role assumption */
807
+ externalId?: string;
808
+ /** How to handle source paths (flatten: use filename only, preserve: keep path structure) */
809
+ pathMode?: ImportPathMode;
810
+ /** Target folder for imported assets */
811
+ targetFolder?: string;
812
+ /** Email address for completion notification */
813
+ notifyEmail?: string;
814
+ }
815
+ /**
816
+ * Response from creating an import job
817
+ */
818
+ interface CreateImportResponse {
819
+ importId: string;
820
+ status: ImportJobStatus;
821
+ sourceBucket: string;
822
+ sourceRegion: string;
823
+ sourcePrefix: string | null;
824
+ createdAt: Date;
825
+ }
826
+ /**
827
+ * Import job details
828
+ */
829
+ interface ImportJob {
830
+ id: string;
831
+ organizationId: string;
832
+ projectId: string;
833
+ environment: CdnEnvironment;
834
+ sourceBucket: string;
835
+ sourceRegion: string;
836
+ sourcePrefix: string | null;
837
+ authType: ImportAuthType;
838
+ pathMode: ImportPathMode;
839
+ targetFolder: string | null;
840
+ status: ImportJobStatus;
841
+ totalFiles: number;
842
+ processedFiles: number;
843
+ skippedFiles: number;
844
+ failedFiles: number;
845
+ totalBytes: number;
846
+ processedBytes: number;
847
+ errors: ImportError[] | null;
848
+ notifyEmail: string | null;
849
+ startedAt: Date | null;
850
+ completedAt: Date | null;
851
+ createdAt: Date;
852
+ updatedAt: Date | null;
853
+ }
854
+ /**
855
+ * Request to list import jobs
856
+ */
857
+ interface ListImportsRequest {
858
+ projectSlug: string;
859
+ environment?: CdnEnvironment;
860
+ status?: ImportJobStatus;
861
+ sortBy?: "createdAt" | "status" | "totalFiles";
862
+ sortOrder?: "asc" | "desc";
863
+ limit?: number;
864
+ offset?: number;
865
+ }
866
+ /**
867
+ * Import job summary for list responses
868
+ */
869
+ interface ImportJobSummary {
870
+ id: string;
871
+ sourceBucket: string;
872
+ sourceRegion: string;
873
+ sourcePrefix: string | null;
874
+ status: ImportJobStatus;
875
+ totalFiles: number;
876
+ processedFiles: number;
877
+ skippedFiles: number;
878
+ failedFiles: number;
879
+ totalBytes: number;
880
+ processedBytes: number;
881
+ startedAt: Date | null;
882
+ completedAt: Date | null;
883
+ createdAt: Date;
884
+ }
885
+ /**
886
+ * Response from listing import jobs
887
+ */
888
+ interface ListImportsResponse {
889
+ imports: ImportJobSummary[];
890
+ total: number;
891
+ hasMore: boolean;
892
+ }
893
+ /**
894
+ * Response from cancelling an import job
895
+ */
896
+ interface CancelImportResponse {
897
+ success: boolean;
898
+ status: ImportJobStatus;
899
+ }
900
+ /**
901
+ * Response from retrying failed files
902
+ */
903
+ interface RetryImportResponse {
904
+ success: boolean;
905
+ retriedCount: number;
906
+ status: ImportJobStatus;
907
+ }
908
+ /**
909
+ * Request to list files in an import job
910
+ */
911
+ interface ListImportFilesRequest {
912
+ importId: string;
913
+ status?: ImportFileStatus;
914
+ sortBy?: "createdAt" | "sourceKey" | "sourceSize" | "status";
915
+ sortOrder?: "asc" | "desc";
916
+ limit?: number;
917
+ offset?: number;
918
+ }
919
+ /**
920
+ * Individual file within an import job
921
+ */
922
+ interface ImportFile {
923
+ id: string;
924
+ importJobId: string;
925
+ sourceKey: string;
926
+ sourceSize: number;
927
+ sourceMimeType: string | null;
928
+ sourceEtag: string | null;
929
+ assetId: string | null;
930
+ status: ImportFileStatus;
931
+ errorMessage: string | null;
932
+ retryCount: number;
933
+ lastAttemptAt: Date | null;
934
+ createdAt: Date;
935
+ completedAt: Date | null;
936
+ }
937
+ /**
938
+ * Response from listing import files
939
+ */
940
+ interface ListImportFilesResponse {
941
+ files: ImportFile[];
942
+ total: number;
943
+ hasMore: boolean;
944
+ }
717
945
 
718
946
  /**
719
947
  * Stack0 CDN Client
@@ -790,6 +1018,24 @@ declare class CDN {
790
1018
  /** Watermark configuration for images (applied during upload processing) */
791
1019
  watermark?: ImageWatermarkConfig;
792
1020
  }): Promise<Asset>;
1021
+ /**
1022
+ * Upload a file from a remote URL (server-side fetch).
1023
+ * The server streams the file directly from the source URL into storage,
1024
+ * so the client never touches the bytes. Ideal for serverless environments
1025
+ * with tight memory limits.
1026
+ *
1027
+ * @example
1028
+ * ```typescript
1029
+ * const asset = await cdn.uploadFromUrl({
1030
+ * projectSlug: 'my-project',
1031
+ * sourceUrl: 'https://replicate.delivery/output/video.mp4',
1032
+ * filename: 'video.mp4',
1033
+ * mimeType: 'video/mp4',
1034
+ * });
1035
+ * console.log(asset.cdnUrl);
1036
+ * ```
1037
+ */
1038
+ uploadFromUrl(request: UploadFromUrlRequest): Promise<Asset>;
793
1039
  /**
794
1040
  * Get an asset by ID
795
1041
  *
@@ -1033,6 +1279,60 @@ declare class CDN {
1033
1279
  * ```
1034
1280
  */
1035
1281
  extractAudio(request: ExtractAudioRequest): Promise<ExtractAudioResponse>;
1282
+ /**
1283
+ * Generate an animated GIF from a video segment
1284
+ *
1285
+ * Creates an optimized GIF from a portion of the video. Uses two-pass
1286
+ * palette generation by default for smaller file sizes with better quality.
1287
+ *
1288
+ * @example
1289
+ * ```typescript
1290
+ * const gif = await cdn.generateGif({
1291
+ * projectSlug: 'my-project',
1292
+ * assetId: 'video-asset-id',
1293
+ * startTime: 5, // Start at 5 seconds
1294
+ * duration: 3, // 3 second GIF
1295
+ * width: 480, // 480px wide
1296
+ * fps: 10, // 10 frames per second
1297
+ * });
1298
+ *
1299
+ * // Poll for completion
1300
+ * let result = await cdn.getGif(gif.id);
1301
+ * while (result?.status === 'pending' || result?.status === 'processing') {
1302
+ * await new Promise(r => setTimeout(r, 1000));
1303
+ * result = await cdn.getGif(gif.id);
1304
+ * }
1305
+ *
1306
+ * console.log(`GIF URL: ${result?.url}`);
1307
+ * ```
1308
+ */
1309
+ generateGif(request: GenerateGifRequest): Promise<VideoGif>;
1310
+ /**
1311
+ * Get a specific GIF by ID
1312
+ *
1313
+ * @example
1314
+ * ```typescript
1315
+ * const gif = await cdn.getGif('gif-id');
1316
+ * if (gif?.status === 'completed') {
1317
+ * console.log(`GIF URL: ${gif.url}`);
1318
+ * console.log(`Size: ${gif.sizeBytes} bytes`);
1319
+ * }
1320
+ * ```
1321
+ */
1322
+ getGif(gifId: string): Promise<VideoGif | null>;
1323
+ /**
1324
+ * List all GIFs generated for a video asset
1325
+ *
1326
+ * @example
1327
+ * ```typescript
1328
+ * const gifs = await cdn.listGifs({ assetId: 'video-asset-id' });
1329
+ * for (const gif of gifs) {
1330
+ * console.log(`GIF at ${gif.startTime}s: ${gif.url}`);
1331
+ * }
1332
+ * ```
1333
+ */
1334
+ listGifs(request: ListGifsRequest): Promise<VideoGif[]>;
1335
+ private convertGifDates;
1036
1336
  private convertJobDates;
1037
1337
  /**
1038
1338
  * Generate a presigned URL for uploading a private file
@@ -1381,6 +1681,121 @@ declare class CDN {
1381
1681
  }>;
1382
1682
  private convertMergeJobDates;
1383
1683
  private convertMergeJobWithOutputDates;
1684
+ /**
1685
+ * Create an S3 import job to bulk import files from an external S3 bucket.
1686
+ * Requires Pro plan or higher.
1687
+ *
1688
+ * @example
1689
+ * ```typescript
1690
+ * // Using IAM credentials
1691
+ * const job = await cdn.createImport({
1692
+ * projectSlug: 'my-project',
1693
+ * sourceBucket: 'my-external-bucket',
1694
+ * sourceRegion: 'us-east-1',
1695
+ * sourcePrefix: 'images/',
1696
+ * authType: 'iam_credentials',
1697
+ * accessKeyId: 'AKIA...',
1698
+ * secretAccessKey: 'secret...',
1699
+ * pathMode: 'flatten',
1700
+ * notifyEmail: 'admin@example.com',
1701
+ * });
1702
+ *
1703
+ * // Using role assumption
1704
+ * const job = await cdn.createImport({
1705
+ * projectSlug: 'my-project',
1706
+ * sourceBucket: 'partner-bucket',
1707
+ * sourceRegion: 'eu-west-1',
1708
+ * authType: 'role_assumption',
1709
+ * roleArn: 'arn:aws:iam::123456789012:role/Stack0ImportRole',
1710
+ * externalId: 'optional-external-id',
1711
+ * pathMode: 'preserve',
1712
+ * targetFolder: '/imported',
1713
+ * });
1714
+ *
1715
+ * console.log(`Import job started: ${job.importId}`);
1716
+ * ```
1717
+ */
1718
+ createImport(request: CreateImportRequest): Promise<CreateImportResponse>;
1719
+ /**
1720
+ * Get an import job by ID
1721
+ *
1722
+ * @example
1723
+ * ```typescript
1724
+ * const job = await cdn.getImport('import-id');
1725
+ * console.log(`Status: ${job.status}`);
1726
+ * console.log(`Progress: ${job.processedFiles}/${job.totalFiles} files`);
1727
+ * console.log(`Bytes: ${job.processedBytes}/${job.totalBytes}`);
1728
+ * ```
1729
+ */
1730
+ getImport(importId: string): Promise<ImportJob | null>;
1731
+ /**
1732
+ * List import jobs with pagination and filters
1733
+ *
1734
+ * @example
1735
+ * ```typescript
1736
+ * const { imports, total, hasMore } = await cdn.listImports({
1737
+ * projectSlug: 'my-project',
1738
+ * status: 'importing',
1739
+ * limit: 20,
1740
+ * });
1741
+ *
1742
+ * for (const job of imports) {
1743
+ * console.log(`${job.sourceBucket}: ${job.processedFiles}/${job.totalFiles}`);
1744
+ * }
1745
+ * ```
1746
+ */
1747
+ listImports(request: ListImportsRequest): Promise<ListImportsResponse>;
1748
+ /**
1749
+ * Cancel a running import job
1750
+ *
1751
+ * Files already imported will remain. Only pending/validating/importing jobs can be cancelled.
1752
+ *
1753
+ * @example
1754
+ * ```typescript
1755
+ * const result = await cdn.cancelImport('import-id');
1756
+ * console.log(`Cancelled: ${result.success}`);
1757
+ * ```
1758
+ */
1759
+ cancelImport(importId: string): Promise<CancelImportResponse>;
1760
+ /**
1761
+ * Retry failed files in a completed or failed import job
1762
+ *
1763
+ * This resets failed files to pending and re-queues the import for processing.
1764
+ *
1765
+ * @example
1766
+ * ```typescript
1767
+ * const result = await cdn.retryImport('import-id');
1768
+ * console.log(`Retrying ${result.retriedCount} files`);
1769
+ * ```
1770
+ */
1771
+ retryImport(importId: string): Promise<RetryImportResponse>;
1772
+ /**
1773
+ * List files in an import job with optional status filter
1774
+ *
1775
+ * @example
1776
+ * ```typescript
1777
+ * // List all files
1778
+ * const { files, total } = await cdn.listImportFiles({
1779
+ * importId: 'import-id',
1780
+ * limit: 100,
1781
+ * });
1782
+ *
1783
+ * // List only failed files
1784
+ * const { files: failedFiles } = await cdn.listImportFiles({
1785
+ * importId: 'import-id',
1786
+ * status: 'failed',
1787
+ * });
1788
+ *
1789
+ * for (const file of failedFiles) {
1790
+ * console.log(`${file.sourceKey}: ${file.errorMessage}`);
1791
+ * }
1792
+ * ```
1793
+ */
1794
+ listImportFiles(request: ListImportFilesRequest): Promise<ListImportFilesResponse>;
1795
+ private convertCreateImportDates;
1796
+ private convertImportJobDates;
1797
+ private convertImportJobSummaryDates;
1798
+ private convertImportFileDates;
1384
1799
  }
1385
1800
 
1386
- export { type Asset, type AssetStatus, type AssetType, type AudioTrackInput, type BundleDownloadUrlRequest, type BundleDownloadUrlResponse, type BundleStatus, CDN, type CancelMergeJobRequest, type CdnEnvironment, type CdnStorageBreakdownItem, type CdnStorageBreakdownRequest, type CdnStorageBreakdownResponse, type CdnUsageDataPoint, type CdnUsageHistoryRequest, type CdnUsageHistoryResponse, type CdnUsageRequest, type CdnUsageResponse, type ConfirmUploadRequest, type ConfirmUploadResponse, type CreateBundleRequest, type CreateBundleResponse, type CreateFolderRequest, type CreateMergeJobRequest, type DeleteAssetRequest, type DeleteAssetsRequest, type DeleteAssetsResponse, type DownloadBundle, type ExtractAudioRequest, type ExtractAudioResponse, type Folder, type FolderListItem, type FolderTreeNode, type GetAssetRequest, type GetFolderByPathRequest, type GetFolderRequest, type GetFolderTreeRequest, type GetMergeJobRequest, type ImageWatermarkConfig, type ImageWatermarkPosition, type ImageWatermarkSizingMode, type ListAssetsRequest, type ListAssetsResponse, type ListBundlesRequest, type ListBundlesResponse, type ListFoldersRequest, type ListFoldersResponse, type ListJobsRequest, type ListJobsResponse, type ListMergeJobsRequest, type ListMergeJobsResponse, type ListPrivateFilesRequest, type ListPrivateFilesResponse, type ListThumbnailsRequest, type ListThumbnailsResponse, type MergeInputItem, type MergeJob, type MergeJobWithOutput, type MergeOutputConfig, type MergeOutputFormat, type MergeQuality, type MergeStatus, type MoveAssetsRequest, type MoveAssetsResponse, type MoveFolderRequest, type MoveFolderResponse, type MovePrivateFilesRequest, type MovePrivateFilesResponse, type PrivateDownloadUrlRequest, type PrivateDownloadUrlResponse, type PrivateFile, type PrivateFileStatus, type PrivateUploadUrlRequest, type PrivateUploadUrlResponse, type RegenerateThumbnailRequest, type RegenerateThumbnailResponse, type StreamingUrls, type TextOverlay, type TextOverlayShadow, type TextOverlayStroke, type ThumbnailRequest, type ThumbnailResponse, type TranscodeJob, type TranscodeVideoRequest, type TranscodingStatus, type TransformOptions, type TrimOptions, type UpdateAssetRequest, type UpdateFolderRequest, type UpdatePrivateFileRequest, type UploadUrlRequest, type UploadUrlResponse, type VideoCodec, type VideoOutputFormat, type VideoQuality, type VideoThumbnail, type VideoVariant, type WatermarkOptions };
1801
+ export { type Asset, type AssetStatus, type AssetType, type AudioTrackInput, type BundleDownloadUrlRequest, type BundleDownloadUrlResponse, type BundleStatus, CDN, type CancelImportResponse, type CancelMergeJobRequest, type CdnEnvironment, type CdnStorageBreakdownItem, type CdnStorageBreakdownRequest, type CdnStorageBreakdownResponse, type CdnUsageDataPoint, type CdnUsageHistoryRequest, type CdnUsageHistoryResponse, type CdnUsageRequest, type CdnUsageResponse, type ConfirmUploadRequest, type ConfirmUploadResponse, type CreateBundleRequest, type CreateBundleResponse, type CreateFolderRequest, type CreateImportRequest, type CreateImportResponse, type CreateMergeJobRequest, type DeleteAssetRequest, type DeleteAssetsRequest, type DeleteAssetsResponse, type DownloadBundle, type ExtractAudioRequest, type ExtractAudioResponse, type Folder, type FolderListItem, type FolderTreeNode, type GenerateGifRequest, type GetAssetRequest, type GetFolderByPathRequest, type GetFolderRequest, type GetFolderTreeRequest, type GetMergeJobRequest, type GifStatus, type ImageWatermarkConfig, type ImageWatermarkPosition, type ImageWatermarkSizingMode, type ImportAuthType, type ImportError, type ImportFile, type ImportFileStatus, type ImportJob, type ImportJobStatus, type ImportJobSummary, type ImportPathMode, type ListAssetsRequest, type ListAssetsResponse, type ListBundlesRequest, type ListBundlesResponse, type ListFoldersRequest, type ListFoldersResponse, type ListGifsRequest, type ListImportFilesRequest, type ListImportFilesResponse, type ListImportsRequest, type ListImportsResponse, type ListJobsRequest, type ListJobsResponse, type ListMergeJobsRequest, type ListMergeJobsResponse, type ListPrivateFilesRequest, type ListPrivateFilesResponse, type ListThumbnailsRequest, type ListThumbnailsResponse, type MergeInputItem, type MergeJob, type MergeJobWithOutput, type MergeOutputConfig, type MergeOutputFormat, type MergeQuality, type MergeStatus, type MoveAssetsRequest, type MoveAssetsResponse, type MoveFolderRequest, type MoveFolderResponse, type MovePrivateFilesRequest, type MovePrivateFilesResponse, type PrivateDownloadUrlRequest, type PrivateDownloadUrlResponse, type PrivateFile, type PrivateFileStatus, type PrivateUploadUrlRequest, type PrivateUploadUrlResponse, type RegenerateThumbnailRequest, type RegenerateThumbnailResponse, type RetryImportResponse, type StreamingUrls, type TextOverlay, type TextOverlayShadow, type TextOverlayStroke, type ThumbnailRequest, type ThumbnailResponse, type TranscodeJob, type TranscodeVideoRequest, type TranscodingStatus, type TransformOptions, type TrimOptions, type UpdateAssetRequest, type UpdateFolderRequest, type UpdatePrivateFileRequest, type UploadFromUrlRequest, type UploadUrlRequest, type UploadUrlResponse, type VideoCodec, type VideoGif, type VideoOutputFormat, type VideoQuality, type VideoThumbnail, type VideoVariant, type WatermarkOptions };