@ackplus/nest-file-storage 0.1.35
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.
- package/README.md +409 -0
- package/package.json +52 -0
- package/src/index.d.ts +4 -0
- package/src/index.js +8 -0
- package/src/index.js.map +1 -0
- package/src/lib/constants.d.ts +1 -0
- package/src/lib/constants.js +5 -0
- package/src/lib/constants.js.map +1 -0
- package/src/lib/file-storage.service.d.ts +7 -0
- package/src/lib/file-storage.service.js +31 -0
- package/src/lib/file-storage.service.js.map +1 -0
- package/src/lib/index.d.ts +5 -0
- package/src/lib/index.js +9 -0
- package/src/lib/index.js.map +1 -0
- package/src/lib/interceptor/file-storage.interceptor.d.ts +21 -0
- package/src/lib/interceptor/file-storage.interceptor.js +122 -0
- package/src/lib/interceptor/file-storage.interceptor.js.map +1 -0
- package/src/lib/nest-file-storage.module.d.ts +8 -0
- package/src/lib/nest-file-storage.module.js +75 -0
- package/src/lib/nest-file-storage.module.js.map +1 -0
- package/src/lib/storage/azure.storage.d.ts +18 -0
- package/src/lib/storage/azure.storage.js +153 -0
- package/src/lib/storage/azure.storage.js.map +1 -0
- package/src/lib/storage/local.storage.d.ts +17 -0
- package/src/lib/storage/local.storage.js +133 -0
- package/src/lib/storage/local.storage.js.map +1 -0
- package/src/lib/storage/s3.storage.d.ts +19 -0
- package/src/lib/storage/s3.storage.js +208 -0
- package/src/lib/storage/s3.storage.js.map +1 -0
- package/src/lib/storage.factory.d.ts +8 -0
- package/src/lib/storage.factory.js +52 -0
- package/src/lib/storage.factory.js.map +1 -0
- package/src/lib/types.d.ts +76 -0
- package/src/lib/types.js +10 -0
- package/src/lib/types.js.map +1 -0
- package/tsconfig.tsbuildinfo +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
# @ackplus/nest-file-storage
|
|
2
|
+
|
|
3
|
+
A flexible file storage library for NestJS that supports multiple storage providers with simple file mapping capabilities.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @ackplus/nest-file-storage
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Storage Providers
|
|
12
|
+
|
|
13
|
+
This library supports multiple storage providers. You only need to install the dependencies for the storage providers you plan to use.
|
|
14
|
+
|
|
15
|
+
### Local Storage
|
|
16
|
+
|
|
17
|
+
No additional dependencies required. Works out of the box.
|
|
18
|
+
|
|
19
|
+
### Azure Blob Storage
|
|
20
|
+
|
|
21
|
+
To use Azure Blob Storage, install the Azure SDK:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @azure/storage-blob
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### AWS S3 Storage
|
|
28
|
+
|
|
29
|
+
To use AWS S3 Storage, install the AWS SDK:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
The library supports two approaches: **Configuration-based** and **Class Factory**.
|
|
38
|
+
|
|
39
|
+
### Configuration-based Approach (Recommended)
|
|
40
|
+
|
|
41
|
+
This approach uses lazy loading and only loads the storage provider when needed.
|
|
42
|
+
|
|
43
|
+
#### Local Storage
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { NestFileStorageModule, FileStorageEnum } from '@ackplus/nest-file-storage';
|
|
47
|
+
|
|
48
|
+
@Module({
|
|
49
|
+
imports: [
|
|
50
|
+
NestFileStorageModule.forRoot({
|
|
51
|
+
storage: FileStorageEnum.LOCAL,
|
|
52
|
+
localConfig: {
|
|
53
|
+
destination: './uploads'
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
]
|
|
57
|
+
})
|
|
58
|
+
export class AppModule {}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### Azure Blob Storage
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { NestFileStorageModule, FileStorageEnum } from '@ackplus/nest-file-storage';
|
|
65
|
+
|
|
66
|
+
@Module({
|
|
67
|
+
imports: [
|
|
68
|
+
NestFileStorageModule.forRoot({
|
|
69
|
+
storage: FileStorageEnum.AZURE,
|
|
70
|
+
azureConfig: {
|
|
71
|
+
account: 'your-storage-account',
|
|
72
|
+
accountKey: 'your-account-key',
|
|
73
|
+
container: 'your-container'
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
]
|
|
77
|
+
})
|
|
78
|
+
export class AppModule {}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### AWS S3 Storage
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { NestFileStorageModule, FileStorageEnum } from '@ackplus/nest-file-storage';
|
|
85
|
+
|
|
86
|
+
@Module({
|
|
87
|
+
imports: [
|
|
88
|
+
NestFileStorageModule.forRoot({
|
|
89
|
+
storage: FileStorageEnum.S3,
|
|
90
|
+
s3Config: {
|
|
91
|
+
region: 'us-east-1',
|
|
92
|
+
bucket: 'your-bucket',
|
|
93
|
+
accessKeyId: 'your-access-key',
|
|
94
|
+
secretAccessKey: 'your-secret-key'
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
]
|
|
98
|
+
})
|
|
99
|
+
export class AppModule {}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Class Factory Approach
|
|
103
|
+
|
|
104
|
+
This approach allows you to provide your own storage class directly.
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { NestFileStorageModule } from '@ackplus/nest-file-storage';
|
|
108
|
+
|
|
109
|
+
@Module({
|
|
110
|
+
imports: [
|
|
111
|
+
NestFileStorageModule.forRoot({
|
|
112
|
+
storageFactory: async () => {
|
|
113
|
+
// Lazy load the storage class
|
|
114
|
+
const { AzureStorage } = await import('@ackplus/nest-file-storage/lib/storage/azure.storage');
|
|
115
|
+
return AzureStorage;
|
|
116
|
+
},
|
|
117
|
+
options: {
|
|
118
|
+
account: 'your-storage-account',
|
|
119
|
+
accountKey: 'your-account-key',
|
|
120
|
+
container: 'your-container'
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
]
|
|
124
|
+
})
|
|
125
|
+
export class AppModule {}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Custom Storage Class
|
|
129
|
+
|
|
130
|
+
You can also provide your own custom storage implementation:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import { NestFileStorageModule, Storage } from '@ackplus/nest-file-storage';
|
|
134
|
+
|
|
135
|
+
class CustomStorage implements Storage {
|
|
136
|
+
// Implement your custom storage logic
|
|
137
|
+
async getFile(key: string): Promise<Buffer> { /* ... */ }
|
|
138
|
+
async deleteFile(key: string): Promise<void> { /* ... */ }
|
|
139
|
+
async putFile(fileContent: Buffer, key: string): Promise<UploadedFile> { /* ... */ }
|
|
140
|
+
getUrl(key: string): string { /* ... */ }
|
|
141
|
+
async copyFile(oldKey: string, newKey: string): Promise<UploadedFile> { /* ... */ }
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@Module({
|
|
145
|
+
imports: [
|
|
146
|
+
NestFileStorageModule.forRoot({
|
|
147
|
+
storageFactory: () => CustomStorage,
|
|
148
|
+
options: {
|
|
149
|
+
// Your custom options
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
]
|
|
153
|
+
})
|
|
154
|
+
export class AppModule {}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### When to Use Each Approach
|
|
158
|
+
|
|
159
|
+
**Configuration-based Approach:**
|
|
160
|
+
- ✅ Recommended for most use cases
|
|
161
|
+
- ✅ Automatic lazy loading
|
|
162
|
+
- ✅ Built-in error handling for missing dependencies
|
|
163
|
+
- ✅ Simpler configuration
|
|
164
|
+
- ✅ Better for switching between providers
|
|
165
|
+
- ✅ Supports async configuration with dependency injection
|
|
166
|
+
|
|
167
|
+
**Class Factory Approach:**
|
|
168
|
+
- ✅ More control over storage instantiation
|
|
169
|
+
- ✅ Custom storage implementations
|
|
170
|
+
- ✅ Advanced use cases
|
|
171
|
+
- ✅ Still supports lazy loading if implemented correctly
|
|
172
|
+
- ⚠️ More complex configuration
|
|
173
|
+
- ⚠️ Manual dependency management
|
|
174
|
+
|
|
175
|
+
**Async Configuration (forRootAsync):**
|
|
176
|
+
- ✅ Full dependency injection support
|
|
177
|
+
- ✅ `useFactory`, `useClass`, and `useExisting` patterns
|
|
178
|
+
- ✅ Integration with ConfigService and other providers
|
|
179
|
+
- ✅ Environment-based configuration
|
|
180
|
+
- ✅ Perfect for complex application setups
|
|
181
|
+
|
|
182
|
+
### Async Configuration (forRootAsync)
|
|
183
|
+
|
|
184
|
+
For more advanced scenarios, you can use `forRootAsync` with dependency injection:
|
|
185
|
+
|
|
186
|
+
#### Using useFactory
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { NestFileStorageModule, FileStorageEnum } from '@ackplus/nest-file-storage';
|
|
190
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
191
|
+
|
|
192
|
+
@Module({
|
|
193
|
+
imports: [
|
|
194
|
+
ConfigModule,
|
|
195
|
+
NestFileStorageModule.forRootAsync({
|
|
196
|
+
imports: [ConfigModule],
|
|
197
|
+
useFactory: async (configService: ConfigService) => ({
|
|
198
|
+
storage: FileStorageEnum.S3,
|
|
199
|
+
s3Config: {
|
|
200
|
+
region: configService.get('AWS_REGION'),
|
|
201
|
+
bucket: configService.get('AWS_BUCKET'),
|
|
202
|
+
accessKeyId: configService.get('AWS_ACCESS_KEY_ID'),
|
|
203
|
+
secretAccessKey: configService.get('AWS_SECRET_ACCESS_KEY'),
|
|
204
|
+
}
|
|
205
|
+
}),
|
|
206
|
+
inject: [ConfigService],
|
|
207
|
+
})
|
|
208
|
+
]
|
|
209
|
+
})
|
|
210
|
+
export class AppModule {}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### Using useClass
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import { Injectable } from '@nestjs/common';
|
|
217
|
+
import { NestFileStorageModule, FileStorageOptionsFactory, FileStorageModuleOptions, FileStorageEnum } from '@ackplus/nest-file-storage';
|
|
218
|
+
import { ConfigService } from '@nestjs/config';
|
|
219
|
+
|
|
220
|
+
@Injectable()
|
|
221
|
+
export class FileStorageConfigService implements FileStorageOptionsFactory {
|
|
222
|
+
constructor(private configService: ConfigService) {}
|
|
223
|
+
|
|
224
|
+
createFileStorageOptions(): FileStorageModuleOptions {
|
|
225
|
+
return {
|
|
226
|
+
storage: FileStorageEnum.AZURE,
|
|
227
|
+
azureConfig: {
|
|
228
|
+
account: this.configService.get('AZURE_STORAGE_ACCOUNT'),
|
|
229
|
+
accountKey: this.configService.get('AZURE_STORAGE_KEY'),
|
|
230
|
+
container: this.configService.get('AZURE_STORAGE_CONTAINER'),
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
@Module({
|
|
237
|
+
imports: [
|
|
238
|
+
ConfigModule,
|
|
239
|
+
NestFileStorageModule.forRootAsync({
|
|
240
|
+
imports: [ConfigModule],
|
|
241
|
+
useClass: FileStorageConfigService,
|
|
242
|
+
})
|
|
243
|
+
]
|
|
244
|
+
})
|
|
245
|
+
export class AppModule {}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### Using useExisting
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
@Module({
|
|
252
|
+
imports: [
|
|
253
|
+
ConfigModule,
|
|
254
|
+
NestFileStorageModule.forRootAsync({
|
|
255
|
+
imports: [ConfigModule],
|
|
256
|
+
useExisting: FileStorageConfigService,
|
|
257
|
+
})
|
|
258
|
+
],
|
|
259
|
+
providers: [FileStorageConfigService]
|
|
260
|
+
})
|
|
261
|
+
export class AppModule {}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Direct Usage with Storage Factory
|
|
265
|
+
|
|
266
|
+
You can also use the storage factory directly for more control:
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import { StorageFactory, FileStorageEnum } from '@ackplus/nest-file-storage';
|
|
270
|
+
|
|
271
|
+
// This will lazy load only the Azure storage provider
|
|
272
|
+
const azureStorage = await StorageFactory.createStorage(FileStorageEnum.AZURE, {
|
|
273
|
+
account: 'your-storage-account',
|
|
274
|
+
accountKey: 'your-account-key',
|
|
275
|
+
container: 'your-container'
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// Use the storage instance
|
|
279
|
+
const uploadedFile = await azureStorage.putFile(buffer, 'path/to/file.jpg');
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Flexible File Mapping
|
|
283
|
+
|
|
284
|
+
The library includes flexible file mapping functionality that allows you to define custom logic for how uploaded files are transformed and stored in the request body.
|
|
285
|
+
|
|
286
|
+
**Default Behavior**: Without any configuration, uploaded files are automatically mapped to their storage key (path) in the request body.
|
|
287
|
+
|
|
288
|
+
### Default Behavior (No Configuration)
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
import { FileStorageInterceptor } from '@ackplus/nest-file-storage';
|
|
292
|
+
|
|
293
|
+
@Controller('upload')
|
|
294
|
+
export class UploadController {
|
|
295
|
+
@Post('document')
|
|
296
|
+
@UseInterceptors(FileStorageInterceptor('document'))
|
|
297
|
+
async uploadDocument(@Body() body: any) {
|
|
298
|
+
// body.document will contain the file key (storage path)
|
|
299
|
+
console.log(body.document); // "documents/2024/1/1234567890-resume.pdf"
|
|
300
|
+
return { message: 'Document uploaded', data: body };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Return File URL String (Custom Logic)
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
@Post('avatar')
|
|
309
|
+
@UseInterceptors(FileStorageInterceptor('avatar', {
|
|
310
|
+
mapToRequestBody: (file, fieldName, req) => {
|
|
311
|
+
// Return just the URL string for direct DB storage
|
|
312
|
+
return file.url;
|
|
313
|
+
}
|
|
314
|
+
}))
|
|
315
|
+
async uploadAvatar(@Body() body: any) {
|
|
316
|
+
// body.avatar will be a string URL
|
|
317
|
+
console.log(body.avatar); // "http://localhost:3000/uploads/images/avatar.jpg"
|
|
318
|
+
return { message: 'Avatar uploaded', data: body };
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Return Custom Object with Business Logic
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
@Post('document')
|
|
326
|
+
@UseInterceptors(FileStorageInterceptor('document', {
|
|
327
|
+
mapToRequestBody: (file, fieldName, req) => {
|
|
328
|
+
// Return custom object with business logic
|
|
329
|
+
return {
|
|
330
|
+
fileId: `file_${Date.now()}`,
|
|
331
|
+
url: file.url,
|
|
332
|
+
originalName: file.originalName,
|
|
333
|
+
uploadedBy: req.user?.id || 'anonymous',
|
|
334
|
+
uploadedAt: new Date().toISOString(),
|
|
335
|
+
isPublic: req.body.isPublic === 'true'
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
}))
|
|
339
|
+
async uploadDocument(@Body() body: any) {
|
|
340
|
+
// body.document will be a custom object
|
|
341
|
+
console.log(body.document);
|
|
342
|
+
return { message: 'Document uploaded', data: body };
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Multiple Files with Custom Logic
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
@Post('gallery')
|
|
350
|
+
@UseInterceptors(FileStorageInterceptor({
|
|
351
|
+
type: 'array',
|
|
352
|
+
fieldName: 'images',
|
|
353
|
+
maxCount: 5
|
|
354
|
+
}, {
|
|
355
|
+
mapToRequestBody: (files, fieldName, req) => {
|
|
356
|
+
// Return array of custom objects
|
|
357
|
+
return files.map((file, index) => ({
|
|
358
|
+
id: `img_${Date.now()}_${index}`,
|
|
359
|
+
url: file.url,
|
|
360
|
+
isPrimary: index === 0,
|
|
361
|
+
alt: req.body.imageAlts?.[index] || `Image ${index + 1}`
|
|
362
|
+
}));
|
|
363
|
+
}
|
|
364
|
+
}))
|
|
365
|
+
async uploadGallery(@Body() body: any) {
|
|
366
|
+
// body.images will be an array of custom objects
|
|
367
|
+
console.log(body.images);
|
|
368
|
+
return { message: 'Gallery uploaded', data: body };
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Key Features**:
|
|
373
|
+
- **Return anything**: String, object, array, or custom structure
|
|
374
|
+
- **Access request data**: Use `req` parameter for user info, body data, etc.
|
|
375
|
+
- **Field-specific logic**: Use `fieldName` to handle different fields differently
|
|
376
|
+
- **Business logic**: Implement any custom transformation you need
|
|
377
|
+
|
|
378
|
+
For detailed examples, see [FILE_KEY_MAPPING.md](./docs/FILE_KEY_MAPPING.md).
|
|
379
|
+
|
|
380
|
+
## Error Handling
|
|
381
|
+
|
|
382
|
+
If you try to use a storage provider without installing its required dependencies, you'll get a clear error message:
|
|
383
|
+
|
|
384
|
+
- **Azure Storage**: `Azure Storage SDK (@azure/storage-blob) is required when using AzureStorage. Please install it: npm install @azure/storage-blob`
|
|
385
|
+
- **S3 Storage**: `AWS SDK (@aws-sdk/client-s3 and @aws-sdk/s3-request-presigner) is required when using S3Storage. Please install them: npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner`
|
|
386
|
+
|
|
387
|
+
## How Lazy Loading Works
|
|
388
|
+
|
|
389
|
+
The library uses dynamic imports to load storage providers only when they're actually needed:
|
|
390
|
+
|
|
391
|
+
1. **At build time**: Only the storage factory and types are bundled
|
|
392
|
+
2. **At runtime**: When you use a storage provider, it's dynamically imported
|
|
393
|
+
3. **Caching**: Once loaded, storage instances are cached for reuse
|
|
394
|
+
4. **Error handling**: Missing dependencies are caught and provide clear error messages
|
|
395
|
+
|
|
396
|
+
This means:
|
|
397
|
+
- If you only use local storage, Azure/S3 code is never loaded
|
|
398
|
+
- If you only use Azure storage, S3 code is never loaded
|
|
399
|
+
- Your bundle size stays minimal regardless of how many storage providers are available
|
|
400
|
+
|
|
401
|
+
## Benefits
|
|
402
|
+
|
|
403
|
+
- **Lazy Loading**: Storage providers are only loaded when actually used
|
|
404
|
+
- **Smaller bundle size**: Only install the dependencies you need
|
|
405
|
+
- **Flexible**: Switch between storage providers easily
|
|
406
|
+
- **Clear error messages**: Know exactly what to install if a dependency is missing
|
|
407
|
+
- **TypeScript support**: Full type safety for all storage providers
|
|
408
|
+
- **Caching**: Storage instances are cached to avoid repeated initialization
|
|
409
|
+
- **Zero overhead**: Unused storage providers don't affect your application
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ackplus/nest-file-storage",
|
|
3
|
+
"version": "0.1.35",
|
|
4
|
+
"type": "commonjs",
|
|
5
|
+
"main": "./src/index.js",
|
|
6
|
+
"types": "./src/index.d.ts",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/ack-solutions/packages.git"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/ack-solutions/packages.git#readme",
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"typeorm": "^0.3.23",
|
|
18
|
+
"@nestjs/typeorm": "^11.0.0",
|
|
19
|
+
"@nestjs/common": "^10.4.5",
|
|
20
|
+
"@azure/storage-blob": "^12.0.0",
|
|
21
|
+
"@aws-sdk/client-s3": "^3.0.0",
|
|
22
|
+
"@aws-sdk/s3-request-presigner": "^3.0.0"
|
|
23
|
+
},
|
|
24
|
+
"peerDependenciesMeta": {
|
|
25
|
+
"@azure/storage-blob": {
|
|
26
|
+
"optional": true
|
|
27
|
+
},
|
|
28
|
+
"@aws-sdk/client-s3": {
|
|
29
|
+
"optional": true
|
|
30
|
+
},
|
|
31
|
+
"@aws-sdk/s3-request-presigner": {
|
|
32
|
+
"optional": true
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"typeorm": "^0.3.23",
|
|
37
|
+
"@nestjs/typeorm": "^11.0.0",
|
|
38
|
+
"@nestjs/common": "^10.4.5",
|
|
39
|
+
"@types/multer": "^2.0.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"tslib": "^2.3.0",
|
|
43
|
+
"deepmerge": "4.3.1",
|
|
44
|
+
"class-transformer": "^0.5.1",
|
|
45
|
+
"class-validator": "^0.14.1",
|
|
46
|
+
"pluralize": "8.0.0",
|
|
47
|
+
"lodash": "^4.17.21",
|
|
48
|
+
"rxjs": "^7.8.0",
|
|
49
|
+
"multer": "^2.0.1",
|
|
50
|
+
"moment": "^2.30.1"
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/index.d.ts
ADDED
package/src/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./lib/nest-file-storage.module"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./lib/file-storage.service"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./lib/interceptor/file-storage.interceptor"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./lib/types"), exports);
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/nest-file-storage/src/index.ts"],"names":[],"mappings":";;;AAAA,yEAA+C;AAC/C,qEAA2C;AAC3C,qFAA2D;AAC3D,sDAA4B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const FILE_STORAGE_OPTIONS = "FileStorageOptions";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../packages/nest-file-storage/src/lib/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,oBAAoB,GAAG,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FileStorageEnum, FileStorageModuleOptions } from './types';
|
|
2
|
+
export declare class FileStorageService {
|
|
3
|
+
private static options;
|
|
4
|
+
static setOptions(options: FileStorageModuleOptions): void;
|
|
5
|
+
static getOptions(): FileStorageModuleOptions;
|
|
6
|
+
static getStorage(storageType?: FileStorageEnum): Promise<import("./types").Storage>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FileStorageService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const storage_factory_1 = require("./storage.factory");
|
|
6
|
+
class FileStorageService {
|
|
7
|
+
static setOptions(options) {
|
|
8
|
+
FileStorageService.options = options;
|
|
9
|
+
}
|
|
10
|
+
static getOptions() {
|
|
11
|
+
return FileStorageService.options;
|
|
12
|
+
}
|
|
13
|
+
static getStorage(storageType) {
|
|
14
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
const options = this.getOptions();
|
|
16
|
+
if ('storageFactory' in options) {
|
|
17
|
+
const classOptions = options;
|
|
18
|
+
const StorageClass = yield classOptions.storageFactory();
|
|
19
|
+
return new StorageClass(classOptions.options);
|
|
20
|
+
}
|
|
21
|
+
const configOptions = options;
|
|
22
|
+
if (!storageType) {
|
|
23
|
+
storageType = configOptions.storage;
|
|
24
|
+
}
|
|
25
|
+
const config = configOptions[`${storageType}Config`];
|
|
26
|
+
return yield storage_factory_1.StorageFactory.createStorage(storageType, config);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.FileStorageService = FileStorageService;
|
|
31
|
+
//# sourceMappingURL=file-storage.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-storage.service.js","sourceRoot":"","sources":["../../../../../packages/nest-file-storage/src/lib/file-storage.service.ts"],"names":[],"mappings":";;;;AAAA,uDAAmD;AAInD,MAAa,kBAAkB;IAI3B,MAAM,CAAC,UAAU,CAAC,OAAiC;QAC/C,kBAAkB,CAAC,OAAO,GAAG,OAAO,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,UAAU;QACb,OAAO,kBAAkB,CAAC,OAAO,CAAC;IACtC,CAAC;IAED,MAAM,CAAO,UAAU,CAAC,WAA6B;;YACjD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAGlC,IAAI,gBAAgB,IAAI,OAAO,EAAE,CAAC;gBAC9B,MAAM,YAAY,GAAG,OAAkC,CAAC;gBACxD,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;gBACzD,OAAO,IAAI,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAClD,CAAC;YAGD,MAAM,aAAa,GAAG,OAAmC,CAAC;YAC1D,IAAI,CAAC,WAAW,EAAE,CAAC;gBACf,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC;YACxC,CAAC;YACD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,WAAW,QAAQ,CAAC,CAAC;YACrD,OAAO,MAAM,gCAAc,CAAC,aAAa,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACnE,CAAC;KAAA;CAEJ;AA/BD,gDA+BC"}
|
package/src/lib/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./nest-file-storage.module"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./types"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./storage.factory"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./interceptor/file-storage.interceptor"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./file-storage.service"), exports);
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/nest-file-storage/src/lib/index.ts"],"names":[],"mappings":";;;AAAA,qEAA2C;AAC3C,kDAAwB;AACxB,4DAAkC;AAClC,iFAAuD;AACvD,iEAAuC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Request } from 'express';
|
|
3
|
+
import { FileStorageEnum, StorageOptions } from '../types';
|
|
4
|
+
export type FileUploadConfig = {
|
|
5
|
+
type: 'single' | 'array' | 'fields';
|
|
6
|
+
fieldName?: string;
|
|
7
|
+
maxCount?: number;
|
|
8
|
+
fields?: {
|
|
9
|
+
name: string;
|
|
10
|
+
maxCount?: number;
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
export type FileStorageInterceptorOptions = {
|
|
14
|
+
fileName?: (file: any, req?: Request) => string;
|
|
15
|
+
fileDist?: (file: any, req?: Request) => string;
|
|
16
|
+
prefix?: string;
|
|
17
|
+
storageType?: FileStorageEnum;
|
|
18
|
+
storageOptions?: StorageOptions;
|
|
19
|
+
mapToRequestBody?: (file: any, fieldName: string, req?: Request) => any;
|
|
20
|
+
};
|
|
21
|
+
export declare function FileStorageInterceptor(fileConfig: FileUploadConfig | string, interceptorOptions?: FileStorageInterceptorOptions): NestInterceptor;
|