@catbee/utils 1.0.1 → 1.0.2

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/build/index.mjs CHANGED
@@ -9,6 +9,7 @@ import { rateLimit as rateLimit$1 } from 'express-rate-limit';
9
9
  import os, { tmpdir } from 'os';
10
10
  import fsp from 'fs/promises';
11
11
  import { pipeline } from 'stream/promises';
12
+ import { Readable, Transform } from 'stream';
12
13
  import { URL as URL$1, URLSearchParams } from 'url';
13
14
  import express from 'express';
14
15
  import https from 'https';
@@ -2492,6 +2493,234 @@ function verifySignedToken(token, secret) {
2492
2493
  }
2493
2494
  __name(verifySignedToken, "verifySignedToken");
2494
2495
 
2496
+ // src/utils/date.utils.ts
2497
+ function formatDate(date, options = {}) {
2498
+ const { format = "yyyy-MM-dd", locale, timeZone } = options;
2499
+ const d = date instanceof Date ? date : new Date(date);
2500
+ if (format === "yyyy-MM-dd") {
2501
+ const yyyy = d.getFullYear();
2502
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
2503
+ const dd = String(d.getDate()).padStart(2, "0");
2504
+ return `${yyyy}-${mm}-${dd}`;
2505
+ }
2506
+ if (format === "yyyy-MM-dd HH:mm:ss") {
2507
+ const yyyy = d.getFullYear();
2508
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
2509
+ const dd = String(d.getDate()).padStart(2, "0");
2510
+ const HH = String(d.getHours()).padStart(2, "0");
2511
+ const MM = String(d.getMinutes()).padStart(2, "0");
2512
+ const SS = String(d.getSeconds()).padStart(2, "0");
2513
+ return `${yyyy}-${mm}-${dd} ${HH}:${MM}:${SS}`;
2514
+ }
2515
+ if (format === "relative") {
2516
+ return formatRelativeTime(date);
2517
+ }
2518
+ return new Intl.DateTimeFormat(locale, {
2519
+ timeZone,
2520
+ year: format.includes("yyyy") || format.includes("y") ? "numeric" : void 0,
2521
+ month: format.includes("MM") || format.includes("M") ? "numeric" : void 0,
2522
+ day: format.includes("dd") || format.includes("d") ? "numeric" : void 0,
2523
+ hour: format.includes("HH") || format.includes("H") ? "numeric" : void 0,
2524
+ minute: format.includes("mm") || format.includes("m") ? "numeric" : void 0,
2525
+ second: format.includes("ss") || format.includes("s") ? "numeric" : void 0,
2526
+ hour12: !format.includes("HH") && !format.includes("H")
2527
+ }).format(d);
2528
+ }
2529
+ __name(formatDate, "formatDate");
2530
+ function formatRelativeTime(date, now = /* @__PURE__ */ new Date(), locale) {
2531
+ const d1 = date instanceof Date ? date : new Date(date);
2532
+ const d2 = now instanceof Date ? now : new Date(now);
2533
+ const diffMs = d1.getTime() - d2.getTime();
2534
+ const diffSecs = Math.round(diffMs / 1e3);
2535
+ const diffMins = Math.round(diffSecs / 60);
2536
+ const diffHours = Math.round(diffMins / 60);
2537
+ const diffDays = Math.round(diffHours / 24);
2538
+ const diffMonths = Math.round(diffDays / 30);
2539
+ const diffYears = Math.round(diffDays / 365);
2540
+ const formatter = new Intl.RelativeTimeFormat(locale, {
2541
+ numeric: "auto"
2542
+ });
2543
+ if (Math.abs(diffSecs) < 60) return formatter.format(diffSecs, "second");
2544
+ if (Math.abs(diffMins) < 60) return formatter.format(diffMins, "minute");
2545
+ if (Math.abs(diffHours) < 24) return formatter.format(diffHours, "hour");
2546
+ if (Math.abs(diffDays) < 30) return formatter.format(diffDays, "day");
2547
+ if (Math.abs(diffMonths) < 12) return formatter.format(diffMonths, "month");
2548
+ return formatter.format(diffYears, "year");
2549
+ }
2550
+ __name(formatRelativeTime, "formatRelativeTime");
2551
+ function parseDate(input, fallback) {
2552
+ if (typeof input === "number") {
2553
+ return new Date(input);
2554
+ }
2555
+ try {
2556
+ const date = new Date(input);
2557
+ if (isNaN(date.getTime())) {
2558
+ return fallback || null;
2559
+ }
2560
+ return date;
2561
+ } catch {
2562
+ return fallback || null;
2563
+ }
2564
+ }
2565
+ __name(parseDate, "parseDate");
2566
+ function dateDiff(date1, date2 = /* @__PURE__ */ new Date(), unit = "days") {
2567
+ const d1 = date1 instanceof Date ? date1 : new Date(date1);
2568
+ const d2 = date2 instanceof Date ? date2 : new Date(date2);
2569
+ const diffMs = d1.getTime() - d2.getTime();
2570
+ switch (unit) {
2571
+ case "milliseconds":
2572
+ return diffMs;
2573
+ case "seconds":
2574
+ return diffMs / 1e3;
2575
+ case "minutes":
2576
+ return diffMs / (1e3 * 60);
2577
+ case "hours":
2578
+ return diffMs / (1e3 * 60 * 60);
2579
+ case "days":
2580
+ return diffMs / (1e3 * 60 * 60 * 24);
2581
+ case "months":
2582
+ return (d1.getFullYear() - d2.getFullYear()) * 12 + d1.getMonth() - d2.getMonth();
2583
+ case "years":
2584
+ return d1.getFullYear() - d2.getFullYear();
2585
+ default:
2586
+ throw new Error(`Unsupported unit: ${unit}`);
2587
+ }
2588
+ }
2589
+ __name(dateDiff, "dateDiff");
2590
+ function addToDate(date, amount, unit) {
2591
+ const d = date instanceof Date ? new Date(date) : new Date(date);
2592
+ switch (unit) {
2593
+ case "milliseconds":
2594
+ d.setMilliseconds(d.getMilliseconds() + amount);
2595
+ break;
2596
+ case "seconds":
2597
+ d.setSeconds(d.getSeconds() + amount);
2598
+ break;
2599
+ case "minutes":
2600
+ d.setMinutes(d.getMinutes() + amount);
2601
+ break;
2602
+ case "hours":
2603
+ d.setHours(d.getHours() + amount);
2604
+ break;
2605
+ case "days":
2606
+ d.setDate(d.getDate() + amount);
2607
+ break;
2608
+ case "months": {
2609
+ const origDate = d.getDate();
2610
+ const origMonth = d.getMonth();
2611
+ d.setDate(1);
2612
+ d.setMonth(origMonth + amount);
2613
+ const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
2614
+ d.setDate(Math.min(origDate, lastDay));
2615
+ break;
2616
+ }
2617
+ case "years":
2618
+ d.setFullYear(d.getFullYear() + amount);
2619
+ break;
2620
+ default:
2621
+ throw new Error(`Unsupported unit: ${unit}`);
2622
+ }
2623
+ return d;
2624
+ }
2625
+ __name(addToDate, "addToDate");
2626
+ function startOf(date, unit) {
2627
+ const d = date instanceof Date ? new Date(date) : new Date(date);
2628
+ switch (unit) {
2629
+ case "second":
2630
+ d.setMilliseconds(0);
2631
+ break;
2632
+ case "minute":
2633
+ d.setSeconds(0, 0);
2634
+ break;
2635
+ case "hour":
2636
+ d.setMinutes(0, 0, 0);
2637
+ break;
2638
+ case "day":
2639
+ d.setHours(0, 0, 0, 0);
2640
+ break;
2641
+ case "week":
2642
+ d.setHours(0, 0, 0, 0);
2643
+ d.setDate(d.getDate() - d.getDay());
2644
+ break;
2645
+ case "month":
2646
+ d.setDate(1);
2647
+ d.setHours(0, 0, 0, 0);
2648
+ break;
2649
+ case "quarter":
2650
+ d.setMonth(Math.floor(d.getMonth() / 3) * 3, 1);
2651
+ d.setHours(0, 0, 0, 0);
2652
+ break;
2653
+ case "year":
2654
+ d.setMonth(0, 1);
2655
+ d.setHours(0, 0, 0, 0);
2656
+ break;
2657
+ default:
2658
+ throw new Error(`Unsupported unit: ${unit}`);
2659
+ }
2660
+ return d;
2661
+ }
2662
+ __name(startOf, "startOf");
2663
+ function endOf(date, unit) {
2664
+ const d = date instanceof Date ? new Date(date) : new Date(date);
2665
+ switch (unit) {
2666
+ case "second":
2667
+ d.setMilliseconds(999);
2668
+ break;
2669
+ case "minute":
2670
+ d.setSeconds(59, 999);
2671
+ break;
2672
+ case "hour":
2673
+ d.setMinutes(59, 59, 999);
2674
+ break;
2675
+ case "day":
2676
+ d.setHours(23, 59, 59, 999);
2677
+ break;
2678
+ case "week":
2679
+ d.setDate(d.getDate() - d.getDay() + 6);
2680
+ d.setHours(23, 59, 59, 999);
2681
+ break;
2682
+ case "month":
2683
+ d.setMonth(d.getMonth() + 1, 0);
2684
+ d.setHours(23, 59, 59, 999);
2685
+ break;
2686
+ case "quarter":
2687
+ d.setMonth(Math.floor(d.getMonth() / 3) * 3 + 3, 0);
2688
+ d.setHours(23, 59, 59, 999);
2689
+ break;
2690
+ case "year":
2691
+ d.setMonth(11, 31);
2692
+ d.setHours(23, 59, 59, 999);
2693
+ break;
2694
+ default:
2695
+ throw new Error(`Unsupported unit: ${unit}`);
2696
+ }
2697
+ return d;
2698
+ }
2699
+ __name(endOf, "endOf");
2700
+ function isBetween(date, start, end, inclusive = true) {
2701
+ const d = date instanceof Date ? date.getTime() : date;
2702
+ const s = start instanceof Date ? start.getTime() : start;
2703
+ const e = end instanceof Date ? end.getTime() : end;
2704
+ return inclusive ? d >= s && d <= e : d > s && d < e;
2705
+ }
2706
+ __name(isBetween, "isBetween");
2707
+ function isLeapYear(year) {
2708
+ const y = year instanceof Date ? year.getFullYear() : year;
2709
+ return y % 4 === 0 && y % 100 !== 0 || y % 400 === 0;
2710
+ }
2711
+ __name(isLeapYear, "isLeapYear");
2712
+ function daysInMonth(year, month) {
2713
+ if (year instanceof Date) {
2714
+ month = year.getMonth();
2715
+ year = year.getFullYear();
2716
+ }
2717
+ if (month === void 0) {
2718
+ throw new Error("Month is required when year is a number");
2719
+ }
2720
+ return new Date(year, month + 1, 0).getDate();
2721
+ }
2722
+ __name(daysInMonth, "daysInMonth");
2723
+
2495
2724
  // src/utils/response.utils.ts
