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 CHANGED
@@ -1,19 +1,21 @@
1
1
  'use strict';
2
2
 
3
+ var mongoose = require('mongoose');
4
+ var dotenv = require('dotenv');
3
5
  var storageBlob = require('@azure/storage-blob');
4
6
  var fs = require('fs');
5
7
  var cloudinaryModule = require('cloudinary');
6
- var mongoose = require('mongoose');
7
- var dotenv = require('dotenv');
8
8
  var jwt = require('jsonwebtoken');
9
+ var multer = require('multer');
9
10
 
10
11
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
12
 
12
- var fs__default = /*#__PURE__*/_interopDefault(fs);
13
- var cloudinaryModule__default = /*#__PURE__*/_interopDefault(cloudinaryModule);
14
13
  var mongoose__default = /*#__PURE__*/_interopDefault(mongoose);
15
14
  var dotenv__default = /*#__PURE__*/_interopDefault(dotenv);
15
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
16
+ var cloudinaryModule__default = /*#__PURE__*/_interopDefault(cloudinaryModule);
16
17
  var jwt__default = /*#__PURE__*/_interopDefault(jwt);
18
+ var multer__default = /*#__PURE__*/_interopDefault(multer);
17
19
 
18
20
  // src/errors/appError.ts
19
21
  var AppError = class extends Error {
@@ -250,160 +252,6 @@ function pickFields(obj, fields, options = {}) {
250
252
  }
251
253
  return result;
252
254
  }
253
- var AzureBlobService = class {
254
- containerName;
255
- blobServiceClient;
256
- containerClient;
257
- sharedKeyCredential;
258
- constructor(config) {
259
- const { connectionString, accountName, accountKey, containerName } = config;
260
- this.containerName = containerName;
261
- this.blobServiceClient = storageBlob.BlobServiceClient.fromConnectionString(connectionString);
262
- this.containerClient = this.blobServiceClient.getContainerClient(containerName);
263
- this.sharedKeyCredential = new storageBlob.StorageSharedKeyCredential(
264
- accountName,
265
- accountKey
266
- );
267
- }
268
- // Upload file
269
- async uploadFile(localPath, blobName, onProgress) {
270
- const blockBlobClient = this.containerClient.getBlockBlobClient(blobName);
271
- const fileSize = fs__default.default.statSync(localPath).size;
272
- const readStream = fs__default.default.createReadStream(localPath);
273
- await blockBlobClient.uploadStream(
274
- readStream,
275
- 4 * 1024 * 1024,
276
- // buffer size
277
- 20,
278
- // max concurrency
279
- {
280
- onProgress: (ev) => {
281
- if (onProgress) {
282
- const percent = (ev.loadedBytes / fileSize * 100).toFixed(2);
283
- onProgress(percent);
284
- }
285
- }
286
- }
287
- );
288
- return blockBlobClient.url;
289
- }
290
- // Download file
291
- async downloadFile(blobName, downloadPath, onProgress) {
292
- const blobClient = this.containerClient.getBlobClient(blobName);
293
- const response = await blobClient.download();
294
- const fileSize = response.contentLength || 0;
295
- let downloaded = 0;
296
- return new Promise((resolve, reject) => {
297
- const writable = fs__default.default.createWriteStream(downloadPath);
298
- response.readableStreamBody?.on("data", (chunk) => {
299
- downloaded += chunk.length;
300
- if (onProgress && fileSize > 0) {
301
- const percent = (downloaded / fileSize * 100).toFixed(2);
302
- onProgress(percent);
303
- }
304
- });
305
- response.readableStreamBody?.pipe(writable);
306
- writable.on("finish", resolve);
307
- writable.on("error", reject);
308
- });
309
- }
310
- // Delete file
311
- async deleteFile(blobName) {
312
- const blobClient = this.containerClient.getBlobClient(blobName);
313
- await blobClient.deleteIfExists();
314
- return true;
315
- }
316
- // List blobs
317
- async listFiles(prefix = "") {
318
- const result = [];
319
- for await (const blob of this.containerClient.listBlobsFlat({ prefix })) {
320
- result.push(blob.name);
321
- }
322
- return result;
323
- }
324
- // Check existence
325
- async blobExists(blobName) {
326
- const blobClient = this.containerClient.getBlobClient(blobName);
327
- return blobClient.exists();
328
- }
329
- // Generate temporary read-only SAS URL
330
- async generateSasUrl(blobName, expiresInMinutes = 60) {
331
- const blobClient = this.containerClient.getBlobClient(blobName);
332
- const sasToken = storageBlob.generateBlobSASQueryParameters(
333
- {
334
- containerName: this.containerName,
335
- blobName: blobClient.name,
336
- expiresOn: new Date(Date.now() + expiresInMinutes * 60 * 1e3),
337
- permissions: storageBlob.BlobSASPermissions.parse("r")
338
- // read-only
339
- },
340
- this.sharedKeyCredential
341
- ).toString();
342
- return `${blobClient.url}?${sasToken}`;
343
- }
344
- };
345
- var cloudinary = cloudinaryModule__default.default.v2;
346
- var CloudinaryService = class {
347
- rootFolder;
348
- constructor(config) {
349
- const { cloudName, apiKey, apiSecret, rootFolder } = config;
350
- cloudinary.config({
351
- cloud_name: cloudName,
352
- api_key: apiKey,
353
- api_secret: apiSecret,
354
- secure: true
355
- });
356
- this.rootFolder = rootFolder;
357
- }
358
- // Upload file to Cloudinary
359
- async uploadFile(filePath, options = {}) {
360
- if (!fs__default.default.existsSync(filePath)) {
361
- throw new Error(`File not found: ${filePath}`);
362
- }
363
- const folderPath = this.buildFolderPath(options.folder);
364
- const result = await cloudinary.uploader.upload(filePath, {
365
- folder: folderPath,
366
- public_id: options.publicId,
367
- resource_type: options.resourceType || "auto"
368
- });
369
- return result.public_id;
370
- }
371
- // Delete asset by public ID
372
- async deleteFile(publicId) {
373
- const result = await cloudinary.uploader.destroy(publicId);
374
- return result.result === "ok";
375
- }
376
- // Check if asset exists
377
- async fileExists(publicId) {
378
- try {
379
- await cloudinary.api.resource(publicId);
380
- return true;
381
- } catch {
382
- return false;
383
- }
384
- }
385
- // Generate optimized delivery URL
386
- generateUrl(publicId, options = {}) {
387
- return cloudinary.url(publicId, {
388
- secure: true,
389
- ...options
390
- });
391
- }
392
- // Create folder (idempotent)
393
- async createFolder(folder) {
394
- try {
395
- await cloudinary.api.create_folder(folder);
396
- } catch (err) {
397
- }
398
- }
399
- buildFolderPath(subFolder) {
400
- if (!this.rootFolder && !subFolder) return void 0;
401
- if (this.rootFolder && subFolder) {
402
- return `${this.rootFolder}/${subFolder}`;
403
- }
404
- return this.rootFolder || subFolder;
405
- }
406
- };
407
255
 
