@stack0/sdk 0.2.4 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cdn/index.js CHANGED
@@ -64,6 +64,9 @@ var HttpClient = class {
64
64
  async delete(path) {
65
65
  return this.request("DELETE", path);
66
66
  }
67
+ async patch(path, body) {
68
+ return this.request("PATCH", path, body);
69
+ }
67
70
  };
68
71
 
69
72
  // src/cdn/client.ts
@@ -96,7 +99,7 @@ var CDN = class {
96
99
  * ```
97
100
  */
98
101
  async getUploadUrl(request) {
99
- const response = await this.http.post("/cdn/assets/upload-url", request);
102
+ const response = await this.http.post("/cdn/upload", request);
100
103
  if (typeof response.expiresAt === "string") {
101
104
  response.expiresAt = new Date(response.expiresAt);
102
105
  }
@@ -106,8 +109,9 @@ var CDN = class {
106
109
  * Confirm that an upload has completed
107
110
  */
108
111
  async confirmUpload(assetId) {
109
- const response = await this.http.post("/cdn/assets/confirm", { assetId });
110
- return this.convertAssetDates(response.asset);
112
+ const response = await this.http.post(`/cdn/upload/${assetId}/confirm`, {});
113
+ console.log("confirm upload response", response);
114
+ return this.convertAssetDates(response);
111
115
  }
112
116
  /**
113
117
  * Upload a file directly (handles presigned URL flow automatically)
@@ -179,7 +183,7 @@ var CDN = class {
179
183
  */
180
184
  async update(request) {
181
185
  const { id, ...data } = request;
182
- const response = await this.http.put(`/cdn/assets/${id}`, data);
186
+ const response = await this.http.patch(`/cdn/assets/${id}`, data);
183
187
  return this.convertAssetDates(response);
184
188
  }
185
189
  /**
@@ -203,7 +207,7 @@ var CDN = class {
203
207
  * ```
204
208
  */
205
209
  async deleteMany(ids) {
206
- return this.http.post("/cdn/assets/delete-many", { ids });
210
+ return this.http.post("/cdn/assets/delete", { ids });
207
211
  }
208
212
  /**
209
213
  * List assets with filters and pagination
@@ -267,15 +271,7 @@ var CDN = class {
267
271
  * ```
268
272
  */
269
273
  async getTransformUrl(request) {
270
- const params = new URLSearchParams();
271
- params.set("assetId", request.assetId);
272
- const { options } = request;
273
- if (options.width) params.set("width", options.width.toString());
274
- if (options.height) params.set("height", options.height.toString());
275
- if (options.fit) params.set("fit", options.fit);
276
- if (options.format) params.set("format", options.format);
277
- if (options.quality) params.set("quality", options.quality.toString());
278
- return this.http.get(`/cdn/assets/transform?${params.toString()}`);
274
+ return this.http.post("/cdn/transform", request);
279
275
  }
280
276
  /**
281
277
  * Get folder tree for navigation
@@ -292,7 +288,8 @@ var CDN = class {
292
288
  const params = new URLSearchParams();
293
289
  params.set("projectSlug", request.projectSlug);
294
290
  if (request.maxDepth) params.set("maxDepth", request.maxDepth.toString());
295
- return this.http.get(`/cdn/folders/tree?${params.toString()}`);
291
+ const response = await this.http.get(`/cdn/folders/tree?${params.toString()}`);
292
+ return response.tree;
296
293
  }
297
294
  /**
298
295
  * Create a new folder
@@ -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(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(),\n body: body ? JSON.stringify(body) : 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","/**\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 ConfirmUploadResponse,\n UpdateAssetRequest,\n DeleteAssetsResponse,\n ListAssetsRequest,\n ListAssetsResponse,\n MoveAssetsRequest,\n MoveAssetsResponse,\n GetTransformUrlRequest,\n GetTransformUrlResponse,\n GetFolderTreeRequest,\n FolderTreeNode,\n CreateFolderRequest,\n Folder,\n} from \"./types\";\n\nexport class CDN {\n private http: HttpClient;\n\n constructor(config: HttpClientConfig) {\n this.http = new HttpClient(config);\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/assets/upload-url\", 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<ConfirmUploadResponse>(\"/cdn/assets/confirm\", { assetId });\n return this.convertAssetDates(response.asset);\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.put<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 return this.http.delete<{ success: boolean }>(`/cdn/assets/${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-many\", { 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\n *\n * @example\n * ```typescript\n * const { url } = await cdn.getTransformUrl({\n * assetId: 'asset-id',\n * options: {\n * width: 800,\n * height: 600,\n * fit: 'cover',\n * format: 'webp',\n * quality: 80,\n * },\n * });\n * ```\n */\n async getTransformUrl(request: GetTransformUrlRequest): Promise<GetTransformUrlResponse> {\n const params = new URLSearchParams();\n params.set(\"assetId\", request.assetId);\n\n const { options } = request;\n if (options.width) params.set(\"width\", options.width.toString());\n if (options.height) params.set(\"height\", options.height.toString());\n if (options.fit) params.set(\"fit\", options.fit);\n if (options.format) params.set(\"format\", options.format);\n if (options.quality) params.set(\"quality\", options.quality.toString());\n\n return this.http.get<GetTransformUrlResponse>(`/cdn/assets/transform?${params.toString()}`);\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 return this.http.get<FolderTreeNode[]>(`/cdn/folders/tree?${params.toString()}`);\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.delete<{ success: boolean }>(`/cdn/folders/${id}?${params.toString()}`);\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"]}
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(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(),\n body: body ? JSON.stringify(body) : 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 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 GetTransformUrlRequest,\n GetTransformUrlResponse,\n GetFolderTreeRequest,\n FolderTreeNode,\n CreateFolderRequest,\n Folder,\n} from \"./types\";\n\nexport class CDN {\n private http: HttpClient;\n\n constructor(config: HttpClientConfig) {\n this.http = new HttpClient(config);\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\n console.log(\"confirm upload response\", response);\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 return this.http.delete<{ success: boolean }>(`/cdn/assets/${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\n *\n * @example\n * ```typescript\n * const { url } = await cdn.getTransformUrl({\n * assetId: 'asset-id',\n * options: {\n * width: 800,\n * height: 600,\n * fit: 'cover',\n * format: 'webp',\n * quality: 80,\n * },\n * });\n * ```\n */\n async getTransformUrl(request: GetTransformUrlRequest): Promise<GetTransformUrlResponse> {\n return this.http.post<GetTransformUrlResponse>(\"/cdn/transform\", request);\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.delete<{ success: boolean }>(`/cdn/folders/${id}?${params.toString()}`);\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"]}
@@ -62,6 +62,9 @@ var HttpClient = class {
62
62
  async delete(path) {
63
63
  return this.request("DELETE", path);
64
64
  }
65
+ async patch(path, body) {
66
+ return this.request("PATCH", path, body);
67
+ }
65
68
  };
