img-upload-kit 0.0.0-stage → 2.0.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.
Files changed (112) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/LICENSE +21 -0
  3. package/MIGRATION.md +192 -0
  4. package/README.md +242 -2
  5. package/dist/bin.js +1186 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/blur.cjs +41 -0
  8. package/dist/blur.cjs.map +1 -0
  9. package/dist/blur.d.cts +17 -0
  10. package/dist/blur.d.ts +17 -0
  11. package/dist/blur.js +41 -0
  12. package/dist/blur.js.map +1 -0
  13. package/dist/blurDataUtils-DveBRtqE.d.cts +43 -0
  14. package/dist/blurDataUtils-yx9Q6HlU.d.ts +43 -0
  15. package/dist/blurService-D5TpMNji.d.ts +83 -0
  16. package/dist/blurService-DacwylJx.d.cts +83 -0
  17. package/dist/chunk-2OVNXHTN.cjs +514 -0
  18. package/dist/chunk-2OVNXHTN.cjs.map +1 -0
  19. package/dist/chunk-3ICG2SLL.cjs +135 -0
  20. package/dist/chunk-3ICG2SLL.cjs.map +1 -0
  21. package/dist/chunk-4ASFG3KB.js +514 -0
  22. package/dist/chunk-4ASFG3KB.js.map +1 -0
  23. package/dist/chunk-AI3JJLSA.js +2370 -0
  24. package/dist/chunk-AI3JJLSA.js.map +1 -0
  25. package/dist/chunk-CV23O4YU.js +145 -0
  26. package/dist/chunk-CV23O4YU.js.map +1 -0
  27. package/dist/chunk-G7LLSKBV.js +158 -0
  28. package/dist/chunk-G7LLSKBV.js.map +1 -0
  29. package/dist/chunk-IB3TEDLR.js +294 -0
  30. package/dist/chunk-IB3TEDLR.js.map +1 -0
  31. package/dist/chunk-KJVYWKIG.cjs +158 -0
  32. package/dist/chunk-KJVYWKIG.cjs.map +1 -0
  33. package/dist/chunk-NEDBIIE3.cjs +226 -0
  34. package/dist/chunk-NEDBIIE3.cjs.map +1 -0
  35. package/dist/chunk-QHU7FUO4.cjs +37 -0
  36. package/dist/chunk-QHU7FUO4.cjs.map +1 -0
  37. package/dist/chunk-QQHZJKNA.js +135 -0
  38. package/dist/chunk-QQHZJKNA.js.map +1 -0
  39. package/dist/chunk-S2IFAWJK.js +37 -0
  40. package/dist/chunk-S2IFAWJK.js.map +1 -0
  41. package/dist/chunk-TT5C7K3Q.js +226 -0
  42. package/dist/chunk-TT5C7K3Q.js.map +1 -0
  43. package/dist/chunk-U2TWTEBY.cjs +2370 -0
  44. package/dist/chunk-U2TWTEBY.cjs.map +1 -0
  45. package/dist/chunk-WISG74VL.cjs +294 -0
  46. package/dist/chunk-WISG74VL.cjs.map +1 -0
  47. package/dist/chunk-YRXXQUDE.cjs +145 -0
  48. package/dist/chunk-YRXXQUDE.cjs.map +1 -0
  49. package/dist/cli.cjs +1241 -0
  50. package/dist/cli.cjs.map +1 -0
  51. package/dist/cli.d.cts +99 -0
  52. package/dist/cli.d.ts +99 -0
  53. package/dist/cli.js +1194 -0
  54. package/dist/cli.js.map +1 -0
  55. package/dist/headless.cjs +27 -0
  56. package/dist/headless.cjs.map +1 -0
  57. package/dist/headless.d.cts +4 -0
  58. package/dist/headless.d.ts +4 -0
  59. package/dist/headless.js +27 -0
  60. package/dist/headless.js.map +1 -0
  61. package/dist/index-BIdnqtW8.d.ts +234 -0
  62. package/dist/index-Brk_uHs6.d.cts +234 -0
  63. package/dist/index-CPMlaQsC.d.ts +635 -0
  64. package/dist/index-DHINe-rA.d.cts +635 -0
  65. package/dist/index.cjs +65 -0
  66. package/dist/index.cjs.map +1 -0
  67. package/dist/index.d.cts +43 -0
  68. package/dist/index.d.ts +43 -0
  69. package/dist/index.js +65 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/memoryAdapter-Ck0ccZbF.d.cts +25 -0
  72. package/dist/memoryAdapter-DxEKaG0b.d.ts +25 -0
  73. package/dist/placeholders-C4ftwaII.d.ts +5 -0
  74. package/dist/placeholders-x_3rt65M.d.cts +5 -0
  75. package/dist/react.cjs +3779 -0
  76. package/dist/react.cjs.map +1 -0
  77. package/dist/react.d.cts +476 -0
  78. package/dist/react.d.ts +476 -0
  79. package/dist/react.js +3779 -0
  80. package/dist/react.js.map +1 -0
  81. package/dist/server-handler.cjs +14 -0
  82. package/dist/server-handler.cjs.map +1 -0
  83. package/dist/server-handler.d.cts +3 -0
  84. package/dist/server-handler.d.ts +3 -0
  85. package/dist/server-handler.js +14 -0
  86. package/dist/server-handler.js.map +1 -0
  87. package/dist/server.cjs +1801 -0
  88. package/dist/server.cjs.map +1 -0
  89. package/dist/server.d.cts +142 -0
  90. package/dist/server.d.ts +142 -0
  91. package/dist/server.js +1801 -0
  92. package/dist/server.js.map +1 -0
  93. package/dist/storage.cjs +447 -0
  94. package/dist/storage.cjs.map +1 -0
  95. package/dist/storage.d.cts +163 -0
  96. package/dist/storage.d.ts +163 -0
  97. package/dist/storage.js +447 -0
  98. package/dist/storage.js.map +1 -0
  99. package/dist/styles/animated-image.css +112 -0
  100. package/dist/styles/dropzone-and-tiles.css +247 -0
  101. package/dist/styles/modals-and-dock.css +248 -0
  102. package/dist/styles/primitives.css +197 -0
  103. package/dist/styles/quality-and-inputs.css +184 -0
  104. package/dist/styles/tokens.css +123 -0
  105. package/dist/styles.css +1122 -0
  106. package/dist/types-BrP-o9nd.d.cts +85 -0
  107. package/dist/types-sZ3KoFQY.d.ts +85 -0
  108. package/dist/types-yShGNQnW.d.cts +61 -0
  109. package/dist/types-yShGNQnW.d.ts +61 -0
  110. package/dist/upload-C5Trd6Dh.d.cts +154 -0
  111. package/dist/upload-C5Trd6Dh.d.ts +154 -0
  112. package/package.json +198 -4
