elseware-nodejs 1.5.1 → 1.5.3

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,11 +1817,54 @@ 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;
1866
- accessExpires?: SignOptions["expiresIn"];
1867
- refreshExpires?: SignOptions["expiresIn"];
1866
+ accessExpires?: SignOptions["expiresIn"] | string;
1867
+ refreshExpires?: SignOptions["expiresIn"] | string;
1868
1868
  nodeEnv?: string;
1869
1869
  refreshCookieName?: string;
1870
1870
  }
@@ -1884,6 +1884,8 @@ declare class JWTService {
1884
1884
  setRefreshTokenCookie(res: Response, refreshToken: string): void;
1885
1885
  clearRefreshTokenCookie(res: Response): void;
1886
1886
  sendAuthTokens(res: Response, payload: object): string;
1887
+ private normalizeToken;
1888
+ private parseExpires;
1887
1889
  }
1888
1890
 
1889
1891
  declare function errorToString(error: unknown): string;
@@ -1898,4 +1900,4 @@ declare function toMinutes(ms: number): number;
1898
1900
  declare function toHours(ms: number): number;
1899
1901
  declare function sleep(ms: number): Promise<void>;
1900
1902
 
1901
- 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 };
1903
+ 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, 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,11 +1817,54 @@ 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;
1866
- accessExpires?: SignOptions["expiresIn"];
1867
- refreshExpires?: SignOptions["expiresIn"];
1866
+ accessExpires?: SignOptions["expiresIn"] | string;
1867
+ refreshExpires?: SignOptions["expiresIn"] | string;
1868
1868
  nodeEnv?: string;
1869
1869
  refreshCookieName?: string;
1870
1870
  }
@@ -1884,6 +1884,8 @@ declare class JWTService {
1884
1884
  setRefreshTokenCookie(res: Response, refreshToken: string): void;
1885
1885
  clearRefreshTokenCookie(res: Response): void;
1886
1886
  sendAuthTokens(res: Response, payload: object): string;
1887
+ private normalizeToken;
1888
+ private parseExpires;
1887
1889
  }
1888
1890
 
1889
1891
  declare function errorToString(error: unknown): string;
@@ -1898,4 +1900,4 @@ declare function toMinutes(ms: number): number;
1898
1900
  declare function toHours(ms: number): number;
1899
1901
  declare function sleep(ms: number): Promise<void>;
1900
1902
 
1901
- 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 };
1903
+ 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, 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,8 +1,8 @@
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
7
 
8
8
  // src/errors/appError.ts
@@ -240,160 +240,6 @@ function pickFields(obj, fields, options = {}) {
240
240
  }
241
241
  return result;
242
242
  }
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
243
 
398
244
  // src/utils/errorToString.ts
399
245
  function errorToString(error) {
@@ -5287,6 +5133,160 @@ var validate = (schema) => (req, _res, next) => {
5287
5133
  }
5288
5134
  next();
5289
5135
  };
