@outfitcanvas/fitview-sdk 1.0.1

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.
@@ -0,0 +1,729 @@
1
+ /**
2
+ * Available models for virtual try-on
3
+ */
4
+ declare enum OutfitCanvasModel {
5
+ CanvasPro = "canvas-pro",
6
+ CanvasProFast = "canvas-pro-fast",
7
+ CanvasStandard = "canvas-standard",
8
+ CanvasPlus = "canvas-plus",
9
+ CanvasExpress = "canvas-express",
10
+ CanvasInstant = "canvas-instant",
11
+ CanvasFashion = "canvas-fashion",
12
+ CanvasCasual = "canvas-casual",
13
+ CanvasFormal = "canvas-formal",
14
+ Canvas4K = "canvas-4k",
15
+ CanvasVideo = "canvas-video"
16
+ }
17
+ /**
18
+ * Image input format
19
+ */
20
+ interface ImageInput {
21
+ type: 'url' | 'base64';
22
+ data: string;
23
+ mimeType?: string;
24
+ }
25
+ /**
26
+ * Device information
27
+ */
28
+ interface DeviceInfo {
29
+ userAgent?: string;
30
+ ipAddress?: string;
31
+ deviceType?: 'mobile' | 'tablet' | 'desktop' | 'other';
32
+ os?: string;
33
+ browser?: string;
34
+ }
35
+ /**
36
+ * User demographics (with consent)
37
+ */
38
+ interface UserDemographics {
39
+ ageRange?: string;
40
+ age?: string;
41
+ gender?: string;
42
+ income_bracket?: string;
43
+ education_level?: string;
44
+ consentGiven?: boolean;
45
+ }
46
+ /**
47
+ * Location information
48
+ */
49
+ interface LocationInfo {
50
+ country?: string;
51
+ region?: string;
52
+ city?: string;
53
+ timezone?: string;
54
+ latitude?: number;
55
+ longitude?: number;
56
+ }
57
+ /**
58
+ * User preferences
59
+ */
60
+ interface UserPreferences {
61
+ styleKeywords?: string[];
62
+ favoriteBrands?: string[];
63
+ colorPreferences?: string[];
64
+ }
65
+ /**
66
+ * User context
67
+ */
68
+ interface UserContext {
69
+ device?: DeviceInfo;
70
+ demographics?: UserDemographics;
71
+ location?: LocationInfo;
72
+ preferences?: UserPreferences;
73
+ }
74
+ /** Garment category for multi-garment requests */
75
+ type GarmentType = 'top' | 'bottom' | 'shoes' | 'accessories' | 'dress' | 'outerwear' | 'footwear';
76
+ /** Single garment input (for garments array) */
77
+ interface GarmentInput {
78
+ image: string | ImageInput;
79
+ category?: GarmentType;
80
+ order?: number;
81
+ recommended_items?: Array<{
82
+ type: GarmentType;
83
+ id?: string;
84
+ name?: string;
85
+ image_url?: string;
86
+ metadata?: Record<string, unknown>;
87
+ }>;
88
+ size_letters_to_dimensions?: Array<{
89
+ size: string;
90
+ dimensions: Record<string, string>;
91
+ }>;
92
+ metadata?: Record<string, unknown>;
93
+ }
94
+ /** Director mode options (canvas-pro, canvas-fashion) */
95
+ interface DirectorModeOptions {
96
+ pose_presets?: Array<'front_facing' | 'left_shoulder' | 'right_shoulder' | 'three_quarter_left' | 'three_quarter_right' | 'profile_left' | 'profile_right' | 'full_body_front' | 'full_body_side'>;
97
+ number_of_poses?: number;
98
+ video_style_presets?: Array<'walking' | 'posing' | 'turning' | 'casual' | 'runway' | 'natural' | 'dynamic'>;
99
+ image_prompt?: string;
100
+ video_prompt?: string;
101
+ }
102
+ /**
103
+ * FitView generation request
104
+ */
105
+ interface FitViewRequest {
106
+ person_image: string | ImageInput;
107
+ garment_image?: string | ImageInput;
108
+ garments?: GarmentInput[];
109
+ model?: OutfitCanvasModel | string;
110
+ quality?: 'fast' | 'balanced' | 'high';
111
+ use_case?: 'casual' | 'fashion' | 'formal';
112
+ multi_garment_mode?: 'fast' | 'advanced';
113
+ user_id?: string;
114
+ session_id?: string;
115
+ product_id?: string;
116
+ idempotency_key?: string;
117
+ webhook_url?: string;
118
+ video_duration?: 5 | 10;
119
+ video_length?: 'short' | 'long';
120
+ ads_mode?: boolean;
121
+ director_mode?: DirectorModeOptions;
122
+ context?: UserContext;
123
+ demographics?: UserDemographics;
124
+ location?: LocationInfo;
125
+ usage_preferences?: UsagePreferences;
126
+ metadata?: Record<string, unknown>;
127
+ }
128
+ /**
129
+ * Usage and content preferences (top-level or in context)
130
+ */
131
+ interface UsagePreferences {
132
+ person_image_is_actual_user?: boolean;
133
+ allow_public_feed?: boolean;
134
+ occasion?: string;
135
+ marketing_consent?: boolean;
136
+ }
137
+ /**
138
+ * FitView result data
139
+ */
140
+ interface FitViewResultData {
141
+ fitview_url: string;
142
+ thumbnail_url?: string;
143
+ generation_time_ms?: number;
144
+ model_used?: string;
145
+ model_version?: string;
146
+ }
147
+ /**
148
+ * Enriched data
149
+ */
150
+ interface EnrichedData {
151
+ detected_garment_category?: string;
152
+ color_palette?: string[];
153
+ recommended_colors?: string[];
154
+ person_attributes?: Record<string, any>;
155
+ garment_attributes?: Record<string, any>;
156
+ }
157
+ /**
158
+ * FitView error details
159
+ */
160
+ /** Retry guidance from the API */
161
+ interface RetryGuidance {
162
+ shouldRetry?: boolean;
163
+ retryAfter?: number;
164
+ maxRetries?: number;
165
+ guidance?: string;
166
+ isTransient?: boolean;
167
+ }
168
+ interface FitViewError$1 {
169
+ code: string;
170
+ message: string;
171
+ details?: Record<string, unknown>;
172
+ retry?: RetryGuidance;
173
+ }
174
+ /**
175
+ * Response metadata
176
+ */
177
+ interface ResponseMetadata {
178
+ api_version?: string;
179
+ request_id?: string;
180
+ timestamp?: string;
181
+ credit_cost?: number;
182
+ credit_cost_type?: 'estimated' | 'charged';
183
+ total_time_ms?: number;
184
+ }
185
+ /**
186
+ * FitView response from API (inner payload; API wraps in { success, data, requestId, timestamp })
187
+ */
188
+ interface FitViewResponse {
189
+ job_id: string;
190
+ status: 'queued' | 'processing' | 'completed' | 'failed';
191
+ result?: FitViewResultData;
192
+ enriched_data?: EnrichedData;
193
+ error?: FitViewError$1;
194
+ metadata?: ResponseMetadata;
195
+ }
196
+ /** API response envelope */
197
+ interface ApiResponseEnvelope<T> {
198
+ success: boolean;
199
+ data?: T;
200
+ requestId?: string;
201
+ timestamp?: string;
202
+ error?: {
203
+ code: string;
204
+ message: string;
205
+ details?: Record<string, unknown>;
206
+ };
207
+ }
208
+ /**
209
+ * Model information
210
+ */
211
+ interface ModelInfo {
212
+ id: OutfitCanvasModel;
213
+ displayName: string;
214
+ description?: string;
215
+ creditCost: number;
216
+ estimatedLatencyMs: number;
217
+ maxImageSize?: {
218
+ width: number;
219
+ height: number;
220
+ };
221
+ }
222
+ /**
223
+ * Batch request
224
+ */
225
+ interface FitViewBatchRequest {
226
+ requests: FitViewRequest[];
227
+ }
228
+ /**
229
+ * Batch result item
230
+ */
231
+ interface FitViewBatchResultItem {
232
+ request: FitViewRequest;
233
+ response?: FitViewResponse;
234
+ error?: FitViewError$1;
235
+ }
236
+ /**
237
+ * Batch response
238
+ */
239
+ interface FitViewBatchResponse {
240
+ batch_id: string;
241
+ total_requests: number;
242
+ success_count: number;
243
+ failure_count: number;
244
+ results: FitViewBatchResultItem[];
245
+ metadata?: ResponseMetadata;
246
+ }
247
+ /** Rate limit add-on item */
248
+ interface RateLimitAddon {
249
+ id: string;
250
+ additional_requests_per_minute: number;
251
+ duration_days: number;
252
+ expires_at: string;
253
+ created_at: string;
254
+ }
255
+ /** Billing rate limit add-ons response */
256
+ interface RateLimitAddonsResponse {
257
+ active_addons: RateLimitAddon[];
258
+ total_boost: number;
259
+ }
260
+ /** Component health (for readiness) */
261
+ interface ComponentHealth {
262
+ status: 'up' | 'down' | 'degraded';
263
+ latency?: number;
264
+ message?: string;
265
+ }
266
+ /** Health status (ready/live) */
267
+ interface HealthStatus {
268
+ status: 'healthy' | 'degraded' | 'unhealthy';
269
+ version?: string;
270
+ uptime?: number;
271
+ timestamp?: string;
272
+ checks?: {
273
+ database?: ComponentHealth;
274
+ redis?: ComponentHealth;
275
+ providers?: Record<string, ComponentHealth>;
276
+ };
277
+ }
278
+ /**
279
+ * Client configuration options
280
+ */
281
+ interface FitViewClientOptions {
282
+ /**
283
+ * API key for authentication (Bearer token or X-API-Key depending on authMethod)
284
+ */
285
+ apiKey: string;
286
+ /**
287
+ * Base URL of the API (default: https://api.fitview.com)
288
+ */
289
+ baseURL?: string;
290
+ /**
291
+ * Request timeout in milliseconds (default: 300000 = 5 minutes)
292
+ */
293
+ timeout?: number;
294
+ /**
295
+ * API version (default: v1)
296
+ */
297
+ apiVersion?: string;
298
+ /**
299
+ * Max retries for 429 and 5xx (default: 3). Set 0 to disable.
300
+ */
301
+ maxRetries?: number;
302
+ /**
303
+ * Base delay in ms between retries (default: 1000). Exponential backoff is used.
304
+ */
305
+ retryDelay?: number;
306
+ /**
307
+ * Use Bearer token (default) or X-API-Key header
308
+ */
309
+ authMethod?: 'bearer' | 'apiKey';
310
+ /**
311
+ * Custom fetch implementation
312
+ */
313
+ fetch?: typeof fetch;
314
+ /**
315
+ * Additional headers to include in requests
316
+ */
317
+ headers?: Record<string, string>;
318
+ /**
319
+ * Validate image inputs (format, size) before sending (default: true).
320
+ * Reduces unnecessary API calls and returns clear errors from the SDK.
321
+ */
322
+ validateInputImages?: boolean;
323
+ /**
324
+ * Optimize base64 images client-side (resize/recompress) when sharp is available (default: false).
325
+ * Saves backend compute; URLs are not optimized.
326
+ */
327
+ optimizeImages?: boolean;
328
+ /**
329
+ * Options for client-side image optimization (only used when optimizeImages is true).
330
+ */
331
+ optimizeImageOptions?: {
332
+ maxDimension?: number;
333
+ jpegQuality?: number;
334
+ outputFormat?: 'jpeg' | 'png' | 'webp' | 'original';
335
+ };
336
+ }
337
+ /** Response from the upload image endpoint (POST /fitview/upload) */
338
+ interface UploadImageResponse {
339
+ url: string;
340
+ signed_url?: string;
341
+ filename?: string;
342
+ size?: number;
343
+ content_type?: string;
344
+ }
345
+ /**
346
+ * Wait options for polling
347
+ */
348
+ interface WaitOptions {
349
+ /**
350
+ * Maximum time to wait in milliseconds (default: 300000 = 5 minutes)
351
+ */
352
+ timeout?: number;
353
+ /**
354
+ * Ms to wait before the first status fetch. Default: 10000 (10 seconds).
355
+ * ⚠️ Consult FitView support before changing this default; other values may affect rate limits and reliability.
356
+ */
357
+ initialDelay?: number;
358
+ /**
359
+ * Ms between subsequent status fetches after the first. Default: 2000 (2 seconds).
360
+ * ⚠️ Consult FitView support before changing this default; other values may affect rate limits and reliability.
361
+ */
362
+ interval?: number;
363
+ /**
364
+ * Callback function called on each poll
365
+ */
366
+ onProgress?: (response: FitViewResponse | any) => void;
367
+ }
368
+
369
+ /**
370
+ * FitViewResult - Wrapper class for FitView API responses
371
+ * Provides convenient methods and getters for working with results
372
+ */
373
+ declare class FitViewResult {
374
+ private readonly _response;
375
+ private readonly _client;
376
+ constructor(response: FitViewResponse, client: FitViewClient);
377
+ /**
378
+ * Get the job ID
379
+ */
380
+ get jobId(): string;
381
+ /**
382
+ * Get the current status
383
+ */
384
+ get status(): FitViewResponse['status'];
385
+ /**
386
+ * Get the fitview image URL (if completed)
387
+ */
388
+ get fitviewUrl(): string | undefined;
389
+ /**
390
+ * Get the thumbnail URL (if available)
391
+ */
392
+ get thumbnailUrl(): string | undefined;
393
+ /**
394
+ * Get the model used for generation
395
+ */
396
+ get modelUsed(): string | undefined;
397
+ /**
398
+ * Get the model version
399
+ */
400
+ get modelVersion(): string | undefined;
401
+ /**
402
+ * Get generation time in milliseconds
403
+ */
404
+ get generationTimeMs(): number | undefined;
405
+ /**
406
+ * Get enriched data
407
+ */
408
+ get enrichedData(): EnrichedData | undefined;
409
+ /**
410
+ * Get error information (if failed)
411
+ */
412
+ get error(): FitViewError$1 | undefined;
413
+ /**
414
+ * Get the full result data
415
+ */
416
+ get result(): FitViewResultData | undefined;
417
+ /**
418
+ * Get response metadata
419
+ */
420
+ get metadata(): FitViewResponse['metadata'];
421
+ /**
422
+ * Get the raw API response
423
+ */
424
+ get rawResponse(): FitViewResponse;
425
+ /**
426
+ * Check if the job is completed
427
+ */
428
+ isCompleted(): boolean;
429
+ /**
430
+ * Check if the job has failed
431
+ */
432
+ isFailed(): boolean;
433
+ /**
434
+ * Check if the job is still processing
435
+ */
436
+ isProcessing(): boolean;
437
+ /**
438
+ * Download the fitview image
439
+ * @returns Promise resolving to the image as a Buffer or Blob
440
+ */
441
+ download(): Promise<Buffer | Blob>;
442
+ /**
443
+ * Refresh the result by fetching the latest status from the API
444
+ * @returns Updated FitViewResult
445
+ */
446
+ refresh(): Promise<FitViewResult>;
447
+ /**
448
+ * Wait for the job to complete
449
+ * @param options Wait options
450
+ * @returns Promise resolving when job completes
451
+ */
452
+ waitForCompletion(options?: {
453
+ timeout?: number;
454
+ initialDelay?: number;
455
+ interval?: number;
456
+ onProgress?: (result: FitViewResult) => void;
457
+ }): Promise<FitViewResult>;
458
+ /**
459
+ * Convert to JSON
460
+ */
461
+ toJSON(): FitViewResponse;
462
+ /**
463
+ * Convert to string
464
+ */
465
+ toString(): string;
466
+ }
467
+
468
+ /**
469
+ * FitViewClient - Main client class for interacting with the FitView API
470
+ */
471
+ declare class FitViewClient {
472
+ private readonly apiKey;
473
+ private readonly baseURL;
474
+ private readonly timeout;
475
+ private readonly apiVersion;
476
+ private readonly maxRetries;
477
+ private readonly retryDelay;
478
+ readonly fetchImpl: typeof fetch;
479
+ private readonly headers;
480
+ private readonly authHeader;
481
+ private readonly validateInputImages;
482
+ private readonly optimizeImages;
483
+ private readonly optimizeImageOptions;
484
+ constructor(options: FitViewClientOptions);
485
+ /**
486
+ * Make an HTTP request with optional retries for 429 and 5xx
487
+ */
488
+ private request;
489
+ private doRequest;
490
+ /**
491
+ * Handle error responses from the API. Throws a typed error with a clear message.
492
+ */
493
+ private handleErrorResponse;
494
+ /**
495
+ * Create a new virtual try-on job. Use URLs or base64 for person_image and garment_image (or garments array).
496
+ * @param request - FitView generation request. Requires person_image; requires garment_image or garments.
497
+ * @returns Promise resolving to FitViewResult with jobId, status; call waitForCompletion() or poll getFitView(jobId).
498
+ * @throws FitViewValidationError if request is invalid, FitViewInsufficientCreditsError on 402, FitViewRateLimitError on 429
499
+ * @example
500
+ * const result = await client.generateFitView({ person_image: 'https://...', garment_image: 'https://...', model: OutfitCanvasModel.CanvasStandard });
501
+ * const completed = await result.waitForCompletion();
502
+ */
503
+ generateFitView(request: FitViewRequest): Promise<FitViewResult>;
504
+ /**
505
+ * Get the status of a FitView job
506
+ * @param jobId Job ID (must start with 'fv_')
507
+ * @returns Promise resolving to FitViewResult
508
+ */
509
+ getFitView(jobId: string): Promise<FitViewResult>;
510
+ /**
511
+ * Generate multiple virtual try-on results in a batch (max 50)
512
+ * @param requests Array of FitView requests
513
+ * @returns Promise resolving to FitViewBatchResponse with batch_id and results
514
+ */
515
+ batchGenerateFitView(requests: FitViewRequest[]): Promise<FitViewBatchResponse>;
516
+ /**
517
+ * List available models for your account tier
518
+ * @returns Promise resolving to array of ModelInfo (id, displayName, creditCost, etc.)
519
+ */
520
+ listModels(): Promise<ModelInfo[]>;
521
+ /**
522
+ * Get active rate limit add-ons and total boost (billing)
523
+ * @returns Promise resolving to active_addons and total_boost
524
+ */
525
+ getRateLimitAddons(): Promise<RateLimitAddonsResponse>;
526
+ /**
527
+ * Basic health check (no auth required)
528
+ * @returns Promise resolving to { status, timestamp }
529
+ */
530
+ healthCheck(): Promise<{
531
+ status: string;
532
+ timestamp?: string;
533
+ }>;
534
+ /**
535
+ * Readiness check (dependency health; no auth required)
536
+ * @returns Promise resolving to HealthStatus
537
+ */
538
+ readinessCheck(): Promise<HealthStatus>;
539
+ /**
540
+ * Liveness check (no auth required)
541
+ * @returns Promise resolving to { status: 'alive' }
542
+ */
543
+ livenessCheck(): Promise<{
544
+ status: string;
545
+ }>;
546
+ /**
547
+ * Upload an image (base64) to FitView storage and get back a URL.
548
+ * Use this for device images: upload first, then pass the returned URL to generateFitView.
549
+ * @param base64Image Base64 string (with or without data:image/...;base64, prefix)
550
+ * @param filename Optional filename hint for the stored file
551
+ * @returns Object with url (and optionally signed_url, filename, size, content_type)
552
+ */
553
+ uploadImage(base64Image: string, filename?: string): Promise<UploadImageResponse>;
554
+ /**
555
+ * Upload an image from a local file path (Node.js only).
556
+ * Reads the file, encodes as base64, and calls uploadImage. Use for server-side apps.
557
+ * @param filePath Absolute or relative path to the image file
558
+ * @param filename Optional filename hint (defaults to the base name of filePath)
559
+ * @returns Object with url (and optionally signed_url, filename, size, content_type)
560
+ */
561
+ uploadImageFromFile(filePath: string, filename?: string): Promise<UploadImageResponse>;
562
+ /**
563
+ * Generate a new idempotency key (UUID v4) for create-job requests.
564
+ * Send this in the `idempotency_key` field when calling generateFitView to safely retry the same request without creating duplicate jobs.
565
+ */
566
+ static generateIdempotencyKey(): string;
567
+ /**
568
+ * Poll until the job completes, fails, or times out. Defaults: 10s initial delay, then 2s interval.
569
+ * @param jobId - Job ID (e.g. from generateFitView result)
570
+ * @param options - Optional timeout (ms), initialDelay (ms), interval (ms), onProgress callback
571
+ * @returns Promise resolving to completed or failed FitViewResult
572
+ * @throws FitViewTimeoutError if timeout is reached, FitViewAPIError if job fails
573
+ * @example
574
+ * const completed = await client.waitForFitView(result.jobId, { timeout: 300000, onProgress: r => console.log(r.status) });
575
+ */
576
+ waitForFitView(jobId: string, options?: WaitOptions): Promise<FitViewResult>;
577
+ /**
578
+ * Verify webhook signature
579
+ * @param payload Raw webhook payload (string or Buffer)
580
+ * @param signature Signature from X-FitView-Signature header
581
+ * @param secret Webhook signing secret
582
+ * @returns True if signature is valid
583
+ */
584
+ verifyWebhook(payload: string | Buffer, signature: string, secret: string): boolean;
585
+ }
586
+
587
+ /**
588
+ * Generate a new idempotency key (UUID v4) for create-job requests.
589
+ * Use when calling generateFitView to safely retry the same request without creating duplicate jobs.
590
+ */
591
+ declare function generateIdempotencyKey(): string;
592
+
593
+ /**
594
+ * Base error class for all FitView SDK errors
595
+ */
596
+ declare class FitViewError extends Error {
597
+ readonly code: string;
598
+ readonly statusCode?: number;
599
+ readonly details?: Record<string, any>;
600
+ constructor(message: string, code: string, statusCode?: number, details?: Record<string, any>);
601
+ }
602
+ /**
603
+ * API error - errors returned from the FitView API
604
+ */
605
+ declare class FitViewAPIError extends FitViewError {
606
+ readonly response?: Response;
607
+ constructor(message: string, code: string, statusCode: number, response?: Response, details?: Record<string, any>);
608
+ }
609
+ /**
610
+ * Validation error - invalid request parameters
611
+ */
612
+ declare class FitViewValidationError extends FitViewError {
613
+ readonly validationErrors?: Array<{
614
+ path: string;
615
+ message: string;
616
+ }>;
617
+ constructor(message: string, validationErrors?: Array<{
618
+ path: string;
619
+ message: string;
620
+ }>);
621
+ }
622
+ /**
623
+ * Timeout error - request or polling timeout
624
+ */
625
+ declare class FitViewTimeoutError extends FitViewError {
626
+ constructor(message?: string);
627
+ }
628
+ /**
629
+ * Network error - connection or network issues
630
+ */
631
+ declare class FitViewNetworkError extends FitViewError {
632
+ readonly originalError?: Error;
633
+ constructor(message: string, originalError?: Error);
634
+ }
635
+ /**
636
+ * Authentication error - invalid or missing API key
637
+ */
638
+ declare class FitViewAuthenticationError extends FitViewError {
639
+ constructor(message?: string);
640
+ }
641
+ /**
642
+ * Rate limit error - too many requests
643
+ */
644
+ declare class FitViewRateLimitError extends FitViewError {
645
+ readonly retryAfter?: number;
646
+ constructor(message?: string, retryAfter?: number);
647
+ }
648
+ /**
649
+ * Insufficient credits error
650
+ */
651
+ declare class FitViewInsufficientCreditsError extends FitViewError {
652
+ readonly available?: number;
653
+ readonly required?: number;
654
+ constructor(message?: string, available?: number, required?: number);
655
+ }
656
+
657
+ /** Max image size in bytes (20MB - matches API) */
658
+ declare const MAX_IMAGE_SIZE_BYTES: number;
659
+ /** Accepted image formats (lowercase, matches API) */
660
+ declare const ACCEPTED_IMAGE_FORMATS: readonly ["jpeg", "jpg", "png", "webp", "heic", "heif"];
661
+ type AcceptedImageFormat = (typeof ACCEPTED_IMAGE_FORMATS)[number];
662
+ /** Result of validating a single image */
663
+ interface ImageValidationResult {
664
+ valid: boolean;
665
+ message?: string;
666
+ sizeBytes?: number;
667
+ format?: string;
668
+ }
669
+ /** Check if a string looks like valid base64 image data */
670
+ declare function isValidBase64(str: string): boolean;
671
+ /** Get decoded size in bytes from base64 string */
672
+ declare function getBase64Size(base64: string): number;
673
+ /** Detect image format from base64 data URL (e.g. data:image/jpeg;base64,...) */
674
+ declare function detectImageFormat(base64: string): string | null;
675
+ /**
676
+ * Validate a base64 image: format, size, and structure.
677
+ * Use this before sending to the API to fail fast and save backend compute.
678
+ */
679
+ declare function validateBase64Image(base64: string): ImageValidationResult;
680
+ /**
681
+ * Validate a single image input (URL or base64 string).
682
+ * URLs are only checked for valid http(s) format; size/format are validated server-side.
683
+ */
684
+ declare function validateImageInput(input: string): ImageValidationResult;
685
+ /** Constructor for validation errors (e.g. FitViewValidationError) - called with (message: string) */
686
+ type ValidationErrorConstructor = new (message: string) => Error;
687
+ /**
688
+ * Validate all image inputs in a FitView request.
689
+ * Call this before generateFitView when validateInputImages is enabled (default).
690
+ * @throws FitViewValidationError if any image fails validation
691
+ */
692
+ declare function validateFitViewRequestImages(request: {
693
+ person_image?: string | {
694
+ type?: string;
695
+ data?: string;
696
+ };
697
+ garment_image?: string | {
698
+ type?: string;
699
+ data?: string;
700
+ };
701
+ garments?: Array<{
702
+ image?: string | {
703
+ type?: string;
704
+ data?: string;
705
+ };
706
+ }>;
707
+ }, ValidationErrorClass: ValidationErrorConstructor): void;
708
+
709
+ interface OptimizeImageOptions {
710
+ /** Max width or height in pixels (default 2048) */
711
+ maxDimension?: number;
712
+ /** JPEG quality 1–100 when output is JPEG (default 85) */
713
+ jpegQuality?: number;
714
+ /** Output format: jpeg (smaller) or keep original */
715
+ outputFormat?: 'jpeg' | 'png' | 'webp' | 'original';
716
+ }
717
+ /**
718
+ * Optimize a base64 image: resize to max dimension and optionally recompress.
719
+ * Uses sharp if installed; otherwise returns the original string unchanged.
720
+ * Only works in Node.js (sharp is not used in browser builds).
721
+ */
722
+ declare function optimizeBase64Image(base64: string, options?: OptimizeImageOptions): Promise<string>;
723
+ /**
724
+ * Optimize all base64 image fields in a request (in place).
725
+ * URL inputs are left unchanged. Only runs when optimizeImages is true and sharp is available.
726
+ */
727
+ declare function optimizeRequestImages(request: Record<string, unknown>, options?: OptimizeImageOptions): Promise<void>;
728
+
729
+ export { ACCEPTED_IMAGE_FORMATS, type AcceptedImageFormat, type ApiResponseEnvelope, type ComponentHealth, type DeviceInfo, type DirectorModeOptions, type EnrichedData, FitViewAPIError, FitViewAuthenticationError, type FitViewBatchRequest, type FitViewBatchResponse, type FitViewBatchResultItem, FitViewClient, type FitViewClientOptions, FitViewError, type FitViewError$1 as FitViewErrorType, FitViewInsufficientCreditsError, FitViewNetworkError, FitViewRateLimitError, type FitViewRequest, type FitViewResponse, FitViewResult, type FitViewResultData, FitViewTimeoutError, FitViewValidationError, type GarmentInput, type GarmentType, type HealthStatus, type ImageInput, type ImageValidationResult, type LocationInfo, MAX_IMAGE_SIZE_BYTES, type ModelInfo, type OptimizeImageOptions, OutfitCanvasModel, type RateLimitAddon, type RateLimitAddonsResponse, type ResponseMetadata, type RetryGuidance, type UploadImageResponse, type UsagePreferences, type UserContext, type UserDemographics, type UserPreferences, type WaitOptions, detectImageFormat, generateIdempotencyKey, getBase64Size, isValidBase64, optimizeBase64Image, optimizeRequestImages, validateBase64Image, validateFitViewRequestImages, validateImageInput };