@stack0/sdk 0.3.5 → 0.3.41

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.
@@ -234,6 +234,22 @@ interface ThumbnailResponse {
234
234
  width: number;
235
235
  height: number;
236
236
  }
237
+ interface RegenerateThumbnailRequest {
238
+ assetId: string;
239
+ timestamp: number;
240
+ width?: number;
241
+ format?: "jpg" | "png" | "webp";
242
+ }
243
+ interface RegenerateThumbnailResponse {
244
+ id: string | null;
245
+ assetId: string;
246
+ timestamp: number;
247
+ url: string | null;
248
+ width: number | null;
249
+ height: number | null;
250
+ format: string;
251
+ status?: string;
252
+ }
237
253
  interface ExtractAudioRequest {
238
254
  projectSlug: string;
239
255
  assetId: string;
@@ -515,6 +531,23 @@ declare class CDN {
515
531
  * ```
516
532
  */
517
533
  getThumbnail(request: ThumbnailRequest): Promise<ThumbnailResponse>;
534
+ /**
535
+ * Regenerate a thumbnail for a video (force regeneration even if one exists)
536
+ *
537
+ * Useful for retrying failed thumbnail generation or regenerating with different settings.
538
+ *
539
+ * @example
540
+ * ```typescript
541
+ * const result = await cdn.regenerateThumbnail({
542
+ * assetId: 'video-asset-id',
543
+ * timestamp: 5, // 5 seconds into the video
544
+ * width: 1280,
545
+ * format: 'jpg',
546
+ * });
547
+ * console.log(`Thumbnail regeneration queued: ${result.status}`);
548
+ * ```
549
+ */
550
+ regenerateThumbnail(request: RegenerateThumbnailRequest): Promise<RegenerateThumbnailResponse>;
518
551
  /**
519
552
  * Extract audio from a video file
520
553
  *
@@ -532,4 +565,4 @@ declare class CDN {
532
565
  private convertJobDates;
533
566
  }
534
567
 
535
- export { type Asset, type AssetStatus, type AssetType, CDN, type ConfirmUploadRequest, type ConfirmUploadResponse, type CreateFolderRequest, type DeleteAssetRequest, type DeleteAssetsRequest, type DeleteAssetsResponse, type ExtractAudioRequest, type ExtractAudioResponse, type Folder, type FolderTreeNode, type GetAssetRequest, type GetFolderTreeRequest, type ListAssetsRequest, type ListAssetsResponse, type ListJobsRequest, type ListJobsResponse, type MoveAssetsRequest, type MoveAssetsResponse, type StreamingUrls, type ThumbnailRequest, type ThumbnailResponse, type TranscodeJob, type TranscodeVideoRequest, type TranscodingStatus, type TransformOptions, type TrimOptions, type UpdateAssetRequest, type UploadUrlRequest, type UploadUrlResponse, type VideoCodec, type VideoOutputFormat, type VideoQuality, type VideoVariant, type WatermarkOptions };
568
+ export { type Asset, type AssetStatus, type AssetType, CDN, type ConfirmUploadRequest, type ConfirmUploadResponse, type CreateFolderRequest, type DeleteAssetRequest, type DeleteAssetsRequest, type DeleteAssetsResponse, type ExtractAudioRequest, type ExtractAudioResponse, type Folder, type FolderTreeNode, type GetAssetRequest, type GetFolderTreeRequest, type ListAssetsRequest, type ListAssetsResponse, type ListJobsRequest, type ListJobsResponse, type MoveAssetsRequest, type MoveAssetsResponse, type RegenerateThumbnailRequest, type RegenerateThumbnailResponse, type StreamingUrls, type ThumbnailRequest, type ThumbnailResponse, type TranscodeJob, type TranscodeVideoRequest, type TranscodingStatus, type TransformOptions, type TrimOptions, type UpdateAssetRequest, type UploadUrlRequest, type UploadUrlResponse, type VideoCodec, type VideoOutputFormat, type VideoQuality, type VideoVariant, type WatermarkOptions };
@@ -234,6 +234,22 @@ interface ThumbnailResponse {
234
234
  width: number;
235
235
  height: number;
236
236
  }
237
+ interface RegenerateThumbnailRequest {
238
+ assetId: string;
239
+ timestamp: number;
240
+ width?: number;
241
+ format?: "jpg" | "png" | "webp";
242
+ }
243
+ interface RegenerateThumbnailResponse {
244
+ id: string | null;
245
+ assetId: string;
246
+ timestamp: number;
247
+ url: string | null;
248
+ width: number | null;
249
+ height: number | null;
250
+ format: string;
251
+ status?: string;
252
+ }
237
253
  interface ExtractAudioRequest {
238
254
  projectSlug: string;
239
255
  assetId: string;
@@ -515,6 +531,23 @@ declare class CDN {
515
531
  * ```
516
532
  */
517
533
  getThumbnail(request: ThumbnailRequest): Promise<ThumbnailResponse>;
534
+ /**
535
+ * Regenerate a thumbnail for a video (force regeneration even if one exists)
536
+ *
537
+ * Useful for retrying failed thumbnail generation or regenerating with different settings.
538
+ *
539
+ * @example
540
+ * ```typescript
541
+ * const result = await cdn.regenerateThumbnail({
542
+ * assetId: 'video-asset-id',
543
+ * timestamp: 5, // 5 seconds into the video
544
+ * width: 1280,
545
+ * format: 'jpg',
546
+ * });
547
+ * console.log(`Thumbnail regeneration queued: ${result.status}`);
548
+ * ```
549
+ */
550
+ regenerateThumbnail(request: RegenerateThumbnailRequest): Promise<RegenerateThumbnailResponse>;
518
551
  /**
519
552
  * Extract audio from a video file
520
553
  *
@@ -532,4 +565,4 @@ declare class CDN {
532
565
  private convertJobDates;
533
566
  }
534
567
 
535
- export { type Asset, type AssetStatus, type AssetType, CDN, type ConfirmUploadRequest, type ConfirmUploadResponse, type CreateFolderRequest, type DeleteAssetRequest, type DeleteAssetsRequest, type DeleteAssetsResponse, type ExtractAudioRequest, type ExtractAudioResponse, type Folder, type FolderTreeNode, type GetAssetRequest, type GetFolderTreeRequest, type ListAssetsRequest, type ListAssetsResponse, type ListJobsRequest, type ListJobsResponse, type MoveAssetsRequest, type MoveAssetsResponse, type StreamingUrls, type ThumbnailRequest, type ThumbnailResponse, type TranscodeJob, type TranscodeVideoRequest, type TranscodingStatus, type TransformOptions, type TrimOptions, type UpdateAssetRequest, type UploadUrlRequest, type UploadUrlResponse, type VideoCodec, type VideoOutputFormat, type VideoQuality, type VideoVariant, type WatermarkOptions };
568
+ export { type Asset, type AssetStatus, type AssetType, CDN, type ConfirmUploadRequest, type ConfirmUploadResponse, type CreateFolderRequest, type DeleteAssetRequest, type DeleteAssetsRequest, type DeleteAssetsResponse, type ExtractAudioRequest, type ExtractAudioResponse, type Folder, type FolderTreeNode, type GetAssetRequest, type GetFolderTreeRequest, type ListAssetsRequest, type ListAssetsResponse, type ListJobsRequest, type ListJobsResponse, type MoveAssetsRequest, type MoveAssetsResponse, type RegenerateThumbnailRequest, type RegenerateThumbnailResponse, type StreamingUrls, type ThumbnailRequest, type ThumbnailResponse, type TranscodeJob, type TranscodeVideoRequest, type TranscodingStatus, type TransformOptions, type TrimOptions, type UpdateAssetRequest, type UploadUrlRequest, type UploadUrlResponse, type VideoCodec, type VideoOutputFormat, type VideoQuality, type VideoVariant, type WatermarkOptions };
package/dist/cdn/index.js CHANGED
@@ -507,6 +507,25 @@ var CDN = class {
507
507
  if (request.format) params.set("format", request.format);
508
508
  return this.http.get(`/cdn/video/thumbnail/${request.assetId}?${params.toString()}`);
509
509
  }
510
+ /**
511
+ * Regenerate a thumbnail for a video (force regeneration even if one exists)
512
+ *
513
+ * Useful for retrying failed thumbnail generation or regenerating with different settings.
514
+ *
515
+ * @example
516
+ * ```typescript
517
+ * const result = await cdn.regenerateThumbnail({
518
+ * assetId: 'video-asset-id',
519
+ * timestamp: 5, // 5 seconds into the video
520
+ * width: 1280,
521
+ * format: 'jpg',
522
+ * });
523
+ * console.log(`Thumbnail regeneration queued: ${result.status}`);
524
+ * ```
525
+ */
526
+ async regenerateThumbnail(request) {
527
+ return this.http.post("/cdn/video/thumbnail/regenerate", request);
528
+ }
510
529
  /**
511
530
  * Extract audio from a video file
512
531
  *
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/http-client.ts","../../src/cdn/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * HTTP client for Stack0 API\n * Handles authentication, request/response formatting, and error handling\n */\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class HttpClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://api.stack0.dev/v1\";\n }\n\n private getHeaders(includeContentType = true): Record<string, string> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n return headers;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const bodyString = body === undefined ? undefined : JSON.stringify(body);\n const hasBody = bodyString !== undefined;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(hasBody),\n body: hasBody ? bodyString : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && \"statusCode\" in error) {\n throw error; // Re-throw our custom errors\n }\n throw this.createError(\"Network error\", error);\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorBody: { message: string } | undefined;\n try {\n errorBody = (await response.json()) as { message: string };\n } catch {\n errorBody = { message: response.statusText };\n }\n\n const error = new Error(errorBody?.message || `HTTP ${response.status}`) as Error & {\n statusCode: number;\n code: string;\n response: unknown;\n };\n error.statusCode = response.status;\n error.code = (errorBody as unknown as { code: string } | undefined)?.code ?? \"\";\n error.response = errorBody;\n throw error;\n }\n\n private createError(message: string, cause?: unknown): Error {\n const error = new Error(message) as Error & { cause: unknown };\n error.cause = cause;\n return error;\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async deleteWithBody<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"DELETE\", path, body);\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n}\n","/**\n * Stack0 CDN Client\n * Upload, manage, and transform assets\n */\n\nimport { HttpClient, type HttpClientConfig } from \"../lib/http-client\";\nimport type {\n Asset,\n UploadUrlRequest,\n UploadUrlResponse,\n UpdateAssetRequest,\n DeleteAssetsResponse,\n ListAssetsRequest,\n ListAssetsResponse,\n MoveAssetsRequest,\n MoveAssetsResponse,\n TransformOptions,\n GetFolderTreeRequest,\n FolderTreeNode,\n CreateFolderRequest,\n Folder,\n TranscodeVideoRequest,\n TranscodeJob,\n ListJobsRequest,\n ListJobsResponse,\n StreamingUrls,\n ThumbnailRequest,\n ThumbnailResponse,\n ExtractAudioRequest,\n ExtractAudioResponse,\n} from \"./types\";\n\n// Allowed widths that match the CloudFront url-rewriter configuration\nconst ALLOWED_WIDTHS = [256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840];\n\nexport class CDN {\n private http: HttpClient;\n private cdnUrl?: string;\n\n constructor(config: HttpClientConfig, cdnUrl?: string) {\n this.http = new HttpClient(config);\n this.cdnUrl = cdnUrl;\n }\n\n /**\n * Generate a presigned URL for uploading a file\n *\n * @example\n * ```typescript\n * const { uploadUrl, assetId } = await cdn.getUploadUrl({\n * projectSlug: 'my-project',\n * filename: 'image.jpg',\n * mimeType: 'image/jpeg',\n * size: 1024 * 1024,\n * });\n *\n * // Upload file to the presigned URL\n * await fetch(uploadUrl, {\n * method: 'PUT',\n * body: file,\n * headers: { 'Content-Type': 'image/jpeg' },\n * });\n *\n * // Confirm the upload\n * const asset = await cdn.confirmUpload(assetId);\n * ```\n */\n async getUploadUrl(request: UploadUrlRequest): Promise<UploadUrlResponse> {\n const response = await this.http.post<UploadUrlResponse>(\"/cdn/upload\", request);\n\n if (typeof response.expiresAt === \"string\") {\n response.expiresAt = new Date(response.expiresAt);\n }\n\n return response;\n }\n\n /**\n * Confirm that an upload has completed\n */\n async confirmUpload(assetId: string): Promise<Asset> {\n const response = await this.http.post<Asset>(`/cdn/upload/${assetId}/confirm`, {});\n return this.convertAssetDates(response);\n }\n\n /**\n * Upload a file directly (handles presigned URL flow automatically)\n *\n * @example\n * ```typescript\n * const asset = await cdn.upload({\n * projectSlug: 'my-project',\n * file: fileBuffer,\n * filename: 'image.jpg',\n * mimeType: 'image/jpeg',\n * });\n * ```\n */\n async upload(options: {\n projectSlug: string;\n file: Blob | Buffer | ArrayBuffer;\n filename: string;\n mimeType: string;\n folder?: string;\n metadata?: Record<string, unknown>;\n }): Promise<Asset> {\n const { projectSlug, file, filename, mimeType, folder, metadata } = options;\n\n // Get file size\n let size: number;\n if (file instanceof Blob) {\n size = file.size;\n } else if (file instanceof ArrayBuffer) {\n size = file.byteLength;\n } else {\n // Buffer\n size = (file as Buffer).length;\n }\n\n // Get presigned URL\n const { uploadUrl, assetId } = await this.getUploadUrl({\n projectSlug,\n filename,\n mimeType,\n size,\n folder,\n metadata,\n });\n\n // Upload file\n const uploadResponse = await fetch(uploadUrl, {\n method: \"PUT\",\n body: file,\n headers: {\n \"Content-Type\": mimeType,\n },\n });\n\n if (!uploadResponse.ok) {\n throw new Error(`Upload failed: ${uploadResponse.statusText}`);\n }\n\n // Confirm upload\n return this.confirmUpload(assetId);\n }\n\n /**\n * Get an asset by ID\n *\n * @example\n * ```typescript\n * const asset = await cdn.get('asset-id');\n * console.log(asset.cdnUrl);\n * ```\n */\n async get(id: string): Promise<Asset> {\n const response = await this.http.get<Asset>(`/cdn/assets/${id}`);\n return this.convertAssetDates(response);\n }\n\n /**\n * Update asset metadata\n *\n * @example\n * ```typescript\n * const asset = await cdn.update({\n * id: 'asset-id',\n * alt: 'A beautiful sunset',\n * tags: ['nature', 'sunset'],\n * });\n * ```\n */\n async update(request: UpdateAssetRequest): Promise<Asset> {\n const { id, ...data } = request;\n const response = await this.http.patch<Asset>(`/cdn/assets/${id}`, data);\n return this.convertAssetDates(response);\n }\n\n /**\n * Delete an asset\n *\n * @example\n * ```typescript\n * await cdn.delete('asset-id');\n * ```\n */\n async delete(id: string): Promise<{ success: boolean }> {\n // NOTE: Our OpenAPI adapter parses JSON bodies for non-GET methods.\n // Some Fastify setups will throw if Content-Type is JSON but the body is empty.\n // Sending the id in the body keeps this endpoint compatible across adapters.\n return this.http.deleteWithBody<{ success: boolean }>(`/cdn/assets/${id}`, { id });\n }\n\n /**\n * Delete multiple assets\n *\n * @example\n * ```typescript\n * const result = await cdn.deleteMany(['asset-1', 'asset-2']);\n * console.log(`Deleted ${result.deletedCount} assets`);\n * ```\n */\n async deleteMany(ids: string[]): Promise<DeleteAssetsResponse> {\n return this.http.post<DeleteAssetsResponse>(\"/cdn/assets/delete\", { ids });\n }\n\n /**\n * List assets with filters and pagination\n *\n * @example\n * ```typescript\n * const { assets, total, hasMore } = await cdn.list({\n * projectSlug: 'my-project',\n * type: 'image',\n * limit: 20,\n * });\n * ```\n */\n async list(request: ListAssetsRequest): Promise<ListAssetsResponse> {\n const params = new URLSearchParams();\n\n params.set(\"projectSlug\", request.projectSlug);\n if (request.folder !== undefined) params.set(\"folder\", request.folder ?? \"\");\n if (request.type) params.set(\"type\", request.type);\n if (request.status) params.set(\"status\", request.status);\n if (request.search) params.set(\"search\", request.search);\n if (request.tags) params.set(\"tags\", request.tags.join(\",\"));\n if (request.sortBy) params.set(\"sortBy\", request.sortBy);\n if (request.sortOrder) params.set(\"sortOrder\", request.sortOrder);\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.offset) params.set(\"offset\", request.offset.toString());\n\n const response = await this.http.get<ListAssetsResponse>(`/cdn/assets?${params.toString()}`);\n\n return {\n ...response,\n assets: response.assets.map((asset) => this.convertAssetDates(asset)),\n };\n }\n\n /**\n * Move assets to a different folder\n *\n * @example\n * ```typescript\n * await cdn.move({\n * assetIds: ['asset-1', 'asset-2'],\n * folder: '/images/archive',\n * });\n * ```\n */\n async move(request: MoveAssetsRequest): Promise<MoveAssetsResponse> {\n return this.http.post<MoveAssetsResponse>(\"/cdn/assets/move\", request);\n }\n\n /**\n * Get a transformed image URL (client-side, no API call)\n *\n * @example\n * ```typescript\n * // Using asset's cdnUrl directly\n * const url = cdn.getTransformUrl(asset.cdnUrl, {\n * width: 800,\n * height: 600,\n * fit: 'cover',\n * format: 'webp',\n * quality: 80,\n * });\n *\n * // Or using cdnUrl from SDK config + s3Key\n * const url = cdn.getTransformUrl(asset.s3Key, { width: 400 });\n * ```\n */\n getTransformUrl(assetUrlOrS3Key: string, options: TransformOptions): string {\n // Determine base URL\n let baseUrl: string;\n if (assetUrlOrS3Key.startsWith(\"http://\") || assetUrlOrS3Key.startsWith(\"https://\")) {\n // It's already a full URL - extract base and path\n const url = new URL(assetUrlOrS3Key);\n baseUrl = `${url.protocol}//${url.host}${url.pathname}`;\n } else if (this.cdnUrl) {\n // It's an s3Key, use configured CDN URL\n const cdnBase = this.cdnUrl.endsWith(\"/\") ? this.cdnUrl.slice(0, -1) : this.cdnUrl;\n baseUrl = `${cdnBase}/${assetUrlOrS3Key}`;\n } else {\n throw new Error(\"getTransformUrl requires either a full URL or cdnUrl to be configured in Stack0 options\");\n }\n\n // Build query string\n const params = this.buildTransformQuery(options);\n if (!params) {\n return baseUrl;\n }\n return `${baseUrl}?${params}`;\n }\n\n /**\n * Build transform query parameters\n */\n private buildTransformQuery(options: TransformOptions): string {\n const params = new URLSearchParams();\n\n if (options.format) params.set(\"f\", options.format);\n if (options.quality !== undefined) params.set(\"q\", options.quality.toString());\n\n if (options.width !== undefined) {\n // Snap to nearest allowed width for better caching\n const width = this.getNearestWidth(options.width);\n params.set(\"w\", width.toString());\n }\n if (options.height !== undefined) params.set(\"h\", options.height.toString());\n if (options.fit) params.set(\"fit\", options.fit);\n if (options.crop) params.set(\"crop\", options.crop);\n if (options.cropX !== undefined) params.set(\"crop-x\", options.cropX.toString());\n if (options.cropY !== undefined) params.set(\"crop-y\", options.cropY.toString());\n if (options.cropWidth !== undefined) params.set(\"crop-w\", options.cropWidth.toString());\n if (options.cropHeight !== undefined) params.set(\"crop-h\", options.cropHeight.toString());\n if (options.blur !== undefined) params.set(\"blur\", options.blur.toString());\n if (options.sharpen !== undefined) params.set(\"sharpen\", options.sharpen.toString());\n if (options.brightness !== undefined) params.set(\"brightness\", options.brightness.toString());\n if (options.saturation !== undefined) params.set(\"saturation\", options.saturation.toString());\n if (options.grayscale) params.set(\"grayscale\", \"true\");\n if (options.rotate !== undefined) params.set(\"rotate\", options.rotate.toString());\n if (options.flip) params.set(\"flip\", \"y\");\n if (options.flop) params.set(\"flop\", \"x\");\n\n return params.toString();\n }\n\n /**\n * Find the nearest allowed width for optimal caching\n */\n private getNearestWidth(width: number): number {\n return ALLOWED_WIDTHS.reduce((prev, curr) => (Math.abs(curr - width) < Math.abs(prev - width) ? curr : prev));\n }\n\n /**\n * Get folder tree for navigation\n *\n * @example\n * ```typescript\n * const tree = await cdn.getFolderTree({\n * projectSlug: 'my-project',\n * maxDepth: 3,\n * });\n * ```\n */\n async getFolderTree(request: GetFolderTreeRequest): Promise<FolderTreeNode[]> {\n const params = new URLSearchParams();\n params.set(\"projectSlug\", request.projectSlug);\n if (request.maxDepth) params.set(\"maxDepth\", request.maxDepth.toString());\n\n const response = await this.http.get<{ tree: FolderTreeNode[] }>(`/cdn/folders/tree?${params.toString()}`);\n return response.tree;\n }\n\n /**\n * Create a new folder\n *\n * @example\n * ```typescript\n * const folder = await cdn.createFolder({\n * projectSlug: 'my-project',\n * name: 'images',\n * });\n * ```\n */\n async createFolder(request: CreateFolderRequest): Promise<Folder> {\n const response = await this.http.post<Folder>(\"/cdn/folders\", request);\n return this.convertFolderDates(response);\n }\n\n /**\n * Delete a folder\n *\n * @example\n * ```typescript\n * await cdn.deleteFolder('folder-id');\n * ```\n */\n async deleteFolder(id: string, deleteContents = false): Promise<{ success: boolean }> {\n const params = new URLSearchParams();\n if (deleteContents) params.set(\"deleteContents\", \"true\");\n\n return this.http.deleteWithBody<{ success: boolean }>(`/cdn/folders/${id}?${params.toString()}`, {\n id,\n deleteContents,\n });\n }\n\n private convertAssetDates(asset: Asset): Asset {\n if (typeof asset.createdAt === \"string\") {\n asset.createdAt = new Date(asset.createdAt);\n }\n if (asset.updatedAt && typeof asset.updatedAt === \"string\") {\n asset.updatedAt = new Date(asset.updatedAt);\n }\n return asset;\n }\n\n private convertFolderDates(folder: Folder): Folder {\n if (typeof folder.createdAt === \"string\") {\n folder.createdAt = new Date(folder.createdAt);\n }\n if (folder.updatedAt && typeof folder.updatedAt === \"string\") {\n folder.updatedAt = new Date(folder.updatedAt);\n }\n return folder;\n }\n\n // ============================================================================\n // Video Transcoding Methods\n // ============================================================================\n\n /**\n * Start a video transcoding job\n *\n * @example\n * ```typescript\n * const job = await cdn.transcode({\n * projectSlug: 'my-project',\n * assetId: 'video-asset-id',\n * outputFormat: 'hls',\n * variants: [\n * { quality: '720p', codec: 'h264' },\n * { quality: '1080p', codec: 'h264' },\n * ],\n * webhookUrl: 'https://your-app.com/webhook',\n * });\n * console.log(`Job started: ${job.id}`);\n * ```\n */\n async transcode(request: TranscodeVideoRequest): Promise<TranscodeJob> {\n const response = await this.http.post<TranscodeJob>(\"/cdn/video/transcode\", request);\n return this.convertJobDates(response);\n }\n\n /**\n * Get a transcoding job by ID\n *\n * @example\n * ```typescript\n * const job = await cdn.getJob('job-id');\n * console.log(`Status: ${job.status}, Progress: ${job.progress}%`);\n * ```\n */\n async getJob(jobId: string): Promise<TranscodeJob> {\n const response = await this.http.get<TranscodeJob>(`/cdn/video/jobs/${jobId}`);\n return this.convertJobDates(response);\n }\n\n /**\n * List transcoding jobs with filters\n *\n * @example\n * ```typescript\n * const { jobs, total } = await cdn.listJobs({\n * projectSlug: 'my-project',\n * status: 'processing',\n * limit: 20,\n * });\n * ```\n */\n async listJobs(request: ListJobsRequest): Promise<ListJobsResponse> {\n const params = new URLSearchParams();\n params.set(\"projectSlug\", request.projectSlug);\n if (request.assetId) params.set(\"assetId\", request.assetId);\n if (request.status) params.set(\"status\", request.status);\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.offset) params.set(\"offset\", request.offset.toString());\n\n const response = await this.http.get<ListJobsResponse>(`/cdn/video/jobs?${params.toString()}`);\n return {\n ...response,\n jobs: response.jobs.map((job) => this.convertJobDates(job)),\n };\n }\n\n /**\n * Cancel a pending or processing transcoding job\n *\n * @example\n * ```typescript\n * await cdn.cancelJob('job-id');\n * ```\n */\n async cancelJob(jobId: string): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/cdn/video/jobs/${jobId}/cancel`, {});\n }\n\n /**\n * Get streaming URLs for a transcoded video\n *\n * @example\n * ```typescript\n * const urls = await cdn.getStreamingUrls('asset-id');\n * console.log(`HLS URL: ${urls.hlsUrl}`);\n * console.log(`MP4 720p: ${urls.mp4Urls.find(u => u.quality === '720p')?.url}`);\n * ```\n */\n async getStreamingUrls(assetId: string): Promise<StreamingUrls> {\n return this.http.get<StreamingUrls>(`/cdn/video/stream/${assetId}`);\n }\n\n /**\n * Generate a thumbnail from a video at a specific timestamp\n *\n * @example\n * ```typescript\n * const thumbnail = await cdn.getThumbnail({\n * assetId: 'video-asset-id',\n * timestamp: 10.5, // 10.5 seconds into the video\n * width: 320,\n * format: 'webp',\n * });\n * console.log(`Thumbnail URL: ${thumbnail.url}`);\n * ```\n */\n async getThumbnail(request: ThumbnailRequest): Promise<ThumbnailResponse> {\n const params = new URLSearchParams();\n params.set(\"timestamp\", request.timestamp.toString());\n if (request.width) params.set(\"width\", request.width.toString());\n if (request.format) params.set(\"format\", request.format);\n\n return this.http.get<ThumbnailResponse>(`/cdn/video/thumbnail/${request.assetId}?${params.toString()}`);\n }\n\n /**\n * Extract audio from a video file\n *\n * @example\n * ```typescript\n * const { jobId } = await cdn.extractAudio({\n * projectSlug: 'my-project',\n * assetId: 'video-asset-id',\n * format: 'mp3',\n * bitrate: 192,\n * });\n * ```\n */\n async extractAudio(request: ExtractAudioRequest): Promise<ExtractAudioResponse> {\n return this.http.post<ExtractAudioResponse>(\"/cdn/video/extract-audio\", request);\n }\n\n private convertJobDates(job: TranscodeJob): TranscodeJob {\n if (typeof job.createdAt === \"string\") {\n job.createdAt = new Date(job.createdAt);\n }\n if (job.startedAt && typeof job.startedAt === \"string\") {\n job.startedAt = new Date(job.startedAt);\n }\n if (job.completedAt && typeof job.completedAt === \"string\") {\n job.completedAt = new Date(job.completedAt);\n }\n return job;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/lib/http-client.ts","../../src/cdn/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * HTTP client for Stack0 API\n * Handles authentication, request/response formatting, and error handling\n */\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class HttpClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://api.stack0.dev/v1\";\n }\n\n private getHeaders(includeContentType = true): Record<string, string> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n return headers;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const bodyString = body === undefined ? undefined : JSON.stringify(body);\n const hasBody = bodyString !== undefined;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(hasBody),\n body: hasBody ? bodyString : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && \"statusCode\" in error) {\n throw error; // Re-throw our custom errors\n }\n throw this.createError(\"Network error\", error);\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorBody: { message: string } | undefined;\n try {\n errorBody = (await response.json()) as { message: string };\n } catch {\n errorBody = { message: response.statusText };\n }\n\n const error = new Error(errorBody?.message || `HTTP ${response.status}`) as Error & {\n statusCode: number;\n code: string;\n response: unknown;\n };\n error.statusCode = response.status;\n error.code = (errorBody as unknown as { code: string } | undefined)?.code ?? \"\";\n error.response = errorBody;\n throw error;\n }\n\n private createError(message: string, cause?: unknown): Error {\n const error = new Error(message) as Error & { cause: unknown };\n error.cause = cause;\n return error;\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async deleteWithBody<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"DELETE\", path, body);\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n}\n","/**\n * Stack0 CDN Client\n * Upload, manage, and transform assets\n */\n\nimport { HttpClient, type HttpClientConfig } from \"../lib/http-client\";\nimport type {\n Asset,\n UploadUrlRequest,\n UploadUrlResponse,\n UpdateAssetRequest,\n DeleteAssetsResponse,\n ListAssetsRequest,\n ListAssetsResponse,\n MoveAssetsRequest,\n MoveAssetsResponse,\n TransformOptions,\n GetFolderTreeRequest,\n FolderTreeNode,\n CreateFolderRequest,\n Folder,\n TranscodeVideoRequest,\n TranscodeJob,\n ListJobsRequest,\n ListJobsResponse,\n StreamingUrls,\n ThumbnailRequest,\n ThumbnailResponse,\n RegenerateThumbnailRequest,\n RegenerateThumbnailResponse,\n ExtractAudioRequest,\n ExtractAudioResponse,\n} from \"./types\";\n\n// Allowed widths that match the CloudFront url-rewriter configuration\nconst ALLOWED_WIDTHS = [256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840];\n\nexport class CDN {\n private http: HttpClient;\n private cdnUrl?: string;\n\n constructor(config: HttpClientConfig, cdnUrl?: string) {\n this.http = new HttpClient(config);\n this.cdnUrl = cdnUrl;\n }\n\n /**\n * Generate a presigned URL for uploading a file\n *\n * @example\n * ```typescript\n * const { uploadUrl, assetId } = await cdn.getUploadUrl({\n * projectSlug: 'my-project',\n * filename: 'image.jpg',\n * mimeType: 'image/jpeg',\n * size: 1024 * 1024,\n * });\n *\n * // Upload file to the presigned URL\n * await fetch(uploadUrl, {\n * method: 'PUT',\n * body: file,\n * headers: { 'Content-Type': 'image/jpeg' },\n * });\n *\n * // Confirm the upload\n * const asset = await cdn.confirmUpload(assetId);\n * ```\n */\n async getUploadUrl(request: UploadUrlRequest): Promise<UploadUrlResponse> {\n const response = await this.http.post<UploadUrlResponse>(\"/cdn/upload\", request);\n\n if (typeof response.expiresAt === \"string\") {\n response.expiresAt = new Date(response.expiresAt);\n }\n\n return response;\n }\n\n /**\n * Confirm that an upload has completed\n */\n async confirmUpload(assetId: string): Promise<Asset> {\n const response = await this.http.post<Asset>(`/cdn/upload/${assetId}/confirm`, {});\n return this.convertAssetDates(response);\n }\n\n /**\n * Upload a file directly (handles presigned URL flow automatically)\n *\n * @example\n * ```typescript\n * const asset = await cdn.upload({\n * projectSlug: 'my-project',\n * file: fileBuffer,\n * filename: 'image.jpg',\n * mimeType: 'image/jpeg',\n * });\n * ```\n */\n async upload(options: {\n projectSlug: string;\n file: Blob | Buffer | ArrayBuffer;\n filename: string;\n mimeType: string;\n folder?: string;\n metadata?: Record<string, unknown>;\n }): Promise<Asset> {\n const { projectSlug, file, filename, mimeType, folder, metadata } = options;\n\n // Get file size\n let size: number;\n if (file instanceof Blob) {\n size = file.size;\n } else if (file instanceof ArrayBuffer) {\n size = file.byteLength;\n } else {\n // Buffer\n size = (file as Buffer).length;\n }\n\n // Get presigned URL\n const { uploadUrl, assetId } = await this.getUploadUrl({\n projectSlug,\n filename,\n mimeType,\n size,\n folder,\n metadata,\n });\n\n // Upload file\n const uploadResponse = await fetch(uploadUrl, {\n method: \"PUT\",\n body: file,\n headers: {\n \"Content-Type\": mimeType,\n },\n });\n\n if (!uploadResponse.ok) {\n throw new Error(`Upload failed: ${uploadResponse.statusText}`);\n }\n\n // Confirm upload\n return this.confirmUpload(assetId);\n }\n\n /**\n * Get an asset by ID\n *\n * @example\n * ```typescript\n * const asset = await cdn.get('asset-id');\n * console.log(asset.cdnUrl);\n * ```\n */\n async get(id: string): Promise<Asset> {\n const response = await this.http.get<Asset>(`/cdn/assets/${id}`);\n return this.convertAssetDates(response);\n }\n\n /**\n * Update asset metadata\n *\n * @example\n * ```typescript\n * const asset = await cdn.update({\n * id: 'asset-id',\n * alt: 'A beautiful sunset',\n * tags: ['nature', 'sunset'],\n * });\n * ```\n */\n async update(request: UpdateAssetRequest): Promise<Asset> {\n const { id, ...data } = request;\n const response = await this.http.patch<Asset>(`/cdn/assets/${id}`, data);\n return this.convertAssetDates(response);\n }\n\n /**\n * Delete an asset\n *\n * @example\n * ```typescript\n * await cdn.delete('asset-id');\n * ```\n */\n async delete(id: string): Promise<{ success: boolean }> {\n // NOTE: Our OpenAPI adapter parses JSON bodies for non-GET methods.\n // Some Fastify setups will throw if Content-Type is JSON but the body is empty.\n // Sending the id in the body keeps this endpoint compatible across adapters.\n return this.http.deleteWithBody<{ success: boolean }>(`/cdn/assets/${id}`, { id });\n }\n\n /**\n * Delete multiple assets\n *\n * @example\n * ```typescript\n * const result = await cdn.deleteMany(['asset-1', 'asset-2']);\n * console.log(`Deleted ${result.deletedCount} assets`);\n * ```\n */\n async deleteMany(ids: string[]): Promise<DeleteAssetsResponse> {\n return this.http.post<DeleteAssetsResponse>(\"/cdn/assets/delete\", { ids });\n }\n\n /**\n * List assets with filters and pagination\n *\n * @example\n * ```typescript\n * const { assets, total, hasMore } = await cdn.list({\n * projectSlug: 'my-project',\n * type: 'image',\n * limit: 20,\n * });\n * ```\n */\n async list(request: ListAssetsRequest): Promise<ListAssetsResponse> {\n const params = new URLSearchParams();\n\n params.set(\"projectSlug\", request.projectSlug);\n if (request.folder !== undefined) params.set(\"folder\", request.folder ?? \"\");\n if (request.type) params.set(\"type\", request.type);\n if (request.status) params.set(\"status\", request.status);\n if (request.search) params.set(\"search\", request.search);\n if (request.tags) params.set(\"tags\", request.tags.join(\",\"));\n if (request.sortBy) params.set(\"sortBy\", request.sortBy);\n if (request.sortOrder) params.set(\"sortOrder\", request.sortOrder);\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.offset) params.set(\"offset\", request.offset.toString());\n\n const response = await this.http.get<ListAssetsResponse>(`/cdn/assets?${params.toString()}`);\n\n return {\n ...response,\n assets: response.assets.map((asset) => this.convertAssetDates(asset)),\n };\n }\n\n /**\n * Move assets to a different folder\n *\n * @example\n * ```typescript\n * await cdn.move({\n * assetIds: ['asset-1', 'asset-2'],\n * folder: '/images/archive',\n * });\n * ```\n */\n async move(request: MoveAssetsRequest): Promise<MoveAssetsResponse> {\n return this.http.post<MoveAssetsResponse>(\"/cdn/assets/move\", request);\n }\n\n /**\n * Get a transformed image URL (client-side, no API call)\n *\n * @example\n * ```typescript\n * // Using asset's cdnUrl directly\n * const url = cdn.getTransformUrl(asset.cdnUrl, {\n * width: 800,\n * height: 600,\n * fit: 'cover',\n * format: 'webp',\n * quality: 80,\n * });\n *\n * // Or using cdnUrl from SDK config + s3Key\n * const url = cdn.getTransformUrl(asset.s3Key, { width: 400 });\n * ```\n */\n getTransformUrl(assetUrlOrS3Key: string, options: TransformOptions): string {\n // Determine base URL\n let baseUrl: string;\n if (assetUrlOrS3Key.startsWith(\"http://\") || assetUrlOrS3Key.startsWith(\"https://\")) {\n // It's already a full URL - extract base and path\n const url = new URL(assetUrlOrS3Key);\n baseUrl = `${url.protocol}//${url.host}${url.pathname}`;\n } else if (this.cdnUrl) {\n // It's an s3Key, use configured CDN URL\n const cdnBase = this.cdnUrl.endsWith(\"/\") ? this.cdnUrl.slice(0, -1) : this.cdnUrl;\n baseUrl = `${cdnBase}/${assetUrlOrS3Key}`;\n } else {\n throw new Error(\"getTransformUrl requires either a full URL or cdnUrl to be configured in Stack0 options\");\n }\n\n // Build query string\n const params = this.buildTransformQuery(options);\n if (!params) {\n return baseUrl;\n }\n return `${baseUrl}?${params}`;\n }\n\n /**\n * Build transform query parameters\n */\n private buildTransformQuery(options: TransformOptions): string {\n const params = new URLSearchParams();\n\n if (options.format) params.set(\"f\", options.format);\n if (options.quality !== undefined) params.set(\"q\", options.quality.toString());\n\n if (options.width !== undefined) {\n // Snap to nearest allowed width for better caching\n const width = this.getNearestWidth(options.width);\n params.set(\"w\", width.toString());\n }\n if (options.height !== undefined) params.set(\"h\", options.height.toString());\n if (options.fit) params.set(\"fit\", options.fit);\n if (options.crop) params.set(\"crop\", options.crop);\n if (options.cropX !== undefined) params.set(\"crop-x\", options.cropX.toString());\n if (options.cropY !== undefined) params.set(\"crop-y\", options.cropY.toString());\n if (options.cropWidth !== undefined) params.set(\"crop-w\", options.cropWidth.toString());\n if (options.cropHeight !== undefined) params.set(\"crop-h\", options.cropHeight.toString());\n if (options.blur !== undefined) params.set(\"blur\", options.blur.toString());\n if (options.sharpen !== undefined) params.set(\"sharpen\", options.sharpen.toString());\n if (options.brightness !== undefined) params.set(\"brightness\", options.brightness.toString());\n if (options.saturation !== undefined) params.set(\"saturation\", options.saturation.toString());\n if (options.grayscale) params.set(\"grayscale\", \"true\");\n if (options.rotate !== undefined) params.set(\"rotate\", options.rotate.toString());\n if (options.flip) params.set(\"flip\", \"y\");\n if (options.flop) params.set(\"flop\", \"x\");\n\n return params.toString();\n }\n\n /**\n * Find the nearest allowed width for optimal caching\n */\n private getNearestWidth(width: number): number {\n return ALLOWED_WIDTHS.reduce((prev, curr) => (Math.abs(curr - width) < Math.abs(prev - width) ? curr : prev));\n }\n\n /**\n * Get folder tree for navigation\n *\n * @example\n * ```typescript\n * const tree = await cdn.getFolderTree({\n * projectSlug: 'my-project',\n * maxDepth: 3,\n * });\n * ```\n */\n async getFolderTree(request: GetFolderTreeRequest): Promise<FolderTreeNode[]> {\n const params = new URLSearchParams();\n params.set(\"projectSlug\", request.projectSlug);\n if (request.maxDepth) params.set(\"maxDepth\", request.maxDepth.toString());\n\n const response = await this.http.get<{ tree: FolderTreeNode[] }>(`/cdn/folders/tree?${params.toString()}`);\n return response.tree;\n }\n\n /**\n * Create a new folder\n *\n * @example\n * ```typescript\n * const folder = await cdn.createFolder({\n * projectSlug: 'my-project',\n * name: 'images',\n * });\n * ```\n */\n async createFolder(request: CreateFolderRequest): Promise<Folder> {\n const response = await this.http.post<Folder>(\"/cdn/folders\", request);\n return this.convertFolderDates(response);\n }\n\n /**\n * Delete a folder\n *\n * @example\n * ```typescript\n * await cdn.deleteFolder('folder-id');\n * ```\n */\n async deleteFolder(id: string, deleteContents = false): Promise<{ success: boolean }> {\n const params = new URLSearchParams();\n if (deleteContents) params.set(\"deleteContents\", \"true\");\n\n return this.http.deleteWithBody<{ success: boolean }>(`/cdn/folders/${id}?${params.toString()}`, {\n id,\n deleteContents,\n });\n }\n\n private convertAssetDates(asset: Asset): Asset {\n if (typeof asset.createdAt === \"string\") {\n asset.createdAt = new Date(asset.createdAt);\n }\n if (asset.updatedAt && typeof asset.updatedAt === \"string\") {\n asset.updatedAt = new Date(asset.updatedAt);\n }\n return asset;\n }\n\n private convertFolderDates(folder: Folder): Folder {\n if (typeof folder.createdAt === \"string\") {\n folder.createdAt = new Date(folder.createdAt);\n }\n if (folder.updatedAt && typeof folder.updatedAt === \"string\") {\n folder.updatedAt = new Date(folder.updatedAt);\n }\n return folder;\n }\n\n // ============================================================================\n // Video Transcoding Methods\n // ============================================================================\n\n /**\n * Start a video transcoding job\n *\n * @example\n * ```typescript\n * const job = await cdn.transcode({\n * projectSlug: 'my-project',\n * assetId: 'video-asset-id',\n * outputFormat: 'hls',\n * variants: [\n * { quality: '720p', codec: 'h264' },\n * { quality: '1080p', codec: 'h264' },\n * ],\n * webhookUrl: 'https://your-app.com/webhook',\n * });\n * console.log(`Job started: ${job.id}`);\n * ```\n */\n async transcode(request: TranscodeVideoRequest): Promise<TranscodeJob> {\n const response = await this.http.post<TranscodeJob>(\"/cdn/video/transcode\", request);\n return this.convertJobDates(response);\n }\n\n /**\n * Get a transcoding job by ID\n *\n * @example\n * ```typescript\n * const job = await cdn.getJob('job-id');\n * console.log(`Status: ${job.status}, Progress: ${job.progress}%`);\n * ```\n */\n async getJob(jobId: string): Promise<TranscodeJob> {\n const response = await this.http.get<TranscodeJob>(`/cdn/video/jobs/${jobId}`);\n return this.convertJobDates(response);\n }\n\n /**\n * List transcoding jobs with filters\n *\n * @example\n * ```typescript\n * const { jobs, total } = await cdn.listJobs({\n * projectSlug: 'my-project',\n * status: 'processing',\n * limit: 20,\n * });\n * ```\n */\n async listJobs(request: ListJobsRequest): Promise<ListJobsResponse> {\n const params = new URLSearchParams();\n params.set(\"projectSlug\", request.projectSlug);\n if (request.assetId) params.set(\"assetId\", request.assetId);\n if (request.status) params.set(\"status\", request.status);\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.offset) params.set(\"offset\", request.offset.toString());\n\n const response = await this.http.get<ListJobsResponse>(`/cdn/video/jobs?${params.toString()}`);\n return {\n ...response,\n jobs: response.jobs.map((job) => this.convertJobDates(job)),\n };\n }\n\n /**\n * Cancel a pending or processing transcoding job\n *\n * @example\n * ```typescript\n * await cdn.cancelJob('job-id');\n * ```\n */\n async cancelJob(jobId: string): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/cdn/video/jobs/${jobId}/cancel`, {});\n }\n\n /**\n * Get streaming URLs for a transcoded video\n *\n * @example\n * ```typescript\n * const urls = await cdn.getStreamingUrls('asset-id');\n * console.log(`HLS URL: ${urls.hlsUrl}`);\n * console.log(`MP4 720p: ${urls.mp4Urls.find(u => u.quality === '720p')?.url}`);\n * ```\n */\n async getStreamingUrls(assetId: string): Promise<StreamingUrls> {\n return this.http.get<StreamingUrls>(`/cdn/video/stream/${assetId}`);\n }\n\n /**\n * Generate a thumbnail from a video at a specific timestamp\n *\n * @example\n * ```typescript\n * const thumbnail = await cdn.getThumbnail({\n * assetId: 'video-asset-id',\n * timestamp: 10.5, // 10.5 seconds into the video\n * width: 320,\n * format: 'webp',\n * });\n * console.log(`Thumbnail URL: ${thumbnail.url}`);\n * ```\n */\n async getThumbnail(request: ThumbnailRequest): Promise<ThumbnailResponse> {\n const params = new URLSearchParams();\n params.set(\"timestamp\", request.timestamp.toString());\n if (request.width) params.set(\"width\", request.width.toString());\n if (request.format) params.set(\"format\", request.format);\n\n return this.http.get<ThumbnailResponse>(`/cdn/video/thumbnail/${request.assetId}?${params.toString()}`);\n }\n\n /**\n * Regenerate a thumbnail for a video (force regeneration even if one exists)\n *\n * Useful for retrying failed thumbnail generation or regenerating with different settings.\n *\n * @example\n * ```typescript\n * const result = await cdn.regenerateThumbnail({\n * assetId: 'video-asset-id',\n * timestamp: 5, // 5 seconds into the video\n * width: 1280,\n * format: 'jpg',\n * });\n * console.log(`Thumbnail regeneration queued: ${result.status}`);\n * ```\n */\n async regenerateThumbnail(request: RegenerateThumbnailRequest): Promise<RegenerateThumbnailResponse> {\n return this.http.post<RegenerateThumbnailResponse>(\"/cdn/video/thumbnail/regenerate\", request);\n }\n\n /**\n * Extract audio from a video file\n *\n * @example\n * ```typescript\n * const { jobId } = await cdn.extractAudio({\n * projectSlug: 'my-project',\n * assetId: 'video-asset-id',\n * format: 'mp3',\n * bitrate: 192,\n * });\n * ```\n */\n async extractAudio(request: ExtractAudioRequest): Promise<ExtractAudioResponse> {\n return this.http.post<ExtractAudioResponse>(\"/cdn/video/extract-audio\", request);\n }\n\n private convertJobDates(job: TranscodeJob): TranscodeJob {\n if (typeof job.createdAt === \"string\") {\n job.createdAt = new Date(job.createdAt);\n }\n if (job.startedAt && typeof job.startedAt === \"string\") {\n job.startedAt = new Date(job.startedAt);\n }\n if (job.completedAt && typeof job.completedAt === \"string\") {\n job.completedAt = new Date(job.completedAt);\n }\n return job;\n }\n}\n"]}
@@ -505,6 +505,25 @@ var CDN = class {
505
505
  if (request.format) params.set("format", request.format);
506
506
  return this.http.get(`/cdn/video/thumbnail/${request.assetId}?${params.toString()}`);
507
507
  }
508
+ /**
509
+ * Regenerate a thumbnail for a video (force regeneration even if one exists)
510
+ *
511
+ * Useful for retrying failed thumbnail generation or regenerating with different settings.
512
+ *
513
+ * @example
514
+ * ```typescript
515
+ * const result = await cdn.regenerateThumbnail({
516
+ * assetId: 'video-asset-id',
517
+ * timestamp: 5, // 5 seconds into the video
518
+ * width: 1280,
519
+ * format: 'jpg',
520
+ * });
521
+ * console.log(`Thumbnail regeneration queued: ${result.status}`);
522
+ * ```
523
+ */
524
+ async regenerateThumbnail(request) {
525
+ return this.http.post("/cdn/video/thumbnail/regenerate", request);
526
+ }
508
527
  /**
509
528
  * Extract audio from a video file
510
529
  *
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/http-client.ts","../../src/cdn/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * HTTP client for Stack0 API\n * Handles authentication, request/response formatting, and error handling\n */\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class HttpClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://api.stack0.dev/v1\";\n }\n\n private getHeaders(includeContentType = true): Record<string, string> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n return headers;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const bodyString = body === undefined ? undefined : JSON.stringify(body);\n const hasBody = bodyString !== undefined;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(hasBody),\n body: hasBody ? bodyString : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && \"statusCode\" in error) {\n throw error; // Re-throw our custom errors\n }\n throw this.createError(\"Network error\", error);\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorBody: { message: string } | undefined;\n try {\n errorBody = (await response.json()) as { message: string };\n } catch {\n errorBody = { message: response.statusText };\n }\n\n const error = new Error(errorBody?.message || `HTTP ${response.status}`) as Error & {\n statusCode: number;\n code: string;\n response: unknown;\n };\n error.statusCode = response.status;\n error.code = (errorBody as unknown as { code: string } | undefined)?.code ?? \"\";\n error.response = errorBody;\n throw error;\n }\n\n private createError(message: string, cause?: unknown): Error {\n const error = new Error(message) as Error & { cause: unknown };\n error.cause = cause;\n return error;\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async deleteWithBody<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"DELETE\", path, body);\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n}\n","/**\n * Stack0 CDN Client\n * Upload, manage, and transform assets\n */\n\nimport { HttpClient, type HttpClientConfig } from \"../lib/http-client\";\nimport type {\n Asset,\n UploadUrlRequest,\n UploadUrlResponse,\n UpdateAssetRequest,\n DeleteAssetsResponse,\n ListAssetsRequest,\n ListAssetsResponse,\n MoveAssetsRequest,\n MoveAssetsResponse,\n TransformOptions,\n GetFolderTreeRequest,\n FolderTreeNode,\n CreateFolderRequest,\n Folder,\n TranscodeVideoRequest,\n TranscodeJob,\n ListJobsRequest,\n ListJobsResponse,\n StreamingUrls,\n ThumbnailRequest,\n ThumbnailResponse,\n ExtractAudioRequest,\n ExtractAudioResponse,\n} from \"./types\";\n\n// Allowed widths that match the CloudFront url-rewriter configuration\nconst ALLOWED_WIDTHS = [256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840];\n\nexport class CDN {\n private http: HttpClient;\n private cdnUrl?: string;\n\n constructor(config: HttpClientConfig, cdnUrl?: string) {\n this.http = new HttpClient(config);\n this.cdnUrl = cdnUrl;\n }\n\n /**\n * Generate a presigned URL for uploading a file\n *\n * @example\n * ```typescript\n * const { uploadUrl, assetId } = await cdn.getUploadUrl({\n * projectSlug: 'my-project',\n * filename: 'image.jpg',\n * mimeType: 'image/jpeg',\n * size: 1024 * 1024,\n * });\n *\n * // Upload file to the presigned URL\n * await fetch(uploadUrl, {\n * method: 'PUT',\n * body: file,\n * headers: { 'Content-Type': 'image/jpeg' },\n * });\n *\n * // Confirm the upload\n * const asset = await cdn.confirmUpload(assetId);\n * ```\n */\n async getUploadUrl(request: UploadUrlRequest): Promise<UploadUrlResponse> {\n const response = await this.http.post<UploadUrlResponse>(\"/cdn/upload\", request);\n\n if (typeof response.expiresAt === \"string\") {\n response.expiresAt = new Date(response.expiresAt);\n }\n\n return response;\n }\n\n /**\n * Confirm that an upload has completed\n */\n async confirmUpload(assetId: string): Promise<Asset> {\n const response = await this.http.post<Asset>(`/cdn/upload/${assetId}/confirm`, {});\n return this.convertAssetDates(response);\n }\n\n /**\n * Upload a file directly (handles presigned URL flow automatically)\n *\n * @example\n * ```typescript\n * const asset = await cdn.upload({\n * projectSlug: 'my-project',\n * file: fileBuffer,\n * filename: 'image.jpg',\n * mimeType: 'image/jpeg',\n * });\n * ```\n */\n async upload(options: {\n projectSlug: string;\n file: Blob | Buffer | ArrayBuffer;\n filename: string;\n mimeType: string;\n folder?: string;\n metadata?: Record<string, unknown>;\n }): Promise<Asset> {\n const { projectSlug, file, filename, mimeType, folder, metadata } = options;\n\n // Get file size\n let size: number;\n if (file instanceof Blob) {\n size = file.size;\n } else if (file instanceof ArrayBuffer) {\n size = file.byteLength;\n } else {\n // Buffer\n size = (file as Buffer).length;\n }\n\n // Get presigned URL\n const { uploadUrl, assetId } = await this.getUploadUrl({\n projectSlug,\n filename,\n mimeType,\n size,\n folder,\n metadata,\n });\n\n // Upload file\n const uploadResponse = await fetch(uploadUrl, {\n method: \"PUT\",\n body: file,\n headers: {\n \"Content-Type\": mimeType,\n },\n });\n\n if (!uploadResponse.ok) {\n throw new Error(`Upload failed: ${uploadResponse.statusText}`);\n }\n\n // Confirm upload\n return this.confirmUpload(assetId);\n }\n\n /**\n * Get an asset by ID\n *\n * @example\n * ```typescript\n * const asset = await cdn.get('asset-id');\n * console.log(asset.cdnUrl);\n * ```\n */\n async get(id: string): Promise<Asset> {\n const response = await this.http.get<Asset>(`/cdn/assets/${id}`);\n return this.convertAssetDates(response);\n }\n\n /**\n * Update asset metadata\n *\n * @example\n * ```typescript\n * const asset = await cdn.update({\n * id: 'asset-id',\n * alt: 'A beautiful sunset',\n * tags: ['nature', 'sunset'],\n * });\n * ```\n */\n async update(request: UpdateAssetRequest): Promise<Asset> {\n const { id, ...data } = request;\n const response = await this.http.patch<Asset>(`/cdn/assets/${id}`, data);\n return this.convertAssetDates(response);\n }\n\n /**\n * Delete an asset\n *\n * @example\n * ```typescript\n * await cdn.delete('asset-id');\n * ```\n */\n async delete(id: string): Promise<{ success: boolean }> {\n // NOTE: Our OpenAPI adapter parses JSON bodies for non-GET methods.\n // Some Fastify setups will throw if Content-Type is JSON but the body is empty.\n // Sending the id in the body keeps this endpoint compatible across adapters.\n return this.http.deleteWithBody<{ success: boolean }>(`/cdn/assets/${id}`, { id });\n }\n\n /**\n * Delete multiple assets\n *\n * @example\n * ```typescript\n * const result = await cdn.deleteMany(['asset-1', 'asset-2']);\n * console.log(`Deleted ${result.deletedCount} assets`);\n * ```\n */\n async deleteMany(ids: string[]): Promise<DeleteAssetsResponse> {\n return this.http.post<DeleteAssetsResponse>(\"/cdn/assets/delete\", { ids });\n }\n\n /**\n * List assets with filters and pagination\n *\n * @example\n * ```typescript\n * const { assets, total, hasMore } = await cdn.list({\n * projectSlug: 'my-project',\n * type: 'image',\n * limit: 20,\n * });\n * ```\n */\n async list(request: ListAssetsRequest): Promise<ListAssetsResponse> {\n const params = new URLSearchParams();\n\n params.set(\"projectSlug\", request.projectSlug);\n if (request.folder !== undefined) params.set(\"folder\", request.folder ?? \"\");\n if (request.type) params.set(\"type\", request.type);\n if (request.status) params.set(\"status\", request.status);\n if (request.search) params.set(\"search\", request.search);\n if (request.tags) params.set(\"tags\", request.tags.join(\",\"));\n if (request.sortBy) params.set(\"sortBy\", request.sortBy);\n if (request.sortOrder) params.set(\"sortOrder\", request.sortOrder);\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.offset) params.set(\"offset\", request.offset.toString());\n\n const response = await this.http.get<ListAssetsResponse>(`/cdn/assets?${params.toString()}`);\n\n return {\n ...response,\n assets: response.assets.map((asset) => this.convertAssetDates(asset)),\n };\n }\n\n /**\n * Move assets to a different folder\n *\n * @example\n * ```typescript\n * await cdn.move({\n * assetIds: ['asset-1', 'asset-2'],\n * folder: '/images/archive',\n * });\n * ```\n */\n async move(request: MoveAssetsRequest): Promise<MoveAssetsResponse> {\n return this.http.post<MoveAssetsResponse>(\"/cdn/assets/move\", request);\n }\n\n /**\n * Get a transformed image URL (client-side, no API call)\n *\n * @example\n * ```typescript\n * // Using asset's cdnUrl directly\n * const url = cdn.getTransformUrl(asset.cdnUrl, {\n * width: 800,\n * height: 600,\n * fit: 'cover',\n * format: 'webp',\n * quality: 80,\n * });\n *\n * // Or using cdnUrl from SDK config + s3Key\n * const url = cdn.getTransformUrl(asset.s3Key, { width: 400 });\n * ```\n */\n getTransformUrl(assetUrlOrS3Key: string, options: TransformOptions): string {\n // Determine base URL\n let baseUrl: string;\n if (assetUrlOrS3Key.startsWith(\"http://\") || assetUrlOrS3Key.startsWith(\"https://\")) {\n // It's already a full URL - extract base and path\n const url = new URL(assetUrlOrS3Key);\n baseUrl = `${url.protocol}//${url.host}${url.pathname}`;\n } else if (this.cdnUrl) {\n // It's an s3Key, use configured CDN URL\n const cdnBase = this.cdnUrl.endsWith(\"/\") ? this.cdnUrl.slice(0, -1) : this.cdnUrl;\n baseUrl = `${cdnBase}/${assetUrlOrS3Key}`;\n } else {\n throw new Error(\"getTransformUrl requires either a full URL or cdnUrl to be configured in Stack0 options\");\n }\n\n // Build query string\n const params = this.buildTransformQuery(options);\n if (!params) {\n return baseUrl;\n }\n return `${baseUrl}?${params}`;\n }\n\n /**\n * Build transform query parameters\n */\n private buildTransformQuery(options: TransformOptions): string {\n const params = new URLSearchParams();\n\n if (options.format) params.set(\"f\", options.format);\n if (options.quality !== undefined) params.set(\"q\", options.quality.toString());\n\n if (options.width !== undefined) {\n // Snap to nearest allowed width for better caching\n const width = this.getNearestWidth(options.width);\n params.set(\"w\", width.toString());\n }\n if (options.height !== undefined) params.set(\"h\", options.height.toString());\n if (options.fit) params.set(\"fit\", options.fit);\n if (options.crop) params.set(\"crop\", options.crop);\n if (options.cropX !== undefined) params.set(\"crop-x\", options.cropX.toString());\n if (options.cropY !== undefined) params.set(\"crop-y\", options.cropY.toString());\n if (options.cropWidth !== undefined) params.set(\"crop-w\", options.cropWidth.toString());\n if (options.cropHeight !== undefined) params.set(\"crop-h\", options.cropHeight.toString());\n if (options.blur !== undefined) params.set(\"blur\", options.blur.toString());\n if (options.sharpen !== undefined) params.set(\"sharpen\", options.sharpen.toString());\n if (options.brightness !== undefined) params.set(\"brightness\", options.brightness.toString());\n if (options.saturation !== undefined) params.set(\"saturation\", options.saturation.toString());\n if (options.grayscale) params.set(\"grayscale\", \"true\");\n if (options.rotate !== undefined) params.set(\"rotate\", options.rotate.toString());\n if (options.flip) params.set(\"flip\", \"y\");\n if (options.flop) params.set(\"flop\", \"x\");\n\n return params.toString();\n }\n\n /**\n * Find the nearest allowed width for optimal caching\n */\n private getNearestWidth(width: number): number {\n return ALLOWED_WIDTHS.reduce((prev, curr) => (Math.abs(curr - width) < Math.abs(prev - width) ? curr : prev));\n }\n\n /**\n * Get folder tree for navigation\n *\n * @example\n * ```typescript\n * const tree = await cdn.getFolderTree({\n * projectSlug: 'my-project',\n * maxDepth: 3,\n * });\n * ```\n */\n async getFolderTree(request: GetFolderTreeRequest): Promise<FolderTreeNode[]> {\n const params = new URLSearchParams();\n params.set(\"projectSlug\", request.projectSlug);\n if (request.maxDepth) params.set(\"maxDepth\", request.maxDepth.toString());\n\n const response = await this.http.get<{ tree: FolderTreeNode[] }>(`/cdn/folders/tree?${params.toString()}`);\n return response.tree;\n }\n\n /**\n * Create a new folder\n *\n * @example\n * ```typescript\n * const folder = await cdn.createFolder({\n * projectSlug: 'my-project',\n * name: 'images',\n * });\n * ```\n */\n async createFolder(request: CreateFolderRequest): Promise<Folder> {\n const response = await this.http.post<Folder>(\"/cdn/folders\", request);\n return this.convertFolderDates(response);\n }\n\n /**\n * Delete a folder\n *\n * @example\n * ```typescript\n * await cdn.deleteFolder('folder-id');\n * ```\n */\n async deleteFolder(id: string, deleteContents = false): Promise<{ success: boolean }> {\n const params = new URLSearchParams();\n if (deleteContents) params.set(\"deleteContents\", \"true\");\n\n return this.http.deleteWithBody<{ success: boolean }>(`/cdn/folders/${id}?${params.toString()}`, {\n id,\n deleteContents,\n });\n }\n\n private convertAssetDates(asset: Asset): Asset {\n if (typeof asset.createdAt === \"string\") {\n asset.createdAt = new Date(asset.createdAt);\n }\n if (asset.updatedAt && typeof asset.updatedAt === \"string\") {\n asset.updatedAt = new Date(asset.updatedAt);\n }\n return asset;\n }\n\n private convertFolderDates(folder: Folder): Folder {\n if (typeof folder.createdAt === \"string\") {\n folder.createdAt = new Date(folder.createdAt);\n }\n if (folder.updatedAt && typeof folder.updatedAt === \"string\") {\n folder.updatedAt = new Date(folder.updatedAt);\n }\n return folder;\n }\n\n // ============================================================================\n // Video Transcoding Methods\n // ============================================================================\n\n /**\n * Start a video transcoding job\n *\n * @example\n * ```typescript\n * const job = await cdn.transcode({\n * projectSlug: 'my-project',\n * assetId: 'video-asset-id',\n * outputFormat: 'hls',\n * variants: [\n * { quality: '720p', codec: 'h264' },\n * { quality: '1080p', codec: 'h264' },\n * ],\n * webhookUrl: 'https://your-app.com/webhook',\n * });\n * console.log(`Job started: ${job.id}`);\n * ```\n */\n async transcode(request: TranscodeVideoRequest): Promise<TranscodeJob> {\n const response = await this.http.post<TranscodeJob>(\"/cdn/video/transcode\", request);\n return this.convertJobDates(response);\n }\n\n /**\n * Get a transcoding job by ID\n *\n * @example\n * ```typescript\n * const job = await cdn.getJob('job-id');\n * console.log(`Status: ${job.status}, Progress: ${job.progress}%`);\n * ```\n */\n async getJob(jobId: string): Promise<TranscodeJob> {\n const response = await this.http.get<TranscodeJob>(`/cdn/video/jobs/${jobId}`);\n return this.convertJobDates(response);\n }\n\n /**\n * List transcoding jobs with filters\n *\n * @example\n * ```typescript\n * const { jobs, total } = await cdn.listJobs({\n * projectSlug: 'my-project',\n * status: 'processing',\n * limit: 20,\n * });\n * ```\n */\n async listJobs(request: ListJobsRequest): Promise<ListJobsResponse> {\n const params = new URLSearchParams();\n params.set(\"projectSlug\", request.projectSlug);\n if (request.assetId) params.set(\"assetId\", request.assetId);\n if (request.status) params.set(\"status\", request.status);\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.offset) params.set(\"offset\", request.offset.toString());\n\n const response = await this.http.get<ListJobsResponse>(`/cdn/video/jobs?${params.toString()}`);\n return {\n ...response,\n jobs: response.jobs.map((job) => this.convertJobDates(job)),\n };\n }\n\n /**\n * Cancel a pending or processing transcoding job\n *\n * @example\n * ```typescript\n * await cdn.cancelJob('job-id');\n * ```\n */\n async cancelJob(jobId: string): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/cdn/video/jobs/${jobId}/cancel`, {});\n }\n\n /**\n * Get streaming URLs for a transcoded video\n *\n * @example\n * ```typescript\n * const urls = await cdn.getStreamingUrls('asset-id');\n * console.log(`HLS URL: ${urls.hlsUrl}`);\n * console.log(`MP4 720p: ${urls.mp4Urls.find(u => u.quality === '720p')?.url}`);\n * ```\n */\n async getStreamingUrls(assetId: string): Promise<StreamingUrls> {\n return this.http.get<StreamingUrls>(`/cdn/video/stream/${assetId}`);\n }\n\n /**\n * Generate a thumbnail from a video at a specific timestamp\n *\n * @example\n * ```typescript\n * const thumbnail = await cdn.getThumbnail({\n * assetId: 'video-asset-id',\n * timestamp: 10.5, // 10.5 seconds into the video\n * width: 320,\n * format: 'webp',\n * });\n * console.log(`Thumbnail URL: ${thumbnail.url}`);\n * ```\n */\n async getThumbnail(request: ThumbnailRequest): Promise<ThumbnailResponse> {\n const params = new URLSearchParams();\n params.set(\"timestamp\", request.timestamp.toString());\n if (request.width) params.set(\"width\", request.width.toString());\n if (request.format) params.set(\"format\", request.format);\n\n return this.http.get<ThumbnailResponse>(`/cdn/video/thumbnail/${request.assetId}?${params.toString()}`);\n }\n\n /**\n * Extract audio from a video file\n *\n * @example\n * ```typescript\n * const { jobId } = await cdn.extractAudio({\n * projectSlug: 'my-project',\n * assetId: 'video-asset-id',\n * format: 'mp3',\n * bitrate: 192,\n * });\n * ```\n */\n async extractAudio(request: ExtractAudioRequest): Promise<ExtractAudioResponse> {\n return this.http.post<ExtractAudioResponse>(\"/cdn/video/extract-audio\", request);\n }\n\n private convertJobDates(job: TranscodeJob): TranscodeJob {\n if (typeof job.createdAt === \"string\") {\n job.createdAt = new Date(job.createdAt);\n }\n if (job.startedAt && typeof job.startedAt === \"string\") {\n job.startedAt = new Date(job.startedAt);\n }\n if (job.completedAt && typeof job.completedAt === \"string\") {\n job.completedAt = new Date(job.completedAt);\n }\n return job;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/lib/http-client.ts","../../src/cdn/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * HTTP client for Stack0 API\n * Handles authentication, request/response formatting, and error handling\n */\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class HttpClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://api.stack0.dev/v1\";\n }\n\n private getHeaders(includeContentType = true): Record<string, string> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n return headers;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const bodyString = body === undefined ? undefined : JSON.stringify(body);\n const hasBody = bodyString !== undefined;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(hasBody),\n body: hasBody ? bodyString : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && \"statusCode\" in error) {\n throw error; // Re-throw our custom errors\n }\n throw this.createError(\"Network error\", error);\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorBody: { message: string } | undefined;\n try {\n errorBody = (await response.json()) as { message: string };\n } catch {\n errorBody = { message: response.statusText };\n }\n\n const error = new Error(errorBody?.message || `HTTP ${response.status}`) as Error & {\n statusCode: number;\n code: string;\n response: unknown;\n };\n error.statusCode = response.status;\n error.code = (errorBody as unknown as { code: string } | undefined)?.code ?? \"\";\n error.response = errorBody;\n throw error;\n }\n\n private createError(message: string, cause?: unknown): Error {\n const error = new Error(message) as Error & { cause: unknown };\n error.cause = cause;\n return error;\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async deleteWithBody<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"DELETE\", path, body);\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n}\n","/**\n * Stack0 CDN Client\n * Upload, manage, and transform assets\n */\n\nimport { HttpClient, type HttpClientConfig } from \"../lib/http-client\";\nimport type {\n Asset,\n UploadUrlRequest,\n UploadUrlResponse,\n UpdateAssetRequest,\n DeleteAssetsResponse,\n ListAssetsRequest,\n ListAssetsResponse,\n MoveAssetsRequest,\n MoveAssetsResponse,\n TransformOptions,\n GetFolderTreeRequest,\n FolderTreeNode,\n CreateFolderRequest,\n Folder,\n TranscodeVideoRequest,\n TranscodeJob,\n ListJobsRequest,\n ListJobsResponse,\n StreamingUrls,\n ThumbnailRequest,\n ThumbnailResponse,\n RegenerateThumbnailRequest,\n RegenerateThumbnailResponse,\n ExtractAudioRequest,\n ExtractAudioResponse,\n} from \"./types\";\n\n// Allowed widths that match the CloudFront url-rewriter configuration\nconst ALLOWED_WIDTHS = [256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840];\n\nexport class CDN {\n private http: HttpClient;\n private cdnUrl?: string;\n\n constructor(config: HttpClientConfig, cdnUrl?: string) {\n this.http = new HttpClient(config);\n this.cdnUrl = cdnUrl;\n }\n\n /**\n * Generate a presigned URL for uploading a file\n *\n * @example\n * ```typescript\n * const { uploadUrl, assetId } = await cdn.getUploadUrl({\n * projectSlug: 'my-project',\n * filename: 'image.jpg',\n * mimeType: 'image/jpeg',\n * size: 1024 * 1024,\n * });\n *\n * // Upload file to the presigned URL\n * await fetch(uploadUrl, {\n * method: 'PUT',\n * body: file,\n * headers: { 'Content-Type': 'image/jpeg' },\n * });\n *\n * // Confirm the upload\n * const asset = await cdn.confirmUpload(assetId);\n * ```\n */\n async getUploadUrl(request: UploadUrlRequest): Promise<UploadUrlResponse> {\n const response = await this.http.post<UploadUrlResponse>(\"/cdn/upload\", request);\n\n if (typeof response.expiresAt === \"string\") {\n response.expiresAt = new Date(response.expiresAt);\n }\n\n return response;\n }\n\n /**\n * Confirm that an upload has completed\n */\n async confirmUpload(assetId: string): Promise<Asset> {\n const response = await this.http.post<Asset>(`/cdn/upload/${assetId}/confirm`, {});\n return this.convertAssetDates(response);\n }\n\n /**\n * Upload a file directly (handles presigned URL flow automatically)\n *\n * @example\n * ```typescript\n * const asset = await cdn.upload({\n * projectSlug: 'my-project',\n * file: fileBuffer,\n * filename: 'image.jpg',\n * mimeType: 'image/jpeg',\n * });\n * ```\n */\n async upload(options: {\n projectSlug: string;\n file: Blob | Buffer | ArrayBuffer;\n filename: string;\n mimeType: string;\n folder?: string;\n metadata?: Record<string, unknown>;\n }): Promise<Asset> {\n const { projectSlug, file, filename, mimeType, folder, metadata } = options;\n\n // Get file size\n let size: number;\n if (file instanceof Blob) {\n size = file.size;\n } else if (file instanceof ArrayBuffer) {\n size = file.byteLength;\n } else {\n // Buffer\n size = (file as Buffer).length;\n }\n\n // Get presigned URL\n const { uploadUrl, assetId } = await this.getUploadUrl({\n projectSlug,\n filename,\n mimeType,\n size,\n folder,\n metadata,\n });\n\n // Upload file\n const uploadResponse = await fetch(uploadUrl, {\n method: \"PUT\",\n body: file,\n headers: {\n \"Content-Type\": mimeType,\n },\n });\n\n if (!uploadResponse.ok) {\n throw new Error(`Upload failed: ${uploadResponse.statusText}`);\n }\n\n // Confirm upload\n return this.confirmUpload(assetId);\n }\n\n /**\n * Get an asset by ID\n *\n * @example\n * ```typescript\n * const asset = await cdn.get('asset-id');\n * console.log(asset.cdnUrl);\n * ```\n */\n async get(id: string): Promise<Asset> {\n const response = await this.http.get<Asset>(`/cdn/assets/${id}`);\n return this.convertAssetDates(response);\n }\n\n /**\n * Update asset metadata\n *\n * @example\n * ```typescript\n * const asset = await cdn.update({\n * id: 'asset-id',\n * alt: 'A beautiful sunset',\n * tags: ['nature', 'sunset'],\n * });\n * ```\n */\n async update(request: UpdateAssetRequest): Promise<Asset> {\n const { id, ...data } = request;\n const response = await this.http.patch<Asset>(`/cdn/assets/${id}`, data);\n return this.convertAssetDates(response);\n }\n\n /**\n * Delete an asset\n *\n * @example\n * ```typescript\n * await cdn.delete('asset-id');\n * ```\n */\n async delete(id: string): Promise<{ success: boolean }> {\n // NOTE: Our OpenAPI adapter parses JSON bodies for non-GET methods.\n // Some Fastify setups will throw if Content-Type is JSON but the body is empty.\n // Sending the id in the body keeps this endpoint compatible across adapters.\n return this.http.deleteWithBody<{ success: boolean }>(`/cdn/assets/${id}`, { id });\n }\n\n /**\n * Delete multiple assets\n *\n * @example\n * ```typescript\n * const result = await cdn.deleteMany(['asset-1', 'asset-2']);\n * console.log(`Deleted ${result.deletedCount} assets`);\n * ```\n */\n async deleteMany(ids: string[]): Promise<DeleteAssetsResponse> {\n return this.http.post<DeleteAssetsResponse>(\"/cdn/assets/delete\", { ids });\n }\n\n /**\n * List assets with filters and pagination\n *\n * @example\n * ```typescript\n * const { assets, total, hasMore } = await cdn.list({\n * projectSlug: 'my-project',\n * type: 'image',\n * limit: 20,\n * });\n * ```\n */\n async list(request: ListAssetsRequest): Promise<ListAssetsResponse> {\n const params = new URLSearchParams();\n\n params.set(\"projectSlug\", request.projectSlug);\n if (request.folder !== undefined) params.set(\"folder\", request.folder ?? \"\");\n if (request.type) params.set(\"type\", request.type);\n if (request.status) params.set(\"status\", request.status);\n if (request.search) params.set(\"search\", request.search);\n if (request.tags) params.set(\"tags\", request.tags.join(\",\"));\n if (request.sortBy) params.set(\"sortBy\", request.sortBy);\n if (request.sortOrder) params.set(\"sortOrder\", request.sortOrder);\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.offset) params.set(\"offset\", request.offset.toString());\n\n const response = await this.http.get<ListAssetsResponse>(`/cdn/assets?${params.toString()}`);\n\n return {\n ...response,\n assets: response.assets.map((asset) => this.convertAssetDates(asset)),\n };\n }\n\n /**\n * Move assets to a different folder\n *\n * @example\n * ```typescript\n * await cdn.move({\n * assetIds: ['asset-1', 'asset-2'],\n * folder: '/images/archive',\n * });\n * ```\n */\n async move(request: MoveAssetsRequest): Promise<MoveAssetsResponse> {\n return this.http.post<MoveAssetsResponse>(\"/cdn/assets/move\", request);\n }\n\n /**\n * Get a transformed image URL (client-side, no API call)\n *\n * @example\n * ```typescript\n * // Using asset's cdnUrl directly\n * const url = cdn.getTransformUrl(asset.cdnUrl, {\n * width: 800,\n * height: 600,\n * fit: 'cover',\n * format: 'webp',\n * quality: 80,\n * });\n *\n * // Or using cdnUrl from SDK config + s3Key\n * const url = cdn.getTransformUrl(asset.s3Key, { width: 400 });\n * ```\n */\n getTransformUrl(assetUrlOrS3Key: string, options: TransformOptions): string {\n // Determine base URL\n let baseUrl: string;\n if (assetUrlOrS3Key.startsWith(\"http://\") || assetUrlOrS3Key.startsWith(\"https://\")) {\n // It's already a full URL - extract base and path\n const url = new URL(assetUrlOrS3Key);\n baseUrl = `${url.protocol}//${url.host}${url.pathname}`;\n } else if (this.cdnUrl) {\n // It's an s3Key, use configured CDN URL\n const cdnBase = this.cdnUrl.endsWith(\"/\") ? this.cdnUrl.slice(0, -1) : this.cdnUrl;\n baseUrl = `${cdnBase}/${assetUrlOrS3Key}`;\n } else {\n throw new Error(\"getTransformUrl requires either a full URL or cdnUrl to be configured in Stack0 options\");\n }\n\n // Build query string\n const params = this.buildTransformQuery(options);\n if (!params) {\n return baseUrl;\n }\n return `${baseUrl}?${params}`;\n }\n\n /**\n * Build transform query parameters\n */\n private buildTransformQuery(options: TransformOptions): string {\n const params = new URLSearchParams();\n\n if (options.format) params.set(\"f\", options.format);\n if (options.quality !== undefined) params.set(\"q\", options.quality.toString());\n\n if (options.width !== undefined) {\n // Snap to nearest allowed width for better caching\n const width = this.getNearestWidth(options.width);\n params.set(\"w\", width.toString());\n }\n if (options.height !== undefined) params.set(\"h\", options.height.toString());\n if (options.fit) params.set(\"fit\", options.fit);\n if (options.crop) params.set(\"crop\", options.crop);\n if (options.cropX !== undefined) params.set(\"crop-x\", options.cropX.toString());\n if (options.cropY !== undefined) params.set(\"crop-y\", options.cropY.toString());\n if (options.cropWidth !== undefined) params.set(\"crop-w\", options.cropWidth.toString());\n if (options.cropHeight !== undefined) params.set(\"crop-h\", options.cropHeight.toString());\n if (options.blur !== undefined) params.set(\"blur\", options.blur.toString());\n if (options.sharpen !== undefined) params.set(\"sharpen\", options.sharpen.toString());\n if (options.brightness !== undefined) params.set(\"brightness\", options.brightness.toString());\n if (options.saturation !== undefined) params.set(\"saturation\", options.saturation.toString());\n if (options.grayscale) params.set(\"grayscale\", \"true\");\n if (options.rotate !== undefined) params.set(\"rotate\", options.rotate.toString());\n if (options.flip) params.set(\"flip\", \"y\");\n if (options.flop) params.set(\"flop\", \"x\");\n\n return params.toString();\n }\n\n /**\n * Find the nearest allowed width for optimal caching\n */\n private getNearestWidth(width: number): number {\n return ALLOWED_WIDTHS.reduce((prev, curr) => (Math.abs(curr - width) < Math.abs(prev - width) ? curr : prev));\n }\n\n /**\n * Get folder tree for navigation\n *\n * @example\n * ```typescript\n * const tree = await cdn.getFolderTree({\n * projectSlug: 'my-project',\n * maxDepth: 3,\n * });\n * ```\n */\n async getFolderTree(request: GetFolderTreeRequest): Promise<FolderTreeNode[]> {\n const params = new URLSearchParams();\n params.set(\"projectSlug\", request.projectSlug);\n if (request.maxDepth) params.set(\"maxDepth\", request.maxDepth.toString());\n\n const response = await this.http.get<{ tree: FolderTreeNode[] }>(`/cdn/folders/tree?${params.toString()}`);\n return response.tree;\n }\n\n /**\n * Create a new folder\n *\n * @example\n * ```typescript\n * const folder = await cdn.createFolder({\n * projectSlug: 'my-project',\n * name: 'images',\n * });\n * ```\n */\n async createFolder(request: CreateFolderRequest): Promise<Folder> {\n const response = await this.http.post<Folder>(\"/cdn/folders\", request);\n return this.convertFolderDates(response);\n }\n\n /**\n * Delete a folder\n *\n * @example\n * ```typescript\n * await cdn.deleteFolder('folder-id');\n * ```\n */\n async deleteFolder(id: string, deleteContents = false): Promise<{ success: boolean }> {\n const params = new URLSearchParams();\n if (deleteContents) params.set(\"deleteContents\", \"true\");\n\n return this.http.deleteWithBody<{ success: boolean }>(`/cdn/folders/${id}?${params.toString()}`, {\n id,\n deleteContents,\n });\n }\n\n private convertAssetDates(asset: Asset): Asset {\n if (typeof asset.createdAt === \"string\") {\n asset.createdAt = new Date(asset.createdAt);\n }\n if (asset.updatedAt && typeof asset.updatedAt === \"string\") {\n asset.updatedAt = new Date(asset.updatedAt);\n }\n return asset;\n }\n\n private convertFolderDates(folder: Folder): Folder {\n if (typeof folder.createdAt === \"string\") {\n folder.createdAt = new Date(folder.createdAt);\n }\n if (folder.updatedAt && typeof folder.updatedAt === \"string\") {\n folder.updatedAt = new Date(folder.updatedAt);\n }\n return folder;\n }\n\n // ============================================================================\n // Video Transcoding Methods\n // ============================================================================\n\n /**\n * Start a video transcoding job\n *\n * @example\n * ```typescript\n * const job = await cdn.transcode({\n * projectSlug: 'my-project',\n * assetId: 'video-asset-id',\n * outputFormat: 'hls',\n * variants: [\n * { quality: '720p', codec: 'h264' },\n * { quality: '1080p', codec: 'h264' },\n * ],\n * webhookUrl: 'https://your-app.com/webhook',\n * });\n * console.log(`Job started: ${job.id}`);\n * ```\n */\n async transcode(request: TranscodeVideoRequest): Promise<TranscodeJob> {\n const response = await this.http.post<TranscodeJob>(\"/cdn/video/transcode\", request);\n return this.convertJobDates(response);\n }\n\n /**\n * Get a transcoding job by ID\n *\n * @example\n * ```typescript\n * const job = await cdn.getJob('job-id');\n * console.log(`Status: ${job.status}, Progress: ${job.progress}%`);\n * ```\n */\n async getJob(jobId: string): Promise<TranscodeJob> {\n const response = await this.http.get<TranscodeJob>(`/cdn/video/jobs/${jobId}`);\n return this.convertJobDates(response);\n }\n\n /**\n * List transcoding jobs with filters\n *\n * @example\n * ```typescript\n * const { jobs, total } = await cdn.listJobs({\n * projectSlug: 'my-project',\n * status: 'processing',\n * limit: 20,\n * });\n * ```\n */\n async listJobs(request: ListJobsRequest): Promise<ListJobsResponse> {\n const params = new URLSearchParams();\n params.set(\"projectSlug\", request.projectSlug);\n if (request.assetId) params.set(\"assetId\", request.assetId);\n if (request.status) params.set(\"status\", request.status);\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.offset) params.set(\"offset\", request.offset.toString());\n\n const response = await this.http.get<ListJobsResponse>(`/cdn/video/jobs?${params.toString()}`);\n return {\n ...response,\n jobs: response.jobs.map((job) => this.convertJobDates(job)),\n };\n }\n\n /**\n * Cancel a pending or processing transcoding job\n *\n * @example\n * ```typescript\n * await cdn.cancelJob('job-id');\n * ```\n */\n async cancelJob(jobId: string): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/cdn/video/jobs/${jobId}/cancel`, {});\n }\n\n /**\n * Get streaming URLs for a transcoded video\n *\n * @example\n * ```typescript\n * const urls = await cdn.getStreamingUrls('asset-id');\n * console.log(`HLS URL: ${urls.hlsUrl}`);\n * console.log(`MP4 720p: ${urls.mp4Urls.find(u => u.quality === '720p')?.url}`);\n * ```\n */\n async getStreamingUrls(assetId: string): Promise<StreamingUrls> {\n return this.http.get<StreamingUrls>(`/cdn/video/stream/${assetId}`);\n }\n\n /**\n * Generate a thumbnail from a video at a specific timestamp\n *\n * @example\n * ```typescript\n * const thumbnail = await cdn.getThumbnail({\n * assetId: 'video-asset-id',\n * timestamp: 10.5, // 10.5 seconds into the video\n * width: 320,\n * format: 'webp',\n * });\n * console.log(`Thumbnail URL: ${thumbnail.url}`);\n * ```\n */\n async getThumbnail(request: ThumbnailRequest): Promise<ThumbnailResponse> {\n const params = new URLSearchParams();\n params.set(\"timestamp\", request.timestamp.toString());\n if (request.width) params.set(\"width\", request.width.toString());\n if (request.format) params.set(\"format\", request.format);\n\n return this.http.get<ThumbnailResponse>(`/cdn/video/thumbnail/${request.assetId}?${params.toString()}`);\n }\n\n /**\n * Regenerate a thumbnail for a video (force regeneration even if one exists)\n *\n * Useful for retrying failed thumbnail generation or regenerating with different settings.\n *\n * @example\n * ```typescript\n * const result = await cdn.regenerateThumbnail({\n * assetId: 'video-asset-id',\n * timestamp: 5, // 5 seconds into the video\n * width: 1280,\n * format: 'jpg',\n * });\n * console.log(`Thumbnail regeneration queued: ${result.status}`);\n * ```\n */\n async regenerateThumbnail(request: RegenerateThumbnailRequest): Promise<RegenerateThumbnailResponse> {\n return this.http.post<RegenerateThumbnailResponse>(\"/cdn/video/thumbnail/regenerate\", request);\n }\n\n /**\n * Extract audio from a video file\n *\n * @example\n * ```typescript\n * const { jobId } = await cdn.extractAudio({\n * projectSlug: 'my-project',\n * assetId: 'video-asset-id',\n * format: 'mp3',\n * bitrate: 192,\n * });\n * ```\n */\n async extractAudio(request: ExtractAudioRequest): Promise<ExtractAudioResponse> {\n return this.http.post<ExtractAudioResponse>(\"/cdn/video/extract-audio\", request);\n }\n\n private convertJobDates(job: TranscodeJob): TranscodeJob {\n if (typeof job.createdAt === \"string\") {\n job.createdAt = new Date(job.createdAt);\n }\n if (job.startedAt && typeof job.startedAt === \"string\") {\n job.startedAt = new Date(job.startedAt);\n }\n if (job.completedAt && typeof job.completedAt === \"string\") {\n job.completedAt = new Date(job.completedAt);\n }\n return job;\n }\n}\n"]}
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Mail } from './mail/index.mjs';
2
2
  export { Attachment, EmailAddress, EmailRecipient, GetEmailResponse, SendEmailRequest, SendEmailResponse, Stack0Error } from './mail/index.mjs';
3
3
  import { CDN } from './cdn/index.mjs';
4
- export { Asset, AssetStatus, AssetType, ConfirmUploadRequest, ConfirmUploadResponse, CreateFolderRequest, DeleteAssetRequest, DeleteAssetsRequest, DeleteAssetsResponse, ExtractAudioRequest, ExtractAudioResponse, Folder, FolderTreeNode, GetAssetRequest, GetFolderTreeRequest, ListAssetsRequest, ListAssetsResponse, ListJobsRequest, ListJobsResponse, MoveAssetsRequest, MoveAssetsResponse, StreamingUrls, ThumbnailRequest, ThumbnailResponse, TranscodeJob, TranscodeVideoRequest, TranscodingStatus, TransformOptions, TrimOptions, UpdateAssetRequest, UploadUrlRequest, UploadUrlResponse, VideoCodec, VideoOutputFormat, VideoQuality, VideoVariant, WatermarkOptions } from './cdn/index.mjs';
4
+ export { Asset, AssetStatus, AssetType, ConfirmUploadRequest, ConfirmUploadResponse, CreateFolderRequest, DeleteAssetRequest, DeleteAssetsRequest, DeleteAssetsResponse, ExtractAudioRequest, ExtractAudioResponse, Folder, FolderTreeNode, GetAssetRequest, GetFolderTreeRequest, ListAssetsRequest, ListAssetsResponse, ListJobsRequest, ListJobsResponse, MoveAssetsRequest, MoveAssetsResponse, RegenerateThumbnailRequest, RegenerateThumbnailResponse, StreamingUrls, ThumbnailRequest, ThumbnailResponse, TranscodeJob, TranscodeVideoRequest, TranscodingStatus, TransformOptions, TrimOptions, UpdateAssetRequest, UploadUrlRequest, UploadUrlResponse, VideoCodec, VideoOutputFormat, VideoQuality, VideoVariant, WatermarkOptions } from './cdn/index.mjs';
5
5
  import { Screenshots } from './screenshots/index.mjs';
6
6
  export { BatchScreenshotJob, Clip, CreateBatchScreenshotsRequest, CreateScreenshotRequest, CreateScreenshotResponse, CreateScreenshotScheduleRequest, DeviceType, GetScreenshotRequest, ListScreenshotsRequest, ListScreenshotsResponse, ResourceType, Screenshot, ScreenshotBatchJobsResponse, ScreenshotFormat, ScreenshotSchedule, ScreenshotSchedulesResponse, ScreenshotStatus, UpdateScreenshotScheduleRequest } from './screenshots/index.mjs';
7
7
  import { Extraction } from './extraction/index.mjs';
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Mail } from './mail/index.js';
2
2
  export { Attachment, EmailAddress, EmailRecipient, GetEmailResponse, SendEmailRequest, SendEmailResponse, Stack0Error } from './mail/index.js';
