fiberx-backend-toolkit 1.0.14 → 1.0.15

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.
@@ -11,6 +11,14 @@ declare class InputValidatorUtil {
11
11
  private static readonly uuid_regex_reg_exp;
12
12
  private static readonly custom_uuid_regex_reg_exp;
13
13
  private static get env_manager();
14
+ static isValidDecimalString(value: string | null | undefined, max_whole_digits?: number, max_fraction_digits?: number, allow_zero?: boolean): boolean;
15
+ static compareDecimalStrings(first_value: string, second_value: string): number;
16
+ static isValidUpperCode(value: string, min_length?: number, max_length?: number): boolean;
17
+ static hasUnsafeControlCharacter(value: string): boolean;
18
+ static stableSerialize(value: unknown): string;
19
+ static hashString(value: string, algorithm?: "sha256" | "sha384" | "sha512"): string;
20
+ static hasSensitiveObjectKey(value: unknown): boolean;
21
+ static getJsonByteLength(value: unknown): number;
14
22
  static isValidateIn: (value: any, allowed: any[]) => boolean;
15
23
  /** ✅ Check member roles */
16
24
  static isAdmin(name: string): boolean;
@@ -25,6 +25,87 @@ class InputValidatorUtil {
25
25
  static get env_manager() {
26
26
  return env_manager_util_1.default.getInstance();
27
27
  }
28
+ // Method to validate a non-negative decimal string with bounded precision.
29
+ static isValidDecimalString(value, max_whole_digits = 18, max_fraction_digits = 18, allow_zero = true) {
30
+ if (value === null ||
31
+ value === undefined ||
32
+ max_whole_digits < 1 ||
33
+ max_fraction_digits < 0) {
34
+ return false;
35
+ }
36
+ const decimal_pattern = new RegExp(`^\\d{1,${max_whole_digits}}${max_fraction_digits > 0 ? `(?:\\.\\d{1,${max_fraction_digits}})?` : ""}$`);
37
+ return (decimal_pattern.test(value) &&
38
+ (allow_zero || this.compareDecimalStrings(value, "0") > 0));
39
+ }
40
+ // Method to compare unsigned decimal strings without floating-point conversion.
41
+ static compareDecimalStrings(first_value, second_value) {
42
+ const normalize_value = (value) => {
43
+ const [whole_value = "0", fraction_value = ""] = value.split(".");
44
+ return [whole_value.replace(/^0+(?=\d)/, "") || "0", fraction_value.replace(/0+$/, "")];
45
+ };
46
+ const [first_whole, first_fraction] = normalize_value(first_value);
47
+ const [second_whole, second_fraction] = normalize_value(second_value);
48
+ if (first_whole.length !== second_whole.length) {
49
+ return first_whole.length > second_whole.length ? 1 : -1;
50
+ }
51
+ if (first_whole !== second_whole) {
52
+ return first_whole > second_whole ? 1 : -1;
53
+ }
54
+ const fraction_length = Math.max(first_fraction.length, second_fraction.length);
55
+ const normalized_first_fraction = first_fraction.padEnd(fraction_length, "0");
56
+ const normalized_second_fraction = second_fraction.padEnd(fraction_length, "0");
57
+ if (normalized_first_fraction === normalized_second_fraction) {
58
+ return 0;
59
+ }
60
+ return normalized_first_fraction > normalized_second_fraction ? 1 : -1;
61
+ }
62
+ // Method to validate an uppercase code containing letters, numbers, underscores, or hyphens.
63
+ static isValidUpperCode(value, min_length = 2, max_length = 80) {
64
+ if (min_length < 1 ||
65
+ max_length < min_length ||
66
+ value.length < min_length ||
67
+ value.length > max_length) {
68
+ return false;
69
+ }
70
+ return /^[A-Z0-9_-]+$/.test(value);
71
+ }
72
+ // Method to detect unsafe control characters while allowing tab and line breaks.
73
+ static hasUnsafeControlCharacter(value) {
74
+ return [...value].some((character) => {
75
+ const character_code = character.charCodeAt(0);
76
+ return character_code < 32 && ![9, 10, 13].includes(character_code);
77
+ });
78
+ }
79
+ // Method to serialize JSON-compatible data using stable object-key ordering.
80
+ static stableSerialize(value) {
81
+ if (Array.isArray(value)) {
82
+ return `[${value.map((item) => this.stableSerialize(item)).join(",")}]`;
83
+ }
84
+ if (value && typeof value === "object") {
85
+ const entries = Object.entries(value).sort(([first_key], [second_key]) => first_key.localeCompare(second_key));
86
+ return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${this.stableSerialize(item)}`).join(",")}}`;
87
+ }
88
+ return JSON.stringify(value) ?? "null";
89
+ }
90
+ // Method to hash a string with a supported cryptographic digest algorithm.
91
+ static hashString(value, algorithm = "sha256") {
92
+ return crypto_1.default.createHash(algorithm).update(value).digest("hex");
93
+ }
94
+ // Method to detect sensitive property names recursively in object or array data.
95
+ static hasSensitiveObjectKey(value) {
96
+ if (Array.isArray(value)) {
97
+ return value.some((item) => this.hasSensitiveObjectKey(item));
98
+ }
99
+ if (!value || typeof value !== "object") {
100
+ return false;
101
+ }
102
+ const sensitive_key_pattern = /(password|secret|credential|token|api[_-]?key|card|cvv|pin)/i;
103
+ return Object.entries(value).some(([key, item]) => sensitive_key_pattern.test(key) || this.hasSensitiveObjectKey(item));
104
+ }
105
+ // Method to return the UTF-8 byte size of JSON-compatible data.
106
+ static getJsonByteLength(value) {
107
+ return Buffer.byteLength(JSON.stringify(value), "utf8");
108
+ }
28
109
  static isValidateIn = (value, allowed) => allowed.includes(value);
29
110
  /** ✅ Check member roles */
30
111
  static isAdmin(name) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fiberx-backend-toolkit",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "A TypeScript backend toolkit providing shared domain logic, infrastructure helpers, and utilities for FiberX server-side applications and services.",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",