66
69
 
67
70
  // src/cdn/client.ts
@@ -94,7 +97,7 @@ var CDN = class {
94
97
  * ```
95
98
  */
96
99
  async getUploadUrl(request) {
97
- const response = await this.http.post("/cdn/assets/upload-url", request);
100
+ const response = await this.http.post("/cdn/upload", request);
98
101
  if (typeof response.expiresAt === "string") {
99
102
  response.expiresAt = new Date(response.expiresAt);
100
103
  }
@@ -104,8 +107,9 @@ var CDN = class {
104
107
  * Confirm that an upload has completed
105
108
  */
106
109
  async confirmUpload(assetId) {
107
- const response = await this.http.post("/cdn/assets/confirm", { assetId });
108
- return this.convertAssetDates(response.asset);
110
+ const response = await this.http.post(`/cdn/upload/${assetId}/confirm`, {});
111
+ console.log("confirm upload response", response);
112
+ return this.convertAssetDates(response);
109
113
  }
110
114
  /**
111
115
  * Upload a file directly (handles presigned URL flow automatically)
@@ -177,7 +181,7 @@ var CDN = class {
177
181
  */
178
182
  async update(request) {
179
183
  const { id, ...data } = request;
180
- const response = await this.http.put(`/cdn/assets/${id}`, data);
184
+ const response = await this.http.patch(`/cdn/assets/${id}`, data);
181
185
  return this.convertAssetDates(response);
182
186
  }
183
187
  /**
@@ -201,7 +205,7 @@ var CDN = class {
201
205
  * ```
202
206
  */
203
207
  async deleteMany(ids) {
204
- return this.http.post("/cdn/assets/delete-many", { ids });
208
+ return this.http.post("/cdn/assets/delete", { ids });
205
209
  }
206
210
  /**
207
211
  * List assets with filters and pagination
@@ -265,15 +269,7 @@ var CDN = class {
265
269
  * ```
266
270
  */
267
271
  async getTransformUrl(request) {
268
- const params = new URLSearchParams();
269
- params.set("assetId", request.assetId);
270
- const { options } = request;
271
- if (options.width) params.set("width", options.width.toString());
272
- if (options.height) params.set("height", options.height.toString());
273
- if (options.fit) params.set("fit", options.fit);
274
- if (options.format) params.set("format", options.format);
275
- if (options.quality) params.set("quality", options.quality.toString());
276
- return this.http.get(`/cdn/assets/transform?${params.toString()}`);
272
+ return this.http.post("/cdn/transform", request);
277
273
  }
278
274
  /**
279
275
  * Get folder tree for navigation
@@ -290,7 +286,8 @@ var CDN = class {
290
286
  const params = new URLSearchParams();
291
287
  params.set("projectSlug", request.projectSlug);
292
288
  if (request.maxDepth) params.set("maxDepth", request.maxDepth.toString());
293
- return this.http.get(`/cdn/folders/tree?${params.toString()}`);
289
+ const response = await this.http.get(`/cdn/folders/tree?${params.toString()}`);
290
+ return response.tree;
294
291
  }
295
292
  /**
296
293
  * Create a new folder
@@ -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(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(),\n body: body ? JSON.stringify(body) : 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","/**\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 ConfirmUploadResponse,\n UpdateAssetRequest,\n DeleteAssetsResponse,\n ListAssetsRequest,\n ListAssetsResponse,\n MoveAssetsRequest,\n MoveAssetsResponse,\n GetTransformUrlRequest,\n GetTransformUrlResponse,\n GetFolderTreeRequest,\n FolderTreeNode,\n CreateFolderRequest,\n Folder,\n} from \"./types\";\n\nexport class CDN {\n private http: HttpClient;\n\n constructor(config: HttpClientConfig) {\n this.http = new HttpClient(config);\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/assets/upload-url\", 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<ConfirmUploadResponse>(\"/cdn/assets/confirm\", { assetId });\n return this.convertAssetDates(response.asset);\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.put<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 return this.http.delete<{ success: boolean }>(`/cdn/assets/${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-many\", { 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\n *\n * @example\n * ```typescript\n * const { url } = await cdn.getTransformUrl({\n * assetId: 'asset-id',\n * options: {\n * width: 800,\n * height: 600,\n * fit: 'cover',\n * format: 'webp',\n * quality: 80,\n * },\n * });\n * ```\n */\n async getTransformUrl(request: GetTransformUrlRequest): Promise<GetTransformUrlResponse> {\n const params = new URLSearchParams();\n params.set(\"assetId\", request.assetId);\n\n const { options } = request;\n if (options.width) params.set(\"width\", options.width.toString());\n if (options.height) params.set(\"height\", options.height.toString());\n if (options.fit) params.set(\"fit\", options.fit);\n if (options.format) params.set(\"format\", options.format);\n if (options.quality) params.set(\"quality\", options.quality.toString());\n\n return this.http.get<GetTransformUrlResponse>(`/cdn/assets/transform?${params.toString()}`);\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 return this.http.get<FolderTreeNode[]>(`/cdn/folders/tree?${params.toString()}`);\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.delete<{ success: boolean }>(`/cdn/folders/${id}?${params.toString()}`);\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"]}
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(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(),\n body: body ? JSON.stringify(body) : 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 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 GetTransformUrlRequest,\n GetTransformUrlResponse,\n GetFolderTreeRequest,\n FolderTreeNode,\n CreateFolderRequest,\n Folder,\n} from \"./types\";\n\nexport class CDN {\n private http: HttpClient;\n\n constructor(config: HttpClientConfig) {\n this.http = new HttpClient(config);\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\n console.log(\"confirm upload response\", response);\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 return this.http.delete<{ success: boolean }>(`/cdn/assets/${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\n *\n * @example\n * ```typescript\n * const { url } = await cdn.getTransformUrl({\n * assetId: 'asset-id',\n * options: {\n * width: 800,\n * height: 600,\n * fit: 'cover',\n * format: 'webp',\n * quality: 80,\n * },\n * });\n * ```\n */\n async getTransformUrl(request: GetTransformUrlRequest): Promise<GetTransformUrlResponse> {\n return this.http.post<GetTransformUrlResponse>(\"/cdn/transform\", request);\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.delete<{ success: boolean }>(`/cdn/folders/${id}?${params.toString()}`);\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"]}
package/dist/index.js CHANGED
@@ -66,6 +66,9 @@ var HttpClient = class {
66
66
  async delete(path) {
67
67
  return this.request("DELETE", path);
68
68
  }
69
+ async patch(path, body) {
70
+ return this.request("PATCH", path, body);
71
+ }
69
72
  };
