@blinkdotnew/sdk 0.14.13 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -353,12 +353,27 @@ const { object: todoList } = await blink.ai.generateObject({
353
353
  // })
354
354
  // Error: "schema must be a JSON Schema of 'type: \"object\"', got 'type: \"array\"'"
355
355
 
356
- // Image generation
356
+ // Generate and modify images with AI
357
+
358
+ // Basic image generation - returns public URLs directly
357
359
  const { data } = await blink.ai.generateImage({
358
- prompt: 'A serene landscape',
360
+ prompt: 'A serene landscape with mountains and a lake at sunset',
359
361
  size: '1024x1024',
360
- quality: 'hd'
362
+ quality: 'hd',
363
+ n: 2
364
+ })
365
+ console.log('Image URL:', data[0].url)
366
+
367
+ // Image editing - transform existing images with prompts
368
+ const { data: headshots } = await blink.ai.modifyImage({
369
+ images: ['https://storage.example.com/user-photo.jpg'], // ... up to 16 images maximum!
370
+ prompt: 'Generate professional business headshot with studio lighting for this person.',
371
+ quality: 'hd',
372
+ n: 4
361
373
  })
374
+ // Options: size ('1024x1024', '1536x1024'), quality ('standard'|'hd'),
375
+ // background ('auto'|'transparent'|'opaque'), n (1-10 images)
376
+
362
377
 
363
378
  // Speech synthesis
364
379
  const { url } = await blink.ai.generateSpeech({
package/dist/index.d.mts CHANGED
@@ -119,8 +119,17 @@ interface FileObject {
119
119
  }
120
120
  interface BlinkStorage {
121
121
  upload(file: File | Blob | Buffer, path: string, options?: StorageUploadOptions): Promise<StorageUploadResponse>;
122
+ download(path: string, options?: {
123
+ filename?: string;
124
+ }): Promise<StorageDownloadResponse>;
122
125
  remove(...paths: string[]): Promise<void>;
123
126
  }
127
+ interface StorageDownloadResponse {
128
+ downloadUrl: string;
129
+ filename: string;
130
+ contentType?: string;
131
+ size?: number;
132
+ }
124
133
  interface TokenUsage {
125
134
  promptTokens: number;
126
135
  completionTokens: number;
@@ -211,10 +220,15 @@ interface ObjectGenerationResponse {
211
220
  interface ImageGenerationRequest {
212
221
  model?: string;
213
222
  prompt: string;
223
+ images?: string[];
214
224
  size?: string;
215
225
  quality?: 'standard' | 'hd';
226
+ background?: 'auto' | 'transparent' | 'opaque';
216
227
  n?: number;
217
228
  response_format?: 'url' | 'b64_json';
229
+ output_format?: 'png' | 'jpeg' | 'webp';
230
+ output_compression?: number;
231
+ moderation?: 'auto' | 'low';
218
232
  signal?: AbortSignal;
219
233
  }
220
234
  interface ImageGenerationResponse {
@@ -273,6 +287,15 @@ interface BlinkAI {
273
287
  generateObject(options: ObjectGenerationRequest): Promise<ObjectGenerationResponse>;
274
288
  streamObject(options: ObjectGenerationRequest, onPartial: (partial: any) => void): Promise<ObjectGenerationResponse>;
275
289
  generateImage(options: ImageGenerationRequest): Promise<ImageGenerationResponse>;
290
+ modifyImage(options: {
291
+ images: string[];
292
+ prompt: string;
293
+ size?: string;
294
+ quality?: "standard" | "hd";
295
+ n?: number;
296
+ background?: "auto" | "transparent" | "opaque";
297
+ signal?: AbortSignal;
298
+ }): Promise<ImageGenerationResponse>;
276
299
  generateSpeech(options: SpeechGenerationRequest): Promise<SpeechGenerationResponse>;
277
300
  transcribeAudio(options: TranscriptionRequest): Promise<TranscriptionResponse>;
278
301
  }
@@ -660,10 +683,15 @@ declare class HttpClient {
660
683
  } | undefined, onPartial: (partial: any) => void): Promise<any>;
661
684
  aiImage(prompt: string, options?: {
662
685
  model?: string;
686
+ images?: string[];
663
687
  size?: string;
664
688
  quality?: 'standard' | 'hd';
689
+ background?: 'auto' | 'transparent' | 'opaque';
665
690
  n?: number;
666
691
  response_format?: 'url' | 'b64_json';
692
+ output_format?: 'png' | 'jpeg' | 'webp';
693
+ output_compression?: number;
694
+ moderation?: 'auto' | 'low';
667
695
  signal?: AbortSignal;
668
696
  }): Promise<BlinkResponse<any>>;
669
697
  aiSpeech(text: string, options?: {
@@ -1130,6 +1158,32 @@ declare class BlinkStorageImpl implements BlinkStorage {
1130
1158
  * ```
1131
1159
  */
1132
1160
  upload(file: File | Blob | Buffer, path: string, options?: StorageUploadOptions): Promise<StorageUploadResponse>;
1161
+ /**
1162
+ * Get a download URL for a file that triggers browser download
1163
+ *
1164
+ * @param path - Path to the file in project storage
1165
+ * @param options - Download options including custom filename
1166
+ * @returns Promise resolving to download response with download URL
1167
+ *
1168
+ * @example
1169
+ * ```ts
1170
+ * // Download with original filename
1171
+ * const { downloadUrl, filename } = await blink.storage.download('images/photo.jpg');
1172
+ * window.open(downloadUrl, '_blank');
1173
+ *
1174
+ * // Download with custom filename
1175
+ * const { downloadUrl } = await blink.storage.download(
1176
+ * 'images/photo.jpg',
1177
+ * { filename: 'my-photo.jpg' }
1178
+ * );
1179
+ *
1180
+ * // Create download link in React
1181
+ * <a href={downloadUrl} download={filename}>Download Image</a>
1182
+ * ```
1183
+ */
1184
+ download(path: string, options?: {
1185
+ filename?: string;
1186
+ }): Promise<StorageDownloadResponse>;
1133
1187
  /**
1134
1188
  * Remove one or more files from project storage
1135
1189
  *
@@ -1362,15 +1416,15 @@ declare class BlinkAIImpl implements BlinkAI {
1362
1416
  */
1363
1417
  streamObject(options: ObjectGenerationRequest, onPartial: (partial: any) => void): Promise<ObjectGenerationResponse>;
1364
1418
  /**
1365
- * Generates images from text descriptions using AI image models.
1419
+ * Generates images from text descriptions using AI.
1366
1420
  *
1367
1421
  * @param options - Object containing:
1368
- * - `prompt`: Text description of the image to generate (required)
1369
- * - `size`: Image dimensions (e.g., "1024x1024", "512x512") - varies by model
1370
- * - `quality`: Image quality ("standard" or "hd")
1422
+ * - `prompt`: Text description of the desired image (required)
1423
+ * - `size`: Image dimensions (default: "1024x1024")
1424
+ * - `quality`: Image quality ("standard" or "hd", default: "standard")
1371
1425
  * - `n`: Number of images to generate (default: 1)
1372
- * - `response_format`: Output format ("url" or "b64_json")
1373
- * - Plus optional model, signal parameters
1426
+ * - `background`: Background handling ("auto", "transparent", "opaque", default: "auto")
1427
+ * - Plus optional signal parameter
1374
1428
  *
1375
1429
  * @example
1376
1430
  * ```ts
@@ -1383,31 +1437,103 @@ declare class BlinkAIImpl implements BlinkAI {
1383
1437
  * // High-quality image with specific size
1384
1438
  * const { data } = await blink.ai.generateImage({
1385
1439
  * prompt: "A futuristic city skyline with flying cars",
1386
- * size: "1792x1024",
1440
+ * size: "1536x1024",
1387
1441
  * quality: "hd",
1388
- * model: "dall-e-3"
1442
+ * background: "transparent"
1389
1443
  * });
1390
1444
  *
1391
1445
  * // Multiple images
1392
1446
  * const { data } = await blink.ai.generateImage({
1393
1447
  * prompt: "A cute robot mascot for a tech company",
1394
1448
  * n: 3,
1395
- * size: "1024x1024"
1449
+ * size: "1024x1024",
1450
+ * quality: "hd"
1396
1451
  * });
1397
1452
  * data.forEach((img, i) => console.log(`Image ${i+1}:`, img.url));
1453
+ * ```
1398
1454
  *
1399
- * // Base64 format for direct embedding
1400
- * const { data } = await blink.ai.generateImage({
1401
- * prompt: "A minimalist logo design",
1402
- * response_format: "b64_json"
1455
+ * @returns Promise<ImageGenerationResponse> - Object containing:
1456
+ * - `data`: Array of generated images with URLs
1457
+ * - `created`: Timestamp of generation
1458
+ * - `usage`: Token usage information
1459
+ */
1460
+ generateImage(options: {
1461
+ prompt: string;
1462
+ size?: string;
1463
+ quality?: "standard" | "hd";
1464
+ n?: number;
1465
+ background?: "auto" | "transparent" | "opaque";
1466
+ signal?: AbortSignal;
1467
+ }): Promise<ImageGenerationResponse>;
1468
+ /**
1469
+ * Modifies existing images using AI with text prompts for image-to-image editing.
1470
+ *
1471
+ * @param options - Object containing:
1472
+ * - `images`: Array of public image URLs to modify (required, up to 16 images)
1473
+ * - `prompt`: Text description of desired modifications (required)
1474
+ * - `size`: Output image dimensions (default: "auto")
1475
+ * - `quality`: Image quality ("standard" or "hd", default: "standard")
1476
+ * - `n`: Number of output images to generate (default: 1)
1477
+ * - `background`: Background handling ("auto", "transparent", "opaque", default: "auto")
1478
+ * - Plus optional signal parameter
1479
+ *
1480
+ * @example
1481
+ * ```ts
1482
+ * // Professional headshots from casual photos
1483
+ * const { data } = await blink.ai.modifyImage({
1484
+ * images: [
1485
+ * "https://storage.example.com/user-photo-1.jpg",
1486
+ * "https://storage.example.com/user-photo-2.jpg"
1487
+ * ],
1488
+ * prompt: "Transform into professional business headshots with studio lighting",
1489
+ * quality: "hd",
1490
+ * n: 4
1491
+ * });
1492
+ * data.forEach((img, i) => console.log(`Headshot ${i+1}:`, img.url));
1493
+ *
1494
+ * // Artistic style transformation
1495
+ * const { data } = await blink.ai.modifyImage({
1496
+ * images: ["https://storage.example.com/portrait.jpg"],
1497
+ * prompt: "Transform into oil painting style with dramatic lighting",
1498
+ * quality: "hd",
1499
+ * size: "1024x1024"
1500
+ * });
1501
+ *
1502
+ * // Background replacement
1503
+ * const { data } = await blink.ai.modifyImage({
1504
+ * images: ["https://storage.example.com/product.jpg"],
1505
+ * prompt: "Remove background and place on clean white studio background",
1506
+ * background: "transparent",
1507
+ * n: 2
1508
+ * });
1509
+ *
1510
+ * // Batch processing multiple photos
1511
+ * const userPhotos = [
1512
+ * "https://storage.example.com/photo1.jpg",
1513
+ * "https://storage.example.com/photo2.jpg",
1514
+ * "https://storage.example.com/photo3.jpg"
1515
+ * ];
1516
+ * const { data } = await blink.ai.modifyImage({
1517
+ * images: userPhotos,
1518
+ * prompt: "Convert to black and white vintage style photographs",
1519
+ * quality: "hd"
1403
1520
  * });
1404
- * console.log("Base64 data:", data[0].b64_json);
1405
1521
  * ```
1406
1522
  *
1407
1523
  * @returns Promise<ImageGenerationResponse> - Object containing:
1408
- * - `data`: Array of generated images with url or b64_json
1524
+ * - `data`: Array of modified images with URLs
1525
+ * - `created`: Timestamp of generation
1526
+ * - `usage`: Token usage information
1409
1527
  */
1410
- generateImage(options: ImageGenerationRequest): Promise<ImageGenerationResponse>;
1528
+ modifyImage(options: {
1529
+ images: string[];
1530
+ prompt: string;
1531
+ size?: string;
1532
+ quality?: "standard" | "hd";
1533
+ n?: number;
1534
+ background?: "auto" | "transparent" | "opaque";
1535
+ signal?: AbortSignal;
1536
+ }): Promise<ImageGenerationResponse>;
1411
1537
  /**
1412
1538
  * Converts text to speech using AI voice synthesis models.
1413
1539
  *
package/dist/index.d.ts CHANGED
@@ -119,8 +119,17 @@ interface FileObject {
119
119
  }
120
120
  interface BlinkStorage {
121
121
  upload(file: File | Blob | Buffer, path: string, options?: StorageUploadOptions): Promise<StorageUploadResponse>;
122
+ download(path: string, options?: {
123
+ filename?: string;
124
+ }): Promise<StorageDownloadResponse>;
122
125
  remove(...paths: string[]): Promise<void>;
123
126
  }
127
+ interface StorageDownloadResponse {
128
+ downloadUrl: string;
129
+ filename: string;
130
+ contentType?: string;
131
+ size?: number;
132
+ }
124
133
  interface TokenUsage {
125
134
  promptTokens: number;
126
135
  completionTokens: number;
@@ -211,10 +220,15 @@ interface ObjectGenerationResponse {
211
220
  interface ImageGenerationRequest {
212
221
  model?: string;
213
222
  prompt: string;
223
+ images?: string[];
214
224
  size?: string;
215
225
  quality?: 'standard' | 'hd';
226
+ background?: 'auto' | 'transparent' | 'opaque';
216
227
  n?: number;
217
228
  response_format?: 'url' | 'b64_json';
229
+ output_format?: 'png' | 'jpeg' | 'webp';
230
+ output_compression?: number;
231
+ moderation?: 'auto' | 'low';
218
232
  signal?: AbortSignal;
219
233
  }
220
234
  interface ImageGenerationResponse {
@@ -273,6 +287,15 @@ interface BlinkAI {
273
287
  generateObject(options: ObjectGenerationRequest): Promise<ObjectGenerationResponse>;
274
288
  streamObject(options: ObjectGenerationRequest, onPartial: (partial: any) => void): Promise<ObjectGenerationResponse>;
275
289
  generateImage(options: ImageGenerationRequest): Promise<ImageGenerationResponse>;
290
+ modifyImage(options: {
291
+ images: string[];
292
+ prompt: string;
293
+ size?: string;
294
+ quality?: "standard" | "hd";
295
+ n?: number;
296
+ background?: "auto" | "transparent" | "opaque";
297
+ signal?: AbortSignal;
298
+ }): Promise<ImageGenerationResponse>;
276
299
  generateSpeech(options: SpeechGenerationRequest): Promise<SpeechGenerationResponse>;
277
300
  transcribeAudio(options: TranscriptionRequest): Promise<TranscriptionResponse>;
278
301
  }
@@ -660,10 +683,15 @@ declare class HttpClient {
660
683
  } | undefined, onPartial: (partial: any) => void): Promise<any>;
661
684
  aiImage(prompt: string, options?: {
662
685
  model?: string;
686
+ images?: string[];
663
687
  size?: string;
664
688
  quality?: 'standard' | 'hd';
689
+ background?: 'auto' | 'transparent' | 'opaque';
665
690
  n?: number;
666
691
  response_format?: 'url' | 'b64_json';
692
+ output_format?: 'png' | 'jpeg' | 'webp';
693
+ output_compression?: number;
694
+ moderation?: 'auto' | 'low';
667
695
  signal?: AbortSignal;
668
696
  }): Promise<BlinkResponse<any>>;
669
697
  aiSpeech(text: string, options?: {
@@ -1130,6 +1158,32 @@ declare class BlinkStorageImpl implements BlinkStorage {
1130
1158
  * ```
1131
1159
  */
1132
1160
  upload(file: File | Blob | Buffer, path: string, options?: StorageUploadOptions): Promise<StorageUploadResponse>;
1161
+ /**
1162
+ * Get a download URL for a file that triggers browser download
1163
+ *
1164
+ * @param path - Path to the file in project storage
1165
+ * @param options - Download options including custom filename
1166
+ * @returns Promise resolving to download response with download URL
1167
+ *
1168
+ * @example
1169
+ * ```ts
1170
+ * // Download with original filename
1171
+ * const { downloadUrl, filename } = await blink.storage.download('images/photo.jpg');
1172
+ * window.open(downloadUrl, '_blank');
1173
+ *
1174
+ * // Download with custom filename
1175
+ * const { downloadUrl } = await blink.storage.download(
1176
+ * 'images/photo.jpg',
1177
+ * { filename: 'my-photo.jpg' }
1178
+ * );
1179
+ *
1180
+ * // Create download link in React
1181
+ * <a href={downloadUrl} download={filename}>Download Image</a>
1182
+ * ```
1183
+ */
1184
+ download(path: string, options?: {
1185
+ filename?: string;
1186
+ }): Promise<StorageDownloadResponse>;
1133
1187
  /**
1134
1188
  * Remove one or more files from project storage
1135
1189
  *
@@ -1362,15 +1416,15 @@ declare class BlinkAIImpl implements BlinkAI {
1362
1416
  */
1363
1417
  streamObject(options: ObjectGenerationRequest, onPartial: (partial: any) => void): Promise<ObjectGenerationResponse>;
1364
1418
  /**
1365
- * Generates images from text descriptions using AI image models.
1419
+ * Generates images from text descriptions using AI.
1366
1420
  *
1367
1421
  * @param options - Object containing:
1368
- * - `prompt`: Text description of the image to generate (required)
1369
- * - `size`: Image dimensions (e.g., "1024x1024", "512x512") - varies by model
1370
- * - `quality`: Image quality ("standard" or "hd")
1422
+ * - `prompt`: Text description of the desired image (required)
1423
+ * - `size`: Image dimensions (default: "1024x1024")
1424
+ * - `quality`: Image quality ("standard" or "hd", default: "standard")
1371
1425
  * - `n`: Number of images to generate (default: 1)
1372
- * - `response_format`: Output format ("url" or "b64_json")
1373
- * - Plus optional model, signal parameters
1426
+ * - `background`: Background handling ("auto", "transparent", "opaque", default: "auto")
1427
+ * - Plus optional signal parameter
1374
1428
  *
1375
1429
  * @example
1376
1430
  * ```ts
@@ -1383,31 +1437,103 @@ declare class BlinkAIImpl implements BlinkAI {
1383
1437
  * // High-quality image with specific size
1384
1438
  * const { data } = await blink.ai.generateImage({
1385
1439
  * prompt: "A futuristic city skyline with flying cars",
1386
- * size: "1792x1024",
1440
+ * size: "1536x1024",
1387
1441
  * quality: "hd",
1388
- * model: "dall-e-3"
1442
+ * background: "transparent"
1389
1443
  * });
1390
1444
  *
1391
1445
  * // Multiple images
1392
1446
  * const { data } = await blink.ai.generateImage({
1393
1447
  * prompt: "A cute robot mascot for a tech company",
1394
1448
  * n: 3,
1395
- * size: "1024x1024"
1449
+ * size: "1024x1024",
1450
+ * quality: "hd"
1396
1451
  * });
1397
1452
  * data.forEach((img, i) => console.log(`Image ${i+1}:`, img.url));
1453
+ * ```
1398
1454
  *
1399
- * // Base64 format for direct embedding
1400
- * const { data } = await blink.ai.generateImage({
1401
- * prompt: "A minimalist logo design",
1402
- * response_format: "b64_json"
1455
+ * @returns Promise<ImageGenerationResponse> - Object containing:
1456
+ * - `data`: Array of generated images with URLs
1457
+ * - `created`: Timestamp of generation
1458
+ * - `usage`: Token usage information
1459
+ */
1460
+ generateImage(options: {
1461
+ prompt: string;
1462
+ size?: string;
1463
+ quality?: "standard" | "hd";
1464
+ n?: number;
1465
+ background?: "auto" | "transparent" | "opaque";
1466
+ signal?: AbortSignal;
1467
+ }): Promise<ImageGenerationResponse>;
1468
+ /**
1469
+ * Modifies existing images using AI with text prompts for image-to-image editing.
1470
+ *
1471
+ * @param options - Object containing:
1472
+ * - `images`: Array of public image URLs to modify (required, up to 16 images)
1473
+ * - `prompt`: Text description of desired modifications (required)
1474
+ * - `size`: Output image dimensions (default: "auto")
1475
+ * - `quality`: Image quality ("standard" or "hd", default: "standard")
1476
+ * - `n`: Number of output images to generate (default: 1)
1477
+ * - `background`: Background handling ("auto", "transparent", "opaque", default: "auto")
1478
+ * - Plus optional signal parameter
1479
+ *
1480
+ * @example
1481
+ * ```ts
1482
+ * // Professional headshots from casual photos
1483
+ * const { data } = await blink.ai.modifyImage({
1484
+ * images: [
1485
+ * "https://storage.example.com/user-photo-1.jpg",
1486
+ * "https://storage.example.com/user-photo-2.jpg"
1487
+ * ],
1488
+ * prompt: "Transform into professional business headshots with studio lighting",
1489
+ * quality: "hd",
1490
+ * n: 4
1491
+ * });
1492
+ * data.forEach((img, i) => console.log(`Headshot ${i+1}:`, img.url));
1493
+ *
1494
+ * // Artistic style transformation
1495
+ * const { data } = await blink.ai.modifyImage({
1496
+ * images: ["https://storage.example.com/portrait.jpg"],
1497
+ * prompt: "Transform into oil painting style with dramatic lighting",
1498
+ * quality: "hd",
1499
+ * size: "1024x1024"
1500
+ * });
1501
+ *
1502
+ * // Background replacement
1503
+ * const { data } = await blink.ai.modifyImage({
1504
+ * images: ["https://storage.example.com/product.jpg"],
1505
+ * prompt: "Remove background and place on clean white studio background",
1506
+ * background: "transparent",
1507
+ * n: 2
1508
+ * });
1509
+ *
1510
+ * // Batch processing multiple photos
1511
+ * const userPhotos = [
1512
+ * "https://storage.example.com/photo1.jpg",
1513
+ * "https://storage.example.com/photo2.jpg",
1514
+ * "https://storage.example.com/photo3.jpg"
1515
+ * ];
1516
+ * const { data } = await blink.ai.modifyImage({
1517
+ * images: userPhotos,
1518
+ * prompt: "Convert to black and white vintage style photographs",
1519
+ * quality: "hd"
1403
1520
  * });
1404
- * console.log("Base64 data:", data[0].b64_json);
1405
1521
  * ```
1406
1522
  *
1407
1523
  * @returns Promise<ImageGenerationResponse> - Object containing:
1408
- * - `data`: Array of generated images with url or b64_json
1524
+ * - `data`: Array of modified images with URLs
1525
+ * - `created`: Timestamp of generation
1526
+ * - `usage`: Token usage information
1409
1527
  */
1410
- generateImage(options: ImageGenerationRequest): Promise<ImageGenerationResponse>;
1528
+ modifyImage(options: {
1529
+ images: string[];
1530
+ prompt: string;
1531
+ size?: string;
1532
+ quality?: "standard" | "hd";
1533
+ n?: number;
1534
+ background?: "auto" | "transparent" | "opaque";
1535
+ signal?: AbortSignal;
1536
+ }): Promise<ImageGenerationResponse>;
1411
1537
  /**
1412
1538
  * Converts text to speech using AI voice synthesis models.
1413
1539
  *
package/dist/index.js CHANGED
@@ -1887,6 +1887,74 @@ var BlinkStorageImpl = class {
1887
1887
  );
1888
1888
  }
1889
1889
  }
1890
+ /**
1891
+ * Get a download URL for a file that triggers browser download
1892
+ *
1893
+ * @param path - Path to the file in project storage
1894
+ * @param options - Download options including custom filename
1895
+ * @returns Promise resolving to download response with download URL
1896
+ *
1897
+ * @example
1898
+ * ```ts
1899
+ * // Download with original filename
1900
+ * const { downloadUrl, filename } = await blink.storage.download('images/photo.jpg');
1901
+ * window.open(downloadUrl, '_blank');
1902
+ *
1903
+ * // Download with custom filename
1904
+ * const { downloadUrl } = await blink.storage.download(
1905
+ * 'images/photo.jpg',
1906
+ * { filename: 'my-photo.jpg' }
1907
+ * );
1908
+ *
1909
+ * // Create download link in React
1910
+ * <a href={downloadUrl} download={filename}>Download Image</a>
1911
+ * ```
1912
+ */
1913
+ async download(path, options = {}) {
1914
+ try {
1915
+ if (!path || typeof path !== "string" || !path.trim()) {
1916
+ throw new BlinkStorageError("Path must be a non-empty string");
1917
+ }
1918
+ const response = await this.httpClient.request(
1919
+ `/api/storage/${this.httpClient.projectId}/download`,
1920
+ {
1921
+ method: "GET",
1922
+ searchParams: {
1923
+ path: path.trim(),
1924
+ ...options.filename && { filename: options.filename }
1925
+ }
1926
+ }
1927
+ );
1928
+ if (response.data?.downloadUrl) {
1929
+ return {
1930
+ downloadUrl: response.data.downloadUrl,
1931
+ filename: response.data.filename || options.filename || path.split("/").pop() || "download",
1932
+ contentType: response.data.contentType,
1933
+ size: response.data.size
1934
+ };
1935
+ } else {
1936
+ throw new BlinkStorageError("Invalid response format: missing downloadUrl");
1937
+ }
1938
+ } catch (error) {
1939
+ if (error instanceof BlinkStorageError) {
1940
+ throw error;
1941
+ }
1942
+ if (error instanceof Error && "status" in error) {
1943
+ const status = error.status;
1944
+ if (status === 404) {
1945
+ throw new BlinkStorageError("File not found", 404);
1946
+ }
1947
+ if (status === 400) {
1948
+ throw new BlinkStorageError("Invalid request parameters", 400);
1949
+ }
1950
+ }
1951
+ throw new BlinkStorageError(
1952
+ `Download failed: ${error instanceof Error ? error.message : "Unknown error"}`,
1953
+ void 0,
1954
+ { originalError: error }
1955
+ );
1956
+ }
1957
+ }
1890
1958
  /**
1891
1959
  * Remove one or more files from project storage
1892
1960
  *
@@ -2354,15 +2422,15 @@ var BlinkAIImpl = class {
2354
2422
  }
2355
2423
  }
2356
2424
  /**
2357
- * Generates images from text descriptions using AI image models.
2425
+ * Generates images from text descriptions using AI.
2358
2426
  *
2359
2427
  * @param options - Object containing:
2360
- * - `prompt`: Text description of the image to generate (required)
2361
- * - `size`: Image dimensions (e.g., "1024x1024", "512x512") - varies by model
2362
- * - `quality`: Image quality ("standard" or "hd")
2428
+ * - `prompt`: Text description of the desired image (required)
2429
+ * - `size`: Image dimensions (default: "1024x1024")
2430
+ * - `quality`: Image quality ("standard" or "hd", default: "standard")
2363
2431
  * - `n`: Number of images to generate (default: 1)
2364
- * - `response_format`: Output format ("url" or "b64_json")
2365
- * - Plus optional model, signal parameters
2432
+ * - `background`: Background handling ("auto", "transparent", "opaque", default: "auto")
2433
+ * - Plus optional signal parameter
2366
2434
  *
2367
2435
  * @example
2368
2436
  * ```ts
@@ -2375,29 +2443,25 @@ var BlinkAIImpl = class {
2375
2443
  * // High-quality image with specific size
2376
2444
  * const { data } = await blink.ai.generateImage({
2377
2445
  * prompt: "A futuristic city skyline with flying cars",
2378
- * size: "1792x1024",
2446
+ * size: "1536x1024",
2379
2447
  * quality: "hd",
2380
- * model: "dall-e-3"
2448
+ * background: "transparent"
2381
2449
  * });
2382
2450
  *
2383
2451
  * // Multiple images
2384
2452
  * const { data } = await blink.ai.generateImage({
2385
2453
  * prompt: "A cute robot mascot for a tech company",
2386
2454
  * n: 3,
2387
- * size: "1024x1024"
2455
+ * size: "1024x1024",
2456
+ * quality: "hd"
2388
2457
  * });
2389
2458
  * data.forEach((img, i) => console.log(`Image ${i+1}:`, img.url));
2390
- *
2391
- * // Base64 format for direct embedding
2392
- * const { data } = await blink.ai.generateImage({
2393
- * prompt: "A minimalist logo design",
2394
- * response_format: "b64_json"
2395
- * });
2396
- * console.log("Base64 data:", data[0].b64_json);
2397
2459
  * ```
2398
2460
  *
2399
2461
  * @returns Promise<ImageGenerationResponse> - Object containing:
2400
- * - `data`: Array of generated images with url or b64_json
2462
+ * - `data`: Array of generated images with URLs
2463
+ * - `created`: Timestamp of generation
2464
+ * - `usage`: Token usage information
2401
2465
  */
2402
2466
  async generateImage(options) {
2403
2467
  try {
@@ -2407,11 +2471,12 @@ var BlinkAIImpl = class {
2407
2471
  const response = await this.httpClient.aiImage(
2408
2472
  options.prompt,
2409
2473
  {
2410
- model: options.model,
2474
+ model: "gpt-image-1",
2411
2475
  size: options.size,
2412
2476
  quality: options.quality,
2413
2477
  n: options.n,
2414
- response_format: options.response_format,
2478
+ background: options.background,
2479
+ response_format: "url",
2415
2480
  signal: options.signal
2416
2481
  }
2417
2482
  );
@@ -2431,10 +2496,8 @@ var BlinkAIImpl = class {
2431
2496
  return { url: item };
2432
2497
  } else if (item.url) {
2433
2498
  return item;
2434
- } else if (item.b64_json) {
2435
- return { b64_json: item.b64_json };
2436
2499
  } else {
2437
- return { url: item };
2500
+ throw new BlinkAIError("Invalid image response format");
2438
2501
  }
2439
2502
  });
2440
2503
  return imageResponse;
@@ -2449,6 +2512,129 @@ var BlinkAIImpl = class {
2449
2512
  );
2450
2513
  }
2451
2514
  }
2515
+ /**
2516
+ * Modifies existing images using AI with text prompts for image-to-image editing.
2517
+ *
2518
+ * @param options - Object containing:
2519
+ * - `images`: Array of public image URLs to modify (required, up to 16 images)
2520
+ * - `prompt`: Text description of desired modifications (required)
2521
+ * - `size`: Output image dimensions (default: "auto")
2522
+ * - `quality`: Image quality ("standard" or "hd", default: "standard")
2523
+ * - `n`: Number of output images to generate (default: 1)
2524
+ * - `background`: Background handling ("auto", "transparent", "opaque", default: "auto")
2525
+ * - Plus optional signal parameter
2526
+ *
2527
+ * @example
2528
+ * ```ts
2529
+ * // Professional headshots from casual photos
2530
+ * const { data } = await blink.ai.modifyImage({
2531
+ * images: [
2532
+ * "https://storage.example.com/user-photo-1.jpg",
2533
+ * "https://storage.example.com/user-photo-2.jpg"
2534
+ * ],
2535
+ * prompt: "Transform into professional business headshots with studio lighting",
2536
+ * quality: "hd",
2537
+ * n: 4
2538
+ * });
2539
+ * data.forEach((img, i) => console.log(`Headshot ${i+1}:`, img.url));
2540
+ *
2541
+ * // Artistic style transformation
2542
+ * const { data } = await blink.ai.modifyImage({
2543
+ * images: ["https://storage.example.com/portrait.jpg"],
2544
+ * prompt: "Transform into oil painting style with dramatic lighting",
2545
+ * quality: "hd",
2546
+ * size: "1024x1024"
2547
+ * });
2548
+ *
2549
+ * // Background replacement
2550
+ * const { data } = await blink.ai.modifyImage({
2551
+ * images: ["https://storage.example.com/product.jpg"],
2552
+ * prompt: "Remove background and place on clean white studio background",
2553
+ * background: "transparent",
2554
+ * n: 2
2555
+ * });
2556
+ *
2557
+ * // Batch processing multiple photos
2558
+ * const userPhotos = [
2559
+ * "https://storage.example.com/photo1.jpg",
2560
+ * "https://storage.example.com/photo2.jpg",
2561
+ * "https://storage.example.com/photo3.jpg"
2562
+ * ];
2563
+ * const { data } = await blink.ai.modifyImage({
2564
+ * images: userPhotos,
2565
+ * prompt: "Convert to black and white vintage style photographs",
2566
+ * quality: "hd"
2567
+ * });
2568
+ * ```
2569
+ *
2570
+ * @returns Promise<ImageGenerationResponse> - Object containing:
2571
+ * - `data`: Array of modified images with URLs
2572
+ * - `created`: Timestamp of generation
2573
+ * - `usage`: Token usage information
2574
+ */
2575
+ async modifyImage(options) {
2576
+ try {
2577
+ if (!options.prompt) {
2578
+ throw new BlinkAIError("Prompt is required");
2579
+ }
2580
+ if (!options.images || !Array.isArray(options.images) || options.images.length === 0) {
2581
+ throw new BlinkAIError("Images array is required and must contain at least one image URL");
2582
+ }
2583
+ if (options.images.length > 16) {
2584
+ throw new BlinkAIError("Maximum 16 images allowed");
2585
+ }
2586
+ for (let i = 0; i < options.images.length; i++) {
2587
+ const validation = this.validateImageUrl(options.images[i]);
2588
+ if (!validation.isValid) {
2589
+ throw new BlinkAIError(`Image ${i + 1}: ${validation.error}`);
2590
+ }
2591
+ }
2592
+ const response = await this.httpClient.aiImage(
2593
+ options.prompt,
2594
+ // Non-null assertion since we validated above
2595
+ {
2596
+ model: "gpt-image-1",
2597
+ images: options.images,
2598
+ size: options.size,
2599
+ quality: options.quality,
2600
+ n: options.n,
2601
+ background: options.background,
2602
+ response_format: "url",
2603
+ signal: options.signal
2604
+ }
2605
+ );
2606
+ let imageResponse;
2607
+ if (response.data?.result?.data) {
2608
+ imageResponse = response.data.result;
2609
+ } else if (response.data?.data) {
2610
+ imageResponse = response.data;
2611
+ } else {
2612
+ throw new BlinkAIError("Invalid response format: missing image data");
2613
+ }
2614
+ if (!Array.isArray(imageResponse.data)) {
2615
+ throw new BlinkAIError("Invalid response format: data should be an array");
2616
+ }
2617
+ imageResponse.data = imageResponse.data.map((item) => {
2618
+ if (typeof item === "string") {
2619
+ return { url: item };
2620
+ } else if (item.url) {
2621
+ return item;
2622
+ } else {
2623
+ throw new BlinkAIError("Invalid image response format");
2624
+ }
2625
+ });
2626
+ return imageResponse;
2627
+ } catch (error) {
2628
+ if (error instanceof BlinkAIError) {
2629
+ throw error;
2630
+ }
2631
+ throw new BlinkAIError(
2632
+ `Image modification failed: ${error instanceof Error ? error.message : "Unknown error"}`,
2633
+ void 0,
2634
+ { originalError: error }
2635
+ );
2636
+ }
2637
+ }
2452
2638
  /**
2453
2639
  * Converts text to speech using AI voice synthesis models.
2454
2640
  *
package/dist/index.mjs CHANGED
@@ -1885,6 +1885,74 @@ var BlinkStorageImpl = class {
1885
1885
  );
1886
1886
  }
1887
1887
  }
1888
+ /**
1889
+ * Get a download URL for a file that triggers browser download
1890
+ *
1891
+ * @param path - Path to the file in project storage
1892
+ * @param options - Download options including custom filename
1893
+ * @returns Promise resolving to download response with download URL
1894
+ *
1895
+ * @example
1896
+ * ```ts
1897
+ * // Download with original filename
1898
+ * const { downloadUrl, filename } = await blink.storage.download('images/photo.jpg');
1899
+ * window.open(downloadUrl, '_blank');
1900
+ *
1901
+ * // Download with custom filename
1902
+ * const { downloadUrl } = await blink.storage.download(
1903
+ * 'images/photo.jpg',
1904
+ * { filename: 'my-photo.jpg' }
1905
+ * );
1906
+ *
1907
+ * // Create download link in React
1908
+ * <a href={downloadUrl} download={filename}>Download Image</a>
1909
+ * ```
1910
+ */
1911
+ async download(path, options = {}) {
1912
+ try {
1913
+ if (!path || typeof path !== "string" || !path.trim()) {
1914
+ throw new BlinkStorageError("Path must be a non-empty string");
1915
+ }
1916
+ const response = await this.httpClient.request(
1917
+ `/api/storage/${this.httpClient.projectId}/download`,
1918
+ {
1919
+ method: "GET",
1920
+ searchParams: {
1921
+ path: path.trim(),
1922
+ ...options.filename && { filename: options.filename }
1923
+ }
1924
+ }
1925
+ );
1926
+ if (response.data?.downloadUrl) {
1927
+ return {
1928
+ downloadUrl: response.data.downloadUrl,
1929
+ filename: response.data.filename || options.filename || path.split("/").pop() || "download",
1930
+ contentType: response.data.contentType,
1931
+ size: response.data.size
1932
+ };
1933
+ } else {
1934
+ throw new BlinkStorageError("Invalid response format: missing downloadUrl");
1935
+ }
1936
+ } catch (error) {
1937
+ if (error instanceof BlinkStorageError) {
1938
+ throw error;
1939
+ }
1940
+ if (error instanceof Error && "status" in error) {
1941
+ const status = error.status;
1942
+ if (status === 404) {
1943
+ throw new BlinkStorageError("File not found", 404);
1944
+ }
1945
+ if (status === 400) {
1946
+ throw new BlinkStorageError("Invalid request parameters", 400);
1947
+ }
1948
+ }
1949
+ throw new BlinkStorageError(
1950
+ `Download failed: ${error instanceof Error ? error.message : "Unknown error"}`,
1951
+ void 0,
1952
+ { originalError: error }
1953
+ );
1954
+ }
1955
+ }
1888
1956
  /**
1889
1957
  * Remove one or more files from project storage
1890
1958
  *
@@ -2352,15 +2420,15 @@ var BlinkAIImpl = class {
2352
2420
  }
2353
2421
  }
2354
2422
  /**
2355
- * Generates images from text descriptions using AI image models.
2423
+ * Generates images from text descriptions using AI.
2356
2424
  *
2357
2425
  * @param options - Object containing:
2358
- * - `prompt`: Text description of the image to generate (required)
2359
- * - `size`: Image dimensions (e.g., "1024x1024", "512x512") - varies by model
2360
- * - `quality`: Image quality ("standard" or "hd")
2426
+ * - `prompt`: Text description of the desired image (required)
2427
+ * - `size`: Image dimensions (default: "1024x1024")
2428
+ * - `quality`: Image quality ("standard" or "hd", default: "standard")
2361
2429
  * - `n`: Number of images to generate (default: 1)
2362
- * - `response_format`: Output format ("url" or "b64_json")
2363
- * - Plus optional model, signal parameters
2430
+ * - `background`: Background handling ("auto", "transparent", "opaque", default: "auto")
2431
+ * - Plus optional signal parameter
2364
2432
  *
2365
2433
  * @example
2366
2434
  * ```ts
@@ -2373,29 +2441,25 @@ var BlinkAIImpl = class {
2373
2441
  * // High-quality image with specific size
2374
2442
  * const { data } = await blink.ai.generateImage({
2375
2443
  * prompt: "A futuristic city skyline with flying cars",
2376
- * size: "1792x1024",
2444
+ * size: "1536x1024",
2377
2445
  * quality: "hd",
2378
- * model: "dall-e-3"
2446
+ * background: "transparent"
2379
2447
  * });
2380
2448
  *
2381
2449
  * // Multiple images
2382
2450
  * const { data } = await blink.ai.generateImage({
2383
2451
  * prompt: "A cute robot mascot for a tech company",
2384
2452
  * n: 3,
2385
- * size: "1024x1024"
2453
+ * size: "1024x1024",
2454
+ * quality: "hd"
2386
2455
  * });
2387
2456
  * data.forEach((img, i) => console.log(`Image ${i+1}:`, img.url));
2388
- *
2389
- * // Base64 format for direct embedding
2390
- * const { data } = await blink.ai.generateImage({
2391
- * prompt: "A minimalist logo design",
2392
- * response_format: "b64_json"
2393
- * });
2394
- * console.log("Base64 data:", data[0].b64_json);
2395
2457
  * ```
2396
2458
  *
2397
2459
  * @returns Promise<ImageGenerationResponse> - Object containing:
2398
- * - `data`: Array of generated images with url or b64_json
2460
+ * - `data`: Array of generated images with URLs
2461
+ * - `created`: Timestamp of generation
2462
+ * - `usage`: Token usage information
2399
2463
  */
2400
2464
  async generateImage(options) {
2401
2465
  try {
@@ -2405,11 +2469,12 @@ var BlinkAIImpl = class {
2405
2469
  const response = await this.httpClient.aiImage(
2406
2470
  options.prompt,
2407
2471
  {
2408
- model: options.model,
2472
+ model: "gpt-image-1",
2409
2473
  size: options.size,
2410
2474
  quality: options.quality,
2411
2475
  n: options.n,
2412
- response_format: options.response_format,
2476
+ background: options.background,
2477
+ response_format: "url",
2413
2478
  signal: options.signal
2414
2479
  }
2415
2480
  );
@@ -2429,10 +2494,8 @@ var BlinkAIImpl = class {
2429
2494
  return { url: item };
2430
2495
  } else if (item.url) {
2431
2496
  return item;
2432
- } else if (item.b64_json) {
2433
- return { b64_json: item.b64_json };
2434
2497
  } else {
2435
- return { url: item };
2498
+ throw new BlinkAIError("Invalid image response format");
2436
2499
  }
2437
2500
  });
2438
2501
  return imageResponse;
@@ -2447,6 +2510,129 @@ var BlinkAIImpl = class {
2447
2510
  );
2448
2511
  }
2449
2512
  }
2513
+ /**
2514
+ * Modifies existing images using AI with text prompts for image-to-image editing.
2515
+ *
2516
+ * @param options - Object containing:
2517
+ * - `images`: Array of public image URLs to modify (required, up to 16 images)
2518
+ * - `prompt`: Text description of desired modifications (required)
2519
+ * - `size`: Output image dimensions (default: "auto")
2520
+ * - `quality`: Image quality ("standard" or "hd", default: "standard")
2521
+ * - `n`: Number of output images to generate (default: 1)
2522
+ * - `background`: Background handling ("auto", "transparent", "opaque", default: "auto")
2523
+ * - Plus optional signal parameter
2524
+ *
2525
+ * @example
2526
+ * ```ts
2527
+ * // Professional headshots from casual photos
2528
+ * const { data } = await blink.ai.modifyImage({
2529
+ * images: [
2530
+ * "https://storage.example.com/user-photo-1.jpg",
2531
+ * "https://storage.example.com/user-photo-2.jpg"
2532
+ * ],
2533
+ * prompt: "Transform into professional business headshots with studio lighting",
2534
+ * quality: "hd",
2535
+ * n: 4
2536
+ * });
2537
+ * data.forEach((img, i) => console.log(`Headshot ${i+1}:`, img.url));
2538
+ *
2539
+ * // Artistic style transformation
2540
+ * const { data } = await blink.ai.modifyImage({
2541
+ * images: ["https://storage.example.com/portrait.jpg"],
2542
+ * prompt: "Transform into oil painting style with dramatic lighting",
2543
+ * quality: "hd",
2544
+ * size: "1024x1024"
2545
+ * });
2546
+ *
2547
+ * // Background replacement
2548
+ * const { data } = await blink.ai.modifyImage({
2549
+ * images: ["https://storage.example.com/product.jpg"],
2550
+ * prompt: "Remove background and place on clean white studio background",
2551
+ * background: "transparent",
2552
+ * n: 2
2553
+ * });
2554
+ *
2555
+ * // Batch processing multiple photos
2556
+ * const userPhotos = [
2557
+ * "https://storage.example.com/photo1.jpg",
2558
+ * "https://storage.example.com/photo2.jpg",
2559
+ * "https://storage.example.com/photo3.jpg"
2560
+ * ];
2561
+ * const { data } = await blink.ai.modifyImage({
2562
+ * images: userPhotos,
2563
+ * prompt: "Convert to black and white vintage style photographs",
2564
+ * quality: "hd"
2565
+ * });
2566
+ * ```
2567
+ *
2568
+ * @returns Promise<ImageGenerationResponse> - Object containing:
2569
+ * - `data`: Array of modified images with URLs
2570
+ * - `created`: Timestamp of generation
2571
+ * - `usage`: Token usage information
2572
+ */
2573
+ async modifyImage(options) {
2574
+ try {
2575
+ if (!options.prompt) {
2576
+ throw new BlinkAIError("Prompt is required");
2577
+ }
2578
+ if (!options.images || !Array.isArray(options.images) || options.images.length === 0) {
2579
+ throw new BlinkAIError("Images array is required and must contain at least one image URL");
2580
+ }
2581
+ if (options.images.length > 16) {
2582
+ throw new BlinkAIError("Maximum 16 images allowed");
2583
+ }
2584
+ for (let i = 0; i < options.images.length; i++) {
2585
+ const validation = this.validateImageUrl(options.images[i]);
2586
+ if (!validation.isValid) {
2587
+ throw new BlinkAIError(`Image ${i + 1}: ${validation.error}`);
2588
+ }
2589
+ }
2590
+ const response = await this.httpClient.aiImage(
2591
+ options.prompt,
2592
+ // Non-null assertion since we validated above
2593
+ {
2594
+ model: "gpt-image-1",
2595
+ images: options.images,
2596
+ size: options.size,
2597
+ quality: options.quality,
2598
+ n: options.n,
2599
+ background: options.background,
2600
+ response_format: "url",
2601
+ signal: options.signal
2602
+ }
2603
+ );
2604
+ let imageResponse;
2605
+ if (response.data?.result?.data) {
2606
+ imageResponse = response.data.result;
2607
+ } else if (response.data?.data) {
2608
+ imageResponse = response.data;
2609
+ } else {
2610
+ throw new BlinkAIError("Invalid response format: missing image data");
2611
+ }
2612
+ if (!Array.isArray(imageResponse.data)) {
2613
+ throw new BlinkAIError("Invalid response format: data should be an array");
2614
+ }
2615
+ imageResponse.data = imageResponse.data.map((item) => {
2616
+ if (typeof item === "string") {
2617
+ return { url: item };
2618
+ } else if (item.url) {
2619
+ return item;
2620
+ } else {
2621
+ throw new BlinkAIError("Invalid image response format");
2622
+ }
2623
+ });
2624
+ return imageResponse;
2625
+ } catch (error) {
2626
+ if (error instanceof BlinkAIError) {
2627
+ throw error;
2628
+ }
2629
+ throw new BlinkAIError(
2630
+ `Image modification failed: ${error instanceof Error ? error.message : "Unknown error"}`,
2631
+ void 0,
2632
+ { originalError: error }
2633
+ );
2634
+ }
2635
+ }
2450
2636
  /**
2451
2637
  * Converts text to speech using AI voice synthesis models.
2452
2638
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinkdotnew/sdk",
3
- "version": "0.14.13",
3
+ "version": "0.16.0",
4
4
  "description": "Blink TypeScript SDK for client-side applications - Zero-boilerplate CRUD + auth + AI + analytics + notifications for modern SaaS/AI apps",
5
5
  "keywords": [
6
6
  "blink",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "dependencies": {},
52
52
  "devDependencies": {
53
- "@blink/core": "workspace:*",
53
+ "@blink/core": "0.4.0",
54
54
  "tsup": "^8.0.0",
55
55
  "typescript": "^5.0.0"
56
56
  },