@catbee/utils 1.0.1 → 1.0.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/build/index.cjs CHANGED
@@ -11,6 +11,7 @@ var expressRateLimit = require('express-rate-limit');
11
11
  var os = require('os');
12
12
  var fsp = require('fs/promises');
13
13
  var promises = require('stream/promises');
14
+ var stream = require('stream');
14
15
  var url = require('url');
15
16
  var express = require('express');
16
17
  var https = require('https');
@@ -1072,6 +1073,10 @@ var config = {
1072
1073
  */
1073
1074
  pretty: Env.getBoolean("LOGGER_PRETTY", true),
1074
1075
  /**
1076
+ * Enables colorized output for pretty-print (default: true)
1077
+ */
1078
+ colorize: Env.getBoolean("LOGGER_PRETTY_COLORIZE", true),
1079
+ /**
1075
1080
  * Single line output for pretty-print (default: false)
1076
1081
  */
1077
1082
  singleLine: Env.getBoolean("LOGGER_PRETTY_SINGLE_LINE", false)
@@ -1081,6 +1086,20 @@ var config = {
1081
1086
  * Default TTL (time to live) for cache entries in seconds
1082
1087
  */
1083
1088
  defaultTtl: Env.getNumber("CACHE_DEFAULT_TTL_SECONDS", 3600) * 1e3
1089
+ },
1090
+ server: {
1091
+ /**
1092
+ * Skip healthz endpoint even if health checks are configured
1093
+ * Default: false
1094
+ * Set to true to return 200 OK for /healthz without checks
1095
+ * Useful in environments where a simple liveness probe is needed
1096
+ * without performing actual health checks
1097
+ * Example: Kubernetes liveness probe
1098
+ * Note: This does not disable the health check functionality itself
1099
+ * Health checks can still be performed programmatically
1100
+ * or via other endpoints if needed
1101
+ */
1102
+ skipHealthz: Env.getBoolean("SERVER_SKIP_HEALTHZ", false)
1084
1103
  }
1085
1104
  };
1086
1105
  var defaultServerConfig = {
@@ -1684,10 +1703,10 @@ function setupLogger(isGlobal = true) {
1684
1703
  },
1685
1704
  timestamp: pino.stdTimeFunctions.isoTime
1686
1705
  };
