@opensaas/stack-storage 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/CHANGELOG.md +11 -0
  3. package/CLAUDE.md +426 -0
  4. package/LICENSE +21 -0
  5. package/README.md +425 -0
  6. package/dist/config/index.d.ts +19 -0
  7. package/dist/config/index.d.ts.map +1 -0
  8. package/dist/config/index.js +25 -0
  9. package/dist/config/index.js.map +1 -0
  10. package/dist/config/types.d.ts +113 -0
  11. package/dist/config/types.d.ts.map +1 -0
  12. package/dist/config/types.js +2 -0
  13. package/dist/config/types.js.map +1 -0
  14. package/dist/fields/index.d.ts +111 -0
  15. package/dist/fields/index.d.ts.map +1 -0
  16. package/dist/fields/index.js +237 -0
  17. package/dist/fields/index.js.map +1 -0
  18. package/dist/index.d.ts +6 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +11 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/providers/index.d.ts +2 -0
  23. package/dist/providers/index.d.ts.map +1 -0
  24. package/dist/providers/index.js +2 -0
  25. package/dist/providers/index.js.map +1 -0
  26. package/dist/providers/local.d.ts +22 -0
  27. package/dist/providers/local.d.ts.map +1 -0
  28. package/dist/providers/local.js +64 -0
  29. package/dist/providers/local.js.map +1 -0
  30. package/dist/runtime/index.d.ts +75 -0
  31. package/dist/runtime/index.d.ts.map +1 -0
  32. package/dist/runtime/index.js +157 -0
  33. package/dist/runtime/index.js.map +1 -0
  34. package/dist/utils/image.d.ts +18 -0
  35. package/dist/utils/image.d.ts.map +1 -0
  36. package/dist/utils/image.js +82 -0
  37. package/dist/utils/image.js.map +1 -0
  38. package/dist/utils/index.d.ts +3 -0
  39. package/dist/utils/index.d.ts.map +1 -0
  40. package/dist/utils/index.js +3 -0
  41. package/dist/utils/index.js.map +1 -0
  42. package/dist/utils/upload.d.ts +56 -0
  43. package/dist/utils/upload.d.ts.map +1 -0
  44. package/dist/utils/upload.js +74 -0
  45. package/dist/utils/upload.js.map +1 -0
  46. package/package.json +50 -0
  47. package/src/config/index.ts +30 -0
  48. package/src/config/types.ts +127 -0
  49. package/src/fields/index.ts +347 -0
  50. package/src/index.ts +14 -0
  51. package/src/providers/index.ts +1 -0
  52. package/src/providers/local.ts +85 -0
  53. package/src/runtime/index.ts +243 -0
  54. package/src/utils/image.ts +111 -0
  55. package/src/utils/index.ts +2 -0
  56. package/src/utils/upload.ts +122 -0
  57. package/tests/image-utils.test.ts +498 -0
  58. package/tests/local-provider.test.ts +349 -0
  59. package/tests/upload-utils.test.ts +313 -0
  60. package/tsconfig.json +9 -0
  61. package/vitest.config.ts +14 -0
