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 CHANGED
@@ -1,18 +1,18 @@
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
9
 
10
10
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
11
 
12
- var fs__default = /*#__PURE__*/_interopDefault(fs);
13
- var cloudinaryModule__default = /*#__PURE__*/_interopDefault(cloudinaryModule);
14
12
  var mongoose__default = /*#__PURE__*/_interopDefault(mongoose);
15
13
  var dotenv__default = /*#__PURE__*/_interopDefault(dotenv);
14
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
15
+ var cloudinaryModule__default = /*#__PURE__*/_interopDefault(cloudinaryModule);
16
16
  var jwt__default = /*#__PURE__*/_interopDefault(jwt);
17
17
 
18
18
  // src/errors/appError.ts
@@ -250,160 +250,6 @@ function pickFields(obj, fields, options = {}) {
250
250
  }
251
251
  return result;
252
252
  }
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
253
 
408
254
  // src/utils/errorToString.ts
409
255
  function errorToString(error) {
@@ -5297,6 +5143,160 @@ var validate = (schema) => (req, _res, next) => {
5297
5143
  }
5298
5144
  next();
5299
5145
  };
5146
+ var AzureBlobStorageService = class {
5147
+ containerName;
5148
+ blobServiceClient;
5149
+ containerClient;
5150
+ sharedKeyCredential;
5151
+ constructor(config) {
5152
+ const { connectionString, accountName, accountKey, containerName } = config;
5153
+ this.containerName = containerName;
5154
+ this.blobServiceClient = storageBlob.BlobServiceClient.fromConnectionString(connectionString);
5155
+ this.containerClient = this.blobServiceClient.getContainerClient(containerName);
5156
+ this.sharedKeyCredential = new storageBlob.StorageSharedKeyCredential(
5157
+ accountName,
5158
+ accountKey
5159
+ );
5160
+ }
5161
+ // Upload file
5162
+ async uploadFile(localPath, blobName, onProgress) {
5163
+ const blockBlobClient = this.containerClient.getBlockBlobClient(blobName);
5164
+ const fileSize = fs__default.default.statSync(localPath).size;
5165
+ const readStream = fs__default.default.createReadStream(localPath);
5166
+ await blockBlobClient.uploadStream(
5167
+ readStream,
5168
+ 4 * 1024 * 1024,
5169
+ // buffer size
5170
+ 20,
5171
+ // max concurrency
5172
+ {
5173
+ onProgress: (ev) => {
5174
+ if (onProgress) {
5175
+ const percent = (ev.loadedBytes / fileSize * 100).toFixed(2);
5176
+ onProgress(percent);
5177
+ }
5178
+ }
5179
+ }
5180
+ );
5181
+ return blockBlobClient.url;
5182
+ }
5183
+ // Download file
5184
+ async downloadFile(blobName, downloadPath, onProgress) {
5185
+ const blobClient = this.containerClient.getBlobClient(blobName);
5186
+ const response = await blobClient.download();
5187
+ const fileSize = response.contentLength || 0;
5188
+ let downloaded = 0;
5189
+ return new Promise((resolve, reject) => {
5190
+ const writable = fs__default.default.createWriteStream(downloadPath);
5191
+ response.readableStreamBody?.on("data", (chunk) => {
5192
+ downloaded += chunk.length;
5193
+ if (onProgress && fileSize > 0) {
5194
+ const percent = (downloaded / fileSize * 100).toFixed(2);
5195
+ onProgress(percent);
5196
+ }
5197
+ });
5198
+ response.readableStreamBody?.pipe(writable);
5199
+ writable.on("finish", resolve);
5200
+ writable.on("error", reject);
5201
+ });
5202
+ }
5203
+ // Delete file
5204
+ async deleteFile(blobName) {
5205
+ const blobClient = this.containerClient.getBlobClient(blobName);
5206
+ await blobClient.deleteIfExists();
5207
+ return true;
5208
+ }
5209
+ // List blobs
5210
+ async listFiles(prefix = "") {
5211
+ const result = [];
5212
+ for await (const blob of this.containerClient.listBlobsFlat({ prefix })) {
5213
+ result.push(blob.name);
5214
+ }
5215
+ return result;
5216
+ }
5217
+ // Check existence
5218
+ async blobExists(blobName) {
5219
+ const blobClient = this.containerClient.getBlobClient(blobName);
5220
+ return blobClient.exists();
5221
+ }
5222
+ // Generate temporary read-only SAS URL
5223
+ async generateSasUrl(blobName, expiresInMinutes = 60) {
5224
+ const blobClient = this.containerClient.getBlobClient(blobName);
5225
+ const sasToken = storageBlob.generateBlobSASQueryParameters(
5226
+ {
5227
+ containerName: this.containerName,
5228
+ blobName: blobClient.name,
5229
+ expiresOn: new Date(Date.now() + expiresInMinutes * 60 * 1e3),
5230
+ permissions: storageBlob.BlobSASPermissions.parse("r")
5231
+ // read-only
5232
+ },
5233
+ this.sharedKeyCredential
5234
+ ).toString();
5235
+ return `${blobClient.url}?${sasToken}`;
5236
+ }
5237
+ };
5238
+ var cloudinary = cloudinaryModule__default.default.v2;
5239
+ var CloudinaryService = class {
5240
+ rootFolder;
5241
+ constructor(config) {
5242
+ const { cloudName, apiKey, apiSecret, rootFolder } = config;
5243
+ cloudinary.config({
5244
+ cloud_name: cloudName,
5245
+ api_key: apiKey,
5246
+ api_secret: apiSecret,
5247
+ secure: true
5248
+ });
5249
+ this.rootFolder = rootFolder;
5250
+ }
5251
+ // Upload file to Cloudinary
5252
+ async uploadFile(filePath, options = {}) {
5253
+ if (!fs__default.default.existsSync(filePath)) {
5254
+ throw new Error(`File not found: ${filePath}`);
5255
+ }
5256
+ const folderPath = this.buildFolderPath(options.folder);
5257
+ const result = await cloudinary.uploader.upload(filePath, {
5258
+ folder: folderPath,
5259
+ public_id: options.publicId,
5260
+ resource_type: options.resourceType || "auto"
5261
+ });
5262
+ return result.public_id;
5263
+ }
5264
+ // Delete asset by public ID
5265
+ async deleteFile(publicId) {
5266
+ const result = await cloudinary.uploader.destroy(publicId);
5267
+ return result.result === "ok";
5268
+ }
5269
+ // Check if asset exists
5270
+ async fileExists(publicId) {
5271
+ try {
5272
+ await cloudinary.api.resource(publicId);
5273
+ return true;
5274
+ } catch {
5275
+ return false;
5276
+ }
5277
+ }
5278
+ // Generate optimized delivery URL
5279
+ generateUrl(publicId, options = {}) {
5280
+ return cloudinary.url(publicId, {
5281
+ secure: true,
5282
+ ...options
5283
+ });
5284
+ }
5285
+ // Create folder (idempotent)
5286
+ async createFolder(folder) {
5287
+ try {
5288
+ await cloudinary.api.create_folder(folder);
5289
+ } catch (err) {
5290
+ }
5291
+ }
5292
+ buildFolderPath(subFolder) {
5293
+ if (!this.rootFolder && !subFolder) return void 0;
5294
+ if (this.rootFolder && subFolder) {
5295
+ return `${this.rootFolder}/${subFolder}`;
5296
+ }
5297
+ return this.rootFolder || subFolder;
5298
+ }
5299
+ };
5300
5300
  var JWTService = class {
5301
5301
  accessSecret;
5302
5302
  refreshSecret;
@@ -5307,8 +5307,8 @@ var JWTService = class {
5307
5307
  constructor(options) {
5308
5308
  this.accessSecret = options.accessSecret;
5309
5309
  this.refreshSecret = options.refreshSecret;
5310
- this.accessExpires = options.accessExpires || "15m";
5311
- this.refreshExpires = options.refreshExpires || "30d";
5310
+ this.accessExpires = this.parseExpires(options.accessExpires, "15m");
5311
+ this.refreshExpires = this.parseExpires(options.refreshExpires, "30d");
5312
5312
  this.nodeEnv = options.nodeEnv || "development";
5313
5313
  this.refreshCookieName = options.refreshCookieName || "refreshJwt";
5314
5314
  }
@@ -5348,14 +5348,18 @@ var JWTService = class {
5348
5348
  // Token Extraction
5349
5349
  // ---------------------------------
5350
5350
  extractToken(req) {
5351
+ let token = null;
5351
5352
  if (req.headers.authorization?.startsWith("Bearer ")) {
5352
- return req.headers.authorization.split(" ")[1];
5353
+ token = req.headers.authorization.split(" ")[1];
5354
+ return token ? this.normalizeToken(token) : null;
5353
5355
  }
5354
5356
  if (req.cookies?.[this.refreshCookieName]) {
5355
- return req.cookies[this.refreshCookieName];
5357
+ token = req.cookies[this.refreshCookieName];
5358
+ return token ? this.normalizeToken(token) : null;
5356
5359
  }
5357
5360
  if (req.cookies?.jwt) {
5358
- return req.cookies.jwt;
5361
+ token = req.cookies.jwt;
5362
+ return token ? this.normalizeToken(token) : null;
5359
5363
  }
5360
5364
  return null;
5361
5365
  }
@@ -5388,6 +5392,25 @@ var JWTService = class {
5388
5392
  this.setRefreshTokenCookie(res, refreshToken);
5389
5393
  return accessToken;
5390
5394
  }
5395
+ // ---------------------------------
5396
+ // Internal Helpers
5397
+ // ---------------------------------
5398
+ normalizeToken(token) {
5399
+ token = token.trim();
5400
+ if (token.startsWith('"') && token.endsWith('"')) {
5401
+ try {
5402
+ return JSON.parse(token);
5403
+ } catch {
5404
+ return token.slice(1, -1);
5405
+ }
5406
+ }
5407
+ return token;
5408
+ }
5409
+ parseExpires(value, fallback) {
5410
+ if (!value) return fallback;
5411
+ if (typeof value === "number") return value;
5412
+ return value;
5413
+ }
5391
5414
  };
5392
5415
 
5393
5416
  // src/utils/time.ts
@@ -5426,7 +5449,7 @@ exports.AVLTree = AVLTree;
5426
5449
  exports.AdjacencyList = AdjacencyList;
5427
5450
  exports.AdjacencyMatrix = AdjacencyMatrix;
5428
5451
  exports.AppError = AppError;
5429
- exports.AzureBlobService = AzureBlobService;
5452
+ exports.AzureBlobStorageService = AzureBlobStorageService;
5430
5453
  exports.BPlusTree = BPlusTree;
5431
5454
  exports.BTree = BTree;
5432
5455
  exports.BinaryHeap = BinaryHeap;