3
3
  import { CDN } from './cdn/index.js';
4
- export { Asset, AssetStatus, AssetType, ConfirmUploadRequest, ConfirmUploadResponse, CreateFolderRequest, DeleteAssetRequest, DeleteAssetsRequest, DeleteAssetsResponse, ExtractAudioRequest, ExtractAudioResponse, Folder, FolderTreeNode, GetAssetRequest, GetFolderTreeRequest, ListAssetsRequest, ListAssetsResponse, ListJobsRequest, ListJobsResponse, MoveAssetsRequest, MoveAssetsResponse, StreamingUrls, ThumbnailRequest, ThumbnailResponse, TranscodeJob, TranscodeVideoRequest, TranscodingStatus, TransformOptions, TrimOptions, UpdateAssetRequest, UploadUrlRequest, UploadUrlResponse, VideoCodec, VideoOutputFormat, VideoQuality, VideoVariant, WatermarkOptions } from './cdn/index.js';
4
+ export { Asset, AssetStatus, AssetType, ConfirmUploadRequest, ConfirmUploadResponse, CreateFolderRequest, DeleteAssetRequest, DeleteAssetsRequest, DeleteAssetsResponse, ExtractAudioRequest, ExtractAudioResponse, Folder, FolderTreeNode, GetAssetRequest, GetFolderTreeRequest, ListAssetsRequest, ListAssetsResponse, ListJobsRequest, ListJobsResponse, MoveAssetsRequest, MoveAssetsResponse, RegenerateThumbnailRequest, RegenerateThumbnailResponse, StreamingUrls, ThumbnailRequest, ThumbnailResponse, TranscodeJob, TranscodeVideoRequest, TranscodingStatus, TransformOptions, TrimOptions, UpdateAssetRequest, UploadUrlRequest, UploadUrlResponse, VideoCodec, VideoOutputFormat, VideoQuality, VideoVariant, WatermarkOptions } from './cdn/index.js';
5
5
  import { Screenshots } from './screenshots/index.js';