package/README.md ADDED
@@ -0,0 +1,425 @@
1
+ # @opensaas/stack-storage
2
+
3
+ File and image upload field types with pluggable storage providers for OpenSaas Stack.
4
+
5
+ ## Features
6
+
7
+ - 📁 **File Upload Field** - Generic file uploads with metadata storage
8
+ - 🖼️ **Image Upload Field** - Image uploads with automatic transformations
9
+ - 🔌 **Pluggable Storage** - Multiple named storage providers (local, S3, Vercel Blob)
10
+ - 🎨 **Image Transformations** - Automatic thumbnail/variant generation with sharp
11
+ - ✅ **Validation** - File size, MIME type, and extension validation
12
+ - 📦 **JSON Storage** - Metadata stored as JSON in your database
13
+ - 🎯 **Type-Safe** - Full TypeScript support
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pnpm add @opensaas/stack-storage sharp
19
+ ```
20
+
21
+ For S3 storage:
22
+
23
+ ```bash
24
+ pnpm add @opensaas/stack-storage-s3
25
+ ```
26
+
27
+ For Vercel Blob storage:
28
+
29
+ ```bash
30
+ pnpm add @opensaas/stack-storage-vercel
31
+ ```
32
+
33
+ ## Basic Usage
34
+
35
+ ### 1. Configure Storage Providers
36
+
37
+ ```typescript
38
+ // opensaas.config.ts
39
+ import { config, list } from '@opensaas/stack-core'
40
+ import { localStorage } from '@opensaas/stack-storage'
41
+ import { s3Storage } from '@opensaas/stack-storage-s3'
42
+ import { file, image } from '@opensaas/stack-storage/fields'
43
+
44
+ export default config({
45
+ storage: {
46
+ // Local filesystem storage
47
+ documents: localStorage({
48
+ uploadDir: './public/uploads/documents',
49
+ serveUrl: '/uploads/documents',
50
+ }),
51
+
52
+ // S3 storage for images
53
+ avatars: s3Storage({
54
+ bucket: 'my-avatars',
55
+ region: 'us-east-1',
56
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
57
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
58
+ }),
59
+ },
60
+
61
+ lists: {
62
+ User: list({
63
+ fields: {
64
+ // Image field with transformations
65
+ avatar: image({
66
+ storage: 'avatars',
67
+ transformations: {
68
+ thumbnail: { width: 100, height: 100, fit: 'cover' },
69
+ profile: { width: 400, height: 400, fit: 'cover' },
70
+ },
71
+ validation: {
72
+ maxFileSize: 5 * 1024 * 1024, // 5MB
73
+ acceptedMimeTypes: ['image/jpeg', 'image/png', 'image/webp'],
74
+ },
75
+ }),
76
+
77
+ // File field
78
+ resume: file({
79
+ storage: 'documents',
80
+ validation: {
81
+ maxFileSize: 10 * 1024 * 1024, // 10MB
82
+ acceptedMimeTypes: ['application/pdf'],
83
+ },
84
+ }),
85
+ },
86
+ }),
87
+ },
88
+ })
89
+ ```
90
+
91
+ ### 2. Create Upload API Route
92
+
93
+ ```typescript
94
+ // app/api/upload/route.ts
95
+ import { NextRequest, NextResponse } from 'next/server'
96
+ import config from '@/opensaas.config'
97
+ import { uploadFile, uploadImage, parseFileFromFormData } from '@opensaas/stack-storage/runtime'
98
+
99
+ export async function POST(request: NextRequest) {
100
+ try {
101
+ const formData = await request.formData()
102
+ const storageProvider = formData.get('storage') as string
103
+ const fieldType = formData.get('fieldType') as 'file' | 'image'
104
+
105
+ // Parse file from FormData
106
+ const fileData = await parseFileFromFormData(formData, 'file')
107
+ if (!fileData) {
108
+ return NextResponse.json({ error: 'No file provided' }, { status: 400 })
109
+ }
110
+
111
+ // Upload based on field type
112
+ if (fieldType === 'image') {
113
+ // Get transformations from config if needed
114
+ const metadata = await uploadImage(config, storageProvider, fileData, {
115
+ validation: {
116
+ maxFileSize: 5 * 1024 * 1024,
117
+ acceptedMimeTypes: ['image/jpeg', 'image/png', 'image/webp'],
118
+ },
119
+ transformations: {
120
+ thumbnail: { width: 100, height: 100, fit: 'cover' },
121
+ },
122
+ })
123
+ return NextResponse.json(metadata)
124
+ } else {
125
+ const metadata = await uploadFile(config, storageProvider, fileData, {
126
+ validation: {
127
+ maxFileSize: 10 * 1024 * 1024,
128
+ },
129
+ })
130
+ return NextResponse.json(metadata)
131
+ }
132
+ } catch (error) {
133
+ console.error('Upload error:', error)
134
+ return NextResponse.json(
135
+ { error: error instanceof Error ? error.message : 'Upload failed' },
136
+ { status: 500 },
137
+ )
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### 3. Use in Admin UI
143
+
144
+ The file and image fields work automatically in the admin UI. For custom forms, provide an `onUpload` handler:
145
+
146
+ ```typescript
147
+ import { FileField, ImageField } from '@opensaas/stack-ui/fields'
148
+
149
+ function CustomForm() {
150
+ const [avatar, setAvatar] = useState<ImageMetadata | null>(null)
151
+
152
+ const handleUpload = async (file: File) => {
153
+ const formData = new FormData()
154
+ formData.append('file', file)
155
+ formData.append('storage', 'avatars')
156
+ formData.append('fieldType', 'image')
157
+
158
+ const response = await fetch('/api/upload', {
159
+ method: 'POST',
160
+ body: formData,
161
+ })
162
+
163
+ if (!response.ok) {
164
+ throw new Error('Upload failed')
165
+ }
166
+
167
+ return await response.json()
168
+ }
169
+
170
+ return (
171
+ <ImageField
172
+ name="avatar"
173
+ value={avatar}
174
+ onChange={setAvatar}
175
+ label="Avatar"
176
+ onUpload={handleUpload}
177
+ />
178
+ )
179
+ }
180
+ ```
181
+
182
+ ## Storage Providers
183
+
184
+ ### Local Filesystem
185
+
186
+ ```typescript
187
+ import { localStorage } from '@opensaas/stack-storage'
188
+
189
+ storage: {
190
+ documents: localStorage({
191
+ uploadDir: './public/uploads/documents',
192
+ serveUrl: '/uploads/documents',
193
+ generateUniqueFilenames: true, // default
194
+ }),
195
+ }
196
+ ```
197
+
198
+ ### AWS S3
199
+
200
+ ```typescript
201
+ import { s3Storage } from '@opensaas/stack-storage-s3'
202
+
203
+ storage: {
204
+ avatars: s3Storage({
205
+ bucket: 'my-bucket',
206
+ region: 'us-east-1',
207
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
208
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
209
+ pathPrefix: 'avatars', // optional
210
+ acl: 'public-read', // default: 'private'
211
+ customDomain: 'https://cdn.example.com', // optional
212
+ }),
213
+ }
214
+ ```
215
+
216
+ ### S3-Compatible Services (MinIO, Backblaze, etc.)
217
+
218
+ ```typescript
219
+ storage: {
220
+ files: s3Storage({
221
+ bucket: 'my-bucket',
222
+ region: 'us-east-1',
223
+ endpoint: 'https://s3.backblazeb2.com',
224
+ forcePathStyle: true,
225
+ accessKeyId: process.env.B2_KEY_ID,
226
+ secretAccessKey: process.env.B2_APPLICATION_KEY,
227
+ }),
228
+ }
229
+ ```
230
+
231
+ ### Vercel Blob
232
+
233
+ ```typescript
234
+ import { vercelBlobStorage } from '@opensaas/stack-storage-vercel'
235
+
236
+ storage: {
237
+ images: vercelBlobStorage({
238
+ token: process.env.BLOB_READ_WRITE_TOKEN,
239
+ pathPrefix: 'images',
240
+ public: true, // default
241
+ }),
242
+ }
243
+ ```
244
+
245
+ ## Image Transformations
246
+
247
+ Generate multiple image variants automatically:
248
+
249
+ ```typescript
250
+ avatar: image({
251
+ storage: 'avatars',
252
+ transformations: {
253
+ thumbnail: {
254
+ width: 100,
255
+ height: 100,
256
+ fit: 'cover', // crop to fill
257
+ format: 'webp',
258
+ quality: 80,
259
+ },
260
+ large: {
261
+ width: 1200,
262
+ height: 1200,
263
+ fit: 'inside', // scale to fit within bounds
264
+ format: 'jpeg',
265
+ quality: 90,
266
+ },
267
+ },
268
+ })
269
+ ```
270
+
271
+ Available fit modes:
272
+
273
+ - `cover` - Crop to fill dimensions
274
+ - `contain` - Scale to fit within dimensions (letterbox)
275
+ - `fill` - Stretch to fill dimensions
276
+ - `inside` - Scale down to fit within dimensions
277
+ - `outside` - Scale up to cover dimensions
278
+
279
+ ## Validation
280
+
281
+ ```typescript
282
+ file({
283
+ storage: 'documents',
284
+ validation: {
285
+ maxFileSize: 10 * 1024 * 1024, // 10MB in bytes
286
+ acceptedMimeTypes: ['application/pdf', 'application/msword'],
287
+ acceptedExtensions: ['.pdf', '.doc', '.docx'],
288
+ },
289
+ })
290
+ ```
291
+
292
+ ## Metadata Storage
293
+
294
+ Files and images store metadata as JSON in your database:
295
+
296
+ ```typescript
297
+ // FileMetadata
298
+ {
299
+ filename: "1234567890-abc123.pdf",
300
+ originalFilename: "resume.pdf",
301
+ url: "https://bucket.s3.amazonaws.com/...",
302
+ mimeType: "application/pdf",
303
+ size: 245678,
304
+ uploadedAt: "2025-10-31T12:00:00Z",
305
+ storageProvider: "documents",
306
+ metadata: { /* custom metadata */ }
307
+ }
308
+
309
+ // ImageMetadata (extends FileMetadata)
310
+ {
311
+ filename: "1234567890-abc123.jpg",
312
+ originalFilename: "avatar.jpg",
313
+ url: "https://bucket.s3.amazonaws.com/...",
314
+ mimeType: "image/jpeg",
315
+ size: 123456,
316
+ width: 1200,
317
+ height: 800,
318
+ uploadedAt: "2025-10-31T12:00:00Z",
319
+ storageProvider: "avatars",
320
+ transformations: {
321
+ thumbnail: {
322
+ url: "https://...",
323
+ width: 100,
324
+ height: 100,
325
+ size: 5678
326
+ }
327
+ }
328
+ }
329
+ ```
330
+
331
+ ## Runtime Utilities
332
+
333
+ ### Upload Helpers
334
+
335
+ ```typescript
336
+ import { uploadFile, uploadImage, deleteFile, deleteImage } from '@opensaas/stack-storage/runtime'
337
+
338
+ // Upload file
339
+ const metadata = await uploadFile(
340
+ config,
341
+ 'documents',
342
+ { file, buffer },
343
+ {
344
+ validation: { maxFileSize: 10 * 1024 * 1024 },
345
+ },
346
+ )
347
+
348
+ // Upload image with transformations
349
+ const imageMetadata = await uploadImage(
350
+ config,
351
+ 'avatars',
352
+ { file, buffer },
353
+ {
354
+ validation: { maxFileSize: 5 * 1024 * 1024 },
355
+ transformations: {
356
+ thumbnail: { width: 100, height: 100, fit: 'cover' },
357
+ },
358
+ },
359
+ )
360
+
361
+ // Delete file
362
+ await deleteFile(config, 'documents', metadata.filename)
363
+
364
+ // Delete image (includes all transformations)
365
+ await deleteImage(config, imageMetadata)
366
+ ```
367
+
368
+ ### Validation Utilities
369
+
370
+ ```typescript
371
+ import { validateFile, formatFileSize, getMimeType } from '@opensaas/stack-storage/utils'
372
+
373
+ const validation = validateFile(
374
+ { size: file.size, name: file.name, type: file.type },
375
+ { maxFileSize: 10 * 1024 * 1024, acceptedMimeTypes: ['application/pdf'] },
376
+ )
377
+
378
+ if (!validation.valid) {
379
+ console.error(validation.error)
380
+ }
381
+ ```
382
+
383
+ ## Custom Storage Providers
384
+
385
+ Implement the `StorageProvider` interface:
386
+
387
+ ```typescript
388
+ import type { StorageProvider, UploadOptions, UploadResult } from '@opensaas/stack-storage'
389
+
390
+ export class CustomStorageProvider implements StorageProvider {
391
+ async upload(
392
+ file: Buffer | Uint8Array,
393
+ filename: string,
394
+ options?: UploadOptions,
395
+ ): Promise<UploadResult> {
396
+ // Your upload logic
397
+ return {
398
+ filename: 'generated-filename.jpg',
399
+ url: 'https://your-cdn.com/file.jpg',
400
+ size: file.length,
401
+ contentType: options?.contentType || 'application/octet-stream',
402
+ }
403
+ }
404
+
405
+ async download(filename: string): Promise<Buffer> {
406
+ // Your download logic
407
+ }
408
+
409
+ async delete(filename: string): Promise<void> {
410
+ // Your delete logic
411
+ }
412
+
413
+ getUrl(filename: string): string {
414
+ return `https://your-cdn.com/${filename}`
415
+ }
416
+
417
+ async getSignedUrl(filename: string, expiresIn?: number): Promise<string> {
418
+ // Optional: signed URLs for private files
419
+ }
420
+ }
421
+ ```
422
+
423
+ ## License
424
+
425
+ MIT
@@ -0,0 +1,19 @@
1
+ import type { LocalStorageConfig } from './types.js';
2
+ export * from './types.js';
3
+ /**
4
+ * Creates a local filesystem storage configuration
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * const config = config({
9
+ * storage: {
10
+ * documents: localStorage({
11
+ * uploadDir: './uploads/documents',
12
+ * serveUrl: '/api/files',
13
+ * }),
14
+ * },
15
+ * })
16
+ * ```
17
+ */
18
+ export declare function localStorage(config: Pick<LocalStorageConfig, 'uploadDir' | 'serveUrl'> & Partial<Pick<LocalStorageConfig, 'generateUniqueFilenames'>>): LocalStorageConfig;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD,cAAc,YAAY,CAAA;AAE1B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,WAAW,GAAG,UAAU,CAAC,GACxD,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,yBAAyB,CAAC,CAAC,GAC7D,kBAAkB,CAOpB"}
@@ -0,0 +1,25 @@
1
+ export * from './types.js';
2
+ /**
3
+ * Creates a local filesystem storage configuration
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * const config = config({
8
+ * storage: {
9
+ * documents: localStorage({
10
+ * uploadDir: './uploads/documents',
11
+ * serveUrl: '/api/files',
12
+ * }),
13
+ * },
14
+ * })
15
+ * ```
16
+ */
17
+ export function localStorage(config) {
18
+ return {
19
+ type: 'local',
20
+ uploadDir: config.uploadDir,
21
+ serveUrl: config.serveUrl,
22
+ generateUniqueFilenames: config.generateUniqueFilenames ?? true,
23
+ };
24
+ }
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAEA,cAAc,YAAY,CAAA;AAE1B;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAC1B,MAC8D;IAE9D,OAAO;QACL,IAAI,EAAE,OAAO;QACb,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,uBAAuB,EAAE,MAAM,CAAC,uBAAuB,IAAI,IAAI;KAChE,CAAA;AACH,CAAC"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Storage provider interface that all storage backends must implement.
3
+ * This allows pluggable storage solutions (local, S3, Vercel Blob, etc.)
4
+ */
5
+ export interface StorageProvider {
6
+ /**
7
+ * Uploads a file to the storage provider
8
+ * @param file - File data as Buffer or Uint8Array
9
+ * @param filename - Desired filename (may be transformed by provider)
10
+ * @param options - Additional upload options (contentType, metadata, etc.)
11
+ * @returns Upload result with URL and metadata
12
+ */
13
+ upload(file: Buffer | Uint8Array, filename: string, options?: UploadOptions): Promise<UploadResult>;
14
+ /**
15
+ * Downloads a file from the storage provider
16
+ * @param filename - Filename to download
17
+ * @returns File data as Buffer
18
+ */
19
+ download(filename: string): Promise<Buffer>;
20
+ /**
21
+ * Deletes a file from the storage provider
22
+ * @param filename - Filename to delete
23
+ */
24
+ delete(filename: string): Promise<void>;
25
+ /**
26
+ * Gets the public URL for a file
27
+ * @param filename - Filename to get URL for
28
+ * @returns Public URL string
29
+ */
30
+ getUrl(filename: string): string;
31
+ /**
32
+ * Optional: Gets a signed URL for private files
33
+ * @param filename - Filename to get signed URL for
34
+ * @param expiresIn - Expiration time in seconds
35
+ * @returns Signed URL string
36
+ */
37
+ getSignedUrl?(filename: string, expiresIn?: number): Promise<string>;
38
+ }
39
+ /**
40
+ * Options for uploading a file
41
+ */
42
+ export interface UploadOptions {
43
+ /** MIME type of the file */
44
+ contentType?: string;
45
+ /** Custom metadata to store with the file */
46
+ metadata?: Record<string, string>;
47
+ /** Whether the file should be publicly accessible */
48
+ public?: boolean;
49
+ /** Cache control header */
50
+ cacheControl?: string;
51
+ }
52
+ /**
53
+ * Result from uploading a file
54
+ */
55
+ export interface UploadResult {
56
+ /** Generated filename (may differ from input) */
57
+ filename: string;
58
+ /** Public URL to access the file */
59
+ url: string;
60
+ /** File size in bytes */
61
+ size: number;
62
+ /** MIME type */
63
+ contentType: string;
64
+ /** Additional provider-specific metadata */
65
+ metadata?: Record<string, unknown>;
66
+ }
67
+ /**
68
+ * Configuration for local filesystem storage
69
+ */
70
+ export interface LocalStorageConfig {
71
+ type: 'local';
72
+ /** Directory to store uploaded files */
73
+ uploadDir: string;
74
+ /** Base URL for serving files (e.g., '/api/files' or 'https://cdn.example.com') */
75
+ serveUrl: string;
76
+ /** Whether to generate unique filenames (default: true) */
77
+ generateUniqueFilenames?: boolean;
78
+ /** Allow additional properties */
79
+ [key: string]: unknown;
80
+ }
81
+ /**
82
+ * Base configuration shared by all storage providers
83
+ */
84
+ export interface BaseStorageConfig {
85
+ type: string;
86
+ [key: string]: unknown;
87
+ }
88
+ /**
89
+ * Storage configuration - maps names to storage provider configs
90
+ * Example: { avatars: s3Config, documents: localConfig }
91
+ */
92
+ export type StorageConfig = Record<string, BaseStorageConfig | LocalStorageConfig>;
93
+ /**
94
+ * Re-export metadata types from core package
95
+ * These types are now defined in @opensaas/stack-core to avoid circular dependencies
96
+ */
97
+ export type { FileMetadata, ImageMetadata, ImageTransformationResult } from '@opensaas/stack-core';
98
+ /**
99
+ * Configuration for image transformations
100
+ */
101
+ export interface ImageTransformationConfig {
102
+ /** Target width in pixels */
103
+ width?: number;
104
+ /** Target height in pixels */
105
+ height?: number;
106
+ /** Fit mode: cover (crop), contain (letterbox), fill (stretch) */
107
+ fit?: 'cover' | 'contain' | 'fill' | 'inside' | 'outside';
108
+ /** Output format (default: original format) */
109
+ format?: 'jpeg' | 'png' | 'webp' | 'avif';
110
+ /** Quality 1-100 (default: 80) */
111
+ quality?: number;
112
+ }
113
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,MAAM,CACJ,IAAI,EAAE,MAAM,GAAG,UAAU,EACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC,CAAA;IAExB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAE3C;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEvC;;;;OAIG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IAEhC;;;;;OAKG;IACH,YAAY,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACrE;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAA;IAChB,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAA;IACX,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,gBAAgB;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAA;IACb,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,mFAAmF;IACnF,QAAQ,EAAE,MAAM,CAAA;IAChB,2DAA2D;IAC3D,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,kCAAkC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,kBAAkB,CAAC,CAAA;AAElF;;;GAGG;AACH,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AAElG;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kEAAkE;IAClE,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAA;IACzD,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;IACzC,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":""}