@ibgib/ts-gib 0.5.21 → 0.5.23

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/src/helper.mts CHANGED
@@ -75,38 +75,50 @@ export function getIbAndGib({
75
75
  }
76
76
  }
77
77
 
78
+
78
79
  /**
79
- * normalizes via sorting keys and removing values that are undefined.
80
- * values that are null or empty strings are not removed.
80
+ * Normalizes an object/value for consistent hashing.
81
+ * - Recursively processes objects and arrays.
82
+ * - For objects:
83
+ * - Sorts keys alphabetically.
84
+ * - Removes properties whose values are `undefined`.
85
+ * - Keeps properties whose values are `null`.
86
+ * - For arrays:
87
+ * - Preserves element order.
88
+ * - Recursively normalizes each element.
89
+ * - Primitives (strings, numbers, booleans) and `null` are returned as is.
81
90
  *
82
- * this is DUPLICATED code in the respec file. any changes here must
83
- * manually be changed in the respec file!!!
91
+ * @param value The value to normalize.
92
+ * @returns The normalized value.
84
93
  *
85
- * @param obj to normalize (is not changed, e.g. keys aren't sorted in place)
94
+ * This has been adjusted due to conversation with Gemini and working on python
95
+ * port. The main thing here is that we normalize array members, but not the
96
+ * array itself. This way the array's order is preserved, but any object members
97
+ * are themselves normalized.
86
98
  */
87
- export function toNormalizedForHashing(obj: any): any {
88
- if (!obj) {
89
- return obj; /* <<<< returns early */
90
- } else if (typeof obj === 'string' || Array.isArray(obj)) {
91
- return obj.concat(); /* <<<< returns early */
92
- } else if (typeof obj !== 'object') {
93
- // Return non-objects as is, we don't know how to concat/copy it...hmm...
94
- return obj; /* <<<< returns early */
99
+ export function toNormalizedForHashing(value: any): any {
100
+ // Handle null, primitives (string, number, boolean) directly.
101
+ // `undefined` at the top level will be handled by the caller or become part of an object/array.
102
+ if (value === null || typeof value !== 'object') {
103
+ return value;
95
104
  }
96
105
 
97
- // we have an object. we will create a new object and populate it.
98
- const normalized = {};
106
+ // Handle Arrays: recursively normalize elements, preserve order
107
+ if (Array.isArray(value)) {
108
+ return value.map(element => toNormalizedForHashing(element));
109
+ }
99
110
 
100
- // sort keys alphabetically
101
- // NOTE: this does NOT mutate obj as Object.keys produces a new array
102
- const keys = Object.keys(obj).sort();
111
+ // Handle Objects (plain objects)
112
+ const normalizedObject: { [key: string]: any } = {};
113
+ const sortedKeys = Object.keys(value).sort();
103
114
 
104
- for (const key of keys) {
105
- const value = obj[key];
106
- if (value !== undefined) {
107
- // Recursively normalize if the value is an object
108
- normalized[key] = (typeof value === 'object' && value !== null) ? toNormalizedForHashing(value) : value;
115
+ for (const key of sortedKeys) {
116
+ const propertyValue = value[key];
117
+ if (propertyValue !== undefined) { // CRITICAL: Only omit if value is undefined
118
+ normalizedObject[key] = toNormalizedForHashing(propertyValue);
109
119
  }
120
+ // If propertyValue is undefined, it's omitted from normalizedObject.
121
+ // If propertyValue is null, it's included.
110
122
  }
111
- return normalized;
123
+ return normalizedObject;
112
124
  }