5136
+ var AzureBlobStorageService = class {
5137
+ containerName;
5138
+ blobServiceClient;
5139
+ containerClient;
5140
+ sharedKeyCredential;
5141
+ constructor(config) {
5142
+ const { connectionString, accountName, accountKey, containerName } = config;
5143
+ this.containerName = containerName;
5144
+ this.blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
5145
+ this.containerClient = this.blobServiceClient.getContainerClient(containerName);
5146
+ this.sharedKeyCredential = new StorageSharedKeyCredential(
5147
+ accountName,
5148
+ accountKey
5149
+ );
5150
+ }
5151
+ // Upload file
5152
+ async uploadFile(localPath, blobName, onProgress) {
5153
+ const blockBlobClient = this.containerClient.getBlockBlobClient(blobName);
5154
+ const fileSize = fs.statSync(localPath).size;
5155
+ const readStream = fs.createReadStream(localPath);
5156
+ await blockBlobClient.uploadStream(
5157
+ readStream,
5158
+ 4 * 1024 * 1024,
5159
+ // buffer size
5160
+ 20,
5161
+ // max concurrency
5162
+ {
5163
+ onProgress: (ev) => {
5164
+ if (onProgress) {
5165
+ const percent = (ev.loadedBytes / fileSize * 100).toFixed(2);
5166
+ onProgress(percent);
5167
+ }
5168
+ }
5169
+ }
5170
+ );
5171
+ return blockBlobClient.url;
5172
+ }
5173
+ // Download file
5174
+ async downloadFile(blobName, downloadPath, onProgress) {
5175
+ const blobClient = this.containerClient.getBlobClient(blobName);
5176
+ const response = await blobClient.download();
5177
+ const fileSize = response.contentLength || 0;
5178
+ let downloaded = 0;
5179
+ return new Promise((resolve, reject) => {
5180
+ const writable = fs.createWriteStream(downloadPath);
5181
+ response.readableStreamBody?.on("data", (chunk) => {
5182
+ downloaded += chunk.length;
5183
+ if (onProgress && fileSize > 0) {
5184
+ const percent = (downloaded / fileSize * 100).toFixed(2);
5185
+ onProgress(percent);
5186
+ }
5187
+ });
5188
+ response.readableStreamBody?.pipe(writable);
5189
+ writable.on("finish", resolve);
5190
+ writable.on("error", reject);
5191
+ });
5192
+ }
5193
+ // Delete file
5194
+ async deleteFile(blobName) {
5195
+ const blobClient = this.containerClient.getBlobClient(blobName);
5196
+ await blobClient.deleteIfExists();
5197
+ return true;
5198
+ }
5199
+ // List blobs
5200
+ async listFiles(prefix = "") {
5201
+ const result = [];
5202
+ for await (const blob of this.containerClient.listBlobsFlat({ prefix })) {
5203
+ result.push(blob.name);
5204
+ }
5205
+ return result;
5206
+ }
5207
+ // Check existence
5208
+ async blobExists(blobName) {
5209
+ const blobClient = this.containerClient.getBlobClient(blobName);
5210
+ return blobClient.exists();
5211
+ }
5212
+ // Generate temporary read-only SAS URL
5213
+ async generateSasUrl(blobName, expiresInMinutes = 60) {
5214
+ const blobClient = this.containerClient.getBlobClient(blobName);
5215
+ const sasToken = generateBlobSASQueryParameters(
5216
+ {
5217
+ containerName: this.containerName,
5218
+ blobName: blobClient.name,
5219
+ expiresOn: new Date(Date.now() + expiresInMinutes * 60 * 1e3),
5220
+ permissions: BlobSASPermissions.parse("r")
5221
+ // read-only
5222
+ },
5223
+ this.sharedKeyCredential
5224
+ ).toString();
5225
+ return `${blobClient.url}?${sasToken}`;
5226
+ }
5227
+ };
5228
+ var cloudinary = cloudinaryModule.v2;
5229
+ var CloudinaryService = class {
5230
+ rootFolder;
5231
+ constructor(config) {
5232
+ const { cloudName, apiKey, apiSecret, rootFolder } = config;
5233
+ cloudinary.config({
5234
+ cloud_name: cloudName,
5235
+ api_key: apiKey,
5236
+ api_secret: apiSecret,
5237
+ secure: true
5238
+ });
5239
+ this.rootFolder = rootFolder;
5240
+ }
5241
+ // Upload file to Cloudinary
5242
+ async uploadFile(filePath, options = {}) {
5243
+ if (!fs.existsSync(filePath)) {
5244
+ throw new Error(`File not found: ${filePath}`);
5245
+ }
5246
+ const folderPath = this.buildFolderPath(options.folder);
5247
+ const result = await cloudinary.uploader.upload(filePath, {
5248
+ folder: folderPath,
5249
+ public_id: options.publicId,
5250
+ resource_type: options.resourceType || "auto"
5251
+ });
5252
+ return result.public_id;
5253
+ }
5254
+ // Delete asset by public ID
5255
+ async deleteFile(publicId) {
5256
+ const result = await cloudinary.uploader.destroy(publicId);
5257
+ return result.result === "ok";
5258
+ }
5259
+ // Check if asset exists
5260
+ async fileExists(publicId) {
5261
+ try {
5262
+ await cloudinary.api.resource(publicId);
5263
+ return true;
5264
+ } catch {
5265
+ return false;
5266
+ }
5267
+ }
5268
+ // Generate optimized delivery URL
5269
+ generateUrl(publicId, options = {}) {
5270
+ return cloudinary.url(publicId, {
5271
+ secure: true,
5272
+ ...options
5273
+ });
5274
+ }
5275
+ // Create folder (idempotent)
5276
+ async createFolder(folder) {
5277
+ try {
5278
+ await cloudinary.api.create_folder(folder);
5279
+ } catch (err) {
5280
+ }
5281
+ }
5282
+ buildFolderPath(subFolder) {
5283
+ if (!this.rootFolder && !subFolder) return void 0;
5284
+ if (this.rootFolder && subFolder) {
5285
+ return `${this.rootFolder}/${subFolder}`;
5286
+ }
5287
+ return this.rootFolder || subFolder;
5288
+ }
5289
+ };
5290
5290
  var JWTService = class {
5291
5291
  accessSecret;
5292
5292
  refreshSecret;
@@ -5297,8 +5297,8 @@ var JWTService = class {
5297
5297
  constructor(options) {
5298
5298
  this.accessSecret = options.accessSecret;
5299
5299
  this.refreshSecret = options.refreshSecret;
5300
- this.accessExpires = options.accessExpires || "15m";
5301
- this.refreshExpires = options.refreshExpires || "30d";
5300
+ this.accessExpires = this.parseExpires(options.accessExpires, "15m");
5301
+ this.refreshExpires = this.parseExpires(options.refreshExpires, "30d");
5302
5302
  this.nodeEnv = options.nodeEnv || "development";
5303
5303
  this.refreshCookieName = options.refreshCookieName || "refreshJwt";
5304
5304
  }
@@ -5338,14 +5338,18 @@ var JWTService = class {
5338
5338
  // Token Extraction
5339
5339
  // ---------------------------------
5340
5340
  extractToken(req) {
5341
+ let token = null;
5341
5342
  if (req.headers.authorization?.startsWith("Bearer ")) {
5342
- return req.headers.authorization.split(" ")[1];
5343
+ token = req.headers.authorization.split(" ")[1];
5344
+ return token ? this.normalizeToken(token) : null;
5343
5345
  }
5344
5346
  if (req.cookies?.[this.refreshCookieName]) {
5345
- return req.cookies[this.refreshCookieName];
5347
+ token = req.cookies[this.refreshCookieName];
5348
+ return token ? this.normalizeToken(token) : null;
5346
5349
  }
5347
5350
  if (req.cookies?.jwt) {
5348
- return req.cookies.jwt;
5351
+ token = req.cookies.jwt;
5352
+ return token ? this.normalizeToken(token) : null;
5349
5353
  }
5350
5354
  return null;
5351
5355
  }
@@ -5378,6 +5382,25 @@ var JWTService = class {
5378
5382
  this.setRefreshTokenCookie(res, refreshToken);
5379
5383
  return accessToken;
5380
5384
  }
5385
+ // ---------------------------------
5386
+ // Internal Helpers
5387
+ // ---------------------------------
5388
+ normalizeToken(token) {
5389
+ token = token.trim();
5390
+ if (token.startsWith('"') && token.endsWith('"')) {
5391
+ try {
5392
+ return JSON.parse(token);
5393
+ } catch {
5394
+ return token.slice(1, -1);
5395
+ }
5396
+ }
5397
+ return token;
5398
+ }
5399
+ parseExpires(value, fallback) {
5400
+ if (!value) return fallback;
5401
+ if (typeof value === "number") return value;
5402
+ return value;
5403
+ }
5381
5404
  };
5382
5405
 
5383
5406
  // src/utils/time.ts
@@ -5409,6 +5432,6 @@ function sleep(ms) {
5409
5432
  return new Promise((resolve) => setTimeout(resolve, ms));
5410
5433
  }
5411
5434
 
5412
- 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 };
5435
+ 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, 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 };
5413
5436
  //# sourceMappingURL=index.js.map
5414
5437
  //# sourceMappingURL=index.js.map