elseware-nodejs 1.5.2 → 1.6.0

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/dist/index.d.cts CHANGED
@@ -70,49 +70,6 @@ type PickOptions<T extends Record<string, any>, K extends keyof T> = {
70
70
  };
71
71
  declare function pickFields<T extends Record<string, any>, K extends keyof T>(obj: T, fields: readonly K[], options?: PickOptions<T, K>): Partial<Record<K | string, any>>;
72
72
 
73
- interface AzureBlobConfig {
74
- connectionString: string;
75
- accountName: string;
76
- accountKey: string;
77
- containerName: string;
78
- }
79
- type ProgressCallback = (percentage: string) => void;
80
- declare class AzureBlobService {
81
- private containerName;
82
- private blobServiceClient;
83
- private containerClient;
84
- private sharedKeyCredential;
85
- constructor(config: AzureBlobConfig);
86
- uploadFile(localPath: string, blobName: string, onProgress?: ProgressCallback): Promise<string>;
87
- downloadFile(blobName: string, downloadPath: string, onProgress?: ProgressCallback): Promise<void>;
88
- deleteFile(blobName: string): Promise<boolean>;
89
- listFiles(prefix?: string): Promise<string[]>;
90
- blobExists(blobName: string): Promise<boolean>;
91
- generateSasUrl(blobName: string, expiresInMinutes?: number): Promise<string>;
92
- }
93
-
94
- interface CloudinaryConfig {
95
- cloudName: string;
96
- apiKey: string;
97
- apiSecret: string;
98
- rootFolder?: string;
99
- }
100
- interface UploadOptions {
101
- folder?: string;
102
- publicId?: string;
103
- resourceType?: "image" | "video" | "raw" | "auto";
104
- }
105
- declare class CloudinaryService {
106
- private rootFolder?;
107
- constructor(config: CloudinaryConfig);
108
- uploadFile(filePath: string, options?: UploadOptions): Promise<string>;
109
- deleteFile(publicId: string): Promise<boolean>;
110
- fileExists(publicId: string): Promise<boolean>;
111
- generateUrl(publicId: string, options?: Record<string, any>): string;
112
- createFolder(folder: string): Promise<void>;
113
- private buildFolderPath;
114
- }
115
-
116
73
  interface DatabaseConfig {
117
74
  uri: string;
118
75
  }
