@rovela-ai/sdk 0.1.26 → 0.1.27

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 +2 -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 +3 -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 +156 -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 +95 -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 +271 -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,95 @@
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/ImageUpload
5
+ *
6
+ * Single image upload component with preview, progress, and delete functionality.
7
+ */
8
+ import { useState, useCallback } from 'react';
9
+ import Image from 'next/image';
10
+ import { cn } from '../../core/utils';
11
+ import { useUpload } from '../hooks/useUpload';
12
+ import { DropZone } from './DropZone';
13
+ import { DEFAULT_UPLOAD_CONFIG } from '../types';
14
+ /**
15
+ * Single image upload component.
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * <ImageUpload
20
+ * value={categoryImage}
21
+ * onChange={(url) => setCategoryImage(url)}
22
+ * folder="categories"
23
+ * entityId={categoryId}
24
+ * />
25
+ * ```
26
+ */
27
+ export function ImageUpload({ value, onChange, folder, entityId, maxSizeMB = 10, disabled = false, className, placeholder = 'Upload an image', aspectRatio = '16/9', }) {
28
+ const [isDeleting, setIsDeleting] = useState(false);
29
+ // Upload hook
30
+ const { upload, isUploading, progress, error, reset } = useUpload({
31
+ folder,
32
+ entityId,
33
+ config: {
34
+ maxSizeBytes: maxSizeMB * 1024 * 1024,
35
+ },
36
+ onSuccess: (result) => {
37
+ if (result.url) {
38
+ onChange(result.url);
39
+ }
40
+ },
41
+ });
42
+ // Handle file selection
43
+ const handleFiles = useCallback(async (files) => {
44
+ if (files.length === 0 || disabled || isUploading)
45
+ return;
46
+ await upload(files[0]);
47
+ }, [upload, disabled, isUploading]);
48
+ // Handle delete
49
+ const handleDelete = useCallback(async () => {
50
+ if (!value || disabled || isDeleting)
51
+ return;
52
+ setIsDeleting(true);
53
+ try {
54
+ const response = await fetch('/api/media', {
55
+ method: 'DELETE',
56
+ headers: { 'Content-Type': 'application/json' },
57
+ body: JSON.stringify({ url: value }),
58
+ });
59
+ if (response.ok) {
60
+ onChange(null);
61
+ }
62
+ else {
63
+ console.error('Failed to delete image');
64
+ }
65
+ }
66
+ catch (err) {
67
+ console.error('Delete error:', err);
68
+ }
69
+ finally {
70
+ setIsDeleting(false);
71
+ }
72
+ }, [value, disabled, isDeleting, onChange]);
73
+ // Reset error and retry
74
+ const handleRetry = useCallback(() => {
75
+ reset();
76
+ }, [reset]);
77
+ return (_jsxs("div", { className: cn('space-y-2', className), children: [value ? (_jsxs("div", { className: "relative rounded-lg border border-border overflow-hidden", children: [_jsx("div", { className: "relative bg-muted", style: { aspectRatio }, children: _jsx(Image, { src: value, alt: "Uploaded image", fill: true, className: "object-cover", sizes: "(max-width: 768px) 100vw, 50vw" }) }), _jsx("div", { className: "absolute inset-0 bg-black/0 hover:bg-black/40 transition-colors group", children: _jsx("div", { className: "absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity", children: _jsx("button", { type: "button", onClick: handleDelete, disabled: disabled || isDeleting, 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: isDeleting ? (_jsx(SpinnerIcon, { className: "h-5 w-5 animate-spin" })) : (_jsx(TrashIcon, { className: "h-5 w-5" })) }) }) })] })) : (_jsx(DropZone, { onFiles: handleFiles, multiple: false, accept: DEFAULT_UPLOAD_CONFIG.allowedTypes, maxSize: maxSizeMB * 1024 * 1024, disabled: disabled || isUploading, className: cn('min-h-[120px]', aspectRatio && `aspect-[${aspectRatio}]`), 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(ImageIcon, { className: "mx-auto h-10 w-10 mb-2" }), _jsx("p", { className: "text-sm font-medium", children: placeholder }), _jsx("p", { className: "text-xs mt-1", children: "Drop an image or click to browse" }), _jsxs("p", { className: "text-xs text-muted-foreground/70", children: ["Max ", maxSizeMB, "MB"] })] })) }) })), 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: handleRetry, className: "text-primary hover:underline ml-auto", children: "Retry" })] }))] }));
78
+ }
79
+ // =============================================================================
80
+ // Icon Components
81
+ // =============================================================================
82
+ function ImageIcon({ className }) {
83
+ 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("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }), _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" })] }));
84
+ }
85
+ function TrashIcon({ className }) {
86
+ 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" })] }));
87
+ }
88
+ function SpinnerIcon({ className }) {
89
+ 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" }) }));
90
+ }
91
+ function AlertIcon({ className }) {
92
+ 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" })] }));
93
+ }
94
+ export default ImageUpload;
95
+ //# sourceMappingURL=ImageUpload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageUpload.js","sourceRoot":"","sources":["../../../src/media/components/ImageUpload.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/components
3
+ *
4
+ * Media upload components.
5
+ */
6
+ export { DropZone } from './DropZone';
7
+ export { ImageUpload } from './ImageUpload';
8
+ export { ImageGalleryUpload } from './ImageGalleryUpload';
9
+ export type { DropZoneProps, ImageUploadProps, ImageGalleryUploadProps, } from '../types';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/media/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEzD,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,UAAU,CAAA"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/components
3
+ *
4
+ * Media upload components.
5
+ */
6
+ export { DropZone } from './DropZone';
7
+ export { ImageUpload } from './ImageUpload';
8
+ export { ImageGalleryUpload } from './ImageGalleryUpload';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/media/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/config
3
+ *
4
+ * Media storage configuration.
5
+ * Loads R2/S3 credentials from environment variables.
6
+ */
7
+ import type { MediaStorageConfig, UploadConfig } from './types';
8
+ /**
9
+ * Get media storage configuration from environment variables.
10
+ * Returns null if required variables are missing.
11
+ */
12
+ export declare function getMediaConfig(): MediaStorageConfig | null;
13
+ /**
14
+ * Check if media storage is configured
15
+ */
16
+ export declare function isMediaConfigured(): boolean;
17
+ /**
18
+ * Get media configuration or throw an error if not configured.
19
+ * Use this in API routes where configuration is required.
20
+ */
21
+ export declare function requireMediaConfig(): MediaStorageConfig;
22
+ /**
23
+ * Default upload configuration
24
+ */
25
+ export declare const defaultUploadConfig: UploadConfig;
26
+ /**
27
+ * Get upload configuration with optional overrides
28
+ */
29
+ export declare function getUploadConfig(overrides?: Partial<UploadConfig>): UploadConfig;
30
+ /**
31
+ * Build the storage key (path) for a file.
32
+ *
33
+ * Structure: stores/{storeId}/{folder}/{entityId?}/{filename}
34
+ *
35
+ * Examples:
36
+ * - stores/abc123/products/prod456/1699999999_abc123.jpg
37
+ * - stores/abc123/categories/cat789/cover.jpg
38
+ * - stores/abc123/general/1699999999_abc123.jpg
39
+ */
40
+ export declare function buildStorageKey(storeId: string, folder: string, filename: string, entityId?: string): string;
41
+ /**
42
+ * Build the public URL for a stored file
43
+ */
44
+ export declare function buildPublicUrl(publicBaseUrl: string, key: string): string;
45
+ /**
46
+ * Extract the storage key from a public URL
47
+ */
48
+ export declare function extractKeyFromUrl(publicBaseUrl: string, url: string): string | null;
49
+ /**
50
+ * Get MIME type from filename extension
51
+ */
52
+ export declare function getMimeType(filename: string): string;
53
+ /**
54
+ * Check if a MIME type is an allowed image type
55
+ */
56
+ export declare function isAllowedImageType(mimeType: string, config?: UploadConfig): boolean;
57
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/media/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAM/D;;;GAGG;AACH,wBAAgB,cAAc,IAAI,kBAAkB,GAAG,IAAI,CAqB1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,kBAAkB,CASvD;AAMD;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAIjC,CAAA;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAK/E;AAMD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAUR;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAIzE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQnF;AAsBD;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,YAAkC,GACzC,OAAO,CAET"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/config
3
+ *
4
+ * Media storage configuration.
5
+ * Loads R2/S3 credentials from environment variables.
6
+ */
7
+ // =============================================================================
8
+ // Environment Variable Loading
9
+ // =============================================================================
10
+ /**
11
+ * Get media storage configuration from environment variables.
12
+ * Returns null if required variables are missing.
13
+ */
14
+ export function getMediaConfig() {
15
+ const accountId = process.env.R2_ACCOUNT_ID;
16
+ const accessKeyId = process.env.R2_ACCESS_KEY_ID;
17
+ const secretAccessKey = process.env.R2_SECRET_ACCESS_KEY;
18
+ const bucketName = process.env.R2_BUCKET_NAME;
19
+ const publicUrl = process.env.R2_PUBLIC_URL;
20
+ const storeId = process.env.STORE_ID;
21
+ // All are required
22
+ if (!accountId || !accessKeyId || !secretAccessKey || !bucketName || !publicUrl || !storeId) {
23
+ return null;
24
+ }
25
+ return {
26
+ accountId,
27
+ accessKeyId,
28
+ secretAccessKey,
29
+ bucketName,
30
+ publicUrl,
31
+ storeId,
32
+ };
33
+ }
34
+ /**
35
+ * Check if media storage is configured
36
+ */
37
+ export function isMediaConfigured() {
38
+ return getMediaConfig() !== null;
39
+ }
40
+ /**
41
+ * Get media configuration or throw an error if not configured.
42
+ * Use this in API routes where configuration is required.
43
+ */
44
+ export function requireMediaConfig() {
45
+ const config = getMediaConfig();
46
+ if (!config) {
47
+ throw new Error('Media storage not configured. Required environment variables: ' +
48
+ 'R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET_NAME, R2_PUBLIC_URL, STORE_ID');
49
+ }
50
+ return config;
51
+ }
52
+ // =============================================================================
53
+ // Upload Configuration
54
+ // =============================================================================
55
+ /**
56
+ * Default upload configuration
57
+ */
58
+ export const defaultUploadConfig = {
59
+ maxSizeBytes: 10 * 1024 * 1024, // 10MB
60
+ allowedTypes: ['image/jpeg', 'image/png', 'image/webp', 'image/gif'],
61
+ maxFiles: 10,
62
+ };
63
+ /**
64
+ * Get upload configuration with optional overrides
65
+ */
66
+ export function getUploadConfig(overrides) {
67
+ return {
68
+ ...defaultUploadConfig,
69
+ ...overrides,
70
+ };
71
+ }
72
+ // =============================================================================
73
+ // Path Helpers
74
+ // =============================================================================
75
+ /**
76
+ * Build the storage key (path) for a file.
77
+ *
78
+ * Structure: stores/{storeId}/{folder}/{entityId?}/{filename}
79
+ *
80
+ * Examples:
81
+ * - stores/abc123/products/prod456/1699999999_abc123.jpg
82
+ * - stores/abc123/categories/cat789/cover.jpg
83
+ * - stores/abc123/general/1699999999_abc123.jpg
84
+ */
85
+ export function buildStorageKey(storeId, folder, filename, entityId) {
86
+ const parts = ['stores', storeId, folder];
87
+ if (entityId) {
88
+ parts.push(entityId);
89
+ }
90
+ parts.push(filename);
91
+ return parts.join('/');
92
+ }
93
+ /**
94
+ * Build the public URL for a stored file
95
+ */
96
+ export function buildPublicUrl(publicBaseUrl, key) {
97
+ // Remove trailing slash from base URL if present
98
+ const baseUrl = publicBaseUrl.endsWith('/') ? publicBaseUrl.slice(0, -1) : publicBaseUrl;
99
+ return `${baseUrl}/${key}`;
100
+ }
101
+ /**
102
+ * Extract the storage key from a public URL
103
+ */
104
+ export function extractKeyFromUrl(publicBaseUrl, url) {
105
+ const baseUrl = publicBaseUrl.endsWith('/') ? publicBaseUrl.slice(0, -1) : publicBaseUrl;
106
+ if (!url.startsWith(baseUrl)) {
107
+ return null;
108
+ }
109
+ return url.slice(baseUrl.length + 1);
110
+ }
111
+ // =============================================================================
112
+ // Content Type Mapping
113
+ // =============================================================================
114
+ /**
115
+ * Map of file extensions to MIME types
116
+ */
117
+ const EXTENSION_TO_MIME = {
118
+ jpg: 'image/jpeg',
119
+ jpeg: 'image/jpeg',
120
+ png: 'image/png',
121
+ gif: 'image/gif',
122
+ webp: 'image/webp',
123
+ svg: 'image/svg+xml',
124
+ ico: 'image/x-icon',
125
+ bmp: 'image/bmp',
126
+ tiff: 'image/tiff',
127
+ tif: 'image/tiff',
128
+ };
129
+ /**
130
+ * Get MIME type from filename extension
131
+ */
132
+ export function getMimeType(filename) {
133
+ const ext = filename.split('.').pop()?.toLowerCase() || '';
134
+ return EXTENSION_TO_MIME[ext] || 'application/octet-stream';
135
+ }
136
+ /**
137
+ * Check if a MIME type is an allowed image type
138
+ */
139
+ export function isAllowedImageType(mimeType, config = defaultUploadConfig) {
140
+ return config.allowedTypes.includes(mimeType);
141
+ }
142
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/media/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/hooks
3
+ *
4
+ * React hooks for media uploads.
5
+ */
6
+ export { useUpload } from './useUpload';
7
+ export type { UseUploadOptions, UseUploadReturn } from '../types';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/media/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @rovela-ai/sdk/media/hooks
3
+ *
4
+ * React hooks for media uploads.
5
+ */
6
+ export { useUpload } from './useUpload';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/media/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,32 @@
1
+ import type { UseUploadOptions, UseUploadReturn } from '../types';
2
+ /**
3
+ * React hook for uploading files to R2 storage.
4
+ *
5
+ * @param options - Upload configuration options
6
+ * @returns Upload functions and state
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * function ImageUploader() {
11
+ * const { upload, isUploading, progress, error } = useUpload({
12
+ * folder: 'products',
13
+ * entityId: 'prod_123',
14
+ * onSuccess: (result) => console.log('Uploaded:', result.url),
15
+ * });
16
+ *
17
+ * const handleFile = async (file: File) => {
18
+ * const result = await upload(file);
19
+ * if (result.success) {
20
+ * // Use result.url
21
+ * }
22
+ * };
23
+ *
24
+ * return (
25
+ * <input type="file" onChange={(e) => handleFile(e.target.files[0])} />
26
+ * );
27
+ * }
28
+ * ```
29
+ */
30
+ export declare function useUpload(options: UseUploadOptions): UseUploadReturn;
31
+ export default useUpload;
32
+ //# sourceMappingURL=useUpload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useUpload.d.ts","sourceRoot":"","sources":["../../../src/media/hooks/useUpload.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EAMhB,MAAM,UAAU,CAAA;AAOjB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CAqMpE;AAmED,eAAe,SAAS,CAAA"}