6
6
  export { BatchScreenshotJob, Clip, CreateBatchScreenshotsRequest, CreateScreenshotRequest, CreateScreenshotResponse, CreateScreenshotScheduleRequest, DeviceType, GetScreenshotRequest, ListScreenshotsRequest, ListScreenshotsResponse, ResourceType, Screenshot, ScreenshotBatchJobsResponse, ScreenshotFormat, ScreenshotSchedule, ScreenshotSchedulesResponse, ScreenshotStatus, UpdateScreenshotScheduleRequest } from './screenshots/index.js';
7
7
  import { Extraction } from './extraction/index.js';
package/dist/index.js CHANGED
@@ -556,6 +556,25 @@ var CDN = class {
556
556
  if (request.format) params.set("format", request.format);
557
557
  return this.http.get(`/cdn/video/thumbnail/${request.assetId}?${params.toString()}`);
558
558
  }
559
+ /**
560
+ * Regenerate a thumbnail for a video (force regeneration even if one exists)
561
+ *
562
+ * Useful for retrying failed thumbnail generation or regenerating with different settings.
563
+ *
564
+ * @example
565
+ * ```typescript
566
+ * const result = await cdn.regenerateThumbnail({
567
+ * assetId: 'video-asset-id',
568
+ * timestamp: 5, // 5 seconds into the video
569
+ * width: 1280,
570
+ * format: 'jpg',
571
+ * });
572
+ * console.log(`Thumbnail regeneration queued: ${result.status}`);
573
+ * ```
574
+ */
575
+ async regenerateThumbnail(request) {
576
+ return this.http.post("/cdn/video/thumbnail/regenerate", request);
577
+ }
559
578
  /**
560
579
  * Extract audio from a video file
561
580
  *