2496
2725
  var SuccessResponse = class {
2497
2726
  static {
@@ -3515,7 +3744,7 @@ function registerControllers(router, controllers) {
3515
3744
  diContainer.register(ControllerClass);
3516
3745
  }
3517
3746
  const instance = diContainer.get(ControllerClass);
3518
- const basePath = Reflect.getMetadata("basePath", ControllerClass) || "";
3747
+ let basePath = Reflect.getMetadata("basePath", ControllerClass) || "";
3519
3748
  const routes = Reflect.getMetadata(ROUTES_KEY, ControllerClass) || [];
3520
3749
  const controllerRateLimit = Reflect.getMetadata(RATE_LIMIT_KEY, ControllerClass);
3521
3750
  const controllerCache = Reflect.getMetadata(CACHE_KEY, ControllerClass);
@@ -3528,6 +3757,9 @@ function registerControllers(router, controllers) {
3528
3757
  const controllerBeforeHooks = Reflect.getMetadata(BEFORE_KEY, ControllerClass) || [];
3529
3758
  const controllerAfterHooks = Reflect.getMetadata(AFTER_KEY, ControllerClass) || [];
3530
3759
  const controllerContentType = Reflect.getMetadata(CONTENT_TYPE_KEY, ControllerClass);
3760
+ if (controllerVersion?.options?.addPrefix) {
3761
+ basePath = `/${controllerVersion.version}${basePath || ""}`;
3762
+ }
3531
3763
  routes.forEach(({ path: path3, method, handlerName }) => {
3532
3764
  const methodMiddlewares = Reflect.getMetadata(MIDDLEWARE_KEY, instance, handlerName) || [];
3533
3765
  const params = Reflect.getMetadata(PARAMS_KEY, instance, handlerName) || [];
@@ -3557,7 +3789,8 @@ function registerControllers(router, controllers) {
3557
3789
  const roles = Reflect.getMetadata(ROLES_KEY, instance, handlerName) || controllerRoles || [];
3558
3790
  const cache = Reflect.getMetadata(CACHE_KEY, instance, handlerName) || controllerCache;
3559
3791
  const rateLimitOptions = Reflect.getMetadata(RATE_LIMIT_KEY, instance, handlerName) || controllerRateLimit;
3560
- const version = Reflect.getMetadata(VERSION_KEY, instance, handlerName) || controllerVersion;
3792
+ const methodVersion = Reflect.getMetadata(VERSION_KEY, instance, handlerName);
3793
+ const version = methodVersion || controllerVersion;
3561
3794
  const timeout2 = Reflect.getMetadata(TIMEOUT_KEY, instance, handlerName) || controllerTimeout;
3562
3795
  const logConfig = Reflect.getMetadata(LOG_KEY, instance, handlerName) || controllerLogConfig;
3563
3796
  let rateLimiter = null;
@@ -3571,8 +3804,8 @@ function registerControllers(router, controllers) {
3571
3804
  }
3572
3805
  }
3573
3806
  let finalPath = path3;
3574
- if (version?.options?.addPrefix) {
3575
- finalPath = `/${version.version}${path3}`;
3807
+ if (methodVersion?.options?.addPrefix && methodVersion.version !== controllerVersion?.version) {
3808
+ finalPath = `/${methodVersion.version}${path3}`;
3576
3809
  }
3577
3810
  const handler = /* @__PURE__ */ __name(async (req, res, next) => {
3578
3811
  req["startTime"] = Date.now();
@@ -4561,6 +4794,202 @@ function healthCheck(options) {
4561
4794
  }
4562
4795
  __name(healthCheck, "healthCheck");
4563
4796
 
4797
+ // src/utils/performance.utils.ts
4798
+ function timeSync(fn, options = {}) {
4799
+ const { label = fn.name || "anonymous function", log = false, logLevel = "debug" } = options;
4800
+ const startTime = performance.now();
4801
+ const result = fn();
4802
+ const endTime = performance.now();
4803
+ const durationMs = endTime - startTime;
4804
+ const durationSec = durationMs / 1e3;
4805
+ const timing = {
4806
+ durationMs,
4807
+ durationSec,
4808
+ startTime,
4809
+ endTime,
4810
+ label
4811
+ };
4812
+ if (log) {
4813
+ const logger2 = getLogger();
4814
+ const message = `${label} completed in ${durationMs.toFixed(2)}ms`;
4815
+ switch (logLevel) {
4816
+ case "trace":
4817
+ logger2.trace({
4818
+ timing
4819
+ }, message);
4820
+ break;
4821
+ case "debug":
4822
+ logger2.debug({
4823
+ timing
4824
+ }, message);
4825
+ break;
4826
+ case "info":
4827
+ logger2.info({
4828
+ timing
4829
+ }, message);
4830
+ break;
4831
+ case "warn":
4832
+ logger2.warn({
4833
+ timing
4834
+ }, message);
4835
+ break;
4836
+ case "error":
4837
+ logger2.error({
4838
+ timing
4839
+ }, message);
4840
+ break;
4841
+ default:
4842
+ logger2.debug({
4843
+ timing
4844
+ }, message);
4845
+ break;
4846
+ }
4847
+ }
4848
+ return {
4849
+ result,
4850
+ timing
4851
+ };
4852
+ }
4853
+ __name(timeSync, "timeSync");
4854
+ async function timeAsync(fn, options = {}) {
4855
+ const { label = fn.name || "anonymous async function", log = false, logLevel = "debug" } = options;
4856
+ const startTime = performance.now();
4857
+ const result = await fn();
4858
+ const endTime = performance.now();
4859
+ const durationMs = endTime - startTime;
4860
+ const durationSec = durationMs / 1e3;
4861
+ const timing = {
4862
+ durationMs,
4863
+ durationSec,
4864
+ startTime,
4865
+ endTime,
4866
+ label
4867
+ };
4868
+ if (log) {
4869
+ const logger2 = getLogger();
4870
+ const message = `${label} completed in ${durationMs.toFixed(2)}ms`;
4871
+ switch (logLevel) {
4872
+ case "trace":
4873
+ logger2.trace({
4874
+ timing
4875
+ }, message);
4876
+ break;
4877
+ case "debug":
4878
+ logger2.debug({
4879
+ timing
4880
+ }, message);
4881
+ break;
4882
+ case "info":
4883
+ logger2.info({
4884
+ timing
4885
+ }, message);
4886
+ break;
4887
+ case "warn":
4888
+ logger2.warn({
4889
+ timing
4890
+ }, message);
4891
+ break;
4892
+ case "error":
4893
+ logger2.error({
4894
+ timing
4895
+ }, message);
4896
+ break;
4897
+ default:
4898
+ logger2.debug({
4899
+ timing
4900
+ }, message);
4901
+ break;
4902
+ }
4903
+ }
4904
+ return {
4905
+ result,
4906
+ timing
4907
+ };
4908
+ }
4909
+ __name(timeAsync, "timeAsync");
4910
+ function timed(options = {}) {
4911
+ return function(target, propertyKeyOrContext, descriptor) {
4912
+ let propertyKey;
4913
+ let actualDescriptor;
4914
+ if (typeof propertyKeyOrContext === "object" && propertyKeyOrContext !== null && "name" in propertyKeyOrContext) {
4915
+ propertyKey = propertyKeyOrContext.name;
4916
+ actualDescriptor = descriptor ?? Object.getOwnPropertyDescriptor(target, propertyKey);
4917
+ } else {
4918
+ propertyKey = propertyKeyOrContext;
4919
+ actualDescriptor = descriptor ?? Object.getOwnPropertyDescriptor(target, propertyKey);
4920
+ }
4921
+ const originalMethod = actualDescriptor.value;
4922
+ actualDescriptor.value = function(...args) {
4923
+ const methodOptions = {
4924
+ ...options,
4925
+ label: options.label || `${target.constructor.name}.${String(propertyKey)}`
4926
+ };
4927
+ if (originalMethod.constructor.name === "AsyncFunction") {
4928
+ return timeAsync(() => originalMethod.apply(this, args), methodOptions).then(({ result }) => result);
4929
+ } else {
4930
+ return timeSync(() => originalMethod.apply(this, args), methodOptions).result;
4931
+ }
4932
+ };
4933
+ if (descriptor) {
4934
+ descriptor.value = actualDescriptor.value;
4935
+ } else {
4936
+ Object.defineProperty(target, propertyKey, actualDescriptor);
4937
+ }
4938
+ };
4939
+ }
4940
+ __name(timed, "timed");
4941
+ function memoize(fn, options = {}) {
4942
+ const { ttl, maxSize, autoCleanupMs, cacheKey = /* @__PURE__ */ __name((...args) => JSON.stringify(args), "cacheKey") } = options;
4943
+ const cache = new TTLCache({
4944
+ ttlMs: ttl,
4945
+ maxSize,
4946
+ autoCleanupMs
4947
+ });
4948
+ return function(...args) {
4949
+ const key = cacheKey(...args);
4950
+ const cachedValue = cache.get(key);
4951
+ if (cachedValue !== void 0) {
4952
+ return cachedValue;
4953
+ }
4954
+ const value = fn(...args);
4955
+ cache.set(key, value);
4956
+ return value;
4957
+ };
4958
+ }
4959
+ __name(memoize, "memoize");
4960
+ function trackMemoryUsage(fn, options = {}) {
4961
+ const { log = false, label = fn.name || "anonymous function" } = options;
4962
+ if (global.gc) {
4963
+ global.gc();
4964
+ }
4965
+ const beforeMemory = process.memoryUsage();
4966
+ const result = fn();
4967
+ const afterMemory = process.memoryUsage();
4968
+ const diff = {};
4969
+ for (const key in afterMemory) {
4970
+ if (Object.prototype.hasOwnProperty.call(afterMemory, key)) {
4971
+ diff[key] = afterMemory[key] - beforeMemory[key];
4972
+ }
4973
+ }
4974
+ if (log) {
4975
+ getLogger().info({
4976
+ label,
4977
+ memoryBefore: beforeMemory,
4978
+ memoryAfter: afterMemory,
4979
+ memoryDiff: diff
4980
+ }, `Memory usage for ${label}`);
4981
+ }
4982
+ return {
4983
+ result,
4984
+ memoryUsage: {
4985
+ before: beforeMemory,
4986
+ after: afterMemory,
4987
+ diff
4988
+ }
4989
+ };
4990
+ }
4991
+ __name(trackMemoryUsage, "trackMemoryUsage");
4992
+
4564
4993
  // src/utils/request.utils.ts
4565
4994
  var getPaginationParams = /* @__PURE__ */ __name((req) => {
4566
4995
  const query = req.query;
@@ -4719,6 +5148,120 @@ function extractFilterParams(query, allowedFilters) {
4719
5148
  return filters;
4720
5149
  }
4721
5150
  __name(extractFilterParams, "extractFilterParams");
5151
+ function bufferToStream(data) {
5152
+ const readable = new Readable();
5153
+ readable.push(data);
5154
+ readable.push(null);
5155
+ return readable;
5156
+ }
5157
+ __name(bufferToStream, "bufferToStream");
5158
+ async function streamToBuffer(stream) {
5159
+ return new Promise((resolve2, reject) => {
5160
+ const chunks = [];
5161
+ stream.on("data", (chunk2) => chunks.push(Buffer.isBuffer(chunk2) ? chunk2 : Buffer.from(chunk2)));
5162
+ stream.on("end", () => resolve2(Buffer.concat(chunks)));
5163
+ stream.on("error", reject);
5164
+ });
5165
+ }
5166
+ __name(streamToBuffer, "streamToBuffer");
5167
+ async function streamToString(stream, encoding = "utf8") {
5168
+ const buffer = await streamToBuffer(stream);
5169
+ return buffer.toString(encoding);
5170
+ }
5171
+ __name(streamToString, "streamToString");
5172
+ function createThrottleStream(bytesPerSecond) {
5173
+ let bytesSent = 0;
5174
+ let startTime = Date.now();
5175
+ return new Transform({
5176
+ transform(chunk2, _encoding, callback) {
5177
+ const elapsedSeconds = (Date.now() - startTime) / 1e3;
5178
+ const targetBytes = bytesPerSecond * elapsedSeconds;
5179
+ const chunkSize = chunk2.length;
5180
+ if (bytesSent + chunkSize <= targetBytes) {
5181
+ bytesSent += chunkSize;
5182
+ callback(null, chunk2);
5183
+ return;
5184
+ }
5185
+ const delay = ((bytesSent + chunkSize) / bytesPerSecond - elapsedSeconds) * 1e3;
5186
+ setTimeout(() => {
5187
+ bytesSent += chunkSize;
5188
+ callback(null, chunk2);
5189
+ }, delay);
5190
+ }
5191
+ });
5192
+ }
5193
+ __name(createThrottleStream, "createThrottleStream");
5194
+ function createBatchStream(size, options = {}) {
5195
+ const objectMode = options.objectMode !== false;
5196
+ let batch = [];
5197
+ let buffers = [];
5198
+ let bufferSize = 0;
5199
+ return new Transform({
5200
+ objectMode,
5201
+ transform(chunk2, _encoding, callback) {
5202
+ if (objectMode) {
5203
+ batch.push(chunk2);
5204
+ if (batch.length >= size) {
5205
+ this.push(batch);
5206
+ batch = [];
5207
+ }
5208
+ } else {
5209
+ const buffer = Buffer.isBuffer(chunk2) ? chunk2 : Buffer.from(chunk2);
5210
+ buffers.push(buffer);
5211
+ bufferSize += buffer.length;
5212
+ let combined = Buffer.concat(buffers, bufferSize);
5213
+ while (combined.length >= size) {
5214
+ this.push(combined.slice(0, size));
5215
+ combined = combined.slice(size);
5216
+ }
5217
+ buffers = combined.length > 0 ? [
5218
+ combined
5219
+ ] : [];
5220
+ bufferSize = combined.length;
5221
+ }
5222
+ callback();
5223
+ },
5224
+ flush(callback) {
5225
+ if (objectMode && batch.length > 0) {
5226
+ this.push(batch);
5227
+ } else if (!objectMode && buffers.length > 0 && bufferSize > 0) {
5228
+ let combined = Buffer.concat(buffers, bufferSize);
5229
+ while (combined.length >= size) {
5230
+ this.push(combined.slice(0, size));
5231
+ combined = combined.slice(size);
5232
+ }
5233
+ if (combined.length > 0) {
5234
+ this.push(combined);
5235
+ }
5236
+ }
5237
+ callback();
5238
+ }
5239
+ });
5240
+ }
5241
+ __name(createBatchStream, "createBatchStream");
5242
+ function createLineStream(options = {}) {
5243
+ const { encoding = "utf8", includeNewlines = false } = options;
5244
+ let buffer = "";
5245
+ return new Transform({
5246
+ objectMode: true,
5247
+ transform(chunk2, _encoding, callback) {
5248
+ const str = buffer + (Buffer.isBuffer(chunk2) ? chunk2.toString(encoding) : chunk2);
5249
+ const lines = str.split(/\r?\n/);
5250
+ buffer = lines.pop() || "";
5251
+ for (const line of lines) {
5252
+ this.push(includeNewlines ? line + "\n" : line);
5253
+ }
5254
+ callback();
5255
+ },
5256
+ flush(callback) {
5257
+ if (buffer) {
5258
+ this.push(buffer);
5259
+ }
5260
+ callback();
5261
+ }
5262
+ });
5263
+ }
5264
+ __name(createLineStream, "createLineStream");
4722
5265
 
4723
5266
  // src/utils/string.utils.ts
4724
5267
  function capitalize(str) {
@@ -4778,6 +5321,84 @@ function countOccurrences(str, substring, caseSensitive = true) {
4778
5321
  return str.split(substring).length - 1;
4779
5322
  }
4780
5323
  __name(countOccurrences, "countOccurrences");
5324
+
5325
+ // src/utils/type.utils.ts
5326
+ function isPrimitiveType(value, type) {
5327
+ if (type === "array") {
5328
+ return Array.isArray(value);
5329
+ }
5330
+ if (type === "null") {
5331
+ return value === null;
5332
+ }
5333
+ if (type === "undefined") {
5334
+ return value === void 0;
5335
+ }
5336
+ if (type === "object") {
5337
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5338
+ }
5339
+ return typeof value === type;
5340
+ }
5341
+ __name(isPrimitiveType, "isPrimitiveType");
5342
+ function getTypeOf(value) {
5343
+ if (value === null) return "null";
5344
+ if (value === void 0) return "undefined";
5345
+ if (Array.isArray(value)) return "array";
5346
+ return typeof value;
5347
+ }
5348
+ __name(getTypeOf, "getTypeOf");
5349
+ function isArrayOf(value, itemTypeGuard) {
5350
+ if (!Array.isArray(value)) return false;
5351
+ return value.every((item) => itemTypeGuard(item));
5352
+ }
5353
+ __name(isArrayOf, "isArrayOf");
5354
+ function toStr(value, defaultValue = "") {
5355
+ if (value === null || value === void 0) return defaultValue;
5356
+ try {
5357
+ if (typeof value === "object") {
5358
+ return JSON.stringify(value);
5359
+ }
5360
+ return String(value);
5361
+ } catch {
5362
+ return defaultValue;
5363
+ }
5364
+ }
5365
+ __name(toStr, "toStr");
5366
+ function toNum(value, defaultValue = 0) {
5367
+ if (value === null || value === void 0) return defaultValue;
5368
+ if (typeof value === "number") return value;
5369
+ try {
5370
+ const num = Number(value);
5371
+ return isNaN(num) ? defaultValue : num;
5372
+ } catch {
5373
+ return defaultValue;
5374
+ }
5375
+ }
5376
+ __name(toNum, "toNum");
5377
+ function toBool(value, defaultValue = false) {
5378
+ if (value === null || value === void 0) return defaultValue;
5379
+ if (typeof value === "boolean") return value;
5380
+ if (typeof value === "string") {
5381
+ const lowercased = value.toLowerCase();
5382
+ if (lowercased === "true" || lowercased === "yes" || lowercased === "y" || lowercased === "1") {
5383
+ return true;
5384
+ }
5385
+ if (lowercased === "false" || lowercased === "no" || lowercased === "n" || lowercased === "0") {
5386
+ return false;
5387
+ }
5388
+ }
5389
+ if (typeof value === "number") {
5390
+ return value !== 0;
5391
+ }
5392
+ return defaultValue;
5393
+ }
5394
+ __name(toBool, "toBool");
5395
+ function ensureType(value, expectedType, defaultValue) {
5396
+ if (getTypeOf(value) === expectedType) {
5397
+ return value;
5398
+ }
5399
+ return defaultValue;
5400
+ }
5401
+ __name(ensureType, "ensureType");
4781
5402
  function appendQueryParams(url, params) {
4782
5403
  const urlObj = new URL$1(url);
4783
5404
  for (const [key, value] of Object.entries(params)) {
@@ -6632,4 +7253,4 @@ var ExpressServer = class _ExpressServer {
6632
7253
  }
6633
7254
  };
6634
7255
 
6635
- export { After, BUILD_MARKER, BadGatewayException, BadRequestException, Before, Body, Cache, CircuitBreakerOpenError, CircuitBreakerState, ConflictException, Connect, ContentType, ContextStore, Controller, DIContainer, Delete, Env, Environment, ErrorResponse, ExpressServer, ForbiddenException, GatewayTimeoutException, Get, Head, Header, Headers, HttpCode, HttpError, HttpStatusCodes, Inject, Injectable, InsufficientStorageException, InternalServerErrorException, Log, MethodNotAllowedException, NoContentResponse, NotAcceptableException, NotFoundException, Options, PaginatedResponse, Param, Patch, PayloadTooLargeException, Post, Put, Query, RateLimit, Redirect, RedirectResponse, Req, ReqCookie, ReqHeader, ReqId, ReqLogger, RequestTimeoutException, Res, Roles, ServerConfigBuilder, ServiceUnavailableException, SortDirection, StoreKeys, SuccessResponse, TTLCache, Timeout, TooManyRequestsException, Trace, TypedContextKey, UnauthorizedException, UnprocessableEntityException, UnsupportedMediaTypeException, Use, Version, _globalThis, abortable, addRedactFields, addSensitiveFields, appendQueryParams, appendTextFile, capitalize, chunk, circuitBreaker, compact, copyDir, copyFile, countBy, countOccurrences, createChildLogger, createDeferred, createDirectory, createErrorResponse, createFinalErrorResponse, createHttpError, createPaginatedResponse, createParamDecorator, createParamDecoratorWithoutParam, createRequestLogger, createSignedToken, createSuccessResponse, createTaskQueue, createTempDir, createTempFile, createUrlBuilder, debounce, decrypt, deepFreeze, deepObjMerge, defaultSensitiveFields, deleteDirRecursive, deleteFileIfExists, difference, emptyDir, encrypt, ensureDir, ensureEmptyDir, equalsIgnoreCase, errorHandler, extractFilterParams, extractPaginationParams, extractQueryParams, extractSortParams, fileExists, filterObject, findFilesByPattern, findInDir, findNewestFile, findOldestFile, flattenDeep, flattenObject, generateApiKey, generateRandomBytes, generateRandomBytesAsString, getAllPaths, getConfig, getDirSize, getDirStats, getDomain, getErrorMessage, getExtension, getFileSize, getFileStats, getFromContext, getLogger, getPaginationParams, getRedactCensor, getRequestId, getSubdirectories, getValueByPath, groupBy, hasErrorShape, hasRequiredProps, hash, healthCheck, hmac, inject, intersect, isAlpha, isAlphanumeric, isArray, isBase64, isCreditCard, isDateInRange, isDirectory, isEmail, isEqual, isFile, isHexColor, isHttpError, isIPv4, isIPv6, isISODate, isLengthBetween, isNumberBetween, isNumeric, isObjEmpty, isObject, isPhone, isPlainObject, isPort, isStrongPassword, isURL, isUUID, isValidJSON, isValidUrl, joinPaths, listFiles, logError, logger, mapObject, mask, matchesPattern, md5, memoizeAsync, mergeSort, moveDir, moveFile, nanoId, normalizeUrl, omit, parseBooleanParam, parseNumberParam, parseQueryString, parseTypedQueryParams, partition, pick, pluck, random, randomBase64, randomHex, randomInt, randomString, range, rateLimit, readDirectory, readFileBuffer, readJsonFile, readTextFile, redact, registerControllers, removeQueryParams, requestId, responseTime, retry, reverse, runInBatches, runInSeries, runWithConcurrency, safeCompare, safeReadJsonFile, sendResponse, setConfig, setRedactCensor, setSensitiveFields, setValueByPath, settleAll, setupRequestContext, sha1, sha256, sha256Hmac, shuffle, singletonAsync, sleep, slugify, streamFile, stripHtml, take, takeWhile, throttle, timeout, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, truncate, unique, uuid, validateAll, verifySignedToken, walkDir, watchDir, watchDirRecursive, waterfall, withErrorHandling, withTimeout, writeJsonFile, writeTextFile, zip };
7256
+ export { After, BUILD_MARKER, BadGatewayException, BadRequestException, Before, Body, Cache, CircuitBreakerOpenError, CircuitBreakerState, ConflictException, Connect, ContentType, ContextStore, Controller, DIContainer, Delete, Env, Environment, ErrorResponse, ExpressServer, ForbiddenException, GatewayTimeoutException, Get, Head, Header, Headers, HttpCode, HttpError, HttpStatusCodes, Inject, Injectable, InsufficientStorageException, InternalServerErrorException, Log, MethodNotAllowedException, NoContentResponse, NotAcceptableException, NotFoundException, Options, PaginatedResponse, Param, Patch, PayloadTooLargeException, Post, Put, Query, RateLimit, Redirect, RedirectResponse, Req, ReqCookie, ReqHeader, ReqId, ReqLogger, RequestTimeoutException, Res, Roles, ServerConfigBuilder, ServiceUnavailableException, SortDirection, StoreKeys, SuccessResponse, TTLCache, Timeout, TooManyRequestsException, Trace, TypedContextKey, UnauthorizedException, UnprocessableEntityException, UnsupportedMediaTypeException, Use, Version, _globalThis, abortable, addRedactFields, addSensitiveFields, addToDate, appendQueryParams, appendTextFile, bufferToStream, capitalize, chunk, circuitBreaker, compact, copyDir, copyFile, countBy, countOccurrences, createBatchStream, createChildLogger, createDeferred, createDirectory, createErrorResponse, createFinalErrorResponse, createHttpError, createLineStream, createPaginatedResponse, createParamDecorator, createParamDecoratorWithoutParam, createRequestLogger, createSignedToken, createSuccessResponse, createTaskQueue, createTempDir, createTempFile, createThrottleStream, createUrlBuilder, dateDiff, daysInMonth, debounce, decrypt, deepFreeze, deepObjMerge, defaultSensitiveFields, deleteDirRecursive, deleteFileIfExists, difference, emptyDir, encrypt, endOf, ensureDir, ensureEmptyDir, ensureType, equalsIgnoreCase, errorHandler, extractFilterParams, extractPaginationParams, extractQueryParams, extractSortParams, fileExists, filterObject, findFilesByPattern, findInDir, findNewestFile, findOldestFile, flattenDeep, flattenObject, formatDate, formatRelativeTime, generateApiKey, generateRandomBytes, generateRandomBytesAsString, getAllPaths, getConfig, getDirSize, getDirStats, getDomain, getErrorMessage, getExtension, getFileSize, getFileStats, getFromContext, getLogger, getPaginationParams, getRedactCensor, getRequestId, getSubdirectories, getTypeOf, getValueByPath, groupBy, hasErrorShape, hasRequiredProps, hash, healthCheck, hmac, inject, intersect, isAlpha, isAlphanumeric, isArray, isArrayOf, isBase64, isBetween, isCreditCard, isDateInRange, isDirectory, isEmail, isEqual, isFile, isHexColor, isHttpError, isIPv4, isIPv6, isISODate, isLeapYear, isLengthBetween, isNumberBetween, isNumeric, isObjEmpty, isObject, isPhone, isPlainObject, isPort, isPrimitiveType, isStrongPassword, isURL, isUUID, isValidJSON, isValidUrl, joinPaths, listFiles, logError, logger, mapObject, mask, matchesPattern, md5, memoize, memoizeAsync, mergeSort, moveDir, moveFile, nanoId, normalizeUrl, omit, parseBooleanParam, parseDate, parseNumberParam, parseQueryString, parseTypedQueryParams, partition, pick, pluck, random, randomBase64, randomHex, randomInt, randomString, range, rateLimit, readDirectory, readFileBuffer, readJsonFile, readTextFile, redact, registerControllers, removeQueryParams, requestId, responseTime, retry, reverse, runInBatches, runInSeries, runWithConcurrency, safeCompare, safeReadJsonFile, sendResponse, setConfig, setRedactCensor, setSensitiveFields, setValueByPath, settleAll, setupRequestContext, sha1, sha256, sha256Hmac, shuffle, singletonAsync, sleep, slugify, startOf, streamFile, streamToBuffer, streamToString, stripHtml, take, takeWhile, throttle, timeAsync, timeSync, timed, timeout, toBool, toCamelCase, toKebabCase, toNum, toPascalCase, toSnakeCase, toStr, trackMemoryUsage, truncate, unique, uuid, validateAll, verifySignedToken, walkDir, watchDir, watchDirRecursive, waterfall, withErrorHandling, withTimeout, writeJsonFile, writeTextFile, zip };