@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 CHANGED
@@ -26,5 +26,3 @@ export * from './types/giftType';
26
26
  export * from './types/paymentProviderType';
27
27
  export * from './events/subjects';
28
28
  export * from './services/TenantDataService';
29
- export * from './storage/types';
30
- export * from './storage/interfaces/MediaConfiguration';
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) => upload.array(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) => __awaiter(void 0, void 0, void 0, function* () {
38
- try {
39
- const storageService = new storageService_1.StorageService(factory_1.StorageFactory.create());
40
- const tenant = req.headers['x-tenant'] || tenant_1.Tenant.PoliticaBet;
41
- let allFiles = [];
42
- if (req.file) {
43
- allFiles = [req.file];
44
- }
45
- else if (req.files) {
46
- if (Array.isArray(req.files)) {
47
- allFiles = req.files;
48
- }
49
- else {
50
- allFiles = Object.values(req.files).flat();
51
- }
52
- }
53
- if (!allFiles.length)
54
- return next();
55
- // Verificar se mais de 5 imagens ou mais de 1 vídeo
56
- if (req.files && !Array.isArray(req.files)) {
57
- const imageFiles = req.files['images'] || [];
58
- const videoFiles = req.files['videos'] || [];
59
- if (imageFiles.length > 5) {
60
- throw new badRequestError_1.BadRequestError('TooManyImages');
61
- }
62
- if (videoFiles.length > 1) {
63
- throw new badRequestError_1.BadRequestError('TooManyVideos');
64
- }
65
- }
66
- // ✅ Verificar novamente via allFiles se alguém tentar burlar o `fieldname`
67
- const videoCount = allFiles.filter(f => f.mimetype.startsWith('video/')).length;
68
- if (videoCount > 1) {
69
- throw new badRequestError_1.BadRequestError('TooManyVideos');
70
- }
71
- // Validação de tamanho por campo
72
- const fieldConfig = req._uploadFieldConfig || [];
73
- const getMaxSizeForField = (fieldName) => {
74
- const field = fieldConfig.find(f => f.name === fieldName);
75
- return (field === null || field === void 0 ? void 0 : field.maxSizeMB) ? field.maxSizeMB * 1024 * 1024 : undefined;
76
- };
77
- for (const file of allFiles) {
78
- const isVideo = file.mimetype.startsWith('video/');
79
- const isImage = file.mimetype.startsWith('image/');
80
- if (!isImage && !isVideo) {
81
- throw new badRequestError_1.BadRequestError('InvalidFileType');
82
- }
83
- const maxSize = getMaxSizeForField(file.fieldname);
84
- if (maxSize && file.size > maxSize) {
85
- throw new badRequestError_1.BadRequestError(isImage ? 'ImageTooLarge' : 'VideoTooLarge');
86
- }
87
- }
88
- const uploadPromises = allFiles.map((file) => __awaiter(void 0, void 0, void 0, function* () {
89
- var _a;
90
- const isVideo = file.mimetype.startsWith('video/');
91
- const type = isVideo ? 'video' : 'photo';
92
- const options = {
93
- tenant,
94
- userId: (_a = req.currentUser) === null || _a === void 0 ? void 0 : _a.id,
95
- targetId: req.body.targetId || undefined,
96
- type,
97
- generateThumbnail: true
98
- };
99
- return isVideo
100
- ? storageService.uploadVideo(file.buffer, file.originalname, options)
101
- : storageService.uploadImage(file.buffer, file.originalname, options);
102
- }));
103
- const results = yield Promise.all(uploadPromises);
104
- req.uploadResults = results;
105
- if (req.files && !Array.isArray(req.files)) {
106
- req.uploadResultsByField = {};
107
- let index = 0;
108
- for (const [fieldName, files] of Object.entries(req.files)) {
109
- req.uploadResultsByField[fieldName] = results.slice(index, index + files.length);
110
- index += files.length;
111
- }
112
- }
113
- next();
114
- }
115
- catch (error) {
116
- next(error);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrcb/cb-common",
3
- "version": "1.0.468",
3
+ "version": "1.0.470",
4
4
  "description": "Common resources between services",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -1,4 +0,0 @@
1
- import { StorageProvider } from './types';
2
- export declare class StorageFactory {
3
- static create(): StorageProvider;
4
- }
@@ -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;