70
73
 
71
74
  // src/mail/client.ts
@@ -145,7 +148,7 @@ var CDN = class {
145
148
  * ```
146
149
  */
147
150
  async getUploadUrl(request) {
148
- const response = await this.http.post("/cdn/assets/upload-url", request);
151
+ const response = await this.http.post("/cdn/upload", request);
149
152
  if (typeof response.expiresAt === "string") {
150
153
  response.expiresAt = new Date(response.expiresAt);
151
154
  }
@@ -155,8 +158,9 @@ var CDN = class {
155
158
  * Confirm that an upload has completed
156
159
  */
157
160
  async confirmUpload(assetId) {
158
- const response = await this.http.post("/cdn/assets/confirm", { assetId });
159
- return this.convertAssetDates(response.asset);
161
+ const response = await this.http.post(`/cdn/upload/${assetId}/confirm`, {});
162
+ console.log("confirm upload response", response);
163
+ return this.convertAssetDates(response);
160
164
  }
161
165
  /**
162
166
  * Upload a file directly (handles presigned URL flow automatically)
@@ -228,7 +232,7 @@ var CDN = class {
228
232
  */
229
233
  async update(request) {
230
234
  const { id, ...data } = request;
231
- const response = await this.http.put(`/cdn/assets/${id}`, data);
235
+ const response = await this.http.patch(`/cdn/assets/${id}`, data);
232
236
  return this.convertAssetDates(response);
233
237
  }
234
238
  /**
@@ -252,7 +256,7 @@ var CDN = class {
252
256
  * ```
253
257
  */
254
258
  async deleteMany(ids) {
255
- return this.http.post("/cdn/assets/delete-many", { ids });
259
+ return this.http.post("/cdn/assets/delete", { ids });
256
260
  }
257
261
  /**
258
262
  * List assets with filters and pagination
@@ -316,15 +320,7 @@ var CDN = class {
316
320
  * ```
317
321
  */
318
322
  async getTransformUrl(request) {
319
- const params = new URLSearchParams();
320
- params.set("assetId", request.assetId);
321
- const { options } = request;
322
- if (options.width) params.set("width", options.width.toString());
323
- if (options.height) params.set("height", options.height.toString());
324
- if (options.fit) params.set("fit", options.fit);
325
- if (options.format) params.set("format", options.format);
326
- if (options.quality) params.set("quality", options.quality.toString());
327
- return this.http.get(`/cdn/assets/transform?${params.toString()}`);
323
+ return this.http.post("/cdn/transform", request);
328
324
  }
329
325
  /**
330
326
  * Get folder tree for navigation
@@ -341,7 +337,8 @@ var CDN = class {
341
337
  const params = new URLSearchParams();
342
338
  params.set("projectSlug", request.projectSlug);
343
339
  if (request.maxDepth) params.set("maxDepth", request.maxDepth.toString());
344
- return this.http.get(`/cdn/folders/tree?${params.toString()}`);
340
+ const response = await this.http.get(`/cdn/folders/tree?${params.toString()}`);
341
+ return response.tree;
345
342
  }
346
343
  /**
347
344
  * Create a new folder
@@ -460,9 +457,7 @@ var Webdata = class {
460
457
  if (request.limit) params.set("limit", request.limit.toString());
461
458
  if (request.cursor) params.set("cursor", request.cursor);
462
459
  const query = params.toString();
463
- const response = await this.http.get(
464
- `/webdata/screenshots${query ? `?${query}` : ""}`
465
- );
460
+ const response = await this.http.get(`/webdata/screenshots${query ? `?${query}` : ""}`);
466
461
  return {
467
462
  ...response,
468
463
  items: response.items.map((item) => this.convertScreenshotDates(item))
@@ -481,9 +476,7 @@ var Webdata = class {
481
476
  if (request.environment) params.set("environment", request.environment);
482
477
  if (request.projectId) params.set("projectId", request.projectId);
483
478
  const query = params.toString();
484
- return this.http.delete(
485
- `/webdata/screenshots/${request.id}${query ? `?${query}` : ""}`
486
- );
479
+ return this.http.delete(`/webdata/screenshots/${request.id}${query ? `?${query}` : ""}`);
487
480
  }
488
481
  /**
489
482
  * Capture a screenshot and wait for completion
@@ -580,9 +573,7 @@ var Webdata = class {
580
573
  if (request.limit) params.set("limit", request.limit.toString());
581
574
  if (request.cursor) params.set("cursor", request.cursor);
582
575
  const query = params.toString();
583
- const response = await this.http.get(
584
- `/webdata/extractions${query ? `?${query}` : ""}`
585
- );
576
+ const response = await this.http.get(`/webdata/extractions${query ? `?${query}` : ""}`);
586
577
  return {
587
578
  ...response,
588
579
  items: response.items.map((item) => this.convertExtractionDates(item))
@@ -601,9 +592,7 @@ var Webdata = class {
601
592
  if (request.environment) params.set("environment", request.environment);
602
593
  if (request.projectId) params.set("projectId", request.projectId);
603
594
  const query = params.toString();
604
- return this.http.delete(
605
- `/webdata/extractions/${request.id}${query ? `?${query}` : ""}`
606
- );
595
+ return this.http.delete(`/webdata/extractions/${request.id}${query ? `?${query}` : ""}`);
607
596
  }
608
597
  /**
609
598
  * Extract content and wait for completion
@@ -675,10 +664,7 @@ var Webdata = class {
675
664
  if (environment) params.set("environment", environment);
676
665
  if (projectId) params.set("projectId", projectId);
677
666
  const query = params.toString();
678
- return this.http.post(
679
- `/webdata/schedules/${id}${query ? `?${query}` : ""}`,
680
- data
681
- );
667
+ return this.http.patch(`/webdata/schedules/${id}${query ? `?${query}` : ""}`, data);
682
668
  }
683
669
  /**
684
670
  * Get a schedule by ID
@@ -718,9 +704,7 @@ var Webdata = class {
718
704
  if (request.limit) params.set("limit", request.limit.toString());
719
705
  if (request.cursor) params.set("cursor", request.cursor);
720
706
  const query = params.toString();
721
- const response = await this.http.get(
722
- `/webdata/schedules${query ? `?${query}` : ""}`
723
- );
707
+ const response = await this.http.get(`/webdata/schedules${query ? `?${query}` : ""}`);
724
708
  return {
725
709
  ...response,
726
710
  items: response.items.map((item) => this.convertScheduleDates(item))
@@ -739,9 +723,7 @@ var Webdata = class {
739
723
  if (request.environment) params.set("environment", request.environment);
740
724
  if (request.projectId) params.set("projectId", request.projectId);
741
725
  const query = params.toString();
742
- return this.http.delete(
743
- `/webdata/schedules/${request.id}${query ? `?${query}` : ""}`
744
- );
726
+ return this.http.delete(`/webdata/schedules/${request.id}${query ? `?${query}` : ""}`);
745
727
  }
746
728
  /**
747
729
  * Toggle a schedule on or off
@@ -784,9 +766,7 @@ var Webdata = class {
784
766
  if (request.periodStart) params.set("periodStart", request.periodStart);
785
767
  if (request.periodEnd) params.set("periodEnd", request.periodEnd);
786
768
  const query = params.toString();
787
- const response = await this.http.get(
788
- `/webdata/usage${query ? `?${query}` : ""}`
789
- );
769
+ const response = await this.http.get(`/webdata/usage${query ? `?${query}` : ""}`);
790
770
  return this.convertUsageDates(response);
791
771
  }
792
772
  // ==========================================================================
@@ -870,9 +850,7 @@ var Webdata = class {
870
850
  if (request.limit) params.set("limit", request.limit.toString());
871
851
  if (request.cursor) params.set("cursor", request.cursor);
872
852
  const query = params.toString();
873
- const response = await this.http.get(
874
- `/webdata/batch${query ? `?${query}` : ""}`
875
- );
853
+ const response = await this.http.get(`/webdata/batch${query ? `?${query}` : ""}`);
876
854
  return {
877
855
  ...response,
878
856
  items: response.items.map((item) => this.convertBatchJobDates(item))
@@ -891,10 +869,7 @@ var Webdata = class {
891
869
  if (request.environment) params.set("environment", request.environment);
892
870
  if (request.projectId) params.set("projectId", request.projectId);
893
871
  const query = params.toString();
894
- return this.http.post(
895
- `/webdata/batch/${request.id}/cancel${query ? `?${query}` : ""}`,
896
- {}
897
- );
872
+ return this.http.post(`/webdata/batch/${request.id}/cancel${query ? `?${query}` : ""}`, {});
898
873
  }
899
874
  /**
900
875
  * Create a batch screenshot job and wait for completion