elseware-nodejs 1.9.0 → 1.10.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/README.md CHANGED
@@ -1 +1 @@
1
- # elseware-nodejs
1
+ # elseware-nodejs
package/dist/index.cjs CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  var dotenv = require('dotenv');
4
4
  var mongoose = require('mongoose');
5
+ var crypto = require('crypto');
6
+ var async_hooks = require('async_hooks');
5
7
  var storageBlob = require('@azure/storage-blob');
6
8
  var fs3 = require('fs');
7
9
  var cloudinaryModule = require('cloudinary');
@@ -1919,7 +1921,6 @@ var CircularQueue = class {
1919
1921
  }
1920
1922
  this.data = new Array(capacity);
1921
1923
  }
1922
- capacity;
1923
1924
  data;
1924
1925
  head = 0;
1925
1926
  tail = 0;
@@ -4848,8 +4849,6 @@ var DatabaseManager = class {
4848
4849
  this.provider = provider;
4849
4850
  this.options = options;
4850
4851
  }
4851
- provider;
4852
- options;
4853
4852
  async connect() {
4854
4853
  try {
4855
4854
  await this.provider.connect();
@@ -4892,7 +4891,6 @@ var MongoDatabaseProvider = class {
4892
4891
  constructor(config) {
4893
4892
  this.config = config;
4894
4893
  }
4895
- config;
4896
4894
  async connect() {
4897
4895
  mongoose__default.default.set("strictQuery", this.config.strictQuery ?? true);
4898
4896
  await mongoose__default.default.connect(this.config.uri);
@@ -5323,7 +5321,6 @@ var JoiValidator = class {
5323
5321
  constructor(schema) {
5324
5322
  this.schema = schema;
5325
5323
  }
5326
- schema;
5327
5324
  validate(data) {
5328
5325
  const result = this.schema.validate(data, {
5329
5326
  abortEarly: false,
@@ -5352,7 +5349,6 @@ var ZodValidator = class {
5352
5349
  constructor(schema) {
5353
5350
  this.schema = schema;
5354
5351
  }
5355
- schema;
5356
5352
  validate(data) {
5357
5353
  const result = this.schema.safeParse(data);
5358
5354
  if (!result.success) {
@@ -5430,6 +5426,255 @@ function pickFields(obj, fields, options = {}) {
5430
5426
  }
5431
5427
  return result;
5432
5428
  }
5429
+ var CorrelationId = class {
5430
+ static generate() {
5431
+ return crypto.randomUUID();
5432
+ }
5433
+ };
5434
+ var RequestContext = class {
5435
+ static storage = new async_hooks.AsyncLocalStorage();
5436
+ static run(context, callback) {
5437
+ return this.storage.run(context, callback);
5438
+ }
5439
+ static get() {
5440
+ return this.storage.getStore();
5441
+ }
5442
+ static getCorrelationId() {
5443
+ return this.get()?.correlationId;
5444
+ }
5445
+ static getRequestId() {
5446
+ return this.get()?.requestId;
5447
+ }
5448
+ static getUserId() {
5449
+ return this.get()?.userId;
5450
+ }
5451
+ static getTenantId() {
5452
+ return this.get()?.tenantId;
5453
+ }
5454
+ };
5455
+
5456
+ // src/networking/observability/TracingHeaders.ts
5457
+ var TracingHeaders = class {
5458
+ static build() {
5459
+ const headers = {};
5460
+ const correlationId = RequestContext.getCorrelationId();
5461
+ const requestId = RequestContext.getRequestId();
5462
+ const userId = RequestContext.getUserId();
5463
+ const tenantId = RequestContext.getTenantId();
5464
+ if (correlationId) {
5465
+ headers["X-Correlation-Id"] = correlationId;
5466
+ }
5467
+ if (requestId) {
5468
+ headers["X-Request-Id"] = requestId;
5469
+ }
5470
+ if (userId) {
5471
+ headers["X-User-Id"] = userId;
5472
+ }
5473
+ if (tenantId) {
5474
+ headers["X-Tenant-Id"] = tenantId;
5475
+ }
5476
+ return headers;
5477
+ }
5478
+ };
5479
+
5480
+ // src/networking/resilience/ExponentialBackoffRetryPolicy.ts
5481
+ var ExponentialBackoffRetryPolicy = class {
5482
+ retries;
5483
+ baseDelay;
5484
+ maxDelay;
5485
+ constructor(options = {}) {
5486
+ this.retries = options.retries ?? 5;
5487
+ this.baseDelay = options.baseDelay ?? 200;
5488
+ this.maxDelay = options.maxDelay ?? 1e4;
5489
+ }
5490
+ shouldRetry(attempt) {
5491
+ return attempt < this.retries;
5492
+ }
5493
+ getDelay(attempt) {
5494
+ const delay = this.baseDelay * Math.pow(2, attempt);
5495
+ return Math.min(delay, this.maxDelay);
5496
+ }
5497
+ };
5498
+
5499
+ // src/networking/resilience/FixedRetryPolicy.ts
5500
+ var FixedRetryPolicy = class {
5501
+ retries;
5502
+ delay;
5503
+ constructor(options = {}) {
5504
+ this.retries = options.retries ?? 2;
5505
+ this.delay = options.delay ?? 500;
5506
+ }
5507
+ shouldRetry(attempt) {
5508
+ return attempt < this.retries;
5509
+ }
5510
+ getDelay(_attempt, _error) {
5511
+ return this.delay;
5512
+ }
5513
+ };
5514
+
5515
+ // src/networking/security/BearerTokenStrategy.ts
5516
+ var BearerTokenStrategy = class {
5517
+ constructor(tokenProvider) {
5518
+ this.tokenProvider = tokenProvider;
5519
+ }
5520
+ async getHeaders() {
5521
+ const token = await this.tokenProvider.getToken();
5522
+ return {
5523
+ Authorization: `Bearer ${token}`
5524
+ };
5525
+ }
5526
+ };
5527
+
5528
+ // src/networking/security/StaticTokenProvider.ts
5529
+ var StaticTokenProvider = class {
5530
+ constructor(token) {
5531
+ this.token = token;
5532
+ }
5533
+ getToken() {
5534
+ return this.token;
5535
+ }
5536
+ };
5537
+
5538
+ // src/networking/transport/HttpClient.ts
5539
+ var HttpClient = class {
5540
+ baseUrl;
5541
+ timeout;
5542
+ headers;
5543
+ serviceName;
5544
+ authStrategy;
5545
+ retryPolicy;
5546
+ constructor(baseUrl, options = {}) {
5547
+ this.baseUrl = baseUrl;
5548
+ this.timeout = options.timeout ?? 5e3;
5549
+ this.headers = options.headers ?? {};
5550
+ this.serviceName = options.serviceName ?? "UnknownService";
5551
+ this.authStrategy = options.authStrategy;
5552
+ this.retryPolicy = options.retryPolicy ?? new FixedRetryPolicy({
5553
+ retries: 2,
5554
+ delay: 500
5555
+ });
5556
+ }
5557
+ async get(path2) {
5558
+ return this.request("GET", path2);
5559
+ }
5560
+ async post(path2, body) {
5561
+ return this.request("POST", path2, body);
5562
+ }
5563
+ async put(path2, body) {
5564
+ return this.request("PUT", path2, body);
5565
+ }
5566
+ async patch(path2, body) {
5567
+ return this.request("PATCH", path2, body);
5568
+ }
5569
+ async delete(path2) {
5570
+ return this.request("DELETE", path2);
5571
+ }
5572
+ async request(method, path2, body) {
5573
+ let attempt = 0;
5574
+ let lastError;
5575
+ while (true) {
5576
+ try {
5577
+ const controller = new AbortController();
5578
+ const timeout = setTimeout(() => controller.abort(), this.timeout);
5579
+ const authHeaders = await this.authStrategy?.getHeaders();
5580
+ const response = await fetch(`${this.baseUrl}${path2}`, {
5581
+ method,
5582
+ signal: controller.signal,
5583
+ headers: {
5584
+ "Content-Type": "application/json",
5585
+ ...TracingHeaders.build(),
5586
+ ...this.headers,
5587
+ ...authHeaders
5588
+ },
5589
+ body: body !== void 0 ? JSON.stringify(body) : void 0
5590
+ });
5591
+ clearTimeout(timeout);
5592
+ const json = await response.json();
5593
+ if (!response.ok) {
5594
+ throw new AppError(
5595
+ json?.message ?? "HTTP request failed",
5596
+ response.status,
5597
+ {
5598
+ code: json?.code ?? "HTTP_REQUEST_FAILED",
5599
+ details: {
5600
+ service: this.serviceName,
5601
+ method,
5602
+ path: path2
5603
+ }
5604
+ }
5605
+ );
5606
+ }
5607
+ const correlationId2 = RequestContext.getCorrelationId();
5608
+ logger.info(
5609
+ `[${this.serviceName}]` + (correlationId2 ? ` [${correlationId2}]` : "") + ` ${method} ${path2}`
5610
+ );
5611
+ return json;
5612
+ } catch (error) {
5613
+ lastError = error;
5614
+ if (this.retryPolicy.shouldRetry(attempt, error)) {
5615
+ const delay = this.retryPolicy.getDelay(attempt, error);
5616
+ logger.warning(
5617
+ `[${this.serviceName}] retry ${attempt + 1} after ${delay}ms`
5618
+ );
5619
+ await this.sleep(delay);
5620
+ attempt++;
5621
+ continue;
5622
+ }
5623
+ break;
5624
+ }
5625
+ }
5626
+ const correlationId = RequestContext.getCorrelationId();
5627
+ logger.danger(
5628
+ `[${this.serviceName}]` + (correlationId ? ` [${correlationId}]` : "") + ` request failed`,
5629
+ lastError
5630
+ );
5631
+ throw lastError;
5632
+ }
5633
+ sleep(ms) {
5634
+ return new Promise((resolve) => setTimeout(resolve, ms));
5635
+ }
5636
+ };
5637
+
5638
+ // src/networking/services/ServiceClient.ts
5639
+ var ServiceClient = class extends HttpClient {
5640
+ async getData(path2) {
5641
+ const response = await super.get(path2);
5642
+ return response.data;
5643
+ }
5644
+ async postData(path2, body) {
5645
+ const response = await super.post(path2, body);
5646
+ return response.data;
5647
+ }
5648
+ async putData(path2, body) {
5649
+ const response = await super.put(path2, body);
5650
+ return response.data;
5651
+ }
5652
+ async patchData(path2, body) {
5653
+ const response = await super.patch(path2, body);
5654
+ return response.data;
5655
+ }
5656
+ async deleteData(path2) {
5657
+ const response = await super.delete(path2);
5658
+ return response.data;
5659
+ }
5660
+ };
5661
+
5662
+ // src/networking/services/InternalServiceClient.ts
5663
+ var InternalServiceClient = class extends ServiceClient {
5664
+ constructor(baseUrl, serviceToken, serviceName) {
5665
+ super(baseUrl, {
5666
+ serviceName,
5667
+ authStrategy: new BearerTokenStrategy(
5668
+ new StaticTokenProvider(serviceToken)
5669
+ ),
5670
+ timeout: 5e3,
5671
+ retryPolicy: new ExponentialBackoffRetryPolicy({
5672
+ retries: 3,
5673
+ baseDelay: 200
5674
+ })
5675
+ });
5676
+ }
5677
+ };
5433
5678
 
5434
5679
  // src/repositories/providers/MongoRepository.ts
5435
5680
  var MongoRepository = class {
@@ -5438,7 +5683,9 @@ var MongoRepository = class {
5438
5683
  this.model = model;
5439
5684
  }
5440
5685
  buildSelect(select) {
5441
- if (!select) return void 0;
5686
+ if (!select) {
5687
+ return void 0;
5688
+ }
5442
5689
  if (Array.isArray(select)) {
5443
5690
  return select.join(" ");
5444
5691
  }
@@ -5446,14 +5693,22 @@ var MongoRepository = class {
5446
5693
  }
5447
5694
  applyQueryOptions(query, options) {
5448
5695
  const select = this.buildSelect(options.select);
5449
- if (select) query = query.select(select);
5450
- if (options.sort) query = query.sort(options.sort);
5451
- if (options.limit) query = query.limit(options.limit);
5452
- if (options.skip) query = query.skip(options.skip);
5696
+ if (select) {
5697
+ query = query.select(select);
5698
+ }
5699
+ if (options.sort) {
5700
+ query = query.sort(options.sort);
5701
+ }
5702
+ if (options.limit) {
5703
+ query = query.limit(options.limit);
5704
+ }
5705
+ if (options.skip) {
5706
+ query = query.skip(options.skip);
5707
+ }
5453
5708
  if (options.populate) {
5454
5709
  if (Array.isArray(options.populate)) {
5455
- options.populate.forEach((p) => {
5456
- query = query.populate(p);
5710
+ options.populate.forEach((item) => {
5711
+ query = query.populate(item);
5457
5712
  });
5458
5713
  } else {
5459
5714
  query = query.populate(options.populate);
@@ -5462,7 +5717,13 @@ var MongoRepository = class {
5462
5717
  return query;
5463
5718
  }
5464
5719
  toPlain(doc) {
5465
- return doc.toObject();
5720
+ if (!doc) {
5721
+ return doc;
5722
+ }
5723
+ return typeof doc.toObject === "function" ? doc.toObject() : doc;
5724
+ }
5725
+ toPlainArray(docs) {
5726
+ return docs.map((doc) => this.toPlain(doc));
5466
5727
  }
5467
5728
  /**
5468
5729
  * Create
@@ -5473,7 +5734,7 @@ var MongoRepository = class {
5473
5734
  }
5474
5735
  async createMany(data) {
5475
5736
  const docs = await this.model.insertMany(data);
5476
- return docs.map((doc) => this.toPlain(doc));
5737
+ return this.toPlainArray(docs);
5477
5738
  }
5478
5739
  /**
5479
5740
  * Read
@@ -5481,22 +5742,26 @@ var MongoRepository = class {
5481
5742
  async findAll(filter = {}, options = {}) {
5482
5743
  let query = this.model.find(filter);
5483
5744
  query = this.applyQueryOptions(query, options);
5484
- return query.exec();
5745
+ return query.lean().exec();
5485
5746
  }
5486
5747
  async findById(id, options = {}) {
5487
5748
  let query = this.model.findById(id);
5488
5749
  query = this.applyQueryOptions(query, options);
5489
- return query.exec();
5750
+ return query.lean().exec();
5490
5751
  }
5491
5752
  async findOne(filter = {}, options = {}) {
5492
5753
  let query = this.model.findOne(filter);
5493
5754
  query = this.applyQueryOptions(query, options);
5494
- return query.exec();
5755
+ return query.lean().exec();
5495
5756
  }
5496
5757
  async findManyByIds(ids, options = {}) {
5497
- let query = this.model.find({ _id: { $in: ids } });
5758
+ let query = this.model.find({
5759
+ _id: {
5760
+ $in: ids
5761
+ }
5762
+ });
5498
5763
  query = this.applyQueryOptions(query, options);
5499
- return query.exec();
5764
+ return query.lean().exec();
5500
5765
  }
5501
5766
  async count(filter) {
5502
5767
  return this.model.countDocuments(filter).exec();
@@ -5509,12 +5774,22 @@ var MongoRepository = class {
5509
5774
  * Update
5510
5775
  */
5511
5776
  async updateById(id, data, options) {
5512
- const finalOptions = { new: true, runValidators: true, ...options };
5513
- return this.model.findByIdAndUpdate(id, data, finalOptions).exec();
5777
+ const finalOptions = {
5778
+ new: true,
5779
+ runValidators: true,
5780
+ ...options
5781
+ };
5782
+ const doc = await this.model.findByIdAndUpdate(id, data, finalOptions).exec();
5783
+ return doc ? this.toPlain(doc) : null;
5514
5784
  }
5515
5785
  async updateOne(filter, data, options) {
5516
- const finalOptions = { new: true, runValidators: true, ...options };
5517
- return this.model.findOneAndUpdate(filter, data, finalOptions).exec();
5786
+ const finalOptions = {
5787
+ new: true,
5788
+ runValidators: true,
5789
+ ...options
5790
+ };
5791
+ const doc = await this.model.findOneAndUpdate(filter, data, finalOptions).exec();
5792
+ return doc ? this.toPlain(doc) : null;
5518
5793
  }
5519
5794
  async updateMany(filter, data) {
5520
5795
  const result = await this.model.updateMany(filter, data).exec();
@@ -5524,10 +5799,12 @@ var MongoRepository = class {
5524
5799
  * Delete
5525
5800
  */
5526
5801
  async deleteById(id) {
5527
- return this.model.findByIdAndDelete(id).exec();
5802
+ const doc = await this.model.findByIdAndDelete(id).exec();
5803
+ return doc ? this.toPlain(doc) : null;
5528
5804
  }
5529
5805
  async deleteOne(filter) {
5530
- return this.model.findOneAndDelete(filter).exec();
5806
+ const doc = await this.model.findOneAndDelete(filter).exec();
5807
+ return doc ? this.toPlain(doc) : null;
5531
5808
  }
5532
5809
  async deleteMany(filter) {
5533
5810
  const result = await this.model.deleteMany(filter).exec();
@@ -5996,6 +6273,7 @@ exports.AsyncHandler = AsyncHandler;
5996
6273
  exports.AzureBlobStorageService = AzureBlobStorageService;
5997
6274
  exports.BPlusTree = BPlusTree;
5998
6275
  exports.BTree = BTree;
6276
+ exports.BearerTokenStrategy = BearerTokenStrategy;
5999
6277
  exports.BinaryHeap = BinaryHeap;
6000
6278
  exports.BinarySearchTree = BinarySearchTree;
6001
6279
  exports.BinaryTree = BinaryTree;
@@ -6005,6 +6283,7 @@ exports.CircularLinkedList = CircularLinkedList;
6005
6283
  exports.CircularQueue = CircularQueue;
6006
6284
  exports.CloudinaryService = CloudinaryService;
6007
6285
  exports.ConsistentHash = ConsistentHash;
6286
+ exports.CorrelationId = CorrelationId;
6008
6287
  exports.CountMinSketch = CountMinSketch;
6009
6288
  exports.CrudControllerFactory = CrudControllerFactory;
6010
6289
  exports.DEFAULT_LIMIT = DEFAULT_LIMIT;
@@ -6018,13 +6297,17 @@ exports.DoublyLinkedList = DoublyLinkedList;
6018
6297
  exports.DynamicArray = DynamicArray;
6019
6298
  exports.EmailService = EmailService;
6020
6299
  exports.ErrorMiddleware = ErrorMiddleware;
6300
+ exports.ExponentialBackoffRetryPolicy = ExponentialBackoffRetryPolicy;
6021
6301
  exports.FenwickTree = FenwickTree;
6022
6302
  exports.FibNode = FibNode;
6023
6303
  exports.FibonacciHeap = FibonacciHeap;
6304
+ exports.FixedRetryPolicy = FixedRetryPolicy;
6024
6305
  exports.Graph = Graph;
6025
6306
  exports.HashMap = HashMap;
6026
6307
  exports.HashSet = HashSet;
6308
+ exports.HttpClient = HttpClient;
6027
6309
  exports.HyperLogLog = HyperLogLog;
6310
+ exports.InternalServiceClient = InternalServiceClient;
6028
6311
  exports.IntervalTree = IntervalTree;
6029
6312
  exports.JWTService = JWTService;
6030
6313
  exports.JoiValidator = JoiValidator;
@@ -6049,19 +6332,23 @@ exports.QuadTree = QuadTree;
6049
6332
  exports.Queue = Queue;
6050
6333
  exports.RadixTree = RadixTree;
6051
6334
  exports.RedBlackTree = RedBlackTree;
6335
+ exports.RequestContext = RequestContext;
6052
6336
  exports.SMTPProvider = SMTPProvider;
6053
6337
  exports.SUPPORTED_OPERATORS = SUPPORTED_OPERATORS;
6054
6338
  exports.SegmentTree = SegmentTree;
6339
+ exports.ServiceClient = ServiceClient;
6055
6340
  exports.Set = Set2;
6056
6341
  exports.SinglyLinkedList = SinglyLinkedList;
6057
6342
  exports.SparseTable = SparseTable;
6058
6343
  exports.SplayTree = SplayTree;
6059
6344
  exports.Stack = Stack;
6060
6345
  exports.StaticArray = StaticArray;
6346
+ exports.StaticTokenProvider = StaticTokenProvider;
6061
6347
  exports.SuffixArray = SuffixArray;
6062
6348
  exports.SuffixTree = SuffixTree;
6063
6349
  exports.TemplateEngine = TemplateEngine;
6064
6350
  exports.TernarySearchTree = TernarySearchTree;
6351
+ exports.TracingHeaders = TracingHeaders;
6065
6352
  exports.TreeNode = TreeNode;
6066
6353
  exports.Trie = Trie;
6067
6354
  exports.ZodValidator = ZodValidator;