1687
- const logger2 = config.logger.pretty && Env.isDev() ? pino__default.default(logParams, pino__default.default.transport({
1706
+ const logger2 = config.logger.pretty ? pino__default.default(logParams, pino__default.default.transport({
1688
1707
  target: "pino-pretty",
1689
1708
  options: {
1690
- colorize: true,
1709
+ colorize: config.logger.colorize,
1691
1710
  translateTime: "SYS:standard",
1692
1711
  ignore: "pid,hostname",
1693
1712
  singleLine: config.logger.singleLine,
@@ -2504,6 +2523,234 @@ function verifySignedToken(token, secret) {
2504
2523
  }
2505
2524
  __name(verifySignedToken, "verifySignedToken");
2506
2525
 
2526
+ // src/utils/date.utils.ts
2527
+ function formatDate(date, options = {}) {
2528
+ const { format = "yyyy-MM-dd", locale, timeZone } = options;
2529
+ const d = date instanceof Date ? date : new Date(date);
2530
+ if (format === "yyyy-MM-dd") {
2531
+ const yyyy = d.getFullYear();
2532
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
2533
+ const dd = String(d.getDate()).padStart(2, "0");
2534
+ return `${yyyy}-${mm}-${dd}`;
2535
+ }
2536
+ if (format === "yyyy-MM-dd HH:mm:ss") {
2537
+ const yyyy = d.getFullYear();
2538
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
2539
+ const dd = String(d.getDate()).padStart(2, "0");
2540
+ const HH = String(d.getHours()).padStart(2, "0");
2541
+ const MM = String(d.getMinutes()).padStart(2, "0");
2542
+ const SS = String(d.getSeconds()).padStart(2, "0");
2543
+ return `${yyyy}-${mm}-${dd} ${HH}:${MM}:${SS}`;
2544
+ }
2545
+ if (format === "relative") {
2546
+ return formatRelativeTime(date);
2547
+ }
2548
+ return new Intl.DateTimeFormat(locale, {
2549
+ timeZone,
2550
+ year: format.includes("yyyy") || format.includes("y") ? "numeric" : void 0,
2551
+ month: format.includes("MM") || format.includes("M") ? "numeric" : void 0,
2552
+ day: format.includes("dd") || format.includes("d") ? "numeric" : void 0,
2553
+ hour: format.includes("HH") || format.includes("H") ? "numeric" : void 0,
2554
+ minute: format.includes("mm") || format.includes("m") ? "numeric" : void 0,
2555
+ second: format.includes("ss") || format.includes("s") ? "numeric" : void 0,
2556
+ hour12: !format.includes("HH") && !format.includes("H")
2557
+ }).format(d);
2558
+ }
2559
+ __name(formatDate, "formatDate");
2560
+ function formatRelativeTime(date, now = /* @__PURE__ */ new Date(), locale) {
2561
+ const d1 = date instanceof Date ? date : new Date(date);
2562
+ const d2 = now instanceof Date ? now : new Date(now);
2563
+ const diffMs = d1.getTime() - d2.getTime();
2564
+ const diffSecs = Math.round(diffMs / 1e3);
2565
+ const diffMins = Math.round(diffSecs / 60);
2566
+ const diffHours = Math.round(diffMins / 60);
2567
+ const diffDays = Math.round(diffHours / 24);
2568
+ const diffMonths = Math.round(diffDays / 30);
2569
+ const diffYears = Math.round(diffDays / 365);
2570
+ const formatter = new Intl.RelativeTimeFormat(locale, {
2571
+ numeric: "auto"
2572
+ });
2573
+ if (Math.abs(diffSecs) < 60) return formatter.format(diffSecs, "second");
2574
+ if (Math.abs(diffMins) < 60) return formatter.format(diffMins, "minute");
2575
+ if (Math.abs(diffHours) < 24) return formatter.format(diffHours, "hour");
2576
+ if (Math.abs(diffDays) < 30) return formatter.format(diffDays, "day");
2577
+ if (Math.abs(diffMonths) < 12) return formatter.format(diffMonths, "month");
2578
+ return formatter.format(diffYears, "year");
2579
+ }
2580
+ __name(formatRelativeTime, "formatRelativeTime");
2581
+ function parseDate(input, fallback) {
2582
+ if (typeof input === "number") {
2583
+ return new Date(input);
2584
+ }
2585
+ try {
2586
+ const date = new Date(input);
2587
+ if (isNaN(date.getTime())) {
2588
+ return fallback || null;
2589
+ }
2590
+ return date;
2591
+ } catch {
2592
+ return fallback || null;
2593
+ }
2594
+ }
2595
+ __name(parseDate, "parseDate");
2596
+ function dateDiff(date1, date2 = /* @__PURE__ */ new Date(), unit = "days") {
2597
+ const d1 = date1 instanceof Date ? date1 : new Date(date1);
2598
+ const d2 = date2 instanceof Date ? date2 : new Date(date2);
2599
+ const diffMs = d1.getTime() - d2.getTime();
2600
+ switch (unit) {
2601
+ case "milliseconds":
2602
+ return diffMs;
2603
+ case "seconds":
2604
+ return diffMs / 1e3;
2605
+ case "minutes":
2606
+ return diffMs / (1e3 * 60);
2607
+ case "hours":
2608
+ return diffMs / (1e3 * 60 * 60);
2609
+ case "days":
2610
+ return diffMs / (1e3 * 60 * 60 * 24);
2611
+ case "months":
2612
+ return (d1.getFullYear() - d2.getFullYear()) * 12 + d1.getMonth() - d2.getMonth();
2613
+ case "years":
2614
+ return d1.getFullYear() - d2.getFullYear();
2615
+ default:
2616
+ throw new Error(`Unsupported unit: ${unit}`);
2617
+ }
2618
+ }
2619
+ __name(dateDiff, "dateDiff");
2620
+ function addToDate(date, amount, unit) {
2621
+ const d = date instanceof Date ? new Date(date) : new Date(date);
2622
+ switch (unit) {
2623
+ case "milliseconds":
2624
+ d.setMilliseconds(d.getMilliseconds() + amount);
2625
+ break;
2626
+ case "seconds":
2627
+ d.setSeconds(d.getSeconds() + amount);
2628
+ break;
2629
+ case "minutes":
2630
+ d.setMinutes(d.getMinutes() + amount);
2631
+ break;
2632
+ case "hours":
2633
+ d.setHours(d.getHours() + amount);
2634
+ break;
2635
+ case "days":
2636
+ d.setDate(d.getDate() + amount);
2637
+ break;
2638
+ case "months": {
2639
+ const origDate = d.getDate();
2640
+ const origMonth = d.getMonth();
2641
+ d.setDate(1);
2642
+ d.setMonth(origMonth + amount);
2643
+ const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
2644
+ d.setDate(Math.min(origDate, lastDay));
2645
+ break;
2646
+ }
2647
+ case "years":
2648
+ d.setFullYear(d.getFullYear() + amount);
2649
+ break;
2650
+ default:
2651
+ throw new Error(`Unsupported unit: ${unit}`);
2652
+ }
2653
+ return d;
2654
+ }
2655
+ __name(addToDate, "addToDate");
2656
+ function startOf(date, unit) {
2657
+ const d = date instanceof Date ? new Date(date) : new Date(date);
2658
+ switch (unit) {
2659
+ case "second":
2660
+ d.setMilliseconds(0);
2661
+ break;
2662
+ case "minute":
2663
+ d.setSeconds(0, 0);
2664
+ break;
2665
+ case "hour":
2666
+ d.setMinutes(0, 0, 0);
2667
+ break;
2668
+ case "day":
2669
+ d.setHours(0, 0, 0, 0);
2670
+ break;
2671
+ case "week":
2672
+ d.setHours(0, 0, 0, 0);
2673
+ d.setDate(d.getDate() - d.getDay());
2674
+ break;
2675
+ case "month":
2676
+ d.setDate(1);
2677
+ d.setHours(0, 0, 0, 0);
2678
+ break;
2679
+ case "quarter":
2680
+ d.setMonth(Math.floor(d.getMonth() / 3) * 3, 1);
2681
+ d.setHours(0, 0, 0, 0);
2682
+ break;
2683
+ case "year":
2684
+ d.setMonth(0, 1);
2685
+ d.setHours(0, 0, 0, 0);
2686
+ break;
2687
+ default:
2688
+ throw new Error(`Unsupported unit: ${unit}`);
2689
+ }
2690
+ return d;
2691
+ }
2692
+ __name(startOf, "startOf");
2693
+ function endOf(date, unit) {
2694
+ const d = date instanceof Date ? new Date(date) : new Date(date);
2695
+ switch (unit) {
2696
+ case "second":
2697
+ d.setMilliseconds(999);
2698
+ break;
2699
+ case "minute":
2700
+ d.setSeconds(59, 999);
2701
+ break;
2702
+ case "hour":
2703
+ d.setMinutes(59, 59, 999);
2704
+ break;
2705
+ case "day":
2706
+ d.setHours(23, 59, 59, 999);
2707
+ break;
2708
+ case "week":
2709
+ d.setDate(d.getDate() - d.getDay() + 6);
2710
+ d.setHours(23, 59, 59, 999);
2711
+ break;
2712
+ case "month":
2713
+ d.setMonth(d.getMonth() + 1, 0);
2714
+ d.setHours(23, 59, 59, 999);
2715
+ break;
2716
+ case "quarter":
2717
+ d.setMonth(Math.floor(d.getMonth() / 3) * 3 + 3, 0);
2718
+ d.setHours(23, 59, 59, 999);
2719
+ break;
2720
+ case "year":
2721
+ d.setMonth(11, 31);
2722
+ d.setHours(23, 59, 59, 999);
2723
+ break;
2724
+ default:
2725
+ throw new Error(`Unsupported unit: ${unit}`);
2726
+ }
2727
+ return d;
2728
+ }
2729
+ __name(endOf, "endOf");
2730
+ function isBetween(date, start, end, inclusive = true) {
2731
+ const d = date instanceof Date ? date.getTime() : date;
2732
+ const s = start instanceof Date ? start.getTime() : start;
2733
+ const e = end instanceof Date ? end.getTime() : end;
2734
+ return inclusive ? d >= s && d <= e : d > s && d < e;
2735
+ }
2736
+ __name(isBetween, "isBetween");
2737
+ function isLeapYear(year) {
2738
+ const y = year instanceof Date ? year.getFullYear() : year;
2739
+ return y % 4 === 0 && y % 100 !== 0 || y % 400 === 0;
2740
+ }
2741
+ __name(isLeapYear, "isLeapYear");
2742
+ function daysInMonth(year, month) {
2743
+ if (year instanceof Date) {
2744
+ month = year.getMonth();
2745
+ year = year.getFullYear();
2746
+ }
2747
+ if (month === void 0) {
2748
+ throw new Error("Month is required when year is a number");
2749
+ }
2750
+ return new Date(year, month + 1, 0).getDate();
2751
+ }
2752
+ __name(daysInMonth, "daysInMonth");
2753
+
2507
2754
  // src/utils/response.utils.ts
2508
2755
  var SuccessResponse = class {
2509
2756
  static {
@@ -3527,7 +3774,7 @@ function registerControllers(router, controllers) {
3527
3774
  diContainer.register(ControllerClass);
3528
3775
  }
3529
3776
  const instance = diContainer.get(ControllerClass);
3530
- const basePath = Reflect.getMetadata("basePath", ControllerClass) || "";
3777
+ let basePath = Reflect.getMetadata("basePath", ControllerClass) || "";
3531
3778
  const routes = Reflect.getMetadata(ROUTES_KEY, ControllerClass) || [];
3532
3779
  const controllerRateLimit = Reflect.getMetadata(RATE_LIMIT_KEY, ControllerClass);
3533
3780
  const controllerCache = Reflect.getMetadata(CACHE_KEY, ControllerClass);
@@ -3540,6 +3787,9 @@ function registerControllers(router, controllers) {
3540
3787
  const controllerBeforeHooks = Reflect.getMetadata(BEFORE_KEY, ControllerClass) || [];
3541
3788
  const controllerAfterHooks = Reflect.getMetadata(AFTER_KEY, ControllerClass) || [];
3542
3789
  const controllerContentType = Reflect.getMetadata(CONTENT_TYPE_KEY, ControllerClass);
3790
+ if (controllerVersion?.options?.addPrefix) {
3791
+ basePath = `/${controllerVersion.version}${basePath || ""}`;
3792
+ }
3543
3793
  routes.forEach(({ path: path3, method, handlerName }) => {
3544
3794
  const methodMiddlewares = Reflect.getMetadata(MIDDLEWARE_KEY, instance, handlerName) || [];
3545
3795
  const params = Reflect.getMetadata(PARAMS_KEY, instance, handlerName) || [];
@@ -3569,7 +3819,8 @@ function registerControllers(router, controllers) {
3569
3819
  const roles = Reflect.getMetadata(ROLES_KEY, instance, handlerName) || controllerRoles || [];
3570
3820
  const cache = Reflect.getMetadata(CACHE_KEY, instance, handlerName) || controllerCache;
3571
3821
  const rateLimitOptions = Reflect.getMetadata(RATE_LIMIT_KEY, instance, handlerName) || controllerRateLimit;
3572
- const version = Reflect.getMetadata(VERSION_KEY, instance, handlerName) || controllerVersion;
3822
+ const methodVersion = Reflect.getMetadata(VERSION_KEY, instance, handlerName);
3823
+ const version = methodVersion || controllerVersion;
3573
3824
  const timeout2 = Reflect.getMetadata(TIMEOUT_KEY, instance, handlerName) || controllerTimeout;
3574
3825
  const logConfig = Reflect.getMetadata(LOG_KEY, instance, handlerName) || controllerLogConfig;
3575
3826
  let rateLimiter = null;
@@ -3583,8 +3834,8 @@ function registerControllers(router, controllers) {
3583
3834
  }
3584
3835
  }
3585
3836
  let finalPath = path3;
3586
- if (version?.options?.addPrefix) {
3587
- finalPath = `/${version.version}${path3}`;
3837
+ if (methodVersion?.options?.addPrefix && methodVersion.version !== controllerVersion?.version) {
3838
+ finalPath = `/${methodVersion.version}${path3}`;
3588
3839
  }
3589
3840
  const handler = /* @__PURE__ */ __name(async (req, res, next) => {
3590
3841
  req["startTime"] = Date.now();
@@ -4573,6 +4824,202 @@ function healthCheck(options) {
4573
4824
  }
4574
4825
  __name(healthCheck, "healthCheck");
4575
4826
 
4827
+ // src/utils/performance.utils.ts
4828
+ function timeSync(fn, options = {}) {
4829
+ const { label = fn.name || "anonymous function", log = false, logLevel = "debug" } = options;
4830
+ const startTime = performance.now();
4831
+ const result = fn();
4832
+ const endTime = performance.now();
4833
+ const durationMs = endTime - startTime;
4834
+ const durationSec = durationMs / 1e3;
4835
+ const timing = {
4836
+ durationMs,
4837
+ durationSec,
4838
+ startTime,
4839
+ endTime,
4840
+ label
4841
+ };
4842
+ if (log) {
4843
+ const logger2 = getLogger();
4844
+ const message = `${label} completed in ${durationMs.toFixed(2)}ms`;
4845
+ switch (logLevel) {
4846
+ case "trace":
4847
+ logger2.trace({
4848
+ timing
4849
+ }, message);
4850
+ break;
4851
+ case "debug":
4852
+ logger2.debug({
4853
+ timing
4854
+ }, message);
4855
+ break;
4856
+ case "info":
4857
+ logger2.info({
4858
+ timing
4859
+ }, message);
4860
+ break;
4861
+ case "warn":
4862
+ logger2.warn({
4863
+ timing
4864
+ }, message);
4865
+ break;
4866
+ case "error":
4867
+ logger2.error({
4868
+ timing
4869
+ }, message);
4870
+ break;
4871
+ default:
4872
+ logger2.debug({
4873
+ timing
4874
+ }, message);
4875
+ break;
4876
+ }
4877
+ }
4878
+ return {
4879
+ result,
4880
+ timing
4881
+ };
4882
+ }
4883
+ __name(timeSync, "timeSync");
4884
+ async function timeAsync(fn, options = {}) {
4885
+ const { label = fn.name || "anonymous async function", log = false, logLevel = "debug" } = options;
4886
+ const startTime = performance.now();
4887
+ const result = await fn();
4888
+ const endTime = performance.now();
4889
+ const durationMs = endTime - startTime;
4890
+ const durationSec = durationMs / 1e3;
4891
+ const timing = {
4892
+ durationMs,
4893
+ durationSec,
4894
+ startTime,
4895
+ endTime,
4896
+ label
4897
+ };
4898
+ if (log) {
4899
+ const logger2 = getLogger();
4900
+ const message = `${label} completed in ${durationMs.toFixed(2)}ms`;
4901
+ switch (logLevel) {
4902
+ case "trace":
4903
+ logger2.trace({
4904
+ timing
4905
+ }, message);
4906
+ break;
4907
+ case "debug":
4908
+ logger2.debug({
4909
+ timing
4910
+ }, message);
4911
+ break;
4912
+ case "info":
4913
+ logger2.info({
4914
+ timing
4915
+ }, message);
4916
+ break;
4917
+ case "warn":
4918
+ logger2.warn({
4919
+ timing
4920
+ }, message);
4921
+ break;
4922
+ case "error":
4923
+ logger2.error({
4924
+ timing
4925
+ }, message);
4926
+ break;
4927
+ default:
4928
+ logger2.debug({
4929
+ timing
4930
+ }, message);
4931
+ break;
4932
+ }
4933
+ }
4934
+ return {
4935
+ result,
4936
+ timing
4937
+ };
4938
+ }
4939
+ __name(timeAsync, "timeAsync");
4940
+ function timed(options = {}) {
4941
+ return function(target, propertyKeyOrContext, descriptor) {
4942
+ let propertyKey;
4943
+ let actualDescriptor;
4944
+ if (typeof propertyKeyOrContext === "object" && propertyKeyOrContext !== null && "name" in propertyKeyOrContext) {
4945
+ propertyKey = propertyKeyOrContext.name;
4946
+ actualDescriptor = descriptor ?? Object.getOwnPropertyDescriptor(target, propertyKey);
4947
+ } else {
4948
+ propertyKey = propertyKeyOrContext;
4949
+ actualDescriptor = descriptor ?? Object.getOwnPropertyDescriptor(target, propertyKey);
4950
+ }
4951
+ const originalMethod = actualDescriptor.value;
4952
+ actualDescriptor.value = function(...args) {
4953
+ const methodOptions = {
4954
+ ...options,
4955
+ label: options.label || `${target.constructor.name}.${String(propertyKey)}`
4956
+ };
4957
+ if (originalMethod.constructor.name === "AsyncFunction") {
4958
+ return timeAsync(() => originalMethod.apply(this, args), methodOptions).then(({ result }) => result);
4959
+ } else {
4960
+ return timeSync(() => originalMethod.apply(this, args), methodOptions).result;
4961
+ }
4962
+ };
4963
+ if (descriptor) {
4964
+ descriptor.value = actualDescriptor.value;
4965
+ } else {
4966
+ Object.defineProperty(target, propertyKey, actualDescriptor);
4967
+ }
4968
+ };
4969
+ }
4970
+ __name(timed, "timed");
4971
+ function memoize(fn, options = {}) {
4972
+ const { ttl, maxSize, autoCleanupMs, cacheKey = /* @__PURE__ */ __name((...args) => JSON.stringify(args), "cacheKey") } = options;
4973
+ const cache = new TTLCache({
4974
+ ttlMs: ttl,
4975
+ maxSize,
4976
+ autoCleanupMs
4977
+ });
4978
+ return function(...args) {
4979
+ const key = cacheKey(...args);
4980
+ const cachedValue = cache.get(key);
4981
+ if (cachedValue !== void 0) {
4982
+ return cachedValue;
4983
+ }
4984
+ const value = fn(...args);
4985
+ cache.set(key, value);
4986
+ return value;
4987
+ };
4988
+ }
4989
+ __name(memoize, "memoize");
4990
+ function trackMemoryUsage(fn, options = {}) {
4991
+ const { log = false, label = fn.name || "anonymous function" } = options;
4992
+ if (global.gc) {
4993
+ global.gc();
4994
+ }
4995
+ const beforeMemory = process.memoryUsage();
4996
+ const result = fn();
4997
+ const afterMemory = process.memoryUsage();
4998
+ const diff = {};
4999
+ for (const key in afterMemory) {
5000
+ if (Object.prototype.hasOwnProperty.call(afterMemory, key)) {
5001
+ diff[key] = afterMemory[key] - beforeMemory[key];
5002
+ }
5003
+ }
5004
+ if (log) {
5005
+ getLogger().info({
5006
+ label,
5007
+ memoryBefore: beforeMemory,
5008
+ memoryAfter: afterMemory,
5009
+ memoryDiff: diff
5010
+ }, `Memory usage for ${label}`);
5011
+ }
5012
+ return {
5013
+ result,
5014
+ memoryUsage: {
5015
+ before: beforeMemory,
5016
+ after: afterMemory,
5017
+ diff
5018
+ }
5019
+ };
5020
+ }
5021
+ __name(trackMemoryUsage, "trackMemoryUsage");
5022
+
4576
5023
  // src/utils/request.utils.ts
4577
5024
  var getPaginationParams = /* @__PURE__ */ __name((req) => {
4578
5025
  const query = req.query;
@@ -4731,6 +5178,120 @@ function extractFilterParams(query, allowedFilters) {
4731
5178
  return filters;
4732
5179
  }
4733
5180
  __name(extractFilterParams, "extractFilterParams");
5181
+ function bufferToStream(data) {
5182
+ const readable = new stream.Readable();
5183
+ readable.push(data);
5184
+ readable.push(null);
5185
+ return readable;
5186
+ }
5187
+ __name(bufferToStream, "bufferToStream");
5188
+ async function streamToBuffer(stream) {
5189
+ return new Promise((resolve2, reject) => {
5190
+ const chunks = [];
5191
+ stream.on("data", (chunk2) => chunks.push(Buffer.isBuffer(chunk2) ? chunk2 : Buffer.from(chunk2)));
5192
+ stream.on("end", () => resolve2(Buffer.concat(chunks)));
5193
+ stream.on("error", reject);
5194
+ });
5195
+ }
5196
+ __name(streamToBuffer, "streamToBuffer");
5197
+ async function streamToString(stream, encoding = "utf8") {
5198
+ const buffer = await streamToBuffer(stream);
5199
+ return buffer.toString(encoding);
5200
+ }
5201
+ __name(streamToString, "streamToString");
5202
+ function createThrottleStream(bytesPerSecond) {
5203
+ let bytesSent = 0;
5204
+ let startTime = Date.now();
5205
+ return new stream.Transform({
5206
+ transform(chunk2, _encoding, callback) {
5207
+ const elapsedSeconds = (Date.now() - startTime) / 1e3;
5208
+ const targetBytes = bytesPerSecond * elapsedSeconds;
5209
+ const chunkSize = chunk2.length;
5210
+ if (bytesSent + chunkSize <= targetBytes) {
5211
+ bytesSent += chunkSize;
5212
+ callback(null, chunk2);
5213
+ return;
5214
+ }
5215
+ const delay = ((bytesSent + chunkSize) / bytesPerSecond - elapsedSeconds) * 1e3;
5216
+ setTimeout(() => {
5217
+ bytesSent += chunkSize;
5218
+ callback(null, chunk2);
5219
+ }, delay);
5220
+ }
5221
+ });
5222
+ }
5223
+ __name(createThrottleStream, "createThrottleStream");
5224
+ function createBatchStream(size, options = {}) {
5225
+ const objectMode = options.objectMode !== false;
5226
+ let batch = [];
5227
+ let buffers = [];
5228
+ let bufferSize = 0;
5229
+ return new stream.Transform({
5230
+ objectMode,
5231
+ transform(chunk2, _encoding, callback) {
5232
+ if (objectMode) {
5233
+ batch.push(chunk2);
5234
+ if (batch.length >= size) {
5235
+ this.push(batch);
5236
+ batch = [];
5237
+ }
5238
+ } else {
5239
+ const buffer = Buffer.isBuffer(chunk2) ? chunk2 : Buffer.from(chunk2);
5240
+ buffers.push(buffer);
5241
+ bufferSize += buffer.length;
5242
+ let combined = Buffer.concat(buffers, bufferSize);
5243
+ while (combined.length >= size) {
5244
+ this.push(combined.slice(0, size));
5245
+ combined = combined.slice(size);
5246
+ }
5247
+ buffers = combined.length > 0 ? [
5248
+ combined
5249
+ ] : [];
5250
+ bufferSize = combined.length;
5251
+ }
5252
+ callback();
5253
+ },
5254
+ flush(callback) {
5255
+ if (objectMode && batch.length > 0) {
5256
+ this.push(batch);
5257
+ } else if (!objectMode && buffers.length > 0 && bufferSize > 0) {
5258
+ let combined = Buffer.concat(buffers, bufferSize);
5259
+ while (combined.length >= size) {
5260
+ this.push(combined.slice(0, size));
5261
+ combined = combined.slice(size);
5262
+ }
5263
+ if (combined.length > 0) {
5264
+ this.push(combined);
5265
+ }
5266
+ }
5267
+ callback();
5268
+ }
5269
+ });
5270
+ }
5271
+ __name(createBatchStream, "createBatchStream");
5272
+ function createLineStream(options = {}) {
5273
+ const { encoding = "utf8", includeNewlines = false } = options;
5274
+ let buffer = "";
5275
+ return new stream.Transform({
5276
+ objectMode: true,
5277
+ transform(chunk2, _encoding, callback) {
5278
+ const str = buffer + (Buffer.isBuffer(chunk2) ? chunk2.toString(encoding) : chunk2);
5279
+ const lines = str.split(/\r?\n/);
5280
+ buffer = lines.pop() || "";
5281
+ for (const line of lines) {
5282
+ this.push(includeNewlines ? line + "\n" : line);
5283
+ }
5284
+ callback();
5285
+ },
5286
+ flush(callback) {
5287
+ if (buffer) {
5288
+ this.push(buffer);
5289
+ }
5290
+ callback();
5291
+ }
5292
+ });
5293
+ }
5294
+ __name(createLineStream, "createLineStream");
4734
5295
 
4735
5296
  // src/utils/string.utils.ts
4736
5297
  function capitalize(str) {
@@ -4790,6 +5351,84 @@ function countOccurrences(str, substring, caseSensitive = true) {
4790
5351
  return str.split(substring).length - 1;
4791
5352
  }
4792
5353
  __name(countOccurrences, "countOccurrences");
5354
+
5355
+ // src/utils/type.utils.ts
5356
+ function isPrimitiveType(value, type) {
5357
+ if (type === "array") {
5358
+ return Array.isArray(value);
5359
+ }
5360
+ if (type === "null") {
5361
+ return value === null;
5362
+ }
5363
+ if (type === "undefined") {
5364
+ return value === void 0;
5365
+ }
5366
+ if (type === "object") {
5367
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5368
+ }
5369
+ return typeof value === type;
5370
+ }
5371
+ __name(isPrimitiveType, "isPrimitiveType");
5372
+ function getTypeOf(value) {
5373
+ if (value === null) return "null";
5374
+ if (value === void 0) return "undefined";
5375
+ if (Array.isArray(value)) return "array";
5376
+ return typeof value;
5377
+ }
5378
+ __name(getTypeOf, "getTypeOf");
5379
+ function isArrayOf(value, itemTypeGuard) {
5380
+ if (!Array.isArray(value)) return false;
5381
+ return value.every((item) => itemTypeGuard(item));
5382
+ }
5383
+ __name(isArrayOf, "isArrayOf");
5384
+ function toStr(value, defaultValue = "") {
5385
+ if (value === null || value === void 0) return defaultValue;
5386
+ try {
5387
+ if (typeof value === "object") {
5388
+ return JSON.stringify(value);
5389
+ }
5390
+ return String(value);
5391
+ } catch {
5392
+ return defaultValue;
5393
+ }
5394
+ }
5395
+ __name(toStr, "toStr");
5396
+ function toNum(value, defaultValue = 0) {
5397
+ if (value === null || value === void 0) return defaultValue;
5398
+ if (typeof value === "number") return value;
5399
+ try {
5400
+ const num = Number(value);
5401
+ return isNaN(num) ? defaultValue : num;
5402
+ } catch {
5403
+ return defaultValue;
5404
+ }
5405
+ }
5406
+ __name(toNum, "toNum");
5407
+ function toBool(value, defaultValue = false) {
5408
+ if (value === null || value === void 0) return defaultValue;
5409
+ if (typeof value === "boolean") return value;
5410
+ if (typeof value === "string") {
5411
+ const lowercased = value.toLowerCase();
5412
+ if (lowercased === "true" || lowercased === "yes" || lowercased === "y" || lowercased === "1") {
5413
+ return true;
5414
+ }
5415
+ if (lowercased === "false" || lowercased === "no" || lowercased === "n" || lowercased === "0") {
5416
+ return false;
5417
+ }
5418
+ }
5419
+ if (typeof value === "number") {
5420
+ return value !== 0;
5421
+ }
5422
+ return defaultValue;
5423
+ }
5424
+ __name(toBool, "toBool");
5425
+ function ensureType(value, expectedType, defaultValue) {
5426
+ if (getTypeOf(value) === expectedType) {
5427
+ return value;
5428
+ }
5429
+ return defaultValue;
5430
+ }
5431
+ __name(ensureType, "ensureType");
4793
5432
  function appendQueryParams(url$1, params) {
4794
5433
  const urlObj = new url.URL(url$1);
4795
5434
  for (const [key, value] of Object.entries(params)) {
@@ -6179,7 +6818,7 @@ var ExpressServer = class _ExpressServer {
6179
6818
  const healthCheckPath = this.normalizePath(this.config.healthCheck?.path || "/healthz", this.config.healthCheck?.withGlobalPrefix);
6180
6819
  this.app.get(healthCheckPath, async (_req, res) => {
6181
6820
  try {
6182
- if (!this.healthChecks.length) {
6821
+ if (!this.healthChecks.length || config.server.skipHealthz) {
6183
6822
  return res.status(HttpStatusCodes.OK).json(new SuccessResponse("OK"));
6184
6823
  }
6185
6824
  const checkResults = await Promise.allSettled(this.healthChecks.map(async ({ name, check }) => {
@@ -6720,8 +7359,10 @@ exports._globalThis = _globalThis;
6720
7359
  exports.abortable = abortable;
6721
7360
  exports.addRedactFields = addRedactFields;
6722
7361
  exports.addSensitiveFields = addSensitiveFields;
7362
+ exports.addToDate = addToDate;
6723
7363
  exports.appendQueryParams = appendQueryParams;
6724
7364
  exports.appendTextFile = appendTextFile;
7365
+ exports.bufferToStream = bufferToStream;
6725
7366
  exports.capitalize = capitalize;
6726
7367
  exports.chunk = chunk;
6727
7368
  exports.circuitBreaker = circuitBreaker;
@@ -6730,12 +7371,14 @@ exports.copyDir = copyDir;
6730
7371
  exports.copyFile = copyFile;
6731
7372
  exports.countBy = countBy;
6732
7373
  exports.countOccurrences = countOccurrences;
7374
+ exports.createBatchStream = createBatchStream;
6733
7375
  exports.createChildLogger = createChildLogger;
6734
7376
  exports.createDeferred = createDeferred;
6735
7377
  exports.createDirectory = createDirectory;
6736
7378
  exports.createErrorResponse = createErrorResponse;
6737
7379
  exports.createFinalErrorResponse = createFinalErrorResponse;
6738
7380
  exports.createHttpError = createHttpError;
7381
+ exports.createLineStream = createLineStream;
6739
7382
  exports.createPaginatedResponse = createPaginatedResponse;
6740
7383
  exports.createParamDecorator = createParamDecorator;
6741
7384
  exports.createParamDecoratorWithoutParam = createParamDecoratorWithoutParam;
@@ -6745,7 +7388,10 @@ exports.createSuccessResponse = createSuccessResponse;
6745
7388
  exports.createTaskQueue = createTaskQueue;
6746
7389
  exports.createTempDir = createTempDir;
6747
7390
  exports.createTempFile = createTempFile;
7391
+ exports.createThrottleStream = createThrottleStream;
6748
7392
  exports.createUrlBuilder = createUrlBuilder;
7393
+ exports.dateDiff = dateDiff;
7394
+ exports.daysInMonth = daysInMonth;
6749
7395
  exports.debounce = debounce;
6750
7396
  exports.decrypt = decrypt;
6751
7397
  exports.deepFreeze = deepFreeze;
@@ -6756,8 +7402,10 @@ exports.deleteFileIfExists = deleteFileIfExists;
6756
7402
  exports.difference = difference;
6757
7403
  exports.emptyDir = emptyDir;
6758
7404
  exports.encrypt = encrypt;
7405
+ exports.endOf = endOf;
6759
7406
  exports.ensureDir = ensureDir;
6760
7407
  exports.ensureEmptyDir = ensureEmptyDir;
7408
+ exports.ensureType = ensureType;
6761
7409
  exports.equalsIgnoreCase = equalsIgnoreCase;
6762
7410
  exports.errorHandler = errorHandler;
6763
7411
  exports.extractFilterParams = extractFilterParams;
@@ -6772,6 +7420,8 @@ exports.findNewestFile = findNewestFile;
6772
7420
  exports.findOldestFile = findOldestFile;
6773
7421
  exports.flattenDeep = flattenDeep;
6774
7422
  exports.flattenObject = flattenObject;
7423
+ exports.formatDate = formatDate;
7424
+ exports.formatRelativeTime = formatRelativeTime;
6775
7425
  exports.generateApiKey = generateApiKey;
6776
7426
  exports.generateRandomBytes = generateRandomBytes;
6777
7427
  exports.generateRandomBytesAsString = generateRandomBytesAsString;
@@ -6790,6 +7440,7 @@ exports.getPaginationParams = getPaginationParams;
6790
7440
  exports.getRedactCensor = getRedactCensor;
6791
7441
  exports.getRequestId = getRequestId;
6792
7442
  exports.getSubdirectories = getSubdirectories;
7443
+ exports.getTypeOf = getTypeOf;
6793
7444
  exports.getValueByPath = getValueByPath;
6794
7445
  exports.groupBy = groupBy;
6795
7446
  exports.hasErrorShape = hasErrorShape;
@@ -6802,7 +7453,9 @@ exports.intersect = intersect;
6802
7453
  exports.isAlpha = isAlpha;
6803
7454
  exports.isAlphanumeric = isAlphanumeric;
6804
7455
  exports.isArray = isArray;
7456
+ exports.isArrayOf = isArrayOf;
6805
7457
  exports.isBase64 = isBase64;
7458
+ exports.isBetween = isBetween;
6806
7459
  exports.isCreditCard = isCreditCard;
6807
7460
  exports.isDateInRange = isDateInRange;
6808
7461
  exports.isDirectory = isDirectory;
@@ -6814,6 +7467,7 @@ exports.isHttpError = isHttpError;
6814
7467
  exports.isIPv4 = isIPv4;
6815
7468
  exports.isIPv6 = isIPv6;
6816
7469
  exports.isISODate = isISODate;
7470
+ exports.isLeapYear = isLeapYear;
6817
7471
  exports.isLengthBetween = isLengthBetween;
6818
7472
  exports.isNumberBetween = isNumberBetween;
6819
7473
  exports.isNumeric = isNumeric;
@@ -6822,6 +7476,7 @@ exports.isObject = isObject;
6822
7476
  exports.isPhone = isPhone;
6823
7477
  exports.isPlainObject = isPlainObject;
6824
7478
  exports.isPort = isPort;
7479
+ exports.isPrimitiveType = isPrimitiveType;
6825
7480
  exports.isStrongPassword = isStrongPassword;
6826
7481
  exports.isURL = isURL;
6827
7482
  exports.isUUID = isUUID;
@@ -6835,6 +7490,7 @@ exports.mapObject = mapObject;
6835
7490
  exports.mask = mask;
6836
7491
  exports.matchesPattern = matchesPattern;
6837
7492
  exports.md5 = md5;
7493
+ exports.memoize = memoize;
6838
7494
  exports.memoizeAsync = memoizeAsync;
6839
7495
  exports.mergeSort = mergeSort;
6840
7496
  exports.moveDir = moveDir;
@@ -6843,6 +7499,7 @@ exports.nanoId = nanoId;
6843
7499
  exports.normalizeUrl = normalizeUrl;
6844
7500
  exports.omit = omit;
6845
7501
  exports.parseBooleanParam = parseBooleanParam;
7502
+ exports.parseDate = parseDate;
6846
7503
  exports.parseNumberParam = parseNumberParam;
6847
7504
  exports.parseQueryString = parseQueryString;
6848
7505
  exports.parseTypedQueryParams = parseTypedQueryParams;
@@ -6886,16 +7543,26 @@ exports.shuffle = shuffle;
6886
7543
  exports.singletonAsync = singletonAsync;
6887
7544
  exports.sleep = sleep;
6888
7545
  exports.slugify = slugify;
7546
+ exports.startOf = startOf;
6889
7547
  exports.streamFile = streamFile;
7548
+ exports.streamToBuffer = streamToBuffer;
7549
+ exports.streamToString = streamToString;
6890
7550
  exports.stripHtml = stripHtml;
6891
7551
  exports.take = take;
6892
7552
  exports.takeWhile = takeWhile;
6893
7553
  exports.throttle = throttle;
7554
+ exports.timeAsync = timeAsync;
7555
+ exports.timeSync = timeSync;
7556
+ exports.timed = timed;
6894
7557
  exports.timeout = timeout;
7558
+ exports.toBool = toBool;
6895
7559
  exports.toCamelCase = toCamelCase;
6896
7560
  exports.toKebabCase = toKebabCase;
7561
+ exports.toNum = toNum;
6897
7562
  exports.toPascalCase = toPascalCase;
6898
7563
  exports.toSnakeCase = toSnakeCase;
7564
+ exports.toStr = toStr;
7565
+ exports.trackMemoryUsage = trackMemoryUsage;
6899
7566
  exports.truncate = truncate;
6900
7567
  exports.unique = unique;
6901
7568
  exports.uuid = uuid;