408
256
  // src/utils/errorToString.ts
409
257
  function errorToString(error) {
@@ -5297,6 +5145,160 @@ var validate = (schema) => (req, _res, next) => {
5297
5145
  }
5298
5146
  next();
5299
5147
  };
5148
+ var AzureBlobStorageService = class {
5149
+ containerName;
5150
+ blobServiceClient;
5151
+ containerClient;
5152
+ sharedKeyCredential;
5153
+ constructor(config) {
5154
+ const { connectionString, accountName, accountKey, containerName } = config;
5155
+ this.containerName = containerName;
5156
+ this.blobServiceClient = storageBlob.BlobServiceClient.fromConnectionString(connectionString);
5157
+ this.containerClient = this.blobServiceClient.getContainerClient(containerName);
5158
+ this.sharedKeyCredential = new storageBlob.StorageSharedKeyCredential(
5159
+ accountName,
5160
+ accountKey
5161
+ );
5162
+ }
5163
+ // Upload file
5164
+ async uploadFile(localPath, blobName, onProgress) {
5165
+ const blockBlobClient = this.containerClient.getBlockBlobClient(blobName);
5166
+ const fileSize = fs__default.default.statSync(localPath).size;
5167
+ const readStream = fs__default.default.createReadStream(localPath);
5168
+ await blockBlobClient.uploadStream(
5169
+ readStream,
5170
+ 4 * 1024 * 1024,
5171
+ // buffer size
5172
+ 20,
5173
+ // max concurrency
5174
+ {
5175
+ onProgress: (ev) => {
5176
+ if (onProgress) {
5177
+ const percent = (ev.loadedBytes / fileSize * 100).toFixed(2);
5178
+ onProgress(percent);
5179
+ }
5180
+ }
5181
+ }
5182
+ );
5183
+ return blockBlobClient.url;
5184
+ }
5185
+ // Download file
5186
+ async downloadFile(blobName, downloadPath, onProgress) {
5187
+ const blobClient = this.containerClient.getBlobClient(blobName);
5188
+ const response = await blobClient.download();
5189
+ const fileSize = response.contentLength || 0;
5190
+ let downloaded = 0;
5191
+ return new Promise((resolve, reject) => {
5192
+ const writable = fs__default.default.createWriteStream(downloadPath);
5193
+ response.readableStreamBody?.on("data", (chunk) => {
5194
+ downloaded += chunk.length;
5195
+ if (onProgress && fileSize > 0) {
5196
+ const percent = (downloaded / fileSize * 100).toFixed(2);
5197
+ onProgress(percent);
5198
+ }
5199
+ });
5200
+ response.readableStreamBody?.pipe(writable);
5201
+ writable.on("finish", resolve);
5202
+ writable.on("error", reject);
5203
+ });
5204
+ }
5205
+ // Delete file
5206
+ async deleteFile(blobName) {
5207
+ const blobClient = this.containerClient.getBlobClient(blobName);
5208
+ await blobClient.deleteIfExists();
5209
+ return true;
5210
+ }
5211
+ // List blobs
5212
+ async listFiles(prefix = "") {
5213
+ const result = [];
5214
+ for await (const blob of this.containerClient.listBlobsFlat({ prefix })) {
5215
+ result.push(blob.name);
5216
+ }
5217
+ return result;
5218
+ }
5219
+ // Check existence
5220
+ async blobExists(blobName) {
5221
+ const blobClient = this.containerClient.getBlobClient(blobName);
5222
+ return blobClient.exists();
5223
+ }
5224
+ // Generate temporary read-only SAS URL
5225
+ async generateSasUrl(blobName, expiresInMinutes = 60) {
5226
+ const blobClient = this.containerClient.getBlobClient(blobName);
5227
+ const sasToken = storageBlob.generateBlobSASQueryParameters(
5228
+ {
5229
+ containerName: this.containerName,
5230
+ blobName: blobClient.name,
5231
+ expiresOn: new Date(Date.now() + expiresInMinutes * 60 * 1e3),
5232
+ permissions: storageBlob.BlobSASPermissions.parse("r")
5233
+ // read-only
5234
+ },
5235
+ this.sharedKeyCredential
5236
+ ).toString();
5237
+ return `${blobClient.url}?${sasToken}`;
5238
+ }
5239
+ };
5240
+ var cloudinary = cloudinaryModule__default.default.v2;
5241
+ var CloudinaryService = class {
5242
+ rootFolder;
5243
+ constructor(config) {
5244
+ const { cloudName, apiKey, apiSecret, rootFolder } = config;
5245
+ cloudinary.config({
5246
+ cloud_name: cloudName,
5247
+ api_key: apiKey,
5248
+ api_secret: apiSecret,
5249
+ secure: true
5250
+ });
5251
+ this.rootFolder = rootFolder;
5252
+ }
5253
+ // Upload file to Cloudinary
5254
+ async uploadFile(filePath, options = {}) {
5255
+ if (!fs__default.default.existsSync(filePath)) {
5256
+ throw new Error(`File not found: ${filePath}`);
5257
+ }
5258
+ const folderPath = this.buildFolderPath(options.folder);
5259
+ const result = await cloudinary.uploader.upload(filePath, {
5260
+ folder: folderPath,
5261
+ public_id: options.publicId,
5262
+ resource_type: options.resourceType || "auto"
5263
+ });
5264
+ return result.public_id;
5265
+ }
5266
+ // Delete asset by public ID
5267
+ async deleteFile(publicId) {
5268
+ const result = await cloudinary.uploader.destroy(publicId);
5269
+ return result.result === "ok";
5270
+ }
5271
+ // Check if asset exists
5272
+ async fileExists(publicId) {
5273
+ try {
5274
+ await cloudinary.api.resource(publicId);
5275
+ return true;
5276
+ } catch {
5277
+ return false;
5278
+ }
5279
+ }
5280
+ // Generate optimized delivery URL
5281
+ generateUrl(publicId, options = {}) {
5282
+ return cloudinary.url(publicId, {
5283
+ secure: true,
5284
+ ...options
5285
+ });
5286
+ }
5287
+ // Create folder (idempotent)
5288
+ async createFolder(folder) {
5289
+ try {
5290
+ await cloudinary.api.create_folder(folder);
5291
+ } catch (err) {
5292
+ }
5293
+ }
5294
+ buildFolderPath(subFolder) {
5295
+ if (!this.rootFolder && !subFolder) return void 0;
5296
+ if (this.rootFolder && subFolder) {
5297
+ return `${this.rootFolder}/${subFolder}`;
5298
+ }
5299
+ return this.rootFolder || subFolder;
5300
+ }
5301
+ };
5300
5302
  var JWTService = class {
5301
5303
  accessSecret;
5302
5304
  refreshSecret;
@@ -5412,6 +5414,61 @@ var JWTService = class {
5412
5414
  return value;
5413
5415
  }
5414
5416
  };
