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.cjs +187 -164
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -46
- package/dist/index.d.ts +48 -46
- package/dist/index.js +185 -162
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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
|
|
5301
|
-
this.refreshExpires = options.refreshExpires
|
|
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
|
-
|
|
5343
|
+
token = req.headers.authorization.split(" ")[1];
|
|
5344
|
+
return token ? this.normalizeToken(token) : null;
|
|
5343
5345
|
}
|
|
5344
5346
|
if (req.cookies?.[this.refreshCookieName]) {
|
|
5345
|
-
|
|
5347
|
+
token = req.cookies[this.refreshCookieName];
|
|
5348
|
+
return token ? this.normalizeToken(token) : null;
|
|
5346
5349
|
}
|
|
5347
5350
|
if (req.cookies?.jwt) {
|
|
5348
|
-
|
|
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,
|
|
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
|