@elchinabilov/nestjs-media-library 1.0.2

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 (34) hide show
  1. package/README.md +308 -0
  2. package/dist/controllers/media.controller.d.ts +13 -0
  3. package/dist/controllers/media.controller.js +81 -0
  4. package/dist/controllers/media.controller.js.map +1 -0
  5. package/dist/entities/media.entity.d.ts +12 -0
  6. package/dist/entities/media.entity.js +60 -0
  7. package/dist/entities/media.entity.js.map +1 -0
  8. package/dist/index.d.ts +8 -0
  9. package/dist/index.js +25 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/interfaces/media-config.interface.d.ts +20 -0
  12. package/dist/interfaces/media-config.interface.js +3 -0
  13. package/dist/interfaces/media-config.interface.js.map +1 -0
  14. package/dist/media-library.module.d.ts +5 -0
  15. package/dist/media-library.module.js +102 -0
  16. package/dist/media-library.module.js.map +1 -0
  17. package/dist/migrations/1703000000000-CreateMediaTable.d.ts +5 -0
  18. package/dist/migrations/1703000000000-CreateMediaTable.js +64 -0
  19. package/dist/migrations/1703000000000-CreateMediaTable.js.map +1 -0
  20. package/dist/migrations/CreateMediaTable.d.ts +5 -0
  21. package/dist/migrations/CreateMediaTable.js +65 -0
  22. package/dist/migrations/CreateMediaTable.js.map +1 -0
  23. package/dist/services/image.service.d.ts +7 -0
  24. package/dist/services/image.service.js +51 -0
  25. package/dist/services/image.service.js.map +1 -0
  26. package/dist/services/media.service.d.ts +17 -0
  27. package/dist/services/media.service.js +165 -0
  28. package/dist/services/media.service.js.map +1 -0
  29. package/dist/services/s3.service.d.ts +11 -0
  30. package/dist/services/s3.service.js +64 -0
  31. package/dist/services/s3.service.js.map +1 -0
  32. package/dist/tsconfig.tsbuildinfo +1 -0
  33. package/package.json +43 -0
  34. package/tsconfig.json +24 -0