5417
+ var MulterFileHandlerService = class {
5418
+ storage;
5419
+ options;
5420
+ constructor(options = {}) {
5421
+ this.options = options;
5422
+ this.storage = options.storage === "memory" ? multer__default.default.memoryStorage() : multer__default.default.diskStorage({});
5423
+ }
5424
+ // File Filter
5425
+ fileFilter = (req, file, cb) => {
5426
+ const { allowedMimeTypes, allowedExtensions } = this.options;
5427
+ const mimeType = file.mimetype;
5428
+ const extFromMime = mimeType.split("/")[1]?.toLowerCase();
5429
+ if (allowedMimeTypes?.length) {
5430
+ if (!allowedMimeTypes.includes(mimeType)) {
5431
+ return cb(
5432
+ new AppError(
5433
+ `Invalid file type! Allowed: ${allowedMimeTypes.join(", ")}`,
5434
+ 400
5435
+ ),
5436
+ false
5437
+ );
5438
+ }
5439
+ }
5440
+ if (allowedExtensions?.length) {
5441
+ if (!extFromMime || !allowedExtensions.includes(extFromMime)) {
5442
+ return cb(
5443
+ new AppError(
5444
+ `Invalid file extension! Allowed: ${allowedExtensions.join(", ")}`,
5445
+ 400
5446
+ ),
5447
+ false
5448
+ );
5449
+ }
5450
+ }
5451
+ cb(null, true);
5452
+ };
5453
+ // Build multer instance
5454
+ buildUploader() {
5455
+ return multer__default.default({
5456
+ storage: this.storage,
5457
+ fileFilter: this.fileFilter,
5458
+ limits: this.options.fileSizeLimit ? { fileSize: this.options.fileSizeLimit } : void 0
5459
+ });
5460
+ }
5461
+ // Public API
5462
+ single(fieldName) {
5463
+ return this.buildUploader().single(fieldName);
5464
+ }
5465
+ array(fieldName, maxCount) {
5466
+ return this.buildUploader().array(fieldName, maxCount);
5467
+ }
5468
+ fields(fields) {
5469
+ return this.buildUploader().fields(fields);
5470
+ }
5471
+ };
5415
5472
 
5416
5473
  // src/utils/time.ts
5417
5474
  function milliseconds(value) {
@@ -5449,7 +5506,7 @@ exports.AVLTree = AVLTree;
5449
5506
  exports.AdjacencyList = AdjacencyList;
5450
5507
  exports.AdjacencyMatrix = AdjacencyMatrix;
5451
5508
  exports.AppError = AppError;
5452
- exports.AzureBlobService = AzureBlobService;
5509
+ exports.AzureBlobStorageService = AzureBlobStorageService;
5453
5510
  exports.BPlusTree = BPlusTree;
5454
5511
  exports.BTree = BTree;
5455
5512
  exports.BinaryHeap = BinaryHeap;
@@ -5484,6 +5541,7 @@ exports.MaxHeap = MaxHeap;
5484
5541
  exports.MaxStack = MaxStack;
5485
5542
  exports.MinHeap = MinHeap;
5486
5543
  exports.MinStack = MinStack;
5544
+ exports.MulterFileHandlerService = MulterFileHandlerService;
5487
5545
  exports.MultiSet = MultiSet;
5488
5546
  exports.Node = Node;
5489
5547
  exports.OrderedSet = OrderedSet;