@@ -0,0 +1,234 @@
1
+ import { S as StorageAdapter, U as UploadRecordHook } from './types-BrP-o9nd.cjs';
2
+ import { c as ImageOutputFormat, b as ImageDimensions, E as ExplicitOutputFormat, d as ImageUploadOptions, m as UploadedImageData, k as UploadPresetConfig, i as StandardPresetName } from './upload-C5Trd6Dh.cjs';
3
+
4
+ interface OptimizedImageResult {
5
+ buffer: Buffer;
6
+ width: number;
7
+ height: number;
8
+ format: ImageOutputFormat;
9
+ size: number;
10
+ quality?: number;
11
+ }
12
+ interface BlurHashResult {
13
+ dataURL: string;
14
+ color: string;
15
+ blurHash?: string;
16
+ }
17
+ interface OptimizeImageOptions {
18
+ /** Max bounding box dimensions (fit: 'inside', withoutEnlargement: true). Defaults to 1920x1080. */
19
+ maxDimensions?: ImageDimensions;
20
+ /** Explicit output format; omit for smart size-guarded AVIF/WebP selection */
21
+ outputFormat?: ExplicitOutputFormat;
22
+ /** 1–100 compression quality. Defaults to smart photo/graphic heuristic (85–88). */
23
+ quality?: number;
24
+ /** Maximum input pixel count allowed by Sharp (defaults to 50 MP = 50,000,000) */
25
+ limitInputPixels?: number;
26
+ /** AVIF/WebP encoding effort (defaults to 6) */
27
+ effort?: number;
28
+ }
29
+ declare const DEFAULT_LIMIT_INPUT_PIXELS = 50000000;
30
+ interface GenerateBlurOptions {
31
+ width?: number;
32
+ fallbackWidth?: number;
33
+ quality?: number;
34
+ maxDataUrlChars?: number;
35
+ includeBlurHash?: boolean;
36
+ }
37
+ type ColorSamplingMode = 'balanced' | 'edge';
38
+ type EdgeKey = 'top' | 'right' | 'bottom' | 'left';
39
+ type EdgeColorSet = Record<EdgeKey, string>;
40
+ declare const PRIMARY_AVIF_EFFORT = 6;
41
+ declare const RETRY_AVIF_EFFORT = 5;
42
+ declare const BLUR_PLACEHOLDER_WIDTH = 128;
43
+ declare const BLUR_PLACEHOLDER_FALLBACK_WIDTH = 96;
44
+ declare const BLUR_PLACEHOLDER_QUALITY = 80;
45
+ declare const BLUR_PLACEHOLDER_MAX_CHARS = 8000;
46
+ declare const EDGE_COLOR_FALLBACK = "#6B7280";
47
+ declare const EDGE_WHITE_FALLBACK = "#F9FAFB";
48
+ declare const WHITE_DOMINANCE_RATIO = 1.35;
49
+
50
+ interface ProcessedImageBufferResult {
51
+ optimized: OptimizedImageResult;
52
+ blurData: BlurHashResult;
53
+ contentHash: string;
54
+ originalSize: number;
55
+ }
56
+ interface ProcessImageBufferOptions {
57
+ maxDimensions?: ImageDimensions;
58
+ outputFormat?: ExplicitOutputFormat;
59
+ quality?: number;
60
+ includeBlurHash?: boolean;
61
+ optimizationTimeoutMs?: number;
62
+ blurTimeoutMs?: number;
63
+ limitInputPixels?: number;
64
+ effort?: number;
65
+ allowSvg?: boolean;
66
+ signal?: AbortSignal;
67
+ }
68
+ interface StoragePathContext {
69
+ bucket: string;
70
+ folder?: string;
71
+ preset?: string;
72
+ format: ImageOutputFormat;
73
+ extension: string;
74
+ customFilename?: string;
75
+ isClientFilename?: boolean;
76
+ contentHash: string;
77
+ originalName?: string;
78
+ metadata?: Record<string, string>;
79
+ }
80
+ interface GeneratedStorageTarget {
81
+ bucket: string;
82
+ path: string;
83
+ filename: string;
84
+ }
85
+ type StoragePathGenerator = (context: StoragePathContext) => GeneratedStorageTarget;
86
+ interface ImageUploaderOptions<TPresets extends Record<string, UploadPresetConfig> = Record<StandardPresetName, UploadPresetConfig>> {
87
+ /** Pluggable storage backend (Supabase, S3, R2, Local FS, Memory, or custom) */
88
+ storage: StorageAdapter;
89
+ /** Default bucket name when neither `options.bucket` nor `preset.bucket` is provided (defaults to `'images'`) */
90
+ defaultBucket?: string;
91
+ /** Default folder prefix within the bucket (defaults to `''` or preset folder) */
92
+ defaultFolder?: string;
93
+ /** Default max input size in MB (defaults to `10`) */
94
+ defaultMaxSizeMB?: number;
95
+ /** Default allowed MIME formats */
96
+ defaultAllowedFormats?: string[];
97
+ /** Default max bounding box dimensions (defaults to `1920x1080`) */
98
+ defaultMaxDimensions?: ImageDimensions;
99
+ /** Opt-in to allow SVG uploads by default (sanitized before storage). Defaults to `false`. */
100
+ allowSvg?: boolean;
101
+ /** Maximum input pixel count allowed by Sharp (defaults to `50_000_000` = 50 MP) */
102
+ limitInputPixels?: number;
103
+ /** Default AVIF/WebP encoding effort (defaults to `6`) */
104
+ effort?: number;
105
+ /**
106
+ * Project-specific named presets (merged over universal `STANDARD_PRESETS` unless `includeStandardPresets: false`).
107
+ * Preset names are automatically inferred in `uploader.uploadImage(file, { preset })`.
108
+ */
109
+ presets?: TPresets;
110
+ /** Include universal visual role presets (`thumbnail`, `avatar`, `card`, `cover`, `hero`, `logo`, `original`). Defaults to `true`. */
111
+ includeStandardPresets?: boolean;
112
+ /** Custom storage path generator for full control over bucket/folder/filename layout */
113
+ pathGenerator?: StoragePathGenerator;
114
+ /** Optional database/analytics hook invoked after each successful upload */
115
+ onUploadRecord?: UploadRecordHook;
116
+ /** Wait for `onUploadRecord` before returning (defaults to `false` best-effort) */
117
+ awaitRecordHook?: boolean;
118
+ /** Optional error hook invoked when a non-awaited `onUploadRecord` fails */
119
+ onError?: (error: unknown, ctx: {
120
+ action: 'recordHook' | 'mirrorCleanup';
121
+ }) => void;
122
+ /** Max concurrent Sharp + LQIP image processing pipelines (defaults to `2`) */
123
+ concurrency?: number;
124
+ /** Max queued processing jobs waiting for a semaphore slot before rejecting with 503 */
125
+ maxQueue?: number;
126
+ /** Timeout per Sharp optimization job in ms (defaults to `60000`) */
127
+ optimizationTimeoutMs?: number;
128
+ /** Timeout per LQIP/blur generation job in ms (defaults to `30000`) */
129
+ blurTimeoutMs?: number;
130
+ /** Generate compact BlurHash strings by default on every upload */
131
+ includeBlurHash?: boolean;
132
+ }
133
+ type InferredPresetKey<TPresets extends Record<string, UploadPresetConfig>, TIncludeStandard extends boolean = true> = (keyof TPresets & string) | (TIncludeStandard extends false ? never : StandardPresetName) | (string & {});
134
+ interface ImageUploader<TPreset extends string = string> {
135
+ readonly defaultBucket?: string;
136
+ uploadImage(file: File | {
137
+ buffer: Buffer;
138
+ name?: string;
139
+ type: string;
140
+ size?: number;
141
+ }, options?: ImageUploadOptions<TPreset>): Promise<UploadedImageData>;
142
+ processBuffer(buffer: Buffer, options?: ProcessImageBufferOptions): Promise<ProcessedImageBufferResult>;
143
+ deleteImage(path: string, bucket?: string): Promise<void>;
144
+ deleteByUrl(url: string): Promise<boolean>;
145
+ resolvePreset(presetName?: string): UploadPresetConfig | undefined;
146
+ getAllowedBuckets?(): string[];
147
+ getMaxSizeMB?(allowedPresets?: string[]): number;
148
+ parseUrl?(url: string): {
149
+ bucket?: string;
150
+ path: string;
151
+ } | null;
152
+ }
153
+
154
+ interface AuthorizeContext {
155
+ action: 'upload' | 'delete';
156
+ request: Request;
157
+ path?: string;
158
+ bucket?: string;
159
+ preset?: string;
160
+ }
161
+ interface AllowClientOverrides {
162
+ /** Allow client `customFilename` field (always sanitized, forced to output extension, never upserted). */
163
+ filename?: boolean;
164
+ /**
165
+ * Allow client `folder` field. Pass `true` to accept sanitized folder names, or a callback
166
+ * `(folder, ctx) => string | null` that returns the scoped folder (or `null` to reject with 400).
167
+ */
168
+ folder?: boolean | ((folder: string, ctx: AuthorizeContext) => string | null | undefined);
169
+ /** Allow client `maxWidth` / `maxHeight` fields (clamped to the active preset's `maxDimensions`). */
170
+ dimensions?: boolean;
171
+ /** Allow client `outputFormat` field (`jpeg`, `png`, `webp`, `avif`). */
172
+ format?: boolean;
173
+ /** Allow client `quality` field (1–100, clamped to the active preset's `quality` when set). */
174
+ quality?: boolean;
175
+ }
176
+ interface UploadErrorContext {
177
+ action: 'upload' | 'delete';
178
+ request: Request;
179
+ }
180
+ interface UploadHttpHandlerOptions<TPreset extends string = string> {
181
+ uploader: ImageUploader<TPreset>;
182
+ /**
183
+ * Optional authorization check. Return `false` or throw to reject with 401.
184
+ */
185
+ authorize?: (ctx: AuthorizeContext) => boolean | Promise<boolean>;
186
+ /**
187
+ * Optional whitelist of allowed preset names.
188
+ */
189
+ allowedPresets?: TPreset[];
190
+ /**
191
+ * Optional CSRF/CORS origin allowlist (`string[]` of origins or predicate).
192
+ * When set, requests with a missing or disallowed `Origin`/`Referer` are rejected with 403.
193
+ */
194
+ allowedOrigins?: string[] | ((origin: string) => boolean);
195
+ /**
196
+ * Maximum allowed request body size in bytes (enforced via Content-Length precheck and stream cap).
197
+ * Defaults to `1.25 × max(preset.maxSizeMB, defaultMaxSizeMB)` (minimum 1 MB when unset).
198
+ */
199
+ maxBodyBytes?: number;
200
+ /**
201
+ * Opt-in switches for client-supplied FormData overrides. All default to `false` (ignored).
202
+ */
203
+ allowClientOverrides?: AllowClientOverrides;
204
+ /**
205
+ * Allow clients to override `bucket` via FormData or DELETE query params. Defaults to `false`.
206
+ */
207
+ allowClientBucketOverride?: boolean;
208
+ /**
209
+ * Optional explicit allowlist of bucket names permitted for upload and delete operations.
210
+ */
211
+ allowedBuckets?: string[];
212
+ /**
213
+ * Hook invoked when an unexpected 500 internal error occurs. Raw error details are never sent to clients.
214
+ */
215
+ onError?: (error: unknown, ctx: UploadErrorContext) => void;
216
+ }
217
+
218
+ declare class UploadValidationError extends Error {
219
+ readonly status = 400;
220
+ constructor(message: string);
221
+ }
222
+ declare function isClientValidationError(error: unknown): boolean;
223
+
224
+ /**
225
+ * Standard Web Fetch (`Request` -> `Response`) upload & delete route handlers.
226
+ * Works across Next.js App Router, Remix, React Router, SvelteKit, Astro, Hono, and Node Fetch servers.
227
+ */
228
+ declare function createUploadHttpHandler<TPreset extends string = string>(options: UploadHttpHandlerOptions<TPreset>): {
229
+ POST: (request: Request) => Promise<Response>;
230
+ DELETE: (request: Request) => Promise<Response>;
231
+ };
232
+ declare const createUploadHandler: typeof createUploadHttpHandler;
233
+
234
+ export { type AllowClientOverrides as A, type BlurHashResult as B, type ColorSamplingMode as C, DEFAULT_LIMIT_INPUT_PIXELS as D, type EdgeColorSet as E, type GenerateBlurOptions as G, type ImageUploaderOptions as I, type OptimizeImageOptions as O, type ProcessImageBufferOptions as P, RETRY_AVIF_EFFORT as R, type StoragePathGenerator as S, type UploadErrorContext as U, WHITE_DOMINANCE_RATIO as W, type OptimizedImageResult as a, type ProcessedImageBufferResult as b, type ImageUploader as c, type InferredPresetKey as d, type StoragePathContext as e, type GeneratedStorageTarget as f, type AuthorizeContext as g, BLUR_PLACEHOLDER_FALLBACK_WIDTH as h, BLUR_PLACEHOLDER_MAX_CHARS as i, BLUR_PLACEHOLDER_QUALITY as j, BLUR_PLACEHOLDER_WIDTH as k, EDGE_COLOR_FALLBACK as l, EDGE_WHITE_FALLBACK as m, type EdgeKey as n, PRIMARY_AVIF_EFFORT as o, type UploadHttpHandlerOptions as p, UploadValidationError as q, createUploadHandler as r, createUploadHttpHandler as s, isClientValidationError as t };