package/README.md ADDED
@@ -0,0 +1,308 @@
1
+ # @elchinabilov/nestjs-media-library
2
+
3
+ Complete NestJS media management library with S3 integration, automatic image optimization, and multiple size conversions.
4
+
5
+ ## Features
6
+
7
+ ✅ **Database Migrations** - TypeORM migrations included
8
+ ✅ **Single/Multiple File Upload** - Support for both single and multiple file uploads
9
+ ✅ **Retrieve Files** - Get files as objects or arrays
10
+ ✅ **Automatic Image Optimization** - Built-in image compression to WebP format
11
+ ✅ **Multiple Conversions** - Generate thumbnails, medium, large sizes automatically
12
+ ✅ **AWS S3 Integration** - Seamless S3 upload support
13
+ ✅ **Easy Integration** - Simple NestJS dependency injection
14
+ ✅ **RESTful API** - Ready-to-use controllers
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @elchinabilov/nestjs-media-library
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ### 1. Import Module
25
+
26
+ ```typescript
27
+ import { Module } from "@nestjs/common";
28
+ import { TypeOrmModule } from "@nestjs/typeorm";
29
+ import { MediaLibraryModule } from "@elchinabilov/nestjs-media-library";
30
+
31
+ @Module({
32
+ imports: [
33
+ TypeOrmModule.forRoot({
34
+ // your database config
35
+ }),
36
+ MediaLibraryModule.forRoot({
37
+ disk: "s3", // or 'local'
38
+ uploadPath: "media",
39
+ maxFileSize: 10 * 1024 * 1024, // 10MB
40
+ conversions: [
41
+ { suffix: "thumbnail", width: 150 },
42
+ { suffix: "medium", width: 500 },
43
+ { suffix: "large", width: 1200, height: 800 },
44
+ ],
45
+ s3: {
46
+ region: "us-east-1",
47
+ bucket: "your-bucket",
48
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
49
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
50
+ publicUrl: "https://your-cdn.com", // optional
51
+ },
52
+ allowedMimeTypes: ["image/jpeg", "image/png", "image/webp"], // optional
53
+ }),
54
+ ],
55
+ })
56
+ export class AppModule {}
57
+ ```
58
+
59
+ ### 2. Run Migration
60
+
61
+ ```typescript
62
+ // In your TypeORM config
63
+ import { CreateMediaTable1703000000000 } from "@elchinabilov/nestjs-media-library";
64
+
65
+ export const dataSource = new DataSource({
66
+ // ... your config
67
+ migrations: [CreateMediaTable1703000000000],
68
+ });
69
+ ```
70
+
71
+ Or run manually:
72
+
73
+ ```bash
74
+ npm run migration:run
75
+ ```
76
+
77
+ ### 3. Use in Your Service
78
+
79
+ ```typescript
80
+ import { Injectable } from "@nestjs/common";
81
+ import { MediaService } from "@elchinabilov/nestjs-media-library";
82
+
83
+ @Injectable()
84
+ export class YourService {
85
+ constructor(private mediaService: MediaService) {}
86
+
87
+ async uploadFile(file: Express.Multer.File) {
88
+ const media = await this.mediaService.uploadSingle(file);
89
+ console.log("Original:", media.url);
90
+ console.log("Thumbnail:", media.conversions.thumbnail);
91
+ console.log("Medium:", media.conversions.medium);
92
+ return media;
93
+ }
94
+
95
+ async uploadMultiple(files: Express.Multer.File[]) {
96
+ return await this.mediaService.uploadMultiple(files);
97
+ }
98
+
99
+ async getMedia(id: string) {
100
+ return await this.mediaService.findOne(id);
101
+ }
102
+
103
+ async getAllMedia() {
104
+ return await this.mediaService.findAll();
105
+ }
106
+
107
+ async deleteMedia(id: string) {
108
+ await this.mediaService.delete(id);
109
+ }
110
+ }
111
+ ```
112
+
113
+ ## API Endpoints
114
+
115
+ The package provides ready-to-use REST endpoints:
116
+
117
+ ### Upload Single File
118
+
119
+ ```bash
120
+ POST /media/upload
121
+ Content-Type: multipart/form-data
122
+ Body: file (form-data)
123
+ ```
124
+
125
+ Response:
126
+
127
+ ```json
128
+ {
129
+ "id": "uuid",
130
+ "filename": "uuid.webp",
131
+ "originalName": "photo.jpg",
132
+ "mimeType": "image/jpeg",
133
+ "size": 102400,
134
+ "path": "media/uuid.webp",
135
+ "url": "https://bucket.s3.amazonaws.com/media/uuid.webp",
136
+ "conversions": {
137
+ "thumbnail": "https://bucket.s3.amazonaws.com/media/uuid-thumbnail.webp",
138
+ "medium": "https://bucket.s3.amazonaws.com/media/uuid-medium.webp",
139
+ "large": "https://bucket.s3.amazonaws.com/media/uuid-large.webp"
140
+ },
141
+ "disk": "s3",
142
+ "createdAt": "2024-01-01T00:00:00.000Z"
143
+ }
144
+ ```
145
+
146
+ ### Upload Multiple Files
147
+
148
+ ```bash
149
+ POST /media/upload-multiple
150
+ Content-Type: multipart/form-data
151
+ Body: files (form-data, multiple)
152
+ ```
153
+
154
+ ### Get All Media
155
+
156
+ ```bash
157
+ GET /media
158
+ ```
159
+
160
+ ### Get Single Media
161
+
162
+ ```bash
163
+ GET /media/:id
164
+ ```
165
+
166
+ ### Delete Media
167
+
168
+ ```bash
169
+ DELETE /media/:id
170
+ ```
171
+
172
+ ## Configuration Options
173
+
174
+ | Option | Type | Default | Description |
175
+ | ------------------ | -------------------- | ----------- | ----------------------------- |
176
+ | `disk` | `'local' \| 's3'` | `'local'` | Storage driver |
177
+ | `uploadPath` | `string` | `'uploads'` | Upload directory path |
178
+ | `maxFileSize` | `number` | `10485760` | Max file size in bytes (10MB) |
179
+ | `conversions` | `ConversionConfig[]` | `[]` | Image size conversions |
180
+ | `s3` | `S3Config` | - | AWS S3 configuration |
181
+ | `allowedMimeTypes` | `string[]` | - | Allowed file types |
182
+
183
+ ### Conversion Config
184
+
185
+ ```typescript
186
+ interface ConversionConfig {
187
+ suffix: string; // e.g., 'thumbnail', 'medium'
188
+ width: number; // Width in pixels
189
+ height?: number; // Optional height (maintains aspect ratio if omitted)
190
+ }
191
+ ```
192
+
193
+ ## Local Storage Setup
194
+
195
+ ```typescript
196
+ MediaLibraryModule.forRoot({
197
+ disk: "local",
198
+ uploadPath: "public/uploads",
199
+ conversions: [{ suffix: "thumb", width: 200 }],
200
+ });
201
+ ```
202
+
203
+ Don't forget to serve static files:
204
+
205
+ ```typescript
206
+ // main.ts
207
+ import { NestFactory } from "@nestjs/core";
208
+ import { NestExpressApplication } from "@nestjs/platform-express";
209
+ import { join } from "path";
210
+
211
+ async function bootstrap() {
212
+ const app = await NestFactory.create<NestExpressApplication>(AppModule);
213
+ app.useStaticAssets(join(__dirname, "..", "public"));
214
+ await app.listen(3000);
215
+ }
216
+ ```
217
+
218
+ ## Advanced Usage
219
+
220
+ ### Custom Controller
221
+
222
+ ```typescript
223
+ import {
224
+ Controller,
225
+ Post,
226
+ UseInterceptors,
227
+ UploadedFile,
228
+ } from "@nestjs/common";
229
+ import { FileInterceptor } from "@nestjs/platform-express";
230
+ import { MediaService } from "@elchinabilov/nestjs-media-library";
231
+
232
+ @Controller("custom")
233
+ export class CustomController {
234
+ constructor(private mediaService: MediaService) {}
235
+
236
+ @Post("avatar")
237
+ @UseInterceptors(FileInterceptor("avatar"))
238
+ async uploadAvatar(@UploadedFile() file: Express.Multer.File) {
239
+ const media = await this.mediaService.uploadSingle(file);
240
+ return {
241
+ avatarUrl: media.url,
242
+ thumbnailUrl: media.conversions?.thumbnail,
243
+ };
244
+ }
245
+ }
246
+ ```
247
+
248
+ ### Direct S3 Service Usage
249
+
250
+ ```typescript
251
+ import { S3Service } from "@elchinabilov/nestjs-media-library";
252
+
253
+ @Injectable()
254
+ export class MyService {
255
+ constructor(private s3Service: S3Service) {}
256
+
257
+ async uploadCustom(buffer: Buffer) {
258
+ return await this.s3Service.uploadFile(
259
+ buffer,
260
+ "custom/path/file.jpg",
261
+ "image/jpeg"
262
+ );
263
+ }
264
+ }
265
+ ```
266
+
267
+ ### Image Processing
268
+
269
+ ```typescript
270
+ import { ImageService } from "@elchinabilov/nestjs-media-library";
271
+
272
+ @Injectable()
273
+ export class MyService {
274
+ constructor(private imageService: ImageService) {}
275
+
276
+ async processImage(buffer: Buffer) {
277
+ // Optimize to WebP
278
+ const optimized = await this.imageService.optimizeImage(buffer);
279
+
280
+ // Create custom sizes
281
+ const conversions = await this.imageService.createConversions(buffer, [
282
+ { suffix: "small", width: 100 },
283
+ { suffix: "large", width: 2000 },
284
+ ]);
285
+
286
+ return { optimized, conversions };
287
+ }
288
+ }
289
+ ```
290
+
291
+ ## Environment Variables
292
+
293
+ Create a `.env` file:
294
+
295
+ ```env
296
+ AWS_ACCESS_KEY_ID=your_access_key
297
+ AWS_SECRET_ACCESS_KEY=your_secret_key
298
+ AWS_REGION=us-east-1
299
+ AWS_BUCKET=your-bucket-name
300
+ ```
301
+
302
+ ## License
303
+
304
+ MIT © Elchin Abilov
305
+
306
+ ## Support
307
+
308
+ For issues and questions, please open an issue on GitHub.
@@ -0,0 +1,13 @@
1
+ import { MediaService } from "../services/media.service";
2
+ import { Media } from "../entities/media.entity";
3
+ export declare class MediaController {
4
+ private readonly mediaService;
5
+ constructor(mediaService: MediaService);
6
+ uploadSingle(file: Express.Multer.File): Promise<Media>;
7
+ uploadMultiple(files: Express.Multer.File[]): Promise<Media[]>;
8
+ findAll(): Promise<Media[]>;
9
+ findOne(id: string): Promise<Media>;
10
+ delete(id: string): Promise<{
11
+ message: string;
12
+ }>;
13
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.MediaController = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const platform_express_1 = require("@nestjs/platform-express");
18
+ const media_service_1 = require("../services/media.service");
19
+ let MediaController = class MediaController {
20
+ constructor(mediaService) {
21
+ this.mediaService = mediaService;
22
+ }
23
+ async uploadSingle(file) {
24
+ return this.mediaService.uploadSingle(file);
25
+ }
26
+ async uploadMultiple(files) {
27
+ return this.mediaService.uploadMultiple(files);
28
+ }
29
+ async findAll() {
30
+ return this.mediaService.findAll();
31
+ }
32
+ async findOne(id) {
33
+ return this.mediaService.findOne(id);
34
+ }
35
+ async delete(id) {
36
+ await this.mediaService.delete(id);
37
+ return { message: "Media deleted successfully" };
38
+ }
39
+ };
40
+ exports.MediaController = MediaController;
41
+ __decorate([
42
+ (0, common_1.Post)("upload"),
43
+ (0, common_1.UseInterceptors)((0, platform_express_1.FileInterceptor)("file")),
44
+ __param(0, (0, common_1.UploadedFile)()),
45
+ __metadata("design:type", Function),
46
+ __metadata("design:paramtypes", [Object]),
47
+ __metadata("design:returntype", Promise)
48
+ ], MediaController.prototype, "uploadSingle", null);
49
+ __decorate([
50
+ (0, common_1.Post)("upload-multiple"),
51
+ (0, common_1.UseInterceptors)((0, platform_express_1.FilesInterceptor)("files", 10)),
52
+ __param(0, (0, common_1.UploadedFiles)()),
53
+ __metadata("design:type", Function),
54
+ __metadata("design:paramtypes", [Array]),
55
+ __metadata("design:returntype", Promise)
56
+ ], MediaController.prototype, "uploadMultiple", null);
57
+ __decorate([
58
+ (0, common_1.Get)(),
59
+ __metadata("design:type", Function),
60
+ __metadata("design:paramtypes", []),
61
+ __metadata("design:returntype", Promise)
62
+ ], MediaController.prototype, "findAll", null);
63
+ __decorate([
64
+ (0, common_1.Get)(":id"),
65
+ __param(0, (0, common_1.Param)("id")),
66
+ __metadata("design:type", Function),
67
+ __metadata("design:paramtypes", [String]),
68
+ __metadata("design:returntype", Promise)
69
+ ], MediaController.prototype, "findOne", null);
70
+ __decorate([
71
+ (0, common_1.Delete)(":id"),
72
+ __param(0, (0, common_1.Param)("id")),
73
+ __metadata("design:type", Function),
74
+ __metadata("design:paramtypes", [String]),
75
+ __metadata("design:returntype", Promise)
76
+ ], MediaController.prototype, "delete", null);
77
+ exports.MediaController = MediaController = __decorate([
78
+ (0, common_1.Controller)("media"),
79
+ __metadata("design:paramtypes", [media_service_1.MediaService])
80
+ ], MediaController);
81
+ //# sourceMappingURL=media.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.controller.js","sourceRoot":"","sources":["../../src/controllers/media.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CASwB;AACxB,+DAA6E;AAC7E,6DAAyD;AAIlD,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B,YAA6B,YAA0B;QAA1B,iBAAY,GAAZ,YAAY,CAAc;IAAG,CAAC;IAIrD,AAAN,KAAK,CAAC,YAAY,CACA,IAAyB;QAEzC,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAIK,AAAN,KAAK,CAAC,cAAc,CACD,KAA4B;QAE7C,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAGK,AAAN,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;IACrC,CAAC;IAGK,AAAN,KAAK,CAAC,OAAO,CAAc,EAAU;QACnC,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;IAGK,AAAN,KAAK,CAAC,MAAM,CAAc,EAAU;QAClC,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnC,OAAO,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC;IACnD,CAAC;CACF,CAAA;AAlCY,0CAAe;AAKpB;IAFL,IAAA,aAAI,EAAC,QAAQ,CAAC;IACd,IAAA,wBAAe,EAAC,IAAA,kCAAe,EAAC,MAAM,CAAC,CAAC;IAEtC,WAAA,IAAA,qBAAY,GAAE,CAAA;;;;mDAGhB;AAIK;IAFL,IAAA,aAAI,EAAC,iBAAiB,CAAC;IACvB,IAAA,wBAAe,EAAC,IAAA,mCAAgB,EAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAE5C,WAAA,IAAA,sBAAa,GAAE,CAAA;;;;qDAGjB;AAGK;IADL,IAAA,YAAG,GAAE;;;;8CAGL;AAGK;IADL,IAAA,YAAG,EAAC,KAAK,CAAC;IACI,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;;;;8CAEzB;AAGK;IADL,IAAA,eAAM,EAAC,KAAK,CAAC;IACA,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;;;;6CAGxB;0BAjCU,eAAe;IAD3B,IAAA,mBAAU,EAAC,OAAO,CAAC;qCAEyB,4BAAY;GAD5C,eAAe,CAkC3B"}
@@ -0,0 +1,12 @@
1
+ export declare class Media {
2
+ id: string;
3
+ filename: string;
4
+ originalName: string;
5
+ mimeType: string;
6
+ size: number;
7
+ path: string;
8
+ url: string;
9
+ conversions: Record<string, string>;
10
+ disk: string;
11
+ createdAt: Date;
12
+ }
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Media = void 0;
13
+ const typeorm_1 = require("typeorm");
14
+ let Media = class Media {
15
+ };
16
+ exports.Media = Media;
17
+ __decorate([
18
+ (0, typeorm_1.PrimaryGeneratedColumn)("uuid"),
19
+ __metadata("design:type", String)
20
+ ], Media.prototype, "id", void 0);
21
+ __decorate([
22
+ (0, typeorm_1.Column)(),
23
+ __metadata("design:type", String)
24
+ ], Media.prototype, "filename", void 0);
25
+ __decorate([
26
+ (0, typeorm_1.Column)(),
27
+ __metadata("design:type", String)
28
+ ], Media.prototype, "originalName", void 0);
29
+ __decorate([
30
+ (0, typeorm_1.Column)(),
31
+ __metadata("design:type", String)
32
+ ], Media.prototype, "mimeType", void 0);
33
+ __decorate([
34
+ (0, typeorm_1.Column)(),
35
+ __metadata("design:type", Number)
36
+ ], Media.prototype, "size", void 0);
37
+ __decorate([
38
+ (0, typeorm_1.Column)(),
39
+ __metadata("design:type", String)
40
+ ], Media.prototype, "path", void 0);
41
+ __decorate([
42
+ (0, typeorm_1.Column)({ nullable: true }),
43
+ __metadata("design:type", String)
44
+ ], Media.prototype, "url", void 0);
45
+ __decorate([
46
+ (0, typeorm_1.Column)({ type: "json", nullable: true }),
47
+ __metadata("design:type", Object)
48
+ ], Media.prototype, "conversions", void 0);
49
+ __decorate([
50
+ (0, typeorm_1.Column)({ nullable: true }),
51
+ __metadata("design:type", String)
52
+ ], Media.prototype, "disk", void 0);
53
+ __decorate([
54
+ (0, typeorm_1.CreateDateColumn)(),
55
+ __metadata("design:type", Date)
56
+ ], Media.prototype, "createdAt", void 0);
57
+ exports.Media = Media = __decorate([
58
+ (0, typeorm_1.Entity)("media")
59
+ ], Media);
60
+ //# sourceMappingURL=media.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.entity.js","sourceRoot":"","sources":["../../src/entities/media.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAKiB;AAGV,IAAM,KAAK,GAAX,MAAM,KAAK;CA8BjB,CAAA;AA9BY,sBAAK;AAEhB;IADC,IAAA,gCAAsB,EAAC,MAAM,CAAC;;iCACpB;AAGX;IADC,IAAA,gBAAM,GAAE;;uCACQ;AAGjB;IADC,IAAA,gBAAM,GAAE;;2CACY;AAGrB;IADC,IAAA,gBAAM,GAAE;;uCACQ;AAGjB;IADC,IAAA,gBAAM,GAAE;;mCACI;AAGb;IADC,IAAA,gBAAM,GAAE;;mCACI;AAGb;IADC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;kCACf;AAGZ;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;0CACL;AAGpC;IADC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;mCACd;AAGb;IADC,IAAA,0BAAgB,GAAE;8BACR,IAAI;wCAAC;gBA7BL,KAAK;IADjB,IAAA,gBAAM,EAAC,OAAO,CAAC;GACH,KAAK,CA8BjB"}
@@ -0,0 +1,8 @@
1
+ export * from "./media-library.module";
2
+ export * from "./entities/media.entity";
3
+ export * from "./services/media.service";
4
+ export * from "./services/s3.service";
5
+ export * from "./services/image.service";
6
+ export * from "./controllers/media.controller";
7
+ export * from "./interfaces/media-config.interface";
8
+ export * from "./migrations/1703000000000-CreateMediaTable";
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./media-library.module"), exports);
18
+ __exportStar(require("./entities/media.entity"), exports);
19
+ __exportStar(require("./services/media.service"), exports);
20
+ __exportStar(require("./services/s3.service"), exports);
21
+ __exportStar(require("./services/image.service"), exports);
22
+ __exportStar(require("./controllers/media.controller"), exports);
23
+ __exportStar(require("./interfaces/media-config.interface"), exports);
24
+ __exportStar(require("./migrations/1703000000000-CreateMediaTable"), exports);
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC;AACvC,0DAAwC;AACxC,2DAAyC;AACzC,wDAAsC;AACtC,2DAAyC;AACzC,iEAA+C;AAC/C,sEAAoD;AACpD,8EAA4D"}
@@ -0,0 +1,20 @@
1
+ export interface ConversionConfig {
2
+ suffix: string;
3
+ width: number;
4
+ height?: number;
5
+ }
6
+ export interface S3Config {
7
+ region: string;
8
+ bucket: string;
9
+ accessKeyId: string;
10
+ secretAccessKey: string;
11
+ publicUrl?: string;
12
+ }
13
+ export interface MediaLibraryConfig {
14
+ disk?: "local" | "s3";
15
+ uploadPath?: string;
16
+ conversions?: ConversionConfig[];
17
+ s3?: S3Config;
18
+ maxFileSize?: number;
19
+ allowedMimeTypes?: string[];
20
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=media-config.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-config.interface.js","sourceRoot":"","sources":["../../src/interfaces/media-config.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import { DynamicModule } from "@nestjs/common";
2
+ import { MediaLibraryConfig } from "./interfaces/media-config.interface";
3
+ export declare class MediaLibraryModule {
4
+ static forRoot(config: MediaLibraryConfig): DynamicModule;
5
+ }
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var MediaLibraryModule_1;
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.MediaLibraryModule = void 0;
44
+ const common_1 = require("@nestjs/common");
45
+ const typeorm_1 = require("@nestjs/typeorm");
46
+ const platform_express_1 = require("@nestjs/platform-express");
47
+ const media_entity_1 = require("./entities/media.entity");
48
+ const media_service_1 = require("./services/media.service");
49
+ const s3_service_1 = require("./services/s3.service");
50
+ const image_service_1 = require("./services/image.service");
51
+ const media_controller_1 = require("./controllers/media.controller");
52
+ const multer = __importStar(require("multer"));
53
+ let MediaLibraryModule = MediaLibraryModule_1 = class MediaLibraryModule {
54
+ static forRoot(config) {
55
+ return {
56
+ module: MediaLibraryModule_1,
57
+ imports: [
58
+ typeorm_1.TypeOrmModule.forFeature([media_entity_1.Media]),
59
+ platform_express_1.MulterModule.register({
60
+ storage: multer.memoryStorage(),
61
+ limits: {
62
+ fileSize: config.maxFileSize || 10 * 1024 * 1024,
63
+ },
64
+ fileFilter: (req, file, cb) => {
65
+ if (config.allowedMimeTypes && config.allowedMimeTypes.length > 0) {
66
+ if (config.allowedMimeTypes.includes(file.mimetype)) {
67
+ cb(null, true);
68
+ }
69
+ else {
70
+ cb(new Error("Invalid file type"), false);
71
+ }
72
+ }
73
+ else {
74
+ cb(null, true);
75
+ }
76
+ },
77
+ }),
78
+ ],
79
+ controllers: [media_controller_1.MediaController],
80
+ providers: [
81
+ {
82
+ provide: "MEDIA_CONFIG",
83
+ useValue: config,
84
+ },
85
+ {
86
+ provide: "S3_CONFIG",
87
+ useValue: config.s3,
88
+ },
89
+ media_service_1.MediaService,
90
+ s3_service_1.S3Service,
91
+ image_service_1.ImageService,
92
+ ],
93
+ exports: [media_service_1.MediaService, s3_service_1.S3Service, image_service_1.ImageService],
94
+ };
95
+ }
96
+ };
97
+ exports.MediaLibraryModule = MediaLibraryModule;
98
+ exports.MediaLibraryModule = MediaLibraryModule = MediaLibraryModule_1 = __decorate([
99
+ (0, common_1.Global)(),
100
+ (0, common_1.Module)({})
101
+ ], MediaLibraryModule);
102
+ //# sourceMappingURL=media-library.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-library.module.js","sourceRoot":"","sources":["../src/media-library.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA+D;AAC/D,6CAAgD;AAChD,+DAAwD;AACxD,0DAAgD;AAChD,4DAAwD;AACxD,sDAAkD;AAClD,4DAAwD;AACxD,qEAAiE;AAEjE,+CAAiC;AAI1B,IAAM,kBAAkB,0BAAxB,MAAM,kBAAkB;IAC7B,MAAM,CAAC,OAAO,CAAC,MAA0B;QACvC,OAAO;YACL,MAAM,EAAE,oBAAkB;YAC1B,OAAO,EAAE;gBACP,uBAAa,CAAC,UAAU,CAAC,CAAC,oBAAK,CAAC,CAAC;gBACjC,+BAAY,CAAC,QAAQ,CAAC;oBACpB,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE;oBAC/B,MAAM,EAAE;wBACN,QAAQ,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI;qBACjD;oBACD,UAAU,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE;wBAC5B,IAAI,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BAClE,IAAI,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gCACpD,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;4BACjB,CAAC;iCAAM,CAAC;gCACN,EAAE,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,EAAE,KAAK,CAAC,CAAC;4BAC5C,CAAC;wBACH,CAAC;6BAAM,CAAC;4BACN,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;wBACjB,CAAC;oBACH,CAAC;iBACF,CAAC;aACH;YACD,WAAW,EAAE,CAAC,kCAAe,CAAC;YAC9B,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,cAAc;oBACvB,QAAQ,EAAE,MAAM;iBACjB;gBACD;oBACE,OAAO,EAAE,WAAW;oBACpB,QAAQ,EAAE,MAAM,CAAC,EAAE;iBACpB;gBACD,4BAAY;gBACZ,sBAAS;gBACT,4BAAY;aACb;YACD,OAAO,EAAE,CAAC,4BAAY,EAAE,sBAAS,EAAE,4BAAY,CAAC;SACjD,CAAC;IACJ,CAAC;CACF,CAAA;AAzCY,gDAAkB;6BAAlB,kBAAkB;IAF9B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,kBAAkB,CAyC9B"}
@@ -0,0 +1,5 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+ export declare class CreateMediaTable1703000000000 implements MigrationInterface {
3
+ up(queryRunner: QueryRunner): Promise<void>;
4
+ down(queryRunner: QueryRunner): Promise<void>;
5
+ }