@rovela-ai/sdk 0.1.26 → 0.1.28

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 (72) hide show
  1. package/dist/admin/components/CategoryForm.d.ts.map +1 -1
  2. package/dist/admin/components/CategoryForm.js +9 -2
  3. package/dist/admin/components/CategoryForm.js.map +1 -1
  4. package/dist/admin/components/ProductForm.d.ts.map +1 -1
  5. package/dist/admin/components/ProductForm.js +6 -35
  6. package/dist/admin/components/ProductForm.js.map +1 -1
  7. package/dist/core/db/queries.d.ts +7 -7
  8. package/dist/media/api/delete.d.ts +44 -0
  9. package/dist/media/api/delete.d.ts.map +1 -0
  10. package/dist/media/api/delete.js +134 -0
  11. package/dist/media/api/delete.js.map +1 -0
  12. package/dist/media/api/index.d.ts +17 -0
  13. package/dist/media/api/index.d.ts.map +1 -0
  14. package/dist/media/api/index.js +17 -0
  15. package/dist/media/api/index.js.map +1 -0
  16. package/dist/media/api/presign.d.ts +39 -0
  17. package/dist/media/api/presign.d.ts.map +1 -0
  18. package/dist/media/api/presign.js +138 -0
  19. package/dist/media/api/presign.js.map +1 -0
  20. package/dist/media/components/DropZone.d.ts +18 -0
  21. package/dist/media/components/DropZone.d.ts.map +1 -0
  22. package/dist/media/components/DropZone.js +112 -0
  23. package/dist/media/components/DropZone.js.map +1 -0
  24. package/dist/media/components/ImageGalleryUpload.d.ts +18 -0
  25. package/dist/media/components/ImageGalleryUpload.d.ts.map +1 -0
  26. package/dist/media/components/ImageGalleryUpload.js +166 -0
  27. package/dist/media/components/ImageGalleryUpload.js.map +1 -0
  28. package/dist/media/components/ImageUpload.d.ts +17 -0
  29. package/dist/media/components/ImageUpload.d.ts.map +1 -0
  30. package/dist/media/components/ImageUpload.js +103 -0
  31. package/dist/media/components/ImageUpload.js.map +1 -0
  32. package/dist/media/components/index.d.ts +10 -0
  33. package/dist/media/components/index.d.ts.map +1 -0
  34. package/dist/media/components/index.js +9 -0
  35. package/dist/media/components/index.js.map +1 -0
  36. package/dist/media/config.d.ts +57 -0
  37. package/dist/media/config.d.ts.map +1 -0
  38. package/dist/media/config.js +142 -0
  39. package/dist/media/config.js.map +1 -0
  40. package/dist/media/hooks/index.d.ts +8 -0
  41. package/dist/media/hooks/index.d.ts.map +1 -0
  42. package/dist/media/hooks/index.js +7 -0
  43. package/dist/media/hooks/index.js.map +1 -0
  44. package/dist/media/hooks/useUpload.d.ts +32 -0
  45. package/dist/media/hooks/useUpload.d.ts.map +1 -0
  46. package/dist/media/hooks/useUpload.js +258 -0
  47. package/dist/media/hooks/useUpload.js.map +1 -0
  48. package/dist/media/index.d.ts +57 -0
  49. package/dist/media/index.d.ts.map +1 -0
  50. package/dist/media/index.js +68 -0
  51. package/dist/media/index.js.map +1 -0
  52. package/dist/media/server/delete.d.ts +59 -0
  53. package/dist/media/server/delete.d.ts.map +1 -0
  54. package/dist/media/server/delete.js +176 -0
  55. package/dist/media/server/delete.js.map +1 -0
  56. package/dist/media/server/index.d.ts +10 -0
  57. package/dist/media/server/index.d.ts.map +1 -0
  58. package/dist/media/server/index.js +13 -0
  59. package/dist/media/server/index.js.map +1 -0
  60. package/dist/media/server/presign.d.ts +57 -0
  61. package/dist/media/server/presign.d.ts.map +1 -0
  62. package/dist/media/server/presign.js +112 -0
  63. package/dist/media/server/presign.js.map +1 -0
  64. package/dist/media/server/r2-client.d.ts +30 -0
  65. package/dist/media/server/r2-client.d.ts.map +1 -0
  66. package/dist/media/server/r2-client.js +76 -0
  67. package/dist/media/server/r2-client.js.map +1 -0
  68. package/dist/media/types.d.ts +275 -0
  69. package/dist/media/types.d.ts.map +1 -0
  70. package/dist/media/types.js +52 -0
  71. package/dist/media/types.js.map +1 -0
  72. package/package.json +15 -1
