@stack0/sdk 0.5.8 → 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.
- package/README.md +1026 -369
- package/dist/cdn/index.d.mts +316 -1
- package/dist/cdn/index.d.ts +316 -1
- package/dist/cdn/index.js +219 -0
- package/dist/cdn/index.js.map +1 -1
- package/dist/cdn/index.mjs +219 -0
- package/dist/cdn/index.mjs.map +1 -1
- package/dist/index.d.mts +760 -3
- package/dist/index.d.ts +760 -3
- package/dist/index.js +757 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +753 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -6
package/dist/cdn/index.d.ts
CHANGED
|
@@ -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;
|
|
@@ -760,6 +771,177 @@ interface ListMergeJobsResponse {
|
|
|
760
771
|
total: number;
|
|
761
772
|
hasMore: boolean;
|
|
762
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
|
+
}
|
|
763
945
|
|
|
764
946
|
/**
|
|
765
947
|
* Stack0 CDN Client
|
|
@@ -836,6 +1018,24 @@ declare class CDN {
|
|
|
836
1018
|
/** Watermark configuration for images (applied during upload processing) */
|
|
837
1019
|
watermark?: ImageWatermarkConfig;
|
|
838
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>;
|
|
839
1039
|
/**
|
|
840
1040
|
* Get an asset by ID
|
|
841
1041
|
*
|
|
@@ -1481,6 +1681,121 @@ declare class CDN {
|
|
|
1481
1681
|
}>;
|
|
1482
1682
|
private convertMergeJobDates;
|
|
1483
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;
|
|
1484
1799
|
}
|
|
1485
1800
|
|
|
1486
|
-
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 GenerateGifRequest, type GetAssetRequest, type GetFolderByPathRequest, type GetFolderRequest, type GetFolderTreeRequest, type GetMergeJobRequest, type GifStatus, type ImageWatermarkConfig, type ImageWatermarkPosition, type ImageWatermarkSizingMode, type ListAssetsRequest, type ListAssetsResponse, type ListBundlesRequest, type ListBundlesResponse, type ListFoldersRequest, type ListFoldersResponse, type ListGifsRequest, 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 VideoGif, 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 };
|
package/dist/cdn/index.js
CHANGED
|
@@ -182,6 +182,27 @@ var CDN = class {
|
|
|
182
182
|
}
|
|
183
183
|
return this.confirmUpload(assetId);
|
|
184
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Upload a file from a remote URL (server-side fetch).
|
|
187
|
+
* The server streams the file directly from the source URL into storage,
|
|
188
|
+
* so the client never touches the bytes. Ideal for serverless environments
|
|
189
|
+
* with tight memory limits.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* const asset = await cdn.uploadFromUrl({
|
|
194
|
+
* projectSlug: 'my-project',
|
|
195
|
+
* sourceUrl: 'https://replicate.delivery/output/video.mp4',
|
|
196
|
+
* filename: 'video.mp4',
|
|
197
|
+
* mimeType: 'video/mp4',
|
|
198
|
+
* });
|
|
199
|
+
* console.log(asset.cdnUrl);
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
async uploadFromUrl(request) {
|
|
203
|
+
const response = await this.http.post("/cdn/upload-from-url", request);
|
|
204
|
+
return this.convertAssetDates(response);
|
|
205
|
+
}
|
|
185
206
|
/**
|
|
186
207
|
* Get an asset by ID
|
|
187
208
|
*
|
|
@@ -1234,6 +1255,204 @@ var CDN = class {
|
|
|
1234
1255
|
convertMergeJobWithOutputDates(job) {
|
|
1235
1256
|
return this.convertMergeJobDates(job);
|
|
1236
1257
|
}
|
|
1258
|
+
// ============================================================================
|
|
1259
|
+
// S3 Import Methods
|
|
1260
|
+
// ============================================================================
|
|
1261
|
+
/**
|
|
1262
|
+
* Create an S3 import job to bulk import files from an external S3 bucket.
|
|
1263
|
+
* Requires Pro plan or higher.
|
|
1264
|
+
*
|
|
1265
|
+
* @example
|
|
1266
|
+
* ```typescript
|
|
1267
|
+
* // Using IAM credentials
|
|
1268
|
+
* const job = await cdn.createImport({
|
|
1269
|
+
* projectSlug: 'my-project',
|
|
1270
|
+
* sourceBucket: 'my-external-bucket',
|
|
1271
|
+
* sourceRegion: 'us-east-1',
|
|
1272
|
+
* sourcePrefix: 'images/',
|
|
1273
|
+
* authType: 'iam_credentials',
|
|
1274
|
+
* accessKeyId: 'AKIA...',
|
|
1275
|
+
* secretAccessKey: 'secret...',
|
|
1276
|
+
* pathMode: 'flatten',
|
|
1277
|
+
* notifyEmail: 'admin@example.com',
|
|
1278
|
+
* });
|
|
1279
|
+
*
|
|
1280
|
+
* // Using role assumption
|
|
1281
|
+
* const job = await cdn.createImport({
|
|
1282
|
+
* projectSlug: 'my-project',
|
|
1283
|
+
* sourceBucket: 'partner-bucket',
|
|
1284
|
+
* sourceRegion: 'eu-west-1',
|
|
1285
|
+
* authType: 'role_assumption',
|
|
1286
|
+
* roleArn: 'arn:aws:iam::123456789012:role/Stack0ImportRole',
|
|
1287
|
+
* externalId: 'optional-external-id',
|
|
1288
|
+
* pathMode: 'preserve',
|
|
1289
|
+
* targetFolder: '/imported',
|
|
1290
|
+
* });
|
|
1291
|
+
*
|
|
1292
|
+
* console.log(`Import job started: ${job.importId}`);
|
|
1293
|
+
* ```
|
|
1294
|
+
*/
|
|
1295
|
+
async createImport(request) {
|
|
1296
|
+
const response = await this.http.post("/cdn/imports", request);
|
|
1297
|
+
return this.convertCreateImportDates(response);
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Get an import job by ID
|
|
1301
|
+
*
|
|
1302
|
+
* @example
|
|
1303
|
+
* ```typescript
|
|
1304
|
+
* const job = await cdn.getImport('import-id');
|
|
1305
|
+
* console.log(`Status: ${job.status}`);
|
|
1306
|
+
* console.log(`Progress: ${job.processedFiles}/${job.totalFiles} files`);
|
|
1307
|
+
* console.log(`Bytes: ${job.processedBytes}/${job.totalBytes}`);
|
|
1308
|
+
* ```
|
|
1309
|
+
*/
|
|
1310
|
+
async getImport(importId) {
|
|
1311
|
+
const response = await this.http.get(`/cdn/imports/${importId}`);
|
|
1312
|
+
return response ? this.convertImportJobDates(response) : null;
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* List import jobs with pagination and filters
|
|
1316
|
+
*
|
|
1317
|
+
* @example
|
|
1318
|
+
* ```typescript
|
|
1319
|
+
* const { imports, total, hasMore } = await cdn.listImports({
|
|
1320
|
+
* projectSlug: 'my-project',
|
|
1321
|
+
* status: 'importing',
|
|
1322
|
+
* limit: 20,
|
|
1323
|
+
* });
|
|
1324
|
+
*
|
|
1325
|
+
* for (const job of imports) {
|
|
1326
|
+
* console.log(`${job.sourceBucket}: ${job.processedFiles}/${job.totalFiles}`);
|
|
1327
|
+
* }
|
|
1328
|
+
* ```
|
|
1329
|
+
*/
|
|
1330
|
+
async listImports(request) {
|
|
1331
|
+
const params = new URLSearchParams();
|
|
1332
|
+
params.set("projectSlug", request.projectSlug);
|
|
1333
|
+
if (request.environment) params.set("environment", request.environment);
|
|
1334
|
+
if (request.status) params.set("status", request.status);
|
|
1335
|
+
if (request.sortBy) params.set("sortBy", request.sortBy);
|
|
1336
|
+
if (request.sortOrder) params.set("sortOrder", request.sortOrder);
|
|
1337
|
+
if (request.limit) params.set("limit", request.limit.toString());
|
|
1338
|
+
if (request.offset) params.set("offset", request.offset.toString());
|
|
1339
|
+
const response = await this.http.get(`/cdn/imports?${params.toString()}`);
|
|
1340
|
+
return {
|
|
1341
|
+
...response,
|
|
1342
|
+
imports: response.imports.map((job) => this.convertImportJobSummaryDates(job))
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
/**
|
|
1346
|
+
* Cancel a running import job
|
|
1347
|
+
*
|
|
1348
|
+
* Files already imported will remain. Only pending/validating/importing jobs can be cancelled.
|
|
1349
|
+
*
|
|
1350
|
+
* @example
|
|
1351
|
+
* ```typescript
|
|
1352
|
+
* const result = await cdn.cancelImport('import-id');
|
|
1353
|
+
* console.log(`Cancelled: ${result.success}`);
|
|
1354
|
+
* ```
|
|
1355
|
+
*/
|
|
1356
|
+
async cancelImport(importId) {
|
|
1357
|
+
return this.http.post(`/cdn/imports/${importId}/cancel`, {});
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Retry failed files in a completed or failed import job
|
|
1361
|
+
*
|
|
1362
|
+
* This resets failed files to pending and re-queues the import for processing.
|
|
1363
|
+
*
|
|
1364
|
+
* @example
|
|
1365
|
+
* ```typescript
|
|
1366
|
+
* const result = await cdn.retryImport('import-id');
|
|
1367
|
+
* console.log(`Retrying ${result.retriedCount} files`);
|
|
1368
|
+
* ```
|
|
1369
|
+
*/
|
|
1370
|
+
async retryImport(importId) {
|
|
1371
|
+
return this.http.post(`/cdn/imports/${importId}/retry`, {});
|
|
1372
|
+
}
|
|
1373
|
+
/**
|
|
1374
|
+
* List files in an import job with optional status filter
|
|
1375
|
+
*
|
|
1376
|
+
* @example
|
|
1377
|
+
* ```typescript
|
|
1378
|
+
* // List all files
|
|
1379
|
+
* const { files, total } = await cdn.listImportFiles({
|
|
1380
|
+
* importId: 'import-id',
|
|
1381
|
+
* limit: 100,
|
|
1382
|
+
* });
|
|
1383
|
+
*
|
|
1384
|
+
* // List only failed files
|
|
1385
|
+
* const { files: failedFiles } = await cdn.listImportFiles({
|
|
1386
|
+
* importId: 'import-id',
|
|
1387
|
+
* status: 'failed',
|
|
1388
|
+
* });
|
|
1389
|
+
*
|
|
1390
|
+
* for (const file of failedFiles) {
|
|
1391
|
+
* console.log(`${file.sourceKey}: ${file.errorMessage}`);
|
|
1392
|
+
* }
|
|
1393
|
+
* ```
|
|
1394
|
+
*/
|
|
1395
|
+
async listImportFiles(request) {
|
|
1396
|
+
const params = new URLSearchParams();
|
|
1397
|
+
if (request.status) params.set("status", request.status);
|
|
1398
|
+
if (request.sortBy) params.set("sortBy", request.sortBy);
|
|
1399
|
+
if (request.sortOrder) params.set("sortOrder", request.sortOrder);
|
|
1400
|
+
if (request.limit) params.set("limit", request.limit.toString());
|
|
1401
|
+
if (request.offset) params.set("offset", request.offset.toString());
|
|
1402
|
+
const query = params.toString();
|
|
1403
|
+
const response = await this.http.get(
|
|
1404
|
+
`/cdn/imports/${request.importId}/files${query ? `?${query}` : ""}`
|
|
1405
|
+
);
|
|
1406
|
+
return {
|
|
1407
|
+
...response,
|
|
1408
|
+
files: response.files.map((file) => this.convertImportFileDates(file))
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
convertCreateImportDates(response) {
|
|
1412
|
+
if (typeof response.createdAt === "string") {
|
|
1413
|
+
response.createdAt = new Date(response.createdAt);
|
|
1414
|
+
}
|
|
1415
|
+
return response;
|
|
1416
|
+
}
|
|
1417
|
+
convertImportJobDates(job) {
|
|
1418
|
+
if (typeof job.createdAt === "string") {
|
|
1419
|
+
job.createdAt = new Date(job.createdAt);
|
|
1420
|
+
}
|
|
1421
|
+
if (job.updatedAt && typeof job.updatedAt === "string") {
|
|
1422
|
+
job.updatedAt = new Date(job.updatedAt);
|
|
1423
|
+
}
|
|
1424
|
+
if (job.startedAt && typeof job.startedAt === "string") {
|
|
1425
|
+
job.startedAt = new Date(job.startedAt);
|
|
1426
|
+
}
|
|
1427
|
+
if (job.completedAt && typeof job.completedAt === "string") {
|
|
1428
|
+
job.completedAt = new Date(job.completedAt);
|
|
1429
|
+
}
|
|
1430
|
+
return job;
|
|
1431
|
+
}
|
|
1432
|
+
convertImportJobSummaryDates(job) {
|
|
1433
|
+
if (typeof job.createdAt === "string") {
|
|
1434
|
+
job.createdAt = new Date(job.createdAt);
|
|
1435
|
+
}
|
|
1436
|
+
if (job.startedAt && typeof job.startedAt === "string") {
|
|
1437
|
+
job.startedAt = new Date(job.startedAt);
|
|
1438
|
+
}
|
|
1439
|
+
if (job.completedAt && typeof job.completedAt === "string") {
|
|
1440
|
+
job.completedAt = new Date(job.completedAt);
|
|
1441
|
+
}
|
|
1442
|
+
return job;
|
|
1443
|
+
}
|
|
1444
|
+
convertImportFileDates(file) {
|
|
1445
|
+
if (typeof file.createdAt === "string") {
|
|
1446
|
+
file.createdAt = new Date(file.createdAt);
|
|
1447
|
+
}
|
|
1448
|
+
if (file.completedAt && typeof file.completedAt === "string") {
|
|
1449
|
+
file.completedAt = new Date(file.completedAt);
|
|
1450
|
+
}
|
|
1451
|
+
if (file.lastAttemptAt && typeof file.lastAttemptAt === "string") {
|
|
1452
|
+
file.lastAttemptAt = new Date(file.lastAttemptAt);
|
|
1453
|
+
}
|
|
1454
|
+
return file;
|
|
1455
|
+
}
|
|
1237
1456
|
};
|
|
1238
1457
|
|
|
1239
1458
|
exports.CDN = CDN;
|