@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,17 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/api
3
+ *
4
+ * API route handlers for media operations.
5
+ *
6
+ * Usage:
7
+ * ```typescript
8
+ * // app/api/media/presign/route.ts
9
+ * export { POST } from '@rovela-ai/sdk/media/api'
10
+ *
11
+ * // app/api/media/route.ts
12
+ * export { DELETE } from '@rovela-ai/sdk/media/api'
13
+ * ```
14
+ */
15
+ export { POST } from './presign';
16
+ export { DELETE } from './delete';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/media/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/api/presign
3
+ *
4
+ * API route handler for generating presigned upload URLs.
5
+ *
6
+ * Usage:
7
+ * ```typescript
8
+ * // app/api/media/presign/route.ts
9
+ * export { POST } from '@rovela-ai/sdk/media/api/presign'
10
+ * ```
11
+ */
12
+ import { NextRequest, NextResponse } from 'next/server';
13
+ import type { PresignApiResponse, MediaApiError } from '../types';
14
+ /**
15
+ * POST /api/media/presign
16
+ *
17
+ * Generate a presigned URL for uploading a file to R2.
18
+ *
19
+ * Request Body:
20
+ * {
21
+ * filename: string, // Original filename (for extension)
22
+ * contentType: string, // MIME type (must be allowed type)
23
+ * folder: 'products' | 'categories' | 'variants' | 'general',
24
+ * entityId?: string // Optional entity ID for organization
25
+ * }
26
+ *
27
+ * Response:
28
+ * {
29
+ * success: true,
30
+ * data: {
31
+ * uploadUrl: string, // Presigned PUT URL (expires in 5 min)
32
+ * publicUrl: string, // Final accessible URL after upload
33
+ * key: string, // Storage key
34
+ * expiresAt: string // ISO date when URL expires
35
+ * }
36
+ * }
37
+ */
38
+ export declare function POST(request: NextRequest): Promise<NextResponse<PresignApiResponse | MediaApiError>>;
39
+ //# sourceMappingURL=presign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presign.d.ts","sourceRoot":"","sources":["../../../src/media/api/presign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAMvD,OAAO,KAAK,EAEV,kBAAkB,EAClB,aAAa,EAEd,MAAM,UAAU,CAAA;AAkFjB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,CAAC,kBAAkB,GAAG,aAAa,CAAC,CAAC,CAgD3D"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/api/presign
3
+ *
4
+ * API route handler for generating presigned upload URLs.
5
+ *
6
+ * Usage:
7
+ * ```typescript
8
+ * // app/api/media/presign/route.ts
9
+ * export { POST } from '@rovela-ai/sdk/media/api/presign'
10
+ * ```
11
+ */
12
+ import { NextResponse } from 'next/server';
13
+ import { getServerSession } from 'next-auth';
14
+ import { createAuthOptions } from '../../auth/config';
15
+ import { generatePresignedUrl } from '../server/presign';
16
+ import { isMediaConfigured, getUploadConfig } from '../config';
17
+ // =============================================================================
18
+ // Auth Helper
19
+ // =============================================================================
20
+ async function requireAdmin() {
21
+ const session = await getServerSession(createAuthOptions());
22
+ const user = session?.user;
23
+ if (!user?.role || !['owner', 'admin'].includes(user.role)) {
24
+ return NextResponse.json({ success: false, error: 'Unauthorized', code: 'UNAUTHORIZED' }, { status: 401 });
25
+ }
26
+ return null;
27
+ }
28
+ // =============================================================================
29
+ // Validation
30
+ // =============================================================================
31
+ const VALID_FOLDERS = ['products', 'categories', 'variants', 'general'];
32
+ function validateRequest(body) {
33
+ if (!body || typeof body !== 'object') {
34
+ return { valid: false, error: 'Request body is required' };
35
+ }
36
+ const req = body;
37
+ // Validate filename
38
+ if (!req.filename || typeof req.filename !== 'string') {
39
+ return { valid: false, error: 'filename is required' };
40
+ }
41
+ // Validate contentType
42
+ if (!req.contentType || typeof req.contentType !== 'string') {
43
+ return { valid: false, error: 'contentType is required' };
44
+ }
45
+ // Validate folder
46
+ if (!req.folder || typeof req.folder !== 'string') {
47
+ return { valid: false, error: 'folder is required' };
48
+ }
49
+ if (!VALID_FOLDERS.includes(req.folder)) {
50
+ return { valid: false, error: `folder must be one of: ${VALID_FOLDERS.join(', ')}` };
51
+ }
52
+ // Validate entityId (optional)
53
+ if (req.entityId !== undefined && typeof req.entityId !== 'string') {
54
+ return { valid: false, error: 'entityId must be a string' };
55
+ }
56
+ // Validate content type against allowed types
57
+ const uploadConfig = getUploadConfig();
58
+ if (!uploadConfig.allowedTypes.includes(req.contentType)) {
59
+ return {
60
+ valid: false,
61
+ error: `Content type ${req.contentType} is not allowed. Allowed: ${uploadConfig.allowedTypes.join(', ')}`,
62
+ };
63
+ }
64
+ return {
65
+ valid: true,
66
+ data: {
67
+ filename: req.filename,
68
+ contentType: req.contentType,
69
+ folder: req.folder,
70
+ entityId: req.entityId,
71
+ },
72
+ };
73
+ }
74
+ // =============================================================================
75
+ // POST Handler
76
+ // =============================================================================
77
+ /**
78
+ * POST /api/media/presign
79
+ *
80
+ * Generate a presigned URL for uploading a file to R2.
81
+ *
82
+ * Request Body:
83
+ * {
84
+ * filename: string, // Original filename (for extension)
85
+ * contentType: string, // MIME type (must be allowed type)
86
+ * folder: 'products' | 'categories' | 'variants' | 'general',
87
+ * entityId?: string // Optional entity ID for organization
88
+ * }
89
+ *
90
+ * Response:
91
+ * {
92
+ * success: true,
93
+ * data: {
94
+ * uploadUrl: string, // Presigned PUT URL (expires in 5 min)
95
+ * publicUrl: string, // Final accessible URL after upload
96
+ * key: string, // Storage key
97
+ * expiresAt: string // ISO date when URL expires
98
+ * }
99
+ * }
100
+ */
101
+ export async function POST(request) {
102
+ // Check admin auth
103
+ const authError = await requireAdmin();
104
+ if (authError)
105
+ return authError;
106
+ // Check if media is configured
107
+ if (!isMediaConfigured()) {
108
+ return NextResponse.json({
109
+ success: false,
110
+ error: 'Media storage not configured',
111
+ code: 'NOT_CONFIGURED',
112
+ }, { status: 503 });
113
+ }
114
+ try {
115
+ // Parse request body
116
+ const body = await request.json();
117
+ // Validate request
118
+ const validation = validateRequest(body);
119
+ if (!validation.valid || !validation.data) {
120
+ return NextResponse.json({ success: false, error: validation.error || 'Invalid request' }, { status: 400 });
121
+ }
122
+ // Generate presigned URL
123
+ const result = await generatePresignedUrl(validation.data);
124
+ return NextResponse.json({
125
+ success: true,
126
+ data: result,
127
+ });
128
+ }
129
+ catch (error) {
130
+ console.error('[Media API] Presign error:', error);
131
+ return NextResponse.json({
132
+ success: false,
133
+ error: 'Failed to generate upload URL',
134
+ code: 'PRESIGN_FAILED',
135
+ }, { status: 500 });
136
+ }
137
+ }
138
+ //# sourceMappingURL=presign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presign.js","sourceRoot":"","sources":["../../../src/media/api/presign.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { DropZoneProps } from '../types';
2
+ /**
3
+ * DropZone component for drag-and-drop file selection.
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * <DropZone
8
+ * onFiles={(files) => handleFiles(files)}
9
+ * multiple
10
+ * accept={['image/jpeg', 'image/png']}
11
+ * >
12
+ * Drop images here
13
+ * </DropZone>
14
+ * ```
15
+ */
16
+ export declare function DropZone({ onFiles, multiple, accept, maxSize, disabled, className, children, }: DropZoneProps): import("react/jsx-runtime").JSX.Element;
17
+ export default DropZone;
18
+ //# sourceMappingURL=DropZone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DropZone.d.ts","sourceRoot":"","sources":["../../../src/media/components/DropZone.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAG7C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,QAAgB,EAChB,MAA2C,EAC3C,OAA4C,EAC5C,QAAgB,EAChB,SAAS,EACT,QAAQ,GACT,EAAE,aAAa,2CAqKf;AAwBD,eAAe,QAAQ,CAAA"}
@@ -0,0 +1,112 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * @rovela-ai/sdk/media/components/DropZone
5
+ *
6
+ * Drag-and-drop zone for file uploads.
7
+ */
8
+ import { useState, useCallback, useRef } from 'react';
9
+ import { cn } from '../../core/utils';
10
+ import { DEFAULT_UPLOAD_CONFIG } from '../types';
11
+ /**
12
+ * DropZone component for drag-and-drop file selection.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * <DropZone
17
+ * onFiles={(files) => handleFiles(files)}
18
+ * multiple
19
+ * accept={['image/jpeg', 'image/png']}
20
+ * >
21
+ * Drop images here
22
+ * </DropZone>
23
+ * ```
24
+ */
25
+ export function DropZone({ onFiles, multiple = false, accept = DEFAULT_UPLOAD_CONFIG.allowedTypes, maxSize = DEFAULT_UPLOAD_CONFIG.maxSizeBytes, disabled = false, className, children, }) {
26
+ const [isDragging, setIsDragging] = useState(false);
27
+ const fileInputRef = useRef(null);
28
+ // Handle drag events
29
+ const handleDragEnter = useCallback((e) => {
30
+ e.preventDefault();
31
+ e.stopPropagation();
32
+ if (!disabled) {
33
+ setIsDragging(true);
34
+ }
35
+ }, [disabled]);
36
+ const handleDragLeave = useCallback((e) => {
37
+ e.preventDefault();
38
+ e.stopPropagation();
39
+ setIsDragging(false);
40
+ }, []);
41
+ const handleDragOver = useCallback((e) => {
42
+ e.preventDefault();
43
+ e.stopPropagation();
44
+ if (!disabled) {
45
+ setIsDragging(true);
46
+ }
47
+ }, [disabled]);
48
+ // Filter and validate files
49
+ const filterFiles = useCallback((fileList) => {
50
+ if (!fileList)
51
+ return [];
52
+ const files = Array.from(fileList);
53
+ return files.filter((file) => {
54
+ // Check type
55
+ if (accept.length > 0 && !accept.includes(file.type)) {
56
+ console.warn(`File type ${file.type} not accepted`);
57
+ return false;
58
+ }
59
+ // Check size
60
+ if (maxSize && file.size > maxSize) {
61
+ console.warn(`File ${file.name} exceeds size limit`);
62
+ return false;
63
+ }
64
+ return true;
65
+ });
66
+ }, [accept, maxSize]);
67
+ // Handle drop
68
+ const handleDrop = useCallback((e) => {
69
+ e.preventDefault();
70
+ e.stopPropagation();
71
+ setIsDragging(false);
72
+ if (disabled)
73
+ return;
74
+ const files = filterFiles(e.dataTransfer.files);
75
+ if (files.length > 0) {
76
+ onFiles(multiple ? files : [files[0]]);
77
+ }
78
+ }, [disabled, filterFiles, multiple, onFiles]);
79
+ // Handle file input change
80
+ const handleFileChange = useCallback((e) => {
81
+ const files = filterFiles(e.target.files);
82
+ if (files.length > 0) {
83
+ onFiles(multiple ? files : [files[0]]);
84
+ }
85
+ // Reset input so the same file can be selected again
86
+ e.target.value = '';
87
+ }, [filterFiles, multiple, onFiles]);
88
+ // Handle click to open file picker
89
+ const handleClick = useCallback(() => {
90
+ if (!disabled && fileInputRef.current) {
91
+ fileInputRef.current.click();
92
+ }
93
+ }, [disabled]);
94
+ // Handle keyboard activation
95
+ const handleKeyDown = useCallback((e) => {
96
+ if ((e.key === 'Enter' || e.key === ' ') && !disabled) {
97
+ e.preventDefault();
98
+ fileInputRef.current?.click();
99
+ }
100
+ }, [disabled]);
101
+ return (_jsxs("div", { role: "button", tabIndex: disabled ? -1 : 0, onClick: handleClick, onKeyDown: handleKeyDown, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, className: cn('relative rounded-lg border-2 border-dashed transition-colors', 'flex items-center justify-center p-6 text-center', 'cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2', isDragging && !disabled && 'border-primary bg-primary/5', !isDragging && !disabled && 'border-border hover:border-primary/50 hover:bg-muted/50', disabled && 'cursor-not-allowed opacity-50', className), children: [_jsx("input", { ref: fileInputRef, type: "file", multiple: multiple, accept: accept.join(','), onChange: handleFileChange, disabled: disabled, className: "sr-only", tabIndex: -1 }), _jsx("div", { className: "pointer-events-none", children: children || (_jsxs("div", { className: "text-muted-foreground", children: [_jsx(UploadIcon, { className: "mx-auto h-10 w-10 mb-2" }), _jsx("p", { className: "text-sm font-medium", children: isDragging ? 'Drop files here' : 'Drop files or click to upload' }), _jsx("p", { className: "mt-1 text-xs", children: accept.length > 0
102
+ ? `Accepts: ${accept.map((t) => t.split('/')[1]).join(', ')}`
103
+ : 'All file types accepted' })] })) }), isDragging && (_jsx("div", { className: "absolute inset-0 rounded-lg bg-primary/10 pointer-events-none" }))] }));
104
+ }
105
+ /**
106
+ * Simple upload icon component
107
+ */
108
+ function UploadIcon({ className }) {
109
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: className, children: [_jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), _jsx("polyline", { points: "17 8 12 3 7 8" }), _jsx("line", { x1: "12", x2: "12", y1: "3", y2: "15" })] }));
110
+ }
111
+ export default DropZone;
112
+ //# sourceMappingURL=DropZone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DropZone.js","sourceRoot":"","sources":["../../../src/media/components/DropZone.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAErC,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAEhD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,GAAG,KAAK,EAChB,MAAM,GAAG,qBAAqB,CAAC,YAAY,EAC3C,OAAO,GAAG,qBAAqB,CAAC,YAAY,EAC5C,QAAQ,GAAG,KAAK,EAChB,SAAS,EACT,QAAQ,GACM;IACd,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,YAAY,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAA;IAEnD,qBAAqB;IACrB,MAAM,eAAe,GAAG,WAAW,CACjC,CAAC,CAAkB,EAAE,EAAE;QACrB,CAAC,CAAC,cAAc,EAAE,CAAA;QAClB,CAAC,CAAC,eAAe,EAAE,CAAA;QACnB,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,aAAa,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;IACH,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,CAAkB,EAAE,EAAE;QACzD,CAAC,CAAC,cAAc,EAAE,CAAA;QAClB,CAAC,CAAC,eAAe,EAAE,CAAA;QACnB,aAAa,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,cAAc,GAAG,WAAW,CAChC,CAAC,CAAkB,EAAE,EAAE;QACrB,CAAC,CAAC,cAAc,EAAE,CAAA;QAClB,CAAC,CAAC,eAAe,EAAE,CAAA;QACnB,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,aAAa,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;IACH,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,4BAA4B;IAC5B,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,QAAyB,EAAU,EAAE;QACpC,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,CAAA;QAExB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAElC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3B,aAAa;YACb,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrD,OAAO,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,eAAe,CAAC,CAAA;gBACnD,OAAO,KAAK,CAAA;YACd,CAAC;YAED,aAAa;YACb,IAAI,OAAO,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,qBAAqB,CAAC,CAAA;gBACpD,OAAO,KAAK,CAAA;YACd,CAAC;YAED,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;IACJ,CAAC,EACD,CAAC,MAAM,EAAE,OAAO,CAAC,CAClB,CAAA;IAED,cAAc;IACd,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,CAAkB,EAAE,EAAE;QACrB,CAAC,CAAC,cAAc,EAAE,CAAA;QAClB,CAAC,CAAC,eAAe,EAAE,CAAA;QACnB,aAAa,CAAC,KAAK,CAAC,CAAA;QAEpB,IAAI,QAAQ;YAAE,OAAM;QAEpB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QAE/C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACxC,CAAC;IACH,CAAC,EACD,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAC3C,CAAA;IAED,2BAA2B;IAC3B,MAAM,gBAAgB,GAAG,WAAW,CAClC,CAAC,CAAsC,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAEzC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACxC,CAAC;QAED,qDAAqD;QACrD,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAA;IACrB,CAAC,EACD,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CACjC,CAAA;IAED,mCAAmC;IACnC,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,IAAI,CAAC,QAAQ,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YACtC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,6BAA6B;IAC7B,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,CAAsB,EAAE,EAAE;QACzB,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACtD,CAAC,CAAC,cAAc,EAAE,CAAA;YAClB,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;QAC/B,CAAC;IACH,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,OAAO,CACL,eACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC3B,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,WAAW,EAAE,eAAe,EAC5B,WAAW,EAAE,eAAe,EAC5B,UAAU,EAAE,cAAc,EAC1B,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,EAAE,CACX,8DAA8D,EAC9D,kDAAkD,EAClD,uFAAuF,EACvF,UAAU,IAAI,CAAC,QAAQ,IAAI,6BAA6B,EACxD,CAAC,UAAU,IAAI,CAAC,QAAQ,IAAI,yDAAyD,EACrF,QAAQ,IAAI,+BAA+B,EAC3C,SAAS,CACV,aAGD,gBACE,GAAG,EAAE,YAAY,EACjB,IAAI,EAAC,MAAM,EACX,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EACxB,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAC,SAAS,EACnB,QAAQ,EAAE,CAAC,CAAC,GACZ,EAGF,cAAK,SAAS,EAAC,qBAAqB,YACjC,QAAQ,IAAI,CACX,eAAK,SAAS,EAAC,uBAAuB,aACpC,KAAC,UAAU,IAAC,SAAS,EAAC,wBAAwB,GAAG,EACjD,YAAG,SAAS,EAAC,qBAAqB,YAC/B,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,+BAA+B,GAC/D,EACJ,YAAG,SAAS,EAAC,cAAc,YACxB,MAAM,CAAC,MAAM,GAAG,CAAC;gCAChB,CAAC,CAAC,YAAY,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gCAC7D,CAAC,CAAC,yBAAyB,GAC3B,IACA,CACP,GACG,EAGL,UAAU,IAAI,CACb,cAAK,SAAS,EAAC,+DAA+D,GAAG,CAClF,IACG,CACP,CAAA;AACH,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,EAAE,SAAS,EAA0B;IACvD,OAAO,CACL,eACE,KAAK,EAAC,4BAA4B,EAClC,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,SAAS,EAAE,SAAS,aAEpB,eAAM,CAAC,EAAC,2CAA2C,GAAG,EACtD,mBAAU,MAAM,EAAC,eAAe,GAAG,EACnC,eAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,GAAG,IACnC,CACP,CAAA;AACH,CAAC;AAED,eAAe,QAAQ,CAAA"}
@@ -0,0 +1,18 @@
1
+ import type { ImageGalleryUploadProps } from '../types';
2
+ /**
3
+ * Multi-image upload component for products.
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * <ImageGalleryUpload
8
+ * value={productImages}
9
+ * onChange={(urls) => setProductImages(urls)}
10
+ * folder="products"
11
+ * entityId={productId}
12
+ * maxImages={10}
13
+ * />
14
+ * ```
15
+ */
16
+ export declare function ImageGalleryUpload({ value, onChange, onSave, folder, entityId, maxImages, maxSizeMB, disabled, className, }: ImageGalleryUploadProps): import("react/jsx-runtime").JSX.Element;
17
+ export default ImageGalleryUpload;
18
+ //# sourceMappingURL=ImageGalleryUpload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageGalleryUpload.d.ts","sourceRoot":"","sources":["../../../src/media/components/ImageGalleryUpload.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAA;AAGvD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAU,EACV,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,SAAc,EACd,SAAc,EACd,QAAgB,EAChB,SAAS,GACV,EAAE,uBAAuB,2CA2SzB;AA2HD,eAAe,kBAAkB,CAAA"}
@@ -0,0 +1,166 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ /**
4
+ * @rovela-ai/sdk/media/components/ImageGalleryUpload
5
+ *
6
+ * Multi-image upload component with drag-to-reorder functionality.
7
+ * Designed for product images with primary image designation.
8
+ */
9
+ import { useState, useCallback } from 'react';
10
+ import Image from 'next/image';
11
+ import { cn } from '../../core/utils';
12
+ import { useUpload } from '../hooks/useUpload';
13
+ import { DropZone } from './DropZone';
14
+ import { DEFAULT_UPLOAD_CONFIG } from '../types';
15
+ /**
16
+ * Multi-image upload component for products.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * <ImageGalleryUpload
21
+ * value={productImages}
22
+ * onChange={(urls) => setProductImages(urls)}
23
+ * folder="products"
24
+ * entityId={productId}
25
+ * maxImages={10}
26
+ * />
27
+ * ```
28
+ */
29
+ export function ImageGalleryUpload({ value = [], onChange, onSave, folder, entityId, maxImages = 10, maxSizeMB = 10, disabled = false, className, }) {
30
+ const [deletingIndex, setDeletingIndex] = useState(null);
31
+ const [dragIndex, setDragIndex] = useState(null);
32
+ const [dragOverIndex, setDragOverIndex] = useState(null);
33
+ // Upload hook
34
+ const { upload, isUploading, progress, error, reset } = useUpload({
35
+ folder,
36
+ entityId,
37
+ config: {
38
+ maxSizeBytes: maxSizeMB * 1024 * 1024,
39
+ },
40
+ onSuccess: (result) => {
41
+ if (result.url) {
42
+ const newImages = [...value, result.url];
43
+ onChange(newImages);
44
+ // Auto-persist to database if onSave is provided (edit mode)
45
+ onSave?.(newImages).catch((err) => {
46
+ console.error('[ImageGalleryUpload] Failed to save after upload:', err);
47
+ });
48
+ }
49
+ },
50
+ });
51
+ // Handle file selection
52
+ const handleFiles = useCallback(async (files) => {
53
+ if (disabled || isUploading)
54
+ return;
55
+ // Check max images limit
56
+ const remainingSlots = maxImages - value.length;
57
+ if (remainingSlots <= 0)
58
+ return;
59
+ const filesToUpload = files.slice(0, remainingSlots);
60
+ // Upload files sequentially
61
+ for (const file of filesToUpload) {
62
+ await upload(file);
63
+ }
64
+ }, [upload, disabled, isUploading, maxImages, value.length]);
65
+ // Handle delete
66
+ const handleDelete = useCallback(async (index) => {
67
+ if (disabled || deletingIndex !== null)
68
+ return;
69
+ const url = value[index];
70
+ if (!url)
71
+ return;
72
+ setDeletingIndex(index);
73
+ try {
74
+ await fetch('/api/media', {
75
+ method: 'DELETE',
76
+ headers: { 'Content-Type': 'application/json' },
77
+ body: JSON.stringify({ url }),
78
+ });
79
+ // Remove from list after R2 deletion
80
+ const newImages = [...value];
81
+ newImages.splice(index, 1);
82
+ onChange(newImages);
83
+ // Auto-persist to database if onSave is provided (edit mode)
84
+ onSave?.(newImages).catch((err) => {
85
+ console.error('[ImageGalleryUpload] Failed to save after delete:', err);
86
+ });
87
+ }
88
+ catch (err) {
89
+ console.error('Delete error:', err);
90
+ // Still remove from local state (R2 file may already be gone)
91
+ const newImages = [...value];
92
+ newImages.splice(index, 1);
93
+ onChange(newImages);
94
+ // Still try to persist the removal to DB
95
+ onSave?.(newImages).catch(() => { });
96
+ }
97
+ finally {
98
+ setDeletingIndex(null);
99
+ }
100
+ }, [value, onChange, onSave, disabled, deletingIndex]);
101
+ // Drag and drop reordering
102
+ const handleDragStart = useCallback((e, index) => {
103
+ if (disabled)
104
+ return;
105
+ setDragIndex(index);
106
+ e.dataTransfer.effectAllowed = 'move';
107
+ // Set drag image (optional - use the element itself)
108
+ if (e.currentTarget instanceof HTMLElement) {
109
+ e.dataTransfer.setDragImage(e.currentTarget, 50, 50);
110
+ }
111
+ }, [disabled]);
112
+ const handleDragOver = useCallback((e, index) => {
113
+ e.preventDefault();
114
+ if (dragIndex === null || dragIndex === index)
115
+ return;
116
+ setDragOverIndex(index);
117
+ }, [dragIndex]);
118
+ const handleDragEnd = useCallback(() => {
119
+ if (dragIndex !== null && dragOverIndex !== null && dragIndex !== dragOverIndex) {
120
+ // Reorder
121
+ const newImages = [...value];
122
+ const [removed] = newImages.splice(dragIndex, 1);
123
+ newImages.splice(dragOverIndex, 0, removed);
124
+ onChange(newImages);
125
+ }
126
+ setDragIndex(null);
127
+ setDragOverIndex(null);
128
+ }, [dragIndex, dragOverIndex, value, onChange]);
129
+ const handleDragLeave = useCallback(() => {
130
+ setDragOverIndex(null);
131
+ }, []);
132
+ // Move image to primary position
133
+ const handleMakePrimary = useCallback((index) => {
134
+ if (index === 0 || disabled)
135
+ return;
136
+ const newImages = [...value];
137
+ const [removed] = newImages.splice(index, 1);
138
+ newImages.unshift(removed);
139
+ onChange(newImages);
140
+ }, [value, onChange, disabled]);
141
+ const canAddMore = value.length < maxImages;
142
+ return (_jsxs("div", { className: cn('space-y-4', className), children: [value.length > 0 && (_jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4", children: value.map((url, index) => (_jsxs("div", { draggable: !disabled, onDragStart: (e) => handleDragStart(e, index), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, onDragLeave: handleDragLeave, className: cn('relative aspect-square rounded-lg border overflow-hidden group', 'transition-all duration-200', dragIndex === index && 'opacity-50 scale-95', dragOverIndex === index && 'ring-2 ring-primary ring-offset-2', !disabled && 'cursor-grab active:cursor-grabbing'), children: [_jsx(Image, { src: url, alt: `Image ${index + 1}`, fill: true, className: "object-cover", sizes: "(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw" }), index === 0 && (_jsx("div", { className: "absolute top-2 left-2 px-2 py-0.5 rounded-full bg-primary text-primary-foreground text-xs font-medium", children: "Primary" })), _jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/40 transition-colors", children: _jsxs("div", { className: "absolute inset-0 flex items-center justify-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity", children: [index !== 0 && (_jsx("button", { type: "button", onClick: () => handleMakePrimary(index), disabled: disabled, className: cn('rounded-full bg-white/90 p-2 text-gray-700', 'hover:bg-white transition-colors', 'disabled:opacity-50 disabled:cursor-not-allowed'), title: "Make primary", children: _jsx(StarIcon, { className: "h-4 w-4" }) })), _jsx("button", { type: "button", onClick: () => handleDelete(index), disabled: disabled || deletingIndex !== null, className: cn('rounded-full bg-destructive p-2 text-destructive-foreground', 'hover:bg-destructive/90 transition-colors', 'disabled:opacity-50 disabled:cursor-not-allowed'), title: "Remove image", children: deletingIndex === index ? (_jsx(SpinnerIcon, { className: "h-4 w-4 animate-spin" })) : (_jsx(TrashIcon, { className: "h-4 w-4" })) })] }) }), _jsx("div", { className: "absolute top-2 right-2 p-1 rounded bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity", children: _jsx(GripIcon, { className: "h-4 w-4 text-white" }) })] }, url))) })), canAddMore && (_jsx(DropZone, { onFiles: handleFiles, multiple: maxImages - value.length > 1, accept: DEFAULT_UPLOAD_CONFIG.allowedTypes, maxSize: maxSizeMB * 1024 * 1024, disabled: disabled || isUploading, className: "min-h-[120px]", children: _jsx("div", { className: "text-muted-foreground", children: isUploading ? (_jsxs("div", { className: "space-y-2", children: [_jsx(SpinnerIcon, { className: "mx-auto h-8 w-8 animate-spin" }), _jsx("p", { className: "text-sm", children: "Uploading..." }), progress && (_jsxs("div", { className: "w-full max-w-[200px] mx-auto", children: [_jsx("div", { className: "h-1.5 bg-muted rounded-full overflow-hidden", children: _jsx("div", { className: "h-full bg-primary transition-all duration-300", style: { width: `${progress.percentage}%` } }) }), _jsxs("p", { className: "text-xs mt-1", children: [progress.percentage, "%"] })] }))] })) : (_jsxs(_Fragment, { children: [_jsx(ImagePlusIcon, { className: "mx-auto h-10 w-10 mb-2" }), _jsx("p", { className: "text-sm font-medium", children: value.length === 0 ? 'Add product images' : 'Add more images' }), _jsx("p", { className: "text-xs mt-1", children: "Drop images or click to browse" }), _jsxs("p", { className: "text-xs text-muted-foreground/70", children: [value.length, " / ", maxImages, " images"] })] })) }) })), !canAddMore && (_jsxs("p", { className: "text-sm text-muted-foreground text-center", children: ["Maximum ", maxImages, " images reached. Remove an image to add more."] })), error && (_jsxs("div", { className: "flex items-center gap-2 text-sm text-destructive", children: [_jsx(AlertIcon, { className: "h-4 w-4 flex-shrink-0" }), _jsx("span", { children: error }), _jsx("button", { type: "button", onClick: reset, className: "text-primary hover:underline ml-auto", children: "Retry" })] })), value.length > 1 && (_jsx("p", { className: "text-xs text-muted-foreground", children: "Drag images to reorder. First image is the primary product image." }))] }));
143
+ }
144
+ // =============================================================================
145
+ // Icon Components
146
+ // =============================================================================
147
+ function ImagePlusIcon({ className }) {
148
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: className, children: [_jsx("path", { d: "M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7" }), _jsx("line", { x1: "16", x2: "22", y1: "5", y2: "5" }), _jsx("line", { x1: "19", x2: "19", y1: "2", y2: "8" }), _jsx("circle", { cx: "9", cy: "9", r: "2" }), _jsx("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })] }));
149
+ }
150
+ function TrashIcon({ className }) {
151
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: className, children: [_jsx("path", { d: "M3 6h18" }), _jsx("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }), _jsx("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" }), _jsx("line", { x1: "10", x2: "10", y1: "11", y2: "17" }), _jsx("line", { x1: "14", x2: "14", y1: "11", y2: "17" })] }));
152
+ }
153
+ function StarIcon({ className }) {
154
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: className, children: _jsx("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" }) }));
155
+ }
156
+ function GripIcon({ className }) {
157
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: className, children: [_jsx("circle", { cx: "9", cy: "5", r: "1" }), _jsx("circle", { cx: "9", cy: "12", r: "1" }), _jsx("circle", { cx: "9", cy: "19", r: "1" }), _jsx("circle", { cx: "15", cy: "5", r: "1" }), _jsx("circle", { cx: "15", cy: "12", r: "1" }), _jsx("circle", { cx: "15", cy: "19", r: "1" })] }));
158
+ }
159
+ function SpinnerIcon({ className }) {
160
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: className, children: _jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) }));
161
+ }
162
+ function AlertIcon({ className }) {
163
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: className, children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("line", { x1: "12", x2: "12", y1: "8", y2: "12" }), _jsx("line", { x1: "12", x2: "12.01", y1: "16", y2: "16" })] }));
164
+ }
165
+ export default ImageGalleryUpload;
166
+ //# sourceMappingURL=ImageGalleryUpload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageGalleryUpload.js","sourceRoot":"","sources":["../../../src/media/components/ImageGalleryUpload.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { ImageUploadProps } from '../types';
2
+ /**
3
+ * Single image upload component.
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * <ImageUpload
8
+ * value={categoryImage}
9
+ * onChange={(url) => setCategoryImage(url)}
10
+ * folder="categories"
11
+ * entityId={categoryId}
12
+ * />
13
+ * ```
14
+ */
15
+ export declare function ImageUpload({ value, onChange, onSave, folder, entityId, maxSizeMB, disabled, className, placeholder, aspectRatio, }: ImageUploadProps): import("react/jsx-runtime").JSX.Element;
16
+ export default ImageUpload;
17
+ //# sourceMappingURL=ImageUpload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageUpload.d.ts","sourceRoot":"","sources":["../../../src/media/components/ImageUpload.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAGhD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,SAAc,EACd,QAAgB,EAChB,SAAS,EACT,WAA+B,EAC/B,WAAoB,GACrB,EAAE,gBAAgB,2CAyKlB;AAkFD,eAAe,WAAW,CAAA"}