@wrcb/cb-common 1.0.468 → 1.0.470
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/build/index.d.ts +0 -2
- package/build/index.js +0 -2
- package/build/middlewares/uploadMedia.d.ts +0 -3
- package/build/middlewares/uploadMedia.js +87 -98
- package/build/server.d.ts +0 -6
- package/build/server.js +0 -6
- package/package.json +1 -1
- package/build/storage/factory.d.ts +0 -4
- package/build/storage/factory.js +0 -32
- package/build/storage/providers/minio.d.ts +0 -19
- package/build/storage/providers/minio.js +0 -134
- package/build/storage/providers/spaces.d.ts +0 -17
- package/build/storage/providers/spaces.js +0 -128
package/build/index.d.ts
CHANGED
package/build/index.js
CHANGED
|
@@ -42,5 +42,3 @@ __exportStar(require("./types/giftType"), exports);
|
|
|
42
42
|
__exportStar(require("./types/paymentProviderType"), exports);
|
|
43
43
|
__exportStar(require("./events/subjects"), exports);
|
|
44
44
|
__exportStar(require("./services/TenantDataService"), exports);
|
|
45
|
-
__exportStar(require("./storage/types"), exports);
|
|
46
|
-
__exportStar(require("./storage/interfaces/MediaConfiguration"), exports);
|
|
@@ -14,9 +14,6 @@ declare global {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
export declare const uploadMedia: {
|
|
17
|
-
single: (fieldName: string) => import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
|
|
18
|
-
multiple: (fieldName: string, maxCount?: number) => import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
|
|
19
17
|
fields: (fields: ExtendedField[]) => (req: Request, res: Response, next: NextFunction) => void;
|
|
20
|
-
processUpload: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
21
18
|
};
|
|
22
19
|
export {};
|
|
@@ -1,28 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
14
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
6
|
exports.uploadMedia = void 0;
|
|
7
|
+
// NÃO APAGAR ESTE
|
|
16
8
|
const multer_1 = __importDefault(require("multer"));
|
|
17
|
-
const factory_1 = require("../storage/factory");
|
|
18
|
-
const tenant_1 = require("../types/tenant");
|
|
19
|
-
const storageService_1 = require("../storage/services/storageService");
|
|
20
|
-
const badRequestError_1 = require("../errors/badRequestError");
|
|
21
9
|
const storage = multer_1.default.memoryStorage();
|
|
22
10
|
const upload = (0, multer_1.default)({ storage });
|
|
23
11
|
exports.uploadMedia = {
|
|
24
|
-
single: (fieldName) => upload.single(fieldName),
|
|
25
|
-
multiple: (fieldName, maxCount) =>
|
|
12
|
+
// single: (fieldName: string) => upload.single(fieldName),
|
|
13
|
+
// multiple: (fieldName: string, maxCount?: number) =>
|
|
14
|
+
// upload.array(fieldName, maxCount),
|
|
26
15
|
fields: (fields) => {
|
|
27
16
|
const multerFields = fields.map(({ name, maxCount }) => ({
|
|
28
17
|
name,
|
|
@@ -33,87 +22,87 @@ exports.uploadMedia = {
|
|
|
33
22
|
req._uploadFieldConfig = fields;
|
|
34
23
|
middleware(req, res, next);
|
|
35
24
|
};
|
|
36
|
-
}
|
|
37
|
-
processUpload: (req, res, next) =>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
25
|
+
}
|
|
26
|
+
// processUpload: async (req: Request, res: Response, next: NextFunction) => {
|
|
27
|
+
// try {
|
|
28
|
+
// const storageService = new StorageService(StorageFactory.create())
|
|
29
|
+
// const tenant = (req.headers['x-tenant'] as Tenant) || Tenant.PoliticaBet
|
|
30
|
+
// let allFiles: Express.Multer.File[] = []
|
|
31
|
+
// if (req.file) {
|
|
32
|
+
// allFiles = [req.file]
|
|
33
|
+
// } else if (req.files) {
|
|
34
|
+
// if (Array.isArray(req.files)) {
|
|
35
|
+
// allFiles = req.files
|
|
36
|
+
// } else {
|
|
37
|
+
// allFiles = Object.values(req.files).flat()
|
|
38
|
+
// }
|
|
39
|
+
// }
|
|
40
|
+
// if (!allFiles.length) return next()
|
|
41
|
+
// // ✅ Verificar se há mais de 5 imagens ou mais de 1 vídeo
|
|
42
|
+
// if (req.files && !Array.isArray(req.files)) {
|
|
43
|
+
// const imageFiles = req.files['images'] || []
|
|
44
|
+
// const videoFiles = req.files['videos'] || []
|
|
45
|
+
// if (imageFiles.length > 5) {
|
|
46
|
+
// throw new BadRequestError('TooManyImages')
|
|
47
|
+
// }
|
|
48
|
+
// if (videoFiles.length > 1) {
|
|
49
|
+
// throw new BadRequestError('TooManyVideos')
|
|
50
|
+
// }
|
|
51
|
+
// }
|
|
52
|
+
// // ✅ Verificar novamente via allFiles se alguém tentar burlar o `fieldname`
|
|
53
|
+
// const videoCount = allFiles.filter(f =>
|
|
54
|
+
// f.mimetype.startsWith('video/')
|
|
55
|
+
// ).length
|
|
56
|
+
// if (videoCount > 1) {
|
|
57
|
+
// throw new BadRequestError('TooManyVideos')
|
|
58
|
+
// }
|
|
59
|
+
// // Validação de tamanho por campo
|
|
60
|
+
// const fieldConfig = req._uploadFieldConfig || []
|
|
61
|
+
// const getMaxSizeForField = (fieldName: string): number | undefined => {
|
|
62
|
+
// const field = fieldConfig.find(f => f.name === fieldName)
|
|
63
|
+
// return field?.maxSizeMB ? field.maxSizeMB * 1024 * 1024 : undefined
|
|
64
|
+
// }
|
|
65
|
+
// for (const file of allFiles) {
|
|
66
|
+
// const isVideo = file.mimetype.startsWith('video/')
|
|
67
|
+
// const isImage = file.mimetype.startsWith('image/')
|
|
68
|
+
// if (!isImage && !isVideo) {
|
|
69
|
+
// throw new BadRequestError('InvalidFileType')
|
|
70
|
+
// }
|
|
71
|
+
// const maxSize = getMaxSizeForField(file.fieldname)
|
|
72
|
+
// if (maxSize && file.size > maxSize) {
|
|
73
|
+
// throw new BadRequestError(isImage ? 'ImageTooLarge' : 'VideoTooLarge')
|
|
74
|
+
// }
|
|
75
|
+
// }
|
|
76
|
+
// const uploadPromises = allFiles.map(async file => {
|
|
77
|
+
// const isVideo = file.mimetype.startsWith('video/')
|
|
78
|
+
// const type: MediaType = isVideo ? 'video' : 'photo'
|
|
79
|
+
// const options: UploadOptions = {
|
|
80
|
+
// tenant,
|
|
81
|
+
// userId: req.currentUser?.id,
|
|
82
|
+
// targetId: req.body.targetId || undefined,
|
|
83
|
+
// type,
|
|
84
|
+
// generateThumbnail: true
|
|
85
|
+
// }
|
|
86
|
+
// return isVideo
|
|
87
|
+
// ? storageService.uploadVideo(file.buffer, file.originalname, options)
|
|
88
|
+
// : storageService.uploadImage(file.buffer, file.originalname, options)
|
|
89
|
+
// })
|
|
90
|
+
// const results = await Promise.all(uploadPromises)
|
|
91
|
+
// req.uploadResults = results
|
|
92
|
+
// if (req.files && !Array.isArray(req.files)) {
|
|
93
|
+
// req.uploadResultsByField = {}
|
|
94
|
+
// let index = 0
|
|
95
|
+
// for (const [fieldName, files] of Object.entries(req.files)) {
|
|
96
|
+
// req.uploadResultsByField[fieldName] = results.slice(
|
|
97
|
+
// index,
|
|
98
|
+
// index + files.length
|
|
99
|
+
// )
|
|
100
|
+
// index += files.length
|
|
101
|
+
// }
|
|
102
|
+
// }
|
|
103
|
+
// next()
|
|
104
|
+
// } catch (error) {
|
|
105
|
+
// next(error)
|
|
106
|
+
// }
|
|
107
|
+
// }
|
|
119
108
|
};
|
package/build/server.d.ts
CHANGED
|
@@ -61,9 +61,3 @@ export * from './events/private-show/userFollowedEvent';
|
|
|
61
61
|
export * from './services/RedisService';
|
|
62
62
|
export * from './services/TenantDataService';
|
|
63
63
|
export * from './services/WasabiUploader';
|
|
64
|
-
export * from './storage/services/storageService';
|
|
65
|
-
export * from './storage/factory';
|
|
66
|
-
export * from './storage/types';
|
|
67
|
-
export * from './storage/providers/minio';
|
|
68
|
-
export * from './storage/providers/spaces';
|
|
69
|
-
export * from './storage/interfaces/MediaConfiguration';
|
package/build/server.js
CHANGED
|
@@ -77,9 +77,3 @@ __exportStar(require("./events/private-show/userFollowedEvent"), exports);
|
|
|
77
77
|
__exportStar(require("./services/RedisService"), exports);
|
|
78
78
|
__exportStar(require("./services/TenantDataService"), exports);
|
|
79
79
|
__exportStar(require("./services/WasabiUploader"), exports);
|
|
80
|
-
__exportStar(require("./storage/services/storageService"), exports);
|
|
81
|
-
__exportStar(require("./storage/factory"), exports);
|
|
82
|
-
__exportStar(require("./storage/types"), exports);
|
|
83
|
-
__exportStar(require("./storage/providers/minio"), exports);
|
|
84
|
-
__exportStar(require("./storage/providers/spaces"), exports);
|
|
85
|
-
__exportStar(require("./storage/interfaces/MediaConfiguration"), exports);
|
package/package.json
CHANGED
package/build/storage/factory.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.StorageFactory = void 0;
|
|
4
|
-
const minio_1 = require("./providers/minio");
|
|
5
|
-
const spaces_1 = require("./providers/spaces");
|
|
6
|
-
const server_1 = require("../server");
|
|
7
|
-
class StorageFactory {
|
|
8
|
-
static create() {
|
|
9
|
-
const provider = process.env.STORAGE_PROVIDER || 'minio';
|
|
10
|
-
switch (provider) {
|
|
11
|
-
case 'minio':
|
|
12
|
-
return new minio_1.MinioProvider({
|
|
13
|
-
endPoint: process.env.MINIO_ENDPOINT || 'localhost',
|
|
14
|
-
port: parseInt(process.env.MINIO_PORT || '9000'),
|
|
15
|
-
useSSL: process.env.MINIO_USE_SSL === 'true',
|
|
16
|
-
accessKey: process.env.MINIO_ACCESS_KEY || 'minioadmin',
|
|
17
|
-
secretKey: process.env.MINIO_SECRET_KEY || 'minioadmin',
|
|
18
|
-
bucket: process.env.MINIO_BUCKET || 'media-dev'
|
|
19
|
-
});
|
|
20
|
-
case 'spaces':
|
|
21
|
-
return new spaces_1.SpacesProvider({
|
|
22
|
-
endpoint: process.env.DO_SPACES_ENDPOINT || 'nyc3.digitaloceanspaces.com',
|
|
23
|
-
accessKeyId: process.env.DO_SPACES_KEY,
|
|
24
|
-
secretAccessKey: process.env.DO_SPACES_SECRET,
|
|
25
|
-
bucket: process.env.DO_SPACES_BUCKET
|
|
26
|
-
});
|
|
27
|
-
default:
|
|
28
|
-
throw new server_1.BadRequestError('UnknownStorageProvider');
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
exports.StorageFactory = StorageFactory;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { StorageProvider, UploadResult, MediaMetadata, ListFilters } from '../types';
|
|
2
|
-
export declare class MinioProvider implements StorageProvider {
|
|
3
|
-
private client;
|
|
4
|
-
private bucket;
|
|
5
|
-
constructor(config: {
|
|
6
|
-
endPoint: string;
|
|
7
|
-
port: number;
|
|
8
|
-
useSSL: boolean;
|
|
9
|
-
accessKey: string;
|
|
10
|
-
secretKey: string;
|
|
11
|
-
bucket: string;
|
|
12
|
-
});
|
|
13
|
-
private ensureBucket;
|
|
14
|
-
upload(file: Buffer, path: string): Promise<UploadResult>;
|
|
15
|
-
delete(id: string): Promise<boolean>;
|
|
16
|
-
get(id: string): Promise<MediaMetadata | null>;
|
|
17
|
-
list(filters: ListFilters): Promise<MediaMetadata[]>;
|
|
18
|
-
private buildPrefix;
|
|
19
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
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 __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
exports.MinioProvider = void 0;
|
|
36
|
-
// src/storage/providers/minio.ts
|
|
37
|
-
const Minio = __importStar(require("minio"));
|
|
38
|
-
class MinioProvider {
|
|
39
|
-
constructor(config) {
|
|
40
|
-
this.client = new Minio.Client({
|
|
41
|
-
endPoint: config.endPoint,
|
|
42
|
-
port: config.port,
|
|
43
|
-
useSSL: config.useSSL,
|
|
44
|
-
accessKey: config.accessKey,
|
|
45
|
-
secretKey: config.secretKey
|
|
46
|
-
});
|
|
47
|
-
this.bucket = config.bucket;
|
|
48
|
-
this.ensureBucket();
|
|
49
|
-
}
|
|
50
|
-
ensureBucket() {
|
|
51
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
-
const exists = yield this.client.bucketExists(this.bucket);
|
|
53
|
-
if (!exists) {
|
|
54
|
-
yield this.client.makeBucket(this.bucket, 'us-east-1');
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
upload(file, path) {
|
|
59
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
-
const id = path;
|
|
61
|
-
yield this.client.putObject(this.bucket, path, file, file.length);
|
|
62
|
-
const url = `${process.env.STORAGE_PUBLIC_URL}/${this.bucket}/${path}`;
|
|
63
|
-
return {
|
|
64
|
-
id,
|
|
65
|
-
metadata: {
|
|
66
|
-
url,
|
|
67
|
-
size: file.length,
|
|
68
|
-
type: 'image/jpeg', // Você pode detectar isso melhor
|
|
69
|
-
uploadedAt: new Date()
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
delete(id) {
|
|
75
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
try {
|
|
77
|
-
yield this.client.removeObject(this.bucket, id);
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
catch (_a) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
get(id) {
|
|
86
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
87
|
-
try {
|
|
88
|
-
const stat = yield this.client.statObject(this.bucket, id);
|
|
89
|
-
const url = `${process.env.STORAGE_PUBLIC_URL}/${this.bucket}/${id}`;
|
|
90
|
-
return {
|
|
91
|
-
url,
|
|
92
|
-
size: stat.size,
|
|
93
|
-
type: stat.metaData['content-type'] || 'application/octet-stream',
|
|
94
|
-
uploadedAt: stat.lastModified
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
catch (_a) {
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
list(filters) {
|
|
103
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
-
const prefix = this.buildPrefix(filters);
|
|
105
|
-
const stream = this.client.listObjectsV2(this.bucket, prefix, true);
|
|
106
|
-
const results = [];
|
|
107
|
-
return new Promise((resolve, reject) => {
|
|
108
|
-
stream.on('data', obj => {
|
|
109
|
-
if (obj.name) {
|
|
110
|
-
results.push({
|
|
111
|
-
url: `${process.env.STORAGE_PUBLIC_URL}/${this.bucket}/${obj.name}`,
|
|
112
|
-
size: obj.size,
|
|
113
|
-
type: 'application/octet-stream',
|
|
114
|
-
uploadedAt: obj.lastModified
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
stream.on('error', reject);
|
|
119
|
-
stream.on('end', () => resolve(results));
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
buildPrefix(filters) {
|
|
124
|
-
const parts = [filters.tenant];
|
|
125
|
-
if (filters.userId)
|
|
126
|
-
parts.push('users', filters.userId);
|
|
127
|
-
if (filters.targetId)
|
|
128
|
-
parts.push('targets', filters.targetId);
|
|
129
|
-
if (filters.type)
|
|
130
|
-
parts.push(filters.type);
|
|
131
|
-
return parts.join('/');
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
exports.MinioProvider = MinioProvider;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { StorageProvider, UploadResult, MediaMetadata, ListFilters } from '../types';
|
|
2
|
-
export declare class SpacesProvider implements StorageProvider {
|
|
3
|
-
private s3;
|
|
4
|
-
private bucket;
|
|
5
|
-
constructor(config: {
|
|
6
|
-
endpoint: string;
|
|
7
|
-
accessKeyId: string;
|
|
8
|
-
secretAccessKey: string;
|
|
9
|
-
bucket: string;
|
|
10
|
-
});
|
|
11
|
-
upload(file: Buffer, path: string): Promise<UploadResult>;
|
|
12
|
-
delete(id: string): Promise<boolean>;
|
|
13
|
-
get(id: string): Promise<MediaMetadata | null>;
|
|
14
|
-
list(filters: ListFilters): Promise<MediaMetadata[]>;
|
|
15
|
-
private detectContentType;
|
|
16
|
-
private buildPrefix;
|
|
17
|
-
}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.SpacesProvider = void 0;
|
|
16
|
-
// src/storage/providers/minio.ts
|
|
17
|
-
// DIGITAL OCEAN SPACES
|
|
18
|
-
const aws_sdk_1 = __importDefault(require("aws-sdk"));
|
|
19
|
-
class SpacesProvider {
|
|
20
|
-
constructor(config) {
|
|
21
|
-
this.s3 = new aws_sdk_1.default.S3({
|
|
22
|
-
endpoint: new aws_sdk_1.default.Endpoint(config.endpoint),
|
|
23
|
-
accessKeyId: config.accessKeyId,
|
|
24
|
-
secretAccessKey: config.secretAccessKey
|
|
25
|
-
});
|
|
26
|
-
this.bucket = config.bucket;
|
|
27
|
-
}
|
|
28
|
-
upload(file, path) {
|
|
29
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
-
const params = {
|
|
31
|
-
Bucket: this.bucket,
|
|
32
|
-
Key: path,
|
|
33
|
-
Body: file,
|
|
34
|
-
ACL: 'public-read',
|
|
35
|
-
ContentType: this.detectContentType(path)
|
|
36
|
-
};
|
|
37
|
-
const result = yield this.s3.upload(params).promise();
|
|
38
|
-
return {
|
|
39
|
-
id: path,
|
|
40
|
-
metadata: {
|
|
41
|
-
url: result.Location,
|
|
42
|
-
size: file.length,
|
|
43
|
-
type: params.ContentType,
|
|
44
|
-
uploadedAt: new Date()
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
delete(id) {
|
|
50
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
-
try {
|
|
52
|
-
yield this.s3
|
|
53
|
-
.deleteObject({
|
|
54
|
-
Bucket: this.bucket,
|
|
55
|
-
Key: id
|
|
56
|
-
})
|
|
57
|
-
.promise();
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
catch (_a) {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
get(id) {
|
|
66
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
-
try {
|
|
68
|
-
const head = yield this.s3
|
|
69
|
-
.headObject({
|
|
70
|
-
Bucket: this.bucket,
|
|
71
|
-
Key: id
|
|
72
|
-
})
|
|
73
|
-
.promise();
|
|
74
|
-
return {
|
|
75
|
-
url: `https://${this.bucket}.${this.s3.endpoint.hostname}/${id}`,
|
|
76
|
-
size: head.ContentLength || 0,
|
|
77
|
-
type: head.ContentType || 'application/octet-stream',
|
|
78
|
-
uploadedAt: head.LastModified || new Date()
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
catch (_a) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
list(filters) {
|
|
87
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
-
const prefix = this.buildPrefix(filters);
|
|
89
|
-
const params = {
|
|
90
|
-
Bucket: this.bucket,
|
|
91
|
-
Prefix: prefix,
|
|
92
|
-
MaxKeys: filters.limit || 1000
|
|
93
|
-
};
|
|
94
|
-
const result = yield this.s3.listObjectsV2(params).promise();
|
|
95
|
-
return (result.Contents || []).map(obj => ({
|
|
96
|
-
url: `https://${this.bucket}.${this.s3.endpoint.hostname}/${obj.Key}`,
|
|
97
|
-
size: obj.Size || 0,
|
|
98
|
-
type: 'application/octet-stream',
|
|
99
|
-
uploadedAt: obj.LastModified || new Date()
|
|
100
|
-
}));
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
detectContentType(path) {
|
|
104
|
-
var _a;
|
|
105
|
-
const ext = (_a = path.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
106
|
-
const types = {
|
|
107
|
-
jpg: 'image/jpeg',
|
|
108
|
-
jpeg: 'image/jpeg',
|
|
109
|
-
png: 'image/png',
|
|
110
|
-
webp: 'image/webp',
|
|
111
|
-
mp4: 'video/mp4',
|
|
112
|
-
webm: 'video/webm',
|
|
113
|
-
mov: 'video/quicktime'
|
|
114
|
-
};
|
|
115
|
-
return types[ext || ''] || 'application/octet-stream';
|
|
116
|
-
}
|
|
117
|
-
buildPrefix(filters) {
|
|
118
|
-
const parts = [filters.tenant];
|
|
119
|
-
if (filters.userId)
|
|
120
|
-
parts.push('users', filters.userId);
|
|
121
|
-
if (filters.targetId)
|
|
122
|
-
parts.push('targets', filters.targetId);
|
|
123
|
-
if (filters.type)
|
|
124
|
-
parts.push(filters.type);
|
|
125
|
-
return parts.join('/');
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
exports.SpacesProvider = SpacesProvider;
|