@@ -0,0 +1,258 @@
1
+ 'use client';
2
+ /**
3
+ * @rovela-ai/sdk/media/hooks/useUpload
4
+ *
5
+ * React hook for uploading files to R2 storage via presigned URLs.
6
+ */
7
+ import { useState, useCallback, useRef } from 'react';
8
+ import { validateFile, DEFAULT_UPLOAD_CONFIG } from '../types';
9
+ // =============================================================================
10
+ // Hook Implementation
11
+ // =============================================================================
12
+ /**
13
+ * React hook for uploading files to R2 storage.
14
+ *
15
+ * @param options - Upload configuration options
16
+ * @returns Upload functions and state
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * function ImageUploader() {
21
+ * const { upload, isUploading, progress, error } = useUpload({
22
+ * folder: 'products',
23
+ * entityId: 'prod_123',
24
+ * onSuccess: (result) => console.log('Uploaded:', result.url),
25
+ * });
26
+ *
27
+ * const handleFile = async (file: File) => {
28
+ * const result = await upload(file);
29
+ * if (result.success) {
30
+ * // Use result.url
31
+ * }
32
+ * };
33
+ *
34
+ * return (
35
+ * <input type="file" onChange={(e) => handleFile(e.target.files[0])} />
36
+ * );
37
+ * }
38
+ * ```
39
+ */
40
+ export function useUpload(options) {
41
+ const { folder, entityId, config, onSuccess, onError, onProgress } = options;
42
+ // Merge config with defaults
43
+ const uploadConfig = {
44
+ ...DEFAULT_UPLOAD_CONFIG,
45
+ ...config,
46
+ };
47
+ // State
48
+ const [status, setStatus] = useState('idle');
49
+ const [progress, setProgress] = useState(null);
50
+ const [error, setError] = useState(null);
51
+ // Abort controller ref for cancellation
52
+ const abortControllerRef = useRef(null);
53
+ /**
54
+ * Upload a single file
55
+ */
56
+ const upload = useCallback(async (file) => {
57
+ // Validate file
58
+ const validation = validateFile(file, uploadConfig);
59
+ if (!validation.valid) {
60
+ const errorMsg = validation.error || 'File validation failed';
61
+ setError(errorMsg);
62
+ setStatus('error');
63
+ onError?.(errorMsg);
64
+ return {
65
+ success: false,
66
+ filename: file.name,
67
+ size: file.size,
68
+ contentType: file.type,
69
+ error: errorMsg,
70
+ };
71
+ }
72
+ // Reset state
73
+ setError(null);
74
+ setStatus('preparing');
75
+ setProgress(null);
76
+ // Create abort controller
77
+ abortControllerRef.current = new AbortController();
78
+ const signal = abortControllerRef.current.signal;
79
+ try {
80
+ // Step 1: Get presigned URL from API
81
+ const presignResponse = await fetch('/api/media/presign', {
82
+ method: 'POST',
83
+ headers: { 'Content-Type': 'application/json' },
84
+ body: JSON.stringify({
85
+ filename: file.name,
86
+ contentType: file.type,
87
+ folder,
88
+ entityId,
89
+ }),
90
+ signal,
91
+ });
92
+ if (!presignResponse.ok) {
93
+ const errorData = await presignResponse.json().catch(() => ({}));
94
+ throw new Error(errorData.error || 'Failed to get upload URL');
95
+ }
96
+ const presignData = await presignResponse.json();
97
+ if (!presignData.success || !presignData.data) {
98
+ throw new Error(presignData.error || 'Failed to get upload URL');
99
+ }
100
+ // Step 2: Upload file directly to R2
101
+ setStatus('uploading');
102
+ // Use XMLHttpRequest for progress tracking
103
+ const uploadResult = await uploadWithProgress(presignData.data.uploadUrl, file, (prog) => {
104
+ setProgress(prog);
105
+ onProgress?.(prog);
106
+ }, signal);
107
+ if (!uploadResult.success) {
108
+ throw new Error(uploadResult.error || 'Upload failed');
109
+ }
110
+ // Success
111
+ setStatus('success');
112
+ setProgress({ loaded: file.size, total: file.size, percentage: 100 });
113
+ const result = {
114
+ success: true,
115
+ url: presignData.data.publicUrl,
116
+ filename: file.name,
117
+ size: file.size,
118
+ contentType: file.type,
119
+ };
120
+ onSuccess?.(result);
121
+ return result;
122
+ }
123
+ catch (err) {
124
+ // Handle abort
125
+ if (err instanceof Error && err.name === 'AbortError') {
126
+ setStatus('idle');
127
+ setError(null);
128
+ return {
129
+ success: false,
130
+ filename: file.name,
131
+ size: file.size,
132
+ contentType: file.type,
133
+ error: 'Upload cancelled',
134
+ };
135
+ }
136
+ // Handle error
137
+ const errorMsg = err instanceof Error ? err.message : 'Upload failed';
138
+ setError(errorMsg);
139
+ setStatus('error');
140
+ onError?.(errorMsg);
141
+ return {
142
+ success: false,
143
+ filename: file.name,
144
+ size: file.size,
145
+ contentType: file.type,
146
+ error: errorMsg,
147
+ };
148
+ }
149
+ finally {
150
+ abortControllerRef.current = null;
151
+ }
152
+ }, [folder, entityId, uploadConfig, onSuccess, onError, onProgress]);
153
+ /**
154
+ * Upload multiple files
155
+ */
156
+ const uploadMultiple = useCallback(async (files) => {
157
+ // Validate max files
158
+ if (files.length > uploadConfig.maxFiles) {
159
+ const errorMsg = `Maximum ${uploadConfig.maxFiles} files allowed`;
160
+ setError(errorMsg);
161
+ onError?.(errorMsg);
162
+ return files.map((f) => ({
163
+ success: false,
164
+ filename: f.name,
165
+ size: f.size,
166
+ contentType: f.type,
167
+ error: errorMsg,
168
+ }));
169
+ }
170
+ // Upload sequentially to avoid overwhelming the server
171
+ const results = [];
172
+ for (const file of files) {
173
+ const result = await upload(file);
174
+ results.push(result);
175
+ // Stop if there's an error (optional - could continue)
176
+ if (!result.success) {
177
+ break;
178
+ }
179
+ }
180
+ return results;
181
+ }, [upload, uploadConfig.maxFiles, onError]);
182
+ /**
183
+ * Reset state to idle
184
+ */
185
+ const reset = useCallback(() => {
186
+ // Cancel any in-progress upload
187
+ if (abortControllerRef.current) {
188
+ abortControllerRef.current.abort();
189
+ abortControllerRef.current = null;
190
+ }
191
+ setStatus('idle');
192
+ setProgress(null);
193
+ setError(null);
194
+ }, []);
195
+ return {
196
+ upload,
197
+ uploadMultiple,
198
+ status,
199
+ progress,
200
+ isUploading: status === 'preparing' || status === 'uploading',
201
+ error,
202
+ reset,
203
+ };
204
+ }
205
+ // =============================================================================
206
+ // Helper Functions
207
+ // =============================================================================
208
+ /**
209
+ * Upload file with progress tracking using XMLHttpRequest
210
+ */
211
+ function uploadWithProgress(url, file, onProgress, signal) {
212
+ return new Promise((resolve) => {
213
+ const xhr = new XMLHttpRequest();
214
+ // Handle abort
215
+ if (signal) {
216
+ signal.addEventListener('abort', () => {
217
+ xhr.abort();
218
+ resolve({ success: false, error: 'Upload cancelled' });
219
+ });
220
+ }
221
+ // Track progress
222
+ xhr.upload.addEventListener('progress', (event) => {
223
+ if (event.lengthComputable) {
224
+ onProgress({
225
+ loaded: event.loaded,
226
+ total: event.total,
227
+ percentage: Math.round((event.loaded / event.total) * 100),
228
+ });
229
+ }
230
+ });
231
+ // Handle completion
232
+ xhr.addEventListener('load', () => {
233
+ if (xhr.status >= 200 && xhr.status < 300) {
234
+ resolve({ success: true });
235
+ }
236
+ else {
237
+ resolve({ success: false, error: `Upload failed with status ${xhr.status}` });
238
+ }
239
+ });
240
+ // Handle error
241
+ xhr.addEventListener('error', () => {
242
+ resolve({ success: false, error: 'Network error during upload' });
243
+ });
244
+ // Handle abort
245
+ xhr.addEventListener('abort', () => {
246
+ resolve({ success: false, error: 'Upload cancelled' });
247
+ });
248
+ // Send request
249
+ xhr.open('PUT', url);
250
+ xhr.setRequestHeader('Content-Type', file.type);
251
+ xhr.send(file);
252
+ });
253
+ }
254
+ // =============================================================================
255
+ // Exports
256
+ // =============================================================================
257
+ export default useUpload;
258
+ //# sourceMappingURL=useUpload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useUpload.js","sourceRoot":"","sources":["../../../src/media/hooks/useUpload.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAUrD,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAE9D,gFAAgF;AAChF,sBAAsB;AACtB,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,SAAS,CAAC,OAAyB;IACjD,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAA;IAE5E,6BAA6B;IAC7B,MAAM,YAAY,GAAiB;QACjC,GAAG,qBAAqB;QACxB,GAAG,MAAM;KACV,CAAA;IAED,QAAQ;IACR,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAe,MAAM,CAAC,CAAA;IAC1D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAwB,IAAI,CAAC,CAAA;IACrE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAA;IAEvD,wCAAwC;IACxC,MAAM,kBAAkB,GAAG,MAAM,CAAyB,IAAI,CAAC,CAAA;IAE/D;;OAEG;IACH,MAAM,MAAM,GAAG,WAAW,CACxB,KAAK,EAAE,IAAU,EAAyB,EAAE;QAC1C,gBAAgB;QAChB,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;QACnD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,IAAI,wBAAwB,CAAA;YAC7D,QAAQ,CAAC,QAAQ,CAAC,CAAA;YAClB,SAAS,CAAC,OAAO,CAAC,CAAA;YAClB,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAA;YACnB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,IAAI;gBACtB,KAAK,EAAE,QAAQ;aAChB,CAAA;QACH,CAAC;QAED,cAAc;QACd,QAAQ,CAAC,IAAI,CAAC,CAAA;QACd,SAAS,CAAC,WAAW,CAAC,CAAA;QACtB,WAAW,CAAC,IAAI,CAAC,CAAA;QAEjB,0BAA0B;QAC1B,kBAAkB,CAAC,OAAO,GAAG,IAAI,eAAe,EAAE,CAAA;QAClD,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAA;QAEhD,IAAI,CAAC;YACH,qCAAqC;YACrC,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,oBAAoB,EAAE;gBACxD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,WAAW,EAAE,IAAI,CAAC,IAAI;oBACtB,MAAM;oBACN,QAAQ;iBACT,CAAC;gBACF,MAAM;aACP,CAAC,CAAA;YAEF,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;gBAChE,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,IAAI,0BAA0B,CAAC,CAAA;YAChE,CAAC;YAED,MAAM,WAAW,GAAuB,MAAM,eAAe,CAAC,IAAI,EAAE,CAAA;YACpE,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;gBAC9C,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,0BAA0B,CAAC,CAAA;YAClE,CAAC;YAED,qCAAqC;YACrC,SAAS,CAAC,WAAW,CAAC,CAAA;YAEtB,2CAA2C;YAC3C,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAC3C,WAAW,CAAC,IAAI,CAAC,SAAS,EAC1B,IAAI,EACJ,CAAC,IAAI,EAAE,EAAE;gBACP,WAAW,CAAC,IAAI,CAAC,CAAA;gBACjB,UAAU,EAAE,CAAC,IAAI,CAAC,CAAA;YACpB,CAAC,EACD,MAAM,CACP,CAAA;YAED,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,IAAI,eAAe,CAAC,CAAA;YACxD,CAAC;YAED,UAAU;YACV,SAAS,CAAC,SAAS,CAAC,CAAA;YACpB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAA;YAErE,MAAM,MAAM,GAAiB;gBAC3B,OAAO,EAAE,IAAI;gBACb,GAAG,EAAE,WAAW,CAAC,IAAI,CAAC,SAAS;gBAC/B,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,IAAI;aACvB,CAAA;YAED,SAAS,EAAE,CAAC,MAAM,CAAC,CAAA;YACnB,OAAO,MAAM,CAAA;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAe;YACf,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACtD,SAAS,CAAC,MAAM,CAAC,CAAA;gBACjB,QAAQ,CAAC,IAAI,CAAC,CAAA;gBACd,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,WAAW,EAAE,IAAI,CAAC,IAAI;oBACtB,KAAK,EAAE,kBAAkB;iBAC1B,CAAA;YACH,CAAC;YAED,eAAe;YACf,MAAM,QAAQ,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAA;YACrE,QAAQ,CAAC,QAAQ,CAAC,CAAA;YAClB,SAAS,CAAC,OAAO,CAAC,CAAA;YAClB,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAA;YAEnB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,IAAI;gBACtB,KAAK,EAAE,QAAQ;aAChB,CAAA;QACH,CAAC;gBAAS,CAAC;YACT,kBAAkB,CAAC,OAAO,GAAG,IAAI,CAAA;QACnC,CAAC;IACH,CAAC,EACD,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,CACjE,CAAA;IAED;;OAEG;IACH,MAAM,cAAc,GAAG,WAAW,CAChC,KAAK,EAAE,KAAa,EAA2B,EAAE;QAC/C,qBAAqB;QACrB,IAAI,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,WAAW,YAAY,CAAC,QAAQ,gBAAgB,CAAA;YACjE,QAAQ,CAAC,QAAQ,CAAC,CAAA;YAClB,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAA;YACnB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACvB,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,CAAC,CAAC,IAAI;gBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,WAAW,EAAE,CAAC,CAAC,IAAI;gBACnB,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC,CAAA;QACL,CAAC;QAED,uDAAuD;QACvD,MAAM,OAAO,GAAmB,EAAE,CAAA;QAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAA;YACjC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAEpB,uDAAuD;YACvD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAK;YACP,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC,EACD,CAAC,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CACzC,CAAA;IAED;;OAEG;IACH,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,gCAAgC;QAChC,IAAI,kBAAkB,CAAC,OAAO,EAAE,CAAC;YAC/B,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;YAClC,kBAAkB,CAAC,OAAO,GAAG,IAAI,CAAA;QACnC,CAAC;QAED,SAAS,CAAC,MAAM,CAAC,CAAA;QACjB,WAAW,CAAC,IAAI,CAAC,CAAA;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAA;IAChB,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO;QACL,MAAM;QACN,cAAc;QACd,MAAM;QACN,QAAQ;QACR,WAAW,EAAE,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,WAAW;QAC7D,KAAK;QACL,KAAK;KACN,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;GAEG;AACH,SAAS,kBAAkB,CACzB,GAAW,EACX,IAAU,EACV,UAA8C,EAC9C,MAAoB;IAEpB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,IAAI,cAAc,EAAE,CAAA;QAEhC,eAAe;QACf,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;gBACpC,GAAG,CAAC,KAAK,EAAE,CAAA;gBACX,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAA;YACxD,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,iBAAiB;QACjB,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;YAChD,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC3B,UAAU,CAAC;oBACT,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;iBAC3D,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,oBAAoB;QACpB,GAAG,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE;YAChC,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBAC1C,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;YAC5B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;YAC/E,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,eAAe;QACf,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACjC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAA;QACnE,CAAC,CAAC,CAAA;QAEF,eAAe;QACf,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACjC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAA;QACxD,CAAC,CAAC,CAAA;QAEF,eAAe;QACf,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACpB,GAAG,CAAC,gBAAgB,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/C,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAChB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAEhF,eAAe,SAAS,CAAA"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @rovela-ai/sdk/media
3
+ *
4
+ * Media upload module for R2 storage.
5
+ *
6
+ * This module provides:
7
+ * - Server-side presigned URL generation
8
+ * - Client-side upload hooks and components
9
+ * - API route handlers for Next.js
10
+ *
11
+ * ## Quick Start
12
+ *
13
+ * 1. Add environment variables:
14
+ * ```env
15
+ * R2_ACCOUNT_ID=xxx
16
+ * R2_ACCESS_KEY_ID=xxx
17
+ * R2_SECRET_ACCESS_KEY=xxx
18
+ * R2_BUCKET_NAME=xxx
19
+ * R2_PUBLIC_URL=https://pub-xxx.r2.dev
20
+ * STORE_ID=xxx
21
+ * ```
22
+ *
23
+ * 2. Create API routes:
24
+ * ```typescript
25
+ * // app/api/media/presign/route.ts
26
+ * export { POST } from '@rovela-ai/sdk/media/api'
27
+ *
28
+ * // app/api/media/route.ts
29
+ * export { DELETE } from '@rovela-ai/sdk/media/api'
30
+ * ```
31
+ *
32
+ * 3. Use components:
33
+ * ```tsx
34
+ * import { ImageGalleryUpload } from '@rovela-ai/sdk/media'
35
+ *
36
+ * <ImageGalleryUpload
37
+ * value={images}
38
+ * onChange={setImages}
39
+ * folder="products"
40
+ * entityId={productId}
41
+ * />
42
+ * ```
43
+ *
44
+ * ## Module Structure
45
+ *
46
+ * - `@rovela-ai/sdk/media` - Types, config, components, hooks
47
+ * - `@rovela-ai/sdk/media/server` - Server-side utilities (presign, delete)
48
+ * - `@rovela-ai/sdk/media/api` - Next.js API route handlers
49
+ *
50
+ * @module media
51
+ */
52
+ export type { MediaStorageConfig, UploadConfig, MediaFolder, PresignedUrlRequest, PresignedUrlResponse, PresignApiRequest, PresignApiResponse, DeleteApiRequest, DeleteApiResponse, MediaApiError, UploadProgress, UploadStatus, UploadResult, UploadState, UseUploadOptions, UseUploadReturn, DropZoneProps, ImageUploadProps, ImageGalleryUploadProps, FileValidation, } from './types';
53
+ export { DEFAULT_UPLOAD_CONFIG, validateFile, generateUniqueFilename, getFileExtension } from './types';
54
+ export { getMediaConfig, isMediaConfigured, requireMediaConfig, defaultUploadConfig, getUploadConfig, buildStorageKey, buildPublicUrl, extractKeyFromUrl, getMimeType, isAllowedImageType, } from './config';
55
+ export { useUpload } from './hooks';
56
+ export { DropZone, ImageUpload, ImageGalleryUpload } from './components';
57
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAMH,YAAY,EAEV,kBAAkB,EAClB,YAAY,EACZ,WAAW,EAEX,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EAEb,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,WAAW,EAEX,gBAAgB,EAChB,eAAe,EAEf,aAAa,EACb,gBAAgB,EAChB,uBAAuB,EAEvB,cAAc,GACf,MAAM,SAAS,CAAA;AAMhB,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAMvG,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,kBAAkB,GACnB,MAAM,UAAU,CAAA;AAMjB,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAMnC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @rovela-ai/sdk/media
3
+ *
4
+ * Media upload module for R2 storage.
5
+ *
6
+ * This module provides:
7
+ * - Server-side presigned URL generation
8
+ * - Client-side upload hooks and components
9
+ * - API route handlers for Next.js
10
+ *
11
+ * ## Quick Start
12
+ *
13
+ * 1. Add environment variables:
14
+ * ```env
15
+ * R2_ACCOUNT_ID=xxx
16
+ * R2_ACCESS_KEY_ID=xxx
17
+ * R2_SECRET_ACCESS_KEY=xxx
18
+ * R2_BUCKET_NAME=xxx
19
+ * R2_PUBLIC_URL=https://pub-xxx.r2.dev
20
+ * STORE_ID=xxx
21
+ * ```
22
+ *
23
+ * 2. Create API routes:
24
+ * ```typescript
25
+ * // app/api/media/presign/route.ts
26
+ * export { POST } from '@rovela-ai/sdk/media/api'
27
+ *
28
+ * // app/api/media/route.ts
29
+ * export { DELETE } from '@rovela-ai/sdk/media/api'
30
+ * ```
31
+ *
32
+ * 3. Use components:
33
+ * ```tsx
34
+ * import { ImageGalleryUpload } from '@rovela-ai/sdk/media'
35
+ *
36
+ * <ImageGalleryUpload
37
+ * value={images}
38
+ * onChange={setImages}
39
+ * folder="products"
40
+ * entityId={productId}
41
+ * />
42
+ * ```
43
+ *
44
+ * ## Module Structure
45
+ *
46
+ * - `@rovela-ai/sdk/media` - Types, config, components, hooks
47
+ * - `@rovela-ai/sdk/media/server` - Server-side utilities (presign, delete)
48
+ * - `@rovela-ai/sdk/media/api` - Next.js API route handlers
49
+ *
50
+ * @module media
51
+ */
52
+ // =============================================================================
53
+ // Constants & Utilities
54
+ // =============================================================================
55
+ export { DEFAULT_UPLOAD_CONFIG, validateFile, generateUniqueFilename, getFileExtension } from './types';
56
+ // =============================================================================
57
+ // Configuration
58
+ // =============================================================================
59
+ export { getMediaConfig, isMediaConfigured, requireMediaConfig, defaultUploadConfig, getUploadConfig, buildStorageKey, buildPublicUrl, extractKeyFromUrl, getMimeType, isAllowedImageType, } from './config';
60
+ // =============================================================================
61
+ // Hooks
62
+ // =============================================================================
63
+ export { useUpload } from './hooks';
64
+ // =============================================================================
65
+ // Components
66
+ // =============================================================================
67
+ export { DropZone, ImageUpload, ImageGalleryUpload } from './components';
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAmCH,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAEhF,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAEvG,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,kBAAkB,GACnB,MAAM,UAAU,CAAA;AAEjB,gFAAgF;AAChF,QAAQ;AACR,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAEnC,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/server/delete
3
+ *
4
+ * File deletion from R2 storage.
5
+ * Server-side only - do not import in client components.
6
+ */
7
+ import type { MediaStorageConfig } from '../types';
8
+ /**
9
+ * Delete a file from R2 storage.
10
+ *
11
+ * @param url - Public URL of the file to delete
12
+ * @param config - Optional storage configuration override
13
+ * @returns True if deletion was successful
14
+ * @throws Error if URL is invalid or doesn't belong to this store
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * await deleteFile('https://pub-xxx.r2.dev/stores/abc123/products/img.jpg');
19
+ * ```
20
+ */
21
+ export declare function deleteFile(url: string, config?: MediaStorageConfig): Promise<boolean>;
22
+ /**
23
+ * Delete a file by its storage key.
24
+ * Use this when you have the key directly instead of the URL.
25
+ *
26
+ * @param key - Storage key of the file
27
+ * @param config - Optional storage configuration override
28
+ * @returns True if deletion was successful
29
+ */
30
+ export declare function deleteFileByKey(key: string, config?: MediaStorageConfig): Promise<boolean>;
31
+ /**
32
+ * Delete multiple files from R2 storage.
33
+ *
34
+ * @param urls - Array of public URLs to delete
35
+ * @param config - Optional storage configuration override
36
+ * @returns Object with results for each URL
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const results = await deleteFiles([
41
+ * 'https://pub-xxx.r2.dev/stores/abc123/products/img1.jpg',
42
+ * 'https://pub-xxx.r2.dev/stores/abc123/products/img2.jpg',
43
+ * ]);
44
+ * // { succeeded: ['url1', 'url2'], failed: [] }
45
+ * ```
46
+ */
47
+ export declare function deleteFiles(urls: string[], config?: MediaStorageConfig): Promise<{
48
+ succeeded: string[];
49
+ failed: string[];
50
+ }>;
51
+ /**
52
+ * Safely delete a file - returns false instead of throwing if file doesn't exist.
53
+ *
54
+ * @param url - Public URL of the file to delete
55
+ * @param config - Optional storage configuration override
56
+ * @returns True if deleted, false if not found or invalid
57
+ */
58
+ export declare function safeDeleteFile(url: string, config?: MediaStorageConfig): Promise<boolean>;
59
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/media/server/delete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AASlD;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,OAAO,CAAC,CA+BlB;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAoEpD;AAMD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,OAAO,CAAC,CAMlB"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/server/delete
3
+ *
4
+ * File deletion from R2 storage.
5
+ * Server-side only - do not import in client components.
6
+ */
7
+ import { DeleteObjectCommand, DeleteObjectsCommand } from '@aws-sdk/client-s3';
8
+ import { extractKeyFromUrl, requireMediaConfig } from '../config';
9
+ import { getR2Client, getBucketName, getPublicUrlBase } from './r2-client';
10
+ import { validateStoreUrl } from './presign';
11
+ // =============================================================================
12
+ // Single File Deletion
13
+ // =============================================================================
14
+ /**
15
+ * Delete a file from R2 storage.
16
+ *
17
+ * @param url - Public URL of the file to delete
18
+ * @param config - Optional storage configuration override
19
+ * @returns True if deletion was successful
20
+ * @throws Error if URL is invalid or doesn't belong to this store
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * await deleteFile('https://pub-xxx.r2.dev/stores/abc123/products/img.jpg');
25
+ * ```
26
+ */
27
+ export async function deleteFile(url, config) {
28
+ const resolvedConfig = config || requireMediaConfig();
29
+ // Validate URL belongs to this store
30
+ if (!validateStoreUrl(url, resolvedConfig)) {
31
+ throw new Error('Invalid URL: does not belong to this store');
32
+ }
33
+ // Extract key from URL
34
+ const publicUrlBase = getPublicUrlBase(resolvedConfig);
35
+ const key = extractKeyFromUrl(publicUrlBase, url);
36
+ if (!key) {
37
+ throw new Error('Invalid URL: could not extract storage key');
38
+ }
39
+ const client = getR2Client(resolvedConfig);
40
+ const bucketName = getBucketName(resolvedConfig);
41
+ try {
42
+ await client.send(new DeleteObjectCommand({
43
+ Bucket: bucketName,
44
+ Key: key,
45
+ }));
46
+ return true;
47
+ }
48
+ catch (error) {
49
+ console.error('[Media] Delete failed:', error);
50
+ throw new Error('Failed to delete file');
51
+ }
52
+ }
53
+ /**
54
+ * Delete a file by its storage key.
55
+ * Use this when you have the key directly instead of the URL.
56
+ *
57
+ * @param key - Storage key of the file
58
+ * @param config - Optional storage configuration override
59
+ * @returns True if deletion was successful
60
+ */
61
+ export async function deleteFileByKey(key, config) {
62
+ const resolvedConfig = config || requireMediaConfig();
63
+ const client = getR2Client(resolvedConfig);
64
+ const bucketName = getBucketName(resolvedConfig);
65
+ // Validate key belongs to this store
66
+ const expectedPrefix = `stores/${resolvedConfig.storeId}/`;
67
+ if (!key.startsWith(expectedPrefix)) {
68
+ throw new Error('Invalid key: does not belong to this store');
69
+ }
70
+ try {
71
+ await client.send(new DeleteObjectCommand({
72
+ Bucket: bucketName,
73
+ Key: key,
74
+ }));
75
+ return true;
76
+ }
77
+ catch (error) {
78
+ console.error('[Media] Delete by key failed:', error);
79
+ throw new Error('Failed to delete file');
80
+ }
81
+ }
82
+ // =============================================================================
83
+ // Batch Deletion
84
+ // =============================================================================
85
+ /**
86
+ * Delete multiple files from R2 storage.
87
+ *
88
+ * @param urls - Array of public URLs to delete
89
+ * @param config - Optional storage configuration override
90
+ * @returns Object with results for each URL
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const results = await deleteFiles([
95
+ * 'https://pub-xxx.r2.dev/stores/abc123/products/img1.jpg',
96
+ * 'https://pub-xxx.r2.dev/stores/abc123/products/img2.jpg',
97
+ * ]);
98
+ * // { succeeded: ['url1', 'url2'], failed: [] }
99
+ * ```
100
+ */
101
+ export async function deleteFiles(urls, config) {
102
+ const resolvedConfig = config || requireMediaConfig();
103
+ const publicUrlBase = getPublicUrlBase(resolvedConfig);
104
+ // Filter and extract keys
105
+ const validEntries = [];
106
+ const invalidUrls = [];
107
+ for (const url of urls) {
108
+ if (!validateStoreUrl(url, resolvedConfig)) {
109
+ invalidUrls.push(url);
110
+ continue;
111
+ }
112
+ const key = extractKeyFromUrl(publicUrlBase, url);
113
+ if (!key) {
114
+ invalidUrls.push(url);
115
+ continue;
116
+ }
117
+ validEntries.push({ url, key });
118
+ }
119
+ if (validEntries.length === 0) {
120
+ return { succeeded: [], failed: urls };
121
+ }
122
+ const client = getR2Client(resolvedConfig);
123
+ const bucketName = getBucketName(resolvedConfig);
124
+ try {
125
+ // Use batch delete for efficiency
126
+ await client.send(new DeleteObjectsCommand({
127
+ Bucket: bucketName,
128
+ Delete: {
129
+ Objects: validEntries.map(({ key }) => ({ Key: key })),
130
+ Quiet: true,
131
+ },
132
+ }));
133
+ return {
134
+ succeeded: validEntries.map(({ url }) => url),
135
+ failed: invalidUrls,
136
+ };
137
+ }
138
+ catch (error) {
139
+ console.error('[Media] Batch delete failed:', error);
140
+ // On error, try to delete individually
141
+ const succeeded = [];
142
+ const failed = [...invalidUrls];
143
+ for (const { url, key } of validEntries) {
144
+ try {
145
+ await client.send(new DeleteObjectCommand({
146
+ Bucket: bucketName,
147
+ Key: key,
148
+ }));
149
+ succeeded.push(url);
150
+ }
151
+ catch {
152
+ failed.push(url);
153
+ }
154
+ }
155
+ return { succeeded, failed };
156
+ }
157
+ }
158
+ // =============================================================================
159
+ // Safe Deletion (with existence check)
160
+ // =============================================================================
161
+ /**
162
+ * Safely delete a file - returns false instead of throwing if file doesn't exist.
163
+ *
164
+ * @param url - Public URL of the file to delete
165
+ * @param config - Optional storage configuration override
166
+ * @returns True if deleted, false if not found or invalid
167
+ */
168
+ export async function safeDeleteFile(url, config) {
169
+ try {
170
+ return await deleteFile(url, config);
171
+ }
172
+ catch {
173
+ return false;
174
+ }
175
+ }
176
+ //# sourceMappingURL=delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/media/server/delete.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/server
3
+ *
4
+ * Server-side media utilities.
5
+ * Only import this in server components and API routes.
6
+ */
7
+ export { getR2Client, clearR2ClientCache, getBucketName, getPublicUrlBase, getStoreId } from './r2-client';
8
+ export { generatePresignedUrl, generatePresignedUrls, isR2Url, validateStoreUrl, type GeneratePresignedUrlOptions, } from './presign';
9
+ export { deleteFile, deleteFileByKey, deleteFiles, safeDeleteFile } from './delete';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/media/server/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAG1G,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,OAAO,EACP,gBAAgB,EAChB,KAAK,2BAA2B,GACjC,MAAM,WAAW,CAAA;AAGlB,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA"}