@@ -1860,6 +1817,49 @@ declare const GlobalErrorHandler: (isProd?: boolean) => (err: unknown, _req: Req
1860
1817
 
1861
1818
  declare const validate: (schema: Schema) => (req: Request, _res: Response, next: NextFunction) => void;
1862
1819
 
1820
+ interface AzureBlobStorageConfig {
1821
+ connectionString: string;
1822
+ accountName: string;
1823
+ accountKey: string;
1824
+ containerName: string;
1825
+ }
1826
+ type ProgressCallback = (percentage: string) => void;
1827
+ declare class AzureBlobStorageService {
1828
+ private containerName;
1829
+ private blobServiceClient;
1830
+ private containerClient;
1831
+ private sharedKeyCredential;
1832
+ constructor(config: AzureBlobStorageConfig);
1833
+ uploadFile(localPath: string, blobName: string, onProgress?: ProgressCallback): Promise<string>;
1834
+ downloadFile(blobName: string, downloadPath: string, onProgress?: ProgressCallback): Promise<void>;
1835
+ deleteFile(blobName: string): Promise<boolean>;
1836
+ listFiles(prefix?: string): Promise<string[]>;
1837
+ blobExists(blobName: string): Promise<boolean>;
1838
+ generateSasUrl(blobName: string, expiresInMinutes?: number): Promise<string>;
1839
+ }
1840
+
1841
+ interface CloudinaryConfig {
1842
+ cloudName: string;
1843
+ apiKey: string;
1844
+ apiSecret: string;
1845
+ rootFolder?: string;
1846
+ }
1847
+ interface UploadOptions {
1848
+ folder?: string;
1849
+ publicId?: string;
1850
+ resourceType?: "image" | "video" | "raw" | "auto";
1851
+ }
1852
+ declare class CloudinaryService {
1853
+ private rootFolder?;
1854
+ constructor(config: CloudinaryConfig);
1855
+ uploadFile(filePath: string, options?: UploadOptions): Promise<string>;
1856
+ deleteFile(publicId: string): Promise<boolean>;
1857
+ fileExists(publicId: string): Promise<boolean>;
1858
+ generateUrl(publicId: string, options?: Record<string, any>): string;
1859
+ createFolder(folder: string): Promise<void>;
1860
+ private buildFolderPath;
1861
+ }
1862
+
1863
1863
  interface JWTServiceOptions {
1864
1864
  accessSecret: string;
1865
1865
  refreshSecret: string;
@@ -1888,6 +1888,26 @@ declare class JWTService {
1888
1888
  private parseExpires;
1889
1889
  }
1890
1890
 
1891
+ type MulterFileHandlerOptions = {
1892
+ storage?: "memory" | "disk";
1893
+ allowedMimeTypes?: string[];
1894
+ allowedExtensions?: string[];
1895
+ fileSizeLimit?: number;
1896
+ };
1897
+ declare class MulterFileHandlerService {
1898
+ private storage;
1899
+ private options;
1900
+ constructor(options?: MulterFileHandlerOptions);
1901
+ private fileFilter;
1902
+ private buildUploader;
1903
+ single(fieldName: string): any;
1904
+ array(fieldName: string, maxCount: number): any;
1905
+ fields(fields: {
1906
+ name: string;
1907
+ maxCount?: number;
1908
+ }[]): any;
1909
+ }
1910
+
1891
1911
  declare function errorToString(error: unknown): string;
1892
1912
 
1893
1913
  declare function milliseconds(value: number): number;
@@ -1900,4 +1920,4 @@ declare function toMinutes(ms: number): number;
1900
1920
  declare function toHours(ms: number): number;
1901
1921
  declare function sleep(ms: number): Promise<void>;
1902
1922
 
1903
- export { APIFactory, APIFeatures, APIResponse, AVLTree, AdjacencyList, AdjacencyMatrix, type AdjacentEdge, type AllowedOriginsOptions, AppError, type AzureBlobConfig, AzureBlobService, BPlusTree, BTree, BinaryHeap, BinarySearchTree, BinaryTree, BloomFilter, CircularArray, CircularLinkedList, CircularQueue, type CloudinaryConfig, CloudinaryService, ConsistentHash, CountMinSketch, type DatabaseConfig, Deque, type DirectedEdge, DirectedGraph, DisjointSetUnion, DoublyLinkedList, DynamicArray, type Edge, FenwickTree, FibNode, FibonacciHeap, GlobalErrorHandler, Graph, HashMap, HashSet, HyperLogLog, type Interval, IntervalTree, JWTService, type JWTServiceOptions, KDTree, LFUCache, LRUCache, type LoggerOptions, MaxHeap, MaxStack, MinHeap, MinStack, MultiSet, Node, OrderedSet, PairingHeap, PairingNode, type Point, type Point2D, PriorityQueue, type ProgressCallback, QuadTree, Queue, RadixTree, type Rect, RedBlackTree, SegmentTree, Set, SinglyLinkedList, SparseTable, SplayTree, Stack, StaticArray, SuffixArray, SuffixTree, TernarySearchTree, TreeNode, Trie, type UploadOptions, asyncHandler, authMiddleware, connectMongoDB, createAllowedOrigins, createCorsOptions, days, errorToString, hours, loadEnv, logger, milliseconds, minutes, pickFields, seconds, sleep, toHours, toMinutes, toSeconds, validate };
1923
+ export { APIFactory, APIFeatures, APIResponse, AVLTree, AdjacencyList, AdjacencyMatrix, type AdjacentEdge, type AllowedOriginsOptions, AppError, type AzureBlobStorageConfig, AzureBlobStorageService, BPlusTree, BTree, BinaryHeap, BinarySearchTree, BinaryTree, BloomFilter, CircularArray, CircularLinkedList, CircularQueue, type CloudinaryConfig, CloudinaryService, ConsistentHash, CountMinSketch, type DatabaseConfig, Deque, type DirectedEdge, DirectedGraph, DisjointSetUnion, DoublyLinkedList, DynamicArray, type Edge, FenwickTree, FibNode, FibonacciHeap, GlobalErrorHandler, Graph, HashMap, HashSet, HyperLogLog, type Interval, IntervalTree, JWTService, type JWTServiceOptions, KDTree, LFUCache, LRUCache, type LoggerOptions, MaxHeap, MaxStack, MinHeap, MinStack, MulterFileHandlerService, MultiSet, Node, OrderedSet, PairingHeap, PairingNode, type Point, type Point2D, PriorityQueue, type ProgressCallback, QuadTree, Queue, RadixTree, type Rect, RedBlackTree, SegmentTree, Set, SinglyLinkedList, SparseTable, SplayTree, Stack, StaticArray, SuffixArray, SuffixTree, TernarySearchTree, TreeNode, Trie, type UploadOptions, asyncHandler, authMiddleware, connectMongoDB, createAllowedOrigins, createCorsOptions, days, errorToString, hours, loadEnv, logger, milliseconds, minutes, pickFields, seconds, sleep, toHours, toMinutes, toSeconds, validate };
package/dist/index.d.ts CHANGED
@@ -70,49 +70,6 @@ type PickOptions<T extends Record<string, any>, K extends keyof T> = {
70
70
  };
71
71
  declare function pickFields<T extends Record<string, any>, K extends keyof T>(obj: T, fields: readonly K[], options?: PickOptions<T, K>): Partial<Record<K | string, any>>;
72
72
 
73
- interface AzureBlobConfig {
74
- connectionString: string;
75
- accountName: string;
76
- accountKey: string;
77
- containerName: string;
78
- }
79
- type ProgressCallback = (percentage: string) => void;
80
- declare class AzureBlobService {
81
- private containerName;
82
- private blobServiceClient;
83
- private containerClient;
84
- private sharedKeyCredential;
85
- constructor(config: AzureBlobConfig);
86
- uploadFile(localPath: string, blobName: string, onProgress?: ProgressCallback): Promise<string>;
87
- downloadFile(blobName: string, downloadPath: string, onProgress?: ProgressCallback): Promise<void>;
88
- deleteFile(blobName: string): Promise<boolean>;
89
- listFiles(prefix?: string): Promise<string[]>;
90
- blobExists(blobName: string): Promise<boolean>;
91
- generateSasUrl(blobName: string, expiresInMinutes?: number): Promise<string>;
92
- }
93
-
94
- interface CloudinaryConfig {
95
- cloudName: string;
96
- apiKey: string;
97
- apiSecret: string;
98
- rootFolder?: string;
99
- }
100
- interface UploadOptions {
101
- folder?: string;
102
- publicId?: string;
103
- resourceType?: "image" | "video" | "raw" | "auto";
104
- }
105
- declare class CloudinaryService {
106
- private rootFolder?;
107
- constructor(config: CloudinaryConfig);
108
- uploadFile(filePath: string, options?: UploadOptions): Promise<string>;
109
- deleteFile(publicId: string): Promise<boolean>;
110
- fileExists(publicId: string): Promise<boolean>;
111
- generateUrl(publicId: string, options?: Record<string, any>): string;
112
- createFolder(folder: string): Promise<void>;
113
- private buildFolderPath;
114
- }
115
-
116
73
  interface DatabaseConfig {
117
74
  uri: string;
118
75
  }
@@ -1860,6 +1817,49 @@ declare const GlobalErrorHandler: (isProd?: boolean) => (err: unknown, _req: Req
1860
1817
 
1861
1818
  declare const validate: (schema: Schema) => (req: Request, _res: Response, next: NextFunction) => void;
1862
1819
 
1820
+ interface AzureBlobStorageConfig {
1821
+ connectionString: string;
1822
+ accountName: string;
1823
+ accountKey: string;
1824
+ containerName: string;
1825
+ }
1826
+ type ProgressCallback = (percentage: string) => void;
1827
+ declare class AzureBlobStorageService {
1828
+ private containerName;
1829
+ private blobServiceClient;
1830
+ private containerClient;
1831
+ private sharedKeyCredential;
1832
+ constructor(config: AzureBlobStorageConfig);
1833
+ uploadFile(localPath: string, blobName: string, onProgress?: ProgressCallback): Promise<string>;
1834
+ downloadFile(blobName: string, downloadPath: string, onProgress?: ProgressCallback): Promise<void>;
1835
+ deleteFile(blobName: string): Promise<boolean>;
1836
+ listFiles(prefix?: string): Promise<string[]>;
1837
+ blobExists(blobName: string): Promise<boolean>;
1838
+ generateSasUrl(blobName: string, expiresInMinutes?: number): Promise<string>;
1839
+ }
1840
+
1841
+ interface CloudinaryConfig {
1842
+ cloudName: string;
1843
+ apiKey: string;
1844
+ apiSecret: string;
1845
+ rootFolder?: string;
1846
+ }
1847
+ interface UploadOptions {
1848
+ folder?: string;
1849
+ publicId?: string;
1850
+ resourceType?: "image" | "video" | "raw" | "auto";
1851
+ }
1852
+ declare class CloudinaryService {
1853
+ private rootFolder?;
1854
+ constructor(config: CloudinaryConfig);
1855
+ uploadFile(filePath: string, options?: UploadOptions): Promise<string>;
1856
+ deleteFile(publicId: string): Promise<boolean>;
1857
+ fileExists(publicId: string): Promise<boolean>;
1858
+ generateUrl(publicId: string, options?: Record<string, any>): string;
1859
+ createFolder(folder: string): Promise<void>;
1860
+ private buildFolderPath;
1861
+ }
1862
+
1863
1863
  interface JWTServiceOptions {
1864
1864
  accessSecret: string;
1865
1865
  refreshSecret: string;
@@ -1888,6 +1888,26 @@ declare class JWTService {
1888
1888
  private parseExpires;
1889
1889
  }
1890
1890
 
1891
+ type MulterFileHandlerOptions = {
1892
+ storage?: "memory" | "disk";
1893
+ allowedMimeTypes?: string[];
1894
+ allowedExtensions?: string[];
1895
+ fileSizeLimit?: number;
1896
+ };
1897
+ declare class MulterFileHandlerService {
1898
+ private storage;
1899
+ private options;
1900
+ constructor(options?: MulterFileHandlerOptions);
1901
+ private fileFilter;
1902
+ private buildUploader;
1903
+ single(fieldName: string): any;
1904
+ array(fieldName: string, maxCount: number): any;
1905
+ fields(fields: {
1906
+ name: string;
1907
+ maxCount?: number;
1908
+ }[]): any;
1909
+ }
1910
+
1891
1911
  declare function errorToString(error: unknown): string;
1892
1912
 
1893
1913
  declare function milliseconds(value: number): number;
@@ -1900,4 +1920,4 @@ declare function toMinutes(ms: number): number;
1900
1920
  declare function toHours(ms: number): number;
1901
1921
  declare function sleep(ms: number): Promise<void>;
1902
1922
 
1903
- export { APIFactory, APIFeatures, APIResponse, AVLTree, AdjacencyList, AdjacencyMatrix, type AdjacentEdge, type AllowedOriginsOptions, AppError, type AzureBlobConfig, AzureBlobService, BPlusTree, BTree, BinaryHeap, BinarySearchTree, BinaryTree, BloomFilter, CircularArray, CircularLinkedList, CircularQueue, type CloudinaryConfig, CloudinaryService, ConsistentHash, CountMinSketch, type DatabaseConfig, Deque, type DirectedEdge, DirectedGraph, DisjointSetUnion, DoublyLinkedList, DynamicArray, type Edge, FenwickTree, FibNode, FibonacciHeap, GlobalErrorHandler, Graph, HashMap, HashSet, HyperLogLog, type Interval, IntervalTree, JWTService, type JWTServiceOptions, KDTree, LFUCache, LRUCache, type LoggerOptions, MaxHeap, MaxStack, MinHeap, MinStack, MultiSet, Node, OrderedSet, PairingHeap, PairingNode, type Point, type Point2D, PriorityQueue, type ProgressCallback, QuadTree, Queue, RadixTree, type Rect, RedBlackTree, SegmentTree, Set, SinglyLinkedList, SparseTable, SplayTree, Stack, StaticArray, SuffixArray, SuffixTree, TernarySearchTree, TreeNode, Trie, type UploadOptions, asyncHandler, authMiddleware, connectMongoDB, createAllowedOrigins, createCorsOptions, days, errorToString, hours, loadEnv, logger, milliseconds, minutes, pickFields, seconds, sleep, toHours, toMinutes, toSeconds, validate };
1923
+ export { APIFactory, APIFeatures, APIResponse, AVLTree, AdjacencyList, AdjacencyMatrix, type AdjacentEdge, type AllowedOriginsOptions, AppError, type AzureBlobStorageConfig, AzureBlobStorageService, BPlusTree, BTree, BinaryHeap, BinarySearchTree, BinaryTree, BloomFilter, CircularArray, CircularLinkedList, CircularQueue, type CloudinaryConfig, CloudinaryService, ConsistentHash, CountMinSketch, type DatabaseConfig, Deque, type DirectedEdge, DirectedGraph, DisjointSetUnion, DoublyLinkedList, DynamicArray, type Edge, FenwickTree, FibNode, FibonacciHeap, GlobalErrorHandler, Graph, HashMap, HashSet, HyperLogLog, type Interval, IntervalTree, JWTService, type JWTServiceOptions, KDTree, LFUCache, LRUCache, type LoggerOptions, MaxHeap, MaxStack, MinHeap, MinStack, MulterFileHandlerService, MultiSet, Node, OrderedSet, PairingHeap, PairingNode, type Point, type Point2D, PriorityQueue, type ProgressCallback, QuadTree, Queue, RadixTree, type Rect, RedBlackTree, SegmentTree, Set, SinglyLinkedList, SparseTable, SplayTree, Stack, StaticArray, SuffixArray, SuffixTree, TernarySearchTree, TreeNode, Trie, type UploadOptions, asyncHandler, authMiddleware, connectMongoDB, createAllowedOrigins, createCorsOptions, days, errorToString, hours, loadEnv, logger, milliseconds, minutes, pickFields, seconds, sleep, toHours, toMinutes, toSeconds, validate };
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
+ import mongoose from 'mongoose';
2
+ import dotenv from 'dotenv';
1
3
  import { BlobServiceClient, StorageSharedKeyCredential, generateBlobSASQueryParameters, BlobSASPermissions } from '@azure/storage-blob';
2
4
  import fs from 'fs';
3
5
  import cloudinaryModule from 'cloudinary';
4
- import mongoose from 'mongoose';
5
- import dotenv from 'dotenv';
6
6
  import jwt from 'jsonwebtoken';
7
+ import multer from 'multer';
7
8
 
8
9
  // src/errors/appError.ts
9
10
  var AppError = class extends Error {
@@ -240,160 +241,6 @@ function pickFields(obj, fields, options = {}) {
240
241
  }
241
242
  return result;
242
243
  }
243
- var AzureBlobService = class {
244
- containerName;
245
- blobServiceClient;
246
- containerClient;
247
- sharedKeyCredential;
248
- constructor(config) {
249
- const { connectionString, accountName, accountKey, containerName } = config;
250
- this.containerName = containerName;
251
- this.blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
252
- this.containerClient = this.blobServiceClient.getContainerClient(containerName);
253
- this.sharedKeyCredential = new StorageSharedKeyCredential(
254
- accountName,
255
- accountKey
256
- );
257
- }
258
- // Upload file
259
- async uploadFile(localPath, blobName, onProgress) {
260
- const blockBlobClient = this.containerClient.getBlockBlobClient(blobName);
261
- const fileSize = fs.statSync(localPath).size;
262
- const readStream = fs.createReadStream(localPath);
263
- await blockBlobClient.uploadStream(
264
- readStream,
265
- 4 * 1024 * 1024,
266
- // buffer size
267
- 20,
268
- // max concurrency
269
- {
270
- onProgress: (ev) => {
271
- if (onProgress) {
272
- const percent = (ev.loadedBytes / fileSize * 100).toFixed(2);
273
- onProgress(percent);
274
- }
275
- }
276
- }
277
- );
278
- return blockBlobClient.url;
279
- }
280
- // Download file
281
- async downloadFile(blobName, downloadPath, onProgress) {
282
- const blobClient = this.containerClient.getBlobClient(blobName);
283
- const response = await blobClient.download();
284
- const fileSize = response.contentLength || 0;
285
- let downloaded = 0;
286
- return new Promise((resolve, reject) => {
287
- const writable = fs.createWriteStream(downloadPath);
288
- response.readableStreamBody?.on("data", (chunk) => {
289
- downloaded += chunk.length;
290
- if (onProgress && fileSize > 0) {
291
- const percent = (downloaded / fileSize * 100).toFixed(2);
292
- onProgress(percent);
293
- }
294
- });
295
- response.readableStreamBody?.pipe(writable);
296
- writable.on("finish", resolve);
297
- writable.on("error", reject);
298
- });
299
- }
300
- // Delete file
301
- async deleteFile(blobName) {
302
- const blobClient = this.containerClient.getBlobClient(blobName);
303
- await blobClient.deleteIfExists();
304
- return true;
305
- }
306
- // List blobs
307
- async listFiles(prefix = "") {
308
- const result = [];
309
- for await (const blob of this.containerClient.listBlobsFlat({ prefix })) {
310
- result.push(blob.name);
311
- }
312
- return result;
313
- }
314
- // Check existence
315
- async blobExists(blobName) {
316
- const blobClient = this.containerClient.getBlobClient(blobName);
317
- return blobClient.exists();
318
- }
319
- // Generate temporary read-only SAS URL
320
- async generateSasUrl(blobName, expiresInMinutes = 60) {
321
- const blobClient = this.containerClient.getBlobClient(blobName);
322
- const sasToken = generateBlobSASQueryParameters(
323
- {
324
- containerName: this.containerName,
325
- blobName: blobClient.name,
326
- expiresOn: new Date(Date.now() + expiresInMinutes * 60 * 1e3),
327
- permissions: BlobSASPermissions.parse("r")
328
- // read-only
329
- },
330
- this.sharedKeyCredential
331
- ).toString();
332
- return `${blobClient.url}?${sasToken}`;
333
- }
334
- };
335
- var cloudinary = cloudinaryModule.v2;
336
- var CloudinaryService = class {
337
- rootFolder;
338
- constructor(config) {
339
- const { cloudName, apiKey, apiSecret, rootFolder } = config;
340
- cloudinary.config({
341
- cloud_name: cloudName,
342
- api_key: apiKey,
343
- api_secret: apiSecret,
344
- secure: true
345
- });
346
- this.rootFolder = rootFolder;
347
- }
348
- // Upload file to Cloudinary
349
- async uploadFile(filePath, options = {}) {
350
- if (!fs.existsSync(filePath)) {
351
- throw new Error(`File not found: ${filePath}`);
352
- }
353
- const folderPath = this.buildFolderPath(options.folder);
354
- const result = await cloudinary.uploader.upload(filePath, {
355
- folder: folderPath,
356
- public_id: options.publicId,
357
- resource_type: options.resourceType || "auto"
358
- });
359
- return result.public_id;
360
- }
361
- // Delete asset by public ID
362
- async deleteFile(publicId) {
363
- const result = await cloudinary.uploader.destroy(publicId);
364
- return result.result === "ok";
365
- }
366
- // Check if asset exists
367
- async fileExists(publicId) {
368
- try {
369
- await cloudinary.api.resource(publicId);
370
- return true;
371
- } catch {
372
- return false;
373
- }
374
- }
375
- // Generate optimized delivery URL
376
- generateUrl(publicId, options = {}) {
377
- return cloudinary.url(publicId, {
378
- secure: true,
379
- ...options
380
- });
381
- }
382
- // Create folder (idempotent)
383
- async createFolder(folder) {
384
- try {
385
- await cloudinary.api.create_folder(folder);
386
- } catch (err) {
387
- }
388
- }
389
- buildFolderPath(subFolder) {
390
- if (!this.rootFolder && !subFolder) return void 0;
391
- if (this.rootFolder && subFolder) {
392
- return `${this.rootFolder}/${subFolder}`;
393
- }
394
- return this.rootFolder || subFolder;
395
- }
396
- };
397
244
 
398
245
  // src/utils/errorToString.ts
399
246
  function errorToString(error) {
@@ -5287,6 +5134,160 @@ var validate = (schema) => (req, _res, next) => {
5287
5134
  }
5288
5135
  next();
5289
5136
  };
5137
+ var AzureBlobStorageService = class {
5138
+ containerName;
5139
+ blobServiceClient;
5140
+ containerClient;
5141
+ sharedKeyCredential;
5142
+ constructor(config) {
5143
+ const { connectionString, accountName, accountKey, containerName } = config;
5144
+ this.containerName = containerName;
5145
+ this.blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
5146
+ this.containerClient = this.blobServiceClient.getContainerClient(containerName);
5147
+ this.sharedKeyCredential = new StorageSharedKeyCredential(
5148
+ accountName,
5149
+ accountKey
5150
+ );
5151
+ }
5152
+ // Upload file
5153
+ async uploadFile(localPath, blobName, onProgress) {
5154
+ const blockBlobClient = this.containerClient.getBlockBlobClient(blobName);
5155
+ const fileSize = fs.statSync(localPath).size;
5156
+ const readStream = fs.createReadStream(localPath);
5157
+ await blockBlobClient.uploadStream(
5158
+ readStream,
5159
+ 4 * 1024 * 1024,
5160
+ // buffer size
5161
+ 20,
5162
+ // max concurrency
5163
+ {
5164
+ onProgress: (ev) => {
5165
+ if (onProgress) {
5166
+ const percent = (ev.loadedBytes / fileSize * 100).toFixed(2);
5167
+ onProgress(percent);
5168
+ }
5169
+ }
5170
+ }
5171
+ );
5172
+ return blockBlobClient.url;
5173
+ }
5174
+ // Download file
5175
+ async downloadFile(blobName, downloadPath, onProgress) {
5176
+ const blobClient = this.containerClient.getBlobClient(blobName);
5177
+ const response = await blobClient.download();
5178
+ const fileSize = response.contentLength || 0;
5179
+ let downloaded = 0;
5180
+ return new Promise((resolve, reject) => {
5181
+ const writable = fs.createWriteStream(downloadPath);
5182
+ response.readableStreamBody?.on("data", (chunk) => {
5183
+ downloaded += chunk.length;
5184
+ if (onProgress && fileSize > 0) {
5185
+ const percent = (downloaded / fileSize * 100).toFixed(2);
5186
+ onProgress(percent);
5187
+ }
5188
+ });
5189
+ response.readableStreamBody?.pipe(writable);
5190
+ writable.on("finish", resolve);
5191
+ writable.on("error", reject);
5192
+ });
5193
+ }
5194
+ // Delete file
5195
+ async deleteFile(blobName) {
5196
+ const blobClient = this.containerClient.getBlobClient(blobName);
5197
+ await blobClient.deleteIfExists();
5198
+ return true;
5199
+ }
5200
+ // List blobs
5201
+ async listFiles(prefix = "") {
5202
+ const result = [];
5203
+ for await (const blob of this.containerClient.listBlobsFlat({ prefix })) {
5204
+ result.push(blob.name);
5205
+ }
5206
+ return result;
5207
+ }
5208
+ // Check existence
5209
+ async blobExists(blobName) {
5210
+ const blobClient = this.containerClient.getBlobClient(blobName);
5211
+ return blobClient.exists();
5212
+ }
5213
+ // Generate temporary read-only SAS URL
5214
+ async generateSasUrl(blobName, expiresInMinutes = 60) {
5215
+ const blobClient = this.containerClient.getBlobClient(blobName);
5216
+ const sasToken = generateBlobSASQueryParameters(
5217
+ {
5218
+ containerName: this.containerName,
5219
+ blobName: blobClient.name,
5220
+ expiresOn: new Date(Date.now() + expiresInMinutes * 60 * 1e3),
5221
+ permissions: BlobSASPermissions.parse("r")
5222
+ // read-only
5223
+ },
5224
+ this.sharedKeyCredential
5225
+ ).toString();
5226
+ return `${blobClient.url}?${sasToken}`;
5227
+ }
5228
+ };
5229
+ var cloudinary = cloudinaryModule.v2;
5230
+ var CloudinaryService = class {
5231
+ rootFolder;
5232
+ constructor(config) {
5233
+ const { cloudName, apiKey, apiSecret, rootFolder } = config;
5234
+ cloudinary.config({
5235
+ cloud_name: cloudName,
5236
+ api_key: apiKey,
5237
+ api_secret: apiSecret,
5238
+ secure: true
5239
+ });
5240
+ this.rootFolder = rootFolder;
5241
+ }
5242
+ // Upload file to Cloudinary
5243
+ async uploadFile(filePath, options = {}) {
5244
+ if (!fs.existsSync(filePath)) {
5245
+ throw new Error(`File not found: ${filePath}`);
5246
+ }
5247
+ const folderPath = this.buildFolderPath(options.folder);
5248
+ const result = await cloudinary.uploader.upload(filePath, {
5249
+ folder: folderPath,
5250
+ public_id: options.publicId,
5251
+ resource_type: options.resourceType || "auto"
5252
+ });
5253
+ return result.public_id;
5254
+ }
5255
+ // Delete asset by public ID
5256
+ async deleteFile(publicId) {
5257
+ const result = await cloudinary.uploader.destroy(publicId);
5258
+ return result.result === "ok";
5259
+ }
5260
+ // Check if asset exists
5261
+ async fileExists(publicId) {
5262
+ try {
5263
+ await cloudinary.api.resource(publicId);
5264
+ return true;
5265
+ } catch {
5266
+ return false;
5267
+ }
5268
+ }
5269
+ // Generate optimized delivery URL
5270
+ generateUrl(publicId, options = {}) {
5271
+ return cloudinary.url(publicId, {
5272
+ secure: true,
5273
+ ...options
5274
+ });
5275
+ }
5276
+ // Create folder (idempotent)
5277
+ async createFolder(folder) {
5278
+ try {
5279
+ await cloudinary.api.create_folder(folder);
5280
+ } catch (err) {
5281
+ }
5282
+ }
5283
+ buildFolderPath(subFolder) {
5284
+ if (!this.rootFolder && !subFolder) return void 0;
5285
+ if (this.rootFolder && subFolder) {
5286
+ return `${this.rootFolder}/${subFolder}`;
5287
+ }
5288
+ return this.rootFolder || subFolder;
5289
+ }
5290
+ };
5290
5291
  var JWTService = class {
5291
5292
  accessSecret;
5292
5293
  refreshSecret;
@@ -5402,6 +5403,61 @@ var JWTService = class {
5402
5403
  return value;
5403
5404
  }
5404
5405
  };
5406
+ var MulterFileHandlerService = class {
5407
+ storage;
5408
+ options;
5409
+ constructor(options = {}) {
5410
+ this.options = options;
5411
+ this.storage = options.storage === "memory" ? multer.memoryStorage() : multer.diskStorage({});
5412
+ }
5413
+ // File Filter
5414
+ fileFilter = (req, file, cb) => {
5415
+ const { allowedMimeTypes, allowedExtensions } = this.options;
5416
+ const mimeType = file.mimetype;
5417
+ const extFromMime = mimeType.split("/")[1]?.toLowerCase();
5418
+ if (allowedMimeTypes?.length) {
5419
+ if (!allowedMimeTypes.includes(mimeType)) {
5420
+ return cb(
5421
+ new AppError(
5422
+ `Invalid file type! Allowed: ${allowedMimeTypes.join(", ")}`,
5423
+ 400
5424
+ ),
5425
+ false
5426
+ );
5427
+ }
5428
+ }
5429
+ if (allowedExtensions?.length) {
5430
+ if (!extFromMime || !allowedExtensions.includes(extFromMime)) {
5431
+ return cb(
5432
+ new AppError(
5433
+ `Invalid file extension! Allowed: ${allowedExtensions.join(", ")}`,
5434
+ 400
5435
+ ),
5436
+ false
5437
+ );
5438
+ }
5439
+ }
5440
+ cb(null, true);
5441
+ };
5442
+ // Build multer instance
5443
+ buildUploader() {
5444
+ return multer({
5445
+ storage: this.storage,
5446
+ fileFilter: this.fileFilter,
5447
+ limits: this.options.fileSizeLimit ? { fileSize: this.options.fileSizeLimit } : void 0
5448
+ });
5449
+ }
5450
+ // Public API
5451
+ single(fieldName) {
5452
+ return this.buildUploader().single(fieldName);
5453
+ }
5454
+ array(fieldName, maxCount) {
5455
+ return this.buildUploader().array(fieldName, maxCount);
5456
+ }
5457
+ fields(fields) {
5458
+ return this.buildUploader().fields(fields);
5459
+ }
5460
+ };
5405
5461
 
5406
5462
  // src/utils/time.ts
5407
5463
  function milliseconds(value) {
@@ -5432,6 +5488,6 @@ function sleep(ms) {
5432
5488
  return new Promise((resolve) => setTimeout(resolve, ms));
5433
5489
  }
5434
5490
 
5435
- export { APIFactory, apiFeatures_default as APIFeatures, APIResponse, AVLTree, AdjacencyList, AdjacencyMatrix, AppError, AzureBlobService, BPlusTree, BTree, BinaryHeap, BinarySearchTree, BinaryTree, BloomFilter, CircularArray, CircularLinkedList, CircularQueue, CloudinaryService, ConsistentHash, CountMinSketch, Deque, DirectedGraph, DisjointSetUnion, DoublyLinkedList, DynamicArray, FenwickTree, FibNode, FibonacciHeap, GlobalErrorHandler, Graph, HashMap, HashSet, HyperLogLog, IntervalTree, JWTService, KDTree, LFUCache, LRUCache, MaxHeap, MaxStack, MinHeap, MinStack, MultiSet, Node, OrderedSet, PairingHeap, PairingNode, PriorityQueue, QuadTree, Queue, RadixTree, RedBlackTree, SegmentTree, Set2 as Set, SinglyLinkedList, SparseTable, SplayTree, Stack, StaticArray, SuffixArray, SuffixTree, TernarySearchTree, TreeNode, Trie, asyncHandler, authMiddleware, connectMongoDB, createAllowedOrigins, createCorsOptions, days, errorToString, hours, loadEnv, logger, milliseconds, minutes, pickFields, seconds, sleep, toHours, toMinutes, toSeconds, validate };
5491
+ export { APIFactory, apiFeatures_default as APIFeatures, APIResponse, AVLTree, AdjacencyList, AdjacencyMatrix, AppError, AzureBlobStorageService, BPlusTree, BTree, BinaryHeap, BinarySearchTree, BinaryTree, BloomFilter, CircularArray, CircularLinkedList, CircularQueue, CloudinaryService, ConsistentHash, CountMinSketch, Deque, DirectedGraph, DisjointSetUnion, DoublyLinkedList, DynamicArray, FenwickTree, FibNode, FibonacciHeap, GlobalErrorHandler, Graph, HashMap, HashSet, HyperLogLog, IntervalTree, JWTService, KDTree, LFUCache, LRUCache, MaxHeap, MaxStack, MinHeap, MinStack, MulterFileHandlerService, MultiSet, Node, OrderedSet, PairingHeap, PairingNode, PriorityQueue, QuadTree, Queue, RadixTree, RedBlackTree, SegmentTree, Set2 as Set, SinglyLinkedList, SparseTable, SplayTree, Stack, StaticArray, SuffixArray, SuffixTree, TernarySearchTree, TreeNode, Trie, asyncHandler, authMiddleware, connectMongoDB, createAllowedOrigins, createCorsOptions, days, errorToString, hours, loadEnv, logger, milliseconds, minutes, pickFields, seconds, sleep, toHours, toMinutes, toSeconds, validate };
5436
5492
  //# sourceMappingURL=index.js.map
5437
5493
  //# sourceMappingURL=index.js.map