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.cjs +217 -159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -44
- package/dist/index.d.ts +64 -44
- package/dist/index.js +213 -157
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
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
|
|
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
|
|
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,
|
|
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
|