@pagopa/io-react-native-wallet 2.4.2 → 2.5.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/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js +148 -123
- package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
- package/lib/commonjs/sd-jwt/index.js.map +1 -1
- package/lib/commonjs/utils/parser.js +20 -0
- package/lib/commonjs/utils/parser.js.map +1 -0
- package/lib/module/credential/issuance/07-verify-and-parse-credential.js +144 -119
- package/lib/module/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
- package/lib/module/sd-jwt/__test__/index.test.js +1 -1
- package/lib/module/sd-jwt/__test__/index.test.js.map +1 -1
- package/lib/module/sd-jwt/index.js +1 -3
- package/lib/module/sd-jwt/index.js.map +1 -1
- package/lib/module/utils/parser.js +12 -0
- package/lib/module/utils/parser.js.map +1 -0
- package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts.map +1 -1
- package/lib/typescript/sd-jwt/index.d.ts +1 -1
- package/lib/typescript/sd-jwt/index.d.ts.map +1 -1
- package/lib/typescript/utils/parser.d.ts +9 -0
- package/lib/typescript/utils/parser.d.ts.map +1 -0
- package/package.json +7 -2
- package/src/credential/issuance/07-verify-and-parse-credential.ts +138 -94
- package/src/sd-jwt/__test__/index.test.ts +1 -1
- package/src/sd-jwt/index.ts +7 -5
- package/src/utils/parser.ts +18 -0
- package/lib/commonjs/utils/nestedProperty.js +0 -153
- package/lib/commonjs/utils/nestedProperty.js.map +0 -1
- package/lib/module/utils/nestedProperty.js +0 -147
- package/lib/module/utils/nestedProperty.js.map +0 -1
- package/lib/typescript/utils/nestedProperty.d.ts +0 -24
- package/lib/typescript/utils/nestedProperty.d.ts.map +0 -1
- package/src/utils/nestedProperty.ts +0 -223
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { isObject } from "./misc";
|
|
2
|
-
|
|
3
|
-
// The data used to create localized names
|
|
4
|
-
|
|
5
|
-
// The resulting object of localized names { en: "Name", it: "Nome" }
|
|
6
|
-
|
|
7
|
-
// The core structure being built: a node containing the actual value and its localized names
|
|
8
|
-
|
|
9
|
-
// A path can consist of object keys, array indices, or null for mapping
|
|
10
|
-
|
|
11
|
-
// A union of all possible shapes. It can be a custom PropertyNode or a standard object/array structure
|
|
12
|
-
|
|
13
|
-
// Helper to build localized names from the display data.
|
|
14
|
-
const buildName = display => display.reduce((names, _ref) => {
|
|
15
|
-
let {
|
|
16
|
-
locale,
|
|
17
|
-
name
|
|
18
|
-
} = _ref;
|
|
19
|
-
return {
|
|
20
|
-
...names,
|
|
21
|
-
[locale]: name
|
|
22
|
-
};
|
|
23
|
-
}, {});
|
|
24
|
-
|
|
25
|
-
// Handles the case where the path key is `null` (indicating an array)
|
|
26
|
-
const handleNullKeyCase = (currentObject, rest, sourceValue, displayData) => {
|
|
27
|
-
if (!Array.isArray(sourceValue)) return currentObject;
|
|
28
|
-
|
|
29
|
-
// We assert the type here because we know this branch handles PropertyNodes
|
|
30
|
-
const node = currentObject;
|
|
31
|
-
const existingValue = Array.isArray(node.value) ? node.value : [];
|
|
32
|
-
const mappedArray = sourceValue.map((item, idx) =>
|
|
33
|
-
// When mapping over an array, recursively call with `skipMissingLeaves` set to `true`.
|
|
34
|
-
// This tells the function to skip optional keys inside these array objects.
|
|
35
|
-
createNestedProperty(existingValue[idx] || {}, rest, item, displayData, true));
|
|
36
|
-
return {
|
|
37
|
-
...node,
|
|
38
|
-
value: mappedArray,
|
|
39
|
-
name: node.name ?? buildName(displayData)
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Handles the case where the path key is a string
|
|
44
|
-
const handleStringKeyCase = (currentObject, key, rest, sourceValue, displayData, skipMissingLeaves) => {
|
|
45
|
-
let nextSourceValue = sourceValue;
|
|
46
|
-
const isLeaf = rest.length === 0;
|
|
47
|
-
if (isObject(sourceValue)) {
|
|
48
|
-
// Check if any remaining string keys in the path exist in current sourceValue
|
|
49
|
-
// This handles nested object paths (unlike arrays which use null in the path)
|
|
50
|
-
const hasRestKey = rest.some(r => typeof r === "string" && r in sourceValue);
|
|
51
|
-
if (hasRestKey) {
|
|
52
|
-
return handleRestKey(currentObject, key, rest, sourceValue, displayData);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Skip processing when the key is not found within the claim object
|
|
56
|
-
if (!(key in sourceValue)) {
|
|
57
|
-
// If the flag is set (we're inside an array), skip the missing key completely.
|
|
58
|
-
if (skipMissingLeaves) {
|
|
59
|
-
return currentObject;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// If the flag is NOT set, create the empty placeholder
|
|
63
|
-
// so that its children can be attached later.
|
|
64
|
-
if (isLeaf) {
|
|
65
|
-
return {
|
|
66
|
-
...currentObject,
|
|
67
|
-
[key]: {
|
|
68
|
-
value: {},
|
|
69
|
-
name: buildName(displayData)
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
// Skip processing when the key is not found within the claim object
|
|
74
|
-
return currentObject;
|
|
75
|
-
}
|
|
76
|
-
nextSourceValue = sourceValue[key];
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// base case
|
|
80
|
-
if (isLeaf) {
|
|
81
|
-
return {
|
|
82
|
-
...currentObject,
|
|
83
|
-
[key]: {
|
|
84
|
-
value: nextSourceValue,
|
|
85
|
-
name: buildName(displayData)
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// recursive step
|
|
91
|
-
const nextObject = currentObject[key] || {};
|
|
92
|
-
return {
|
|
93
|
-
...currentObject,
|
|
94
|
-
[key]: createNestedProperty(nextObject, rest, nextSourceValue, displayData, skipMissingLeaves)
|
|
95
|
-
};
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// Handles the case where the path key is a number
|
|
99
|
-
const handleNumberKeyCase = (currentObject, key, rest, sourceValue, displayData) => {
|
|
100
|
-
const newArray = Array.isArray(currentObject) ? [...currentObject] : [];
|
|
101
|
-
const nextValue = Array.isArray(sourceValue) ? sourceValue[key] : undefined;
|
|
102
|
-
newArray[key] = createNestedProperty(newArray[key] || {}, rest, nextValue, displayData);
|
|
103
|
-
return newArray;
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Recursively constructs a nested object with descriptive properties from a path.
|
|
108
|
-
*
|
|
109
|
-
* @param currentObject - The object or array being built upon.
|
|
110
|
-
* @param path - The path segments to follow.
|
|
111
|
-
* @param sourceValue - The raw value to place at the end of the path.
|
|
112
|
-
* @param displayData - The data for generating localized names.
|
|
113
|
-
* @param skipMissingLeaves - If true, skips optional keys when mapping over arrays.
|
|
114
|
-
* @returns The new object or array structure.
|
|
115
|
-
*/
|
|
116
|
-
export const createNestedProperty = function (currentObject, path, sourceValue, displayData) {
|
|
117
|
-
let skipMissingLeaves = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
118
|
-
const [key, ...rest] = path;
|
|
119
|
-
switch (true) {
|
|
120
|
-
case key === null:
|
|
121
|
-
return handleNullKeyCase(currentObject, rest, sourceValue, displayData);
|
|
122
|
-
case typeof key === "string":
|
|
123
|
-
return handleStringKeyCase(currentObject, key, rest, sourceValue, displayData, skipMissingLeaves);
|
|
124
|
-
case typeof key === "number":
|
|
125
|
-
return handleNumberKeyCase(currentObject, key, rest, sourceValue, displayData);
|
|
126
|
-
default:
|
|
127
|
-
return currentObject;
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// Handles the case where the next key in the path exists in the source object
|
|
132
|
-
const handleRestKey = (currentObject, key, rest, sourceValue, displayData) => {
|
|
133
|
-
const currentNode = currentObject[key] ?? {};
|
|
134
|
-
const restKey = rest[0];
|
|
135
|
-
const nextSourceValue = sourceValue[restKey];
|
|
136
|
-
if (typeof nextSourceValue === "undefined") {
|
|
137
|
-
return currentObject;
|
|
138
|
-
}
|
|
139
|
-
return {
|
|
140
|
-
...currentObject,
|
|
141
|
-
[key]: {
|
|
142
|
-
...currentNode,
|
|
143
|
-
value: createNestedProperty(currentNode.value ?? {}, rest, nextSourceValue, displayData)
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
};
|
|
147
|
-
//# sourceMappingURL=nestedProperty.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["isObject","buildName","display","reduce","names","_ref","locale","name","handleNullKeyCase","currentObject","rest","sourceValue","displayData","Array","isArray","node","existingValue","value","mappedArray","map","item","idx","createNestedProperty","handleStringKeyCase","key","skipMissingLeaves","nextSourceValue","isLeaf","length","hasRestKey","some","r","handleRestKey","nextObject","handleNumberKeyCase","newArray","nextValue","undefined","path","arguments","currentNode","restKey"],"sourceRoot":"../../../src","sources":["utils/nestedProperty.ts"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,QAAQ;;AAEjC;;AAGA;;AAGA;;AAMA;;AAGA;;AAGA;AACA,MAAMC,SAAS,GAAIC,OAAoB,IACrCA,OAAO,CAACC,MAAM,CACZ,CAACC,KAAK,EAAAC,IAAA;EAAA,IAAE;IAAEC,MAAM;IAAEC;EAAK,CAAC,GAAAF,IAAA;EAAA,OAAM;IAAE,GAAGD,KAAK;IAAE,CAACE,MAAM,GAAGC;EAAK,CAAC;AAAA,CAAC,EAC3D,CAAC,CACH,CAAC;;AAEH;AACA,MAAMC,iBAAiB,GAAGA,CACxBC,aAA8B,EAC9BC,IAAU,EACVC,WAAoB,EACpBC,WAAwB,KACJ;EACpB,IAAI,CAACC,KAAK,CAACC,OAAO,CAACH,WAAW,CAAC,EAAE,OAAOF,aAAa;;EAErD;EACA,MAAMM,IAAI,GAAGN,aAAiD;EAC9D,MAAMO,aAAa,GAAGH,KAAK,CAACC,OAAO,CAACC,IAAI,CAACE,KAAK,CAAC,GAAGF,IAAI,CAACE,KAAK,GAAG,EAAE;EAEjE,MAAMC,WAAW,GAAGP,WAAW,CAACQ,GAAG,CAAC,CAACC,IAAI,EAAEC,GAAG;EAC5C;EACA;EACAC,oBAAoB,CAClBN,aAAa,CAACK,GAAG,CAAC,IAAI,CAAC,CAAC,EACxBX,IAAI,EACJU,IAAI,EACJR,WAAW,EACX,IACF,CACF,CAAC;EAED,OAAO;IACL,GAAGG,IAAI;IACPE,KAAK,EAAEC,WAAW;IAClBX,IAAI,EAAEQ,IAAI,CAACR,IAAI,IAAIN,SAAS,CAACW,WAAW;EAC1C,CAAC;AACH,CAAC;;AAED;AACA,MAAMW,mBAAmB,GAAGA,CAC1Bd,aAA8B,EAC9Be,GAAW,EACXd,IAAU,EACVC,WAAoB,EACpBC,WAAwB,EACxBa,iBAA0B,KACN;EACpB,IAAIC,eAAe,GAAGf,WAAW;EACjC,MAAMgB,MAAM,GAAGjB,IAAI,CAACkB,MAAM,KAAK,CAAC;EAEhC,IAAI5B,QAAQ,CAACW,WAAW,CAAC,EAAE;IACzB;IACA;IACA,MAAMkB,UAAU,GAAGnB,IAAI,CAACoB,IAAI,CACzBC,CAAC,IAAK,OAAOA,CAAC,KAAK,QAAQ,IAAIA,CAAC,IAAIpB,WACvC,CAAC;IAED,IAAIkB,UAAU,EAAE;MACd,OAAOG,aAAa,CAACvB,aAAa,EAAEe,GAAG,EAAEd,IAAI,EAAEC,WAAW,EAAEC,WAAW,CAAC;IAC1E;;IAEA;IACA,IAAI,EAAEY,GAAG,IAAIb,WAAW,CAAC,EAAE;MACzB;MACA,IAAIc,iBAAiB,EAAE;QACrB,OAAOhB,aAAa;MACtB;;MAEA;MACA;MACA,IAAIkB,MAAM,EAAE;QACV,OAAO;UACL,GAAGlB,aAAa;UAChB,CAACe,GAAG,GAAG;YAAEP,KAAK,EAAE,CAAC,CAAC;YAAEV,IAAI,EAAEN,SAAS,CAACW,WAAW;UAAE;QACnD,CAAC;MACH;MACA;MACA,OAAOH,aAAa;IACtB;IAEAiB,eAAe,GAAGf,WAAW,CAACa,GAAG,CAAC;EACpC;;EAEA;EACA,IAAIG,MAAM,EAAE;IACV,OAAO;MACL,GAAGlB,aAAa;MAChB,CAACe,GAAG,GAAG;QAAEP,KAAK,EAAES,eAAe;QAAEnB,IAAI,EAAEN,SAAS,CAACW,WAAW;MAAE;IAChE,CAAC;EACH;;EAEA;EACA,MAAMqB,UAAU,GACbxB,aAAa,CAAqCe,GAAG,CAAC,IAAI,CAAC,CAAC;EAE/D,OAAO;IACL,GAAGf,aAAa;IAChB,CAACe,GAAG,GAAGF,oBAAoB,CACzBW,UAAU,EACVvB,IAAI,EACJgB,eAAe,EACfd,WAAW,EACXa,iBACF;EACF,CAAC;AACH,CAAC;;AAED;AACA,MAAMS,mBAAmB,GAAGA,CAC1BzB,aAA8B,EAC9Be,GAAW,EACXd,IAAU,EACVC,WAAoB,EACpBC,WAAwB,KACJ;EACpB,MAAMuB,QAAQ,GAAGtB,KAAK,CAACC,OAAO,CAACL,aAAa,CAAC,GAAG,CAAC,GAAGA,aAAa,CAAC,GAAG,EAAE;EACvE,MAAM2B,SAAS,GAAGvB,KAAK,CAACC,OAAO,CAACH,WAAW,CAAC,GAAGA,WAAW,CAACa,GAAG,CAAC,GAAGa,SAAS;EAE3EF,QAAQ,CAACX,GAAG,CAAC,GAAGF,oBAAoB,CAClCa,QAAQ,CAACX,GAAG,CAAC,IAAI,CAAC,CAAC,EACnBd,IAAI,EACJ0B,SAAS,EACTxB,WACF,CAAC;EACD,OAAOuB,QAAQ;AACjB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMb,oBAAoB,GAAG,SAAAA,CAClCb,aAA8B,EAC9B6B,IAAU,EACV3B,WAAoB,EACpBC,WAAwB,EAEJ;EAAA,IADpBa,iBAA0B,GAAAc,SAAA,CAAAX,MAAA,QAAAW,SAAA,QAAAF,SAAA,GAAAE,SAAA,MAAG,KAAK;EAElC,MAAM,CAACf,GAAG,EAAE,GAAGd,IAAI,CAAC,GAAG4B,IAAI;EAE3B,QAAQ,IAAI;IACV,KAAKd,GAAG,KAAK,IAAI;MACf,OAAOhB,iBAAiB,CAACC,aAAa,EAAEC,IAAI,EAAEC,WAAW,EAAEC,WAAW,CAAC;IAEzE,KAAK,OAAOY,GAAG,KAAK,QAAQ;MAC1B,OAAOD,mBAAmB,CACxBd,aAAa,EACbe,GAAG,EACHd,IAAI,EACJC,WAAW,EACXC,WAAW,EACXa,iBACF,CAAC;IAEH,KAAK,OAAOD,GAAG,KAAK,QAAQ;MAC1B,OAAOU,mBAAmB,CACxBzB,aAAa,EACbe,GAAG,EACHd,IAAI,EACJC,WAAW,EACXC,WACF,CAAC;IAEH;MACE,OAAOH,aAAa;EACxB;AACF,CAAC;;AAED;AACA,MAAMuB,aAAa,GAAGA,CACpBvB,aAAkC,EAClCe,GAAW,EACXd,IAAU,EACVC,WAAoC,EACpCC,WAAwB,KACJ;EACpB,MAAM4B,WAAW,GAAG/B,aAAa,CAACe,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5C,MAAMiB,OAAO,GAAG/B,IAAI,CAAC,CAAC,CAAW;EACjC,MAAMgB,eAAe,GAAGf,WAAW,CAAC8B,OAAO,CAAC;EAC5C,IAAI,OAAOf,eAAe,KAAK,WAAW,EAAE;IAC1C,OAAOjB,aAAa;EACtB;EAEA,OAAO;IACL,GAAGA,aAAa;IAChB,CAACe,GAAG,GAAG;MACL,GAAGgB,WAAW;MACdvB,KAAK,EAAEK,oBAAoB,CACzBkB,WAAW,CAACvB,KAAK,IAAI,CAAC,CAAC,EACvBP,IAAI,EACJgB,eAAe,EACfd,WACF;IACF;EACF,CAAC;AACH,CAAC"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
type DisplayData = {
|
|
2
|
-
locale: string;
|
|
3
|
-
name: string;
|
|
4
|
-
}[];
|
|
5
|
-
type LocalizedNames = Record<string, string>;
|
|
6
|
-
type PropertyNode<T> = {
|
|
7
|
-
value: T;
|
|
8
|
-
name: LocalizedNames;
|
|
9
|
-
};
|
|
10
|
-
type Path = (string | number | null)[];
|
|
11
|
-
type NodeOrStructure = Partial<PropertyNode<any>> | Record<string, any> | any[];
|
|
12
|
-
/**
|
|
13
|
-
* Recursively constructs a nested object with descriptive properties from a path.
|
|
14
|
-
*
|
|
15
|
-
* @param currentObject - The object or array being built upon.
|
|
16
|
-
* @param path - The path segments to follow.
|
|
17
|
-
* @param sourceValue - The raw value to place at the end of the path.
|
|
18
|
-
* @param displayData - The data for generating localized names.
|
|
19
|
-
* @param skipMissingLeaves - If true, skips optional keys when mapping over arrays.
|
|
20
|
-
* @returns The new object or array structure.
|
|
21
|
-
*/
|
|
22
|
-
export declare const createNestedProperty: (currentObject: NodeOrStructure, path: Path, sourceValue: unknown, displayData: DisplayData, skipMissingLeaves?: boolean) => NodeOrStructure;
|
|
23
|
-
export {};
|
|
24
|
-
//# sourceMappingURL=nestedProperty.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nestedProperty.d.ts","sourceRoot":"","sources":["../../../src/utils/nestedProperty.ts"],"names":[],"mappings":"AAGA,KAAK,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC;AAGtD,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAG7C,KAAK,YAAY,CAAC,CAAC,IAAI;IACrB,KAAK,EAAE,CAAC,CAAC;IACT,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAGF,KAAK,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;AAGvC,KAAK,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;AAkIhF;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,kBAChB,eAAe,2BAEjB,OAAO,gDAED,OAAO,KACzB,eA6BF,CAAC"}
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import { isObject } from "./misc";
|
|
2
|
-
|
|
3
|
-
// The data used to create localized names
|
|
4
|
-
type DisplayData = { locale: string; name: string }[];
|
|
5
|
-
|
|
6
|
-
// The resulting object of localized names { en: "Name", it: "Nome" }
|
|
7
|
-
type LocalizedNames = Record<string, string>;
|
|
8
|
-
|
|
9
|
-
// The core structure being built: a node containing the actual value and its localized names
|
|
10
|
-
type PropertyNode<T> = {
|
|
11
|
-
value: T;
|
|
12
|
-
name: LocalizedNames;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
// A path can consist of object keys, array indices, or null for mapping
|
|
16
|
-
type Path = (string | number | null)[];
|
|
17
|
-
|
|
18
|
-
// A union of all possible shapes. It can be a custom PropertyNode or a standard object/array structure
|
|
19
|
-
type NodeOrStructure = Partial<PropertyNode<any>> | Record<string, any> | any[];
|
|
20
|
-
|
|
21
|
-
// Helper to build localized names from the display data.
|
|
22
|
-
const buildName = (display: DisplayData): LocalizedNames =>
|
|
23
|
-
display.reduce(
|
|
24
|
-
(names, { locale, name }) => ({ ...names, [locale]: name }),
|
|
25
|
-
{}
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
// Handles the case where the path key is `null` (indicating an array)
|
|
29
|
-
const handleNullKeyCase = (
|
|
30
|
-
currentObject: NodeOrStructure,
|
|
31
|
-
rest: Path,
|
|
32
|
-
sourceValue: unknown,
|
|
33
|
-
displayData: DisplayData
|
|
34
|
-
): NodeOrStructure => {
|
|
35
|
-
if (!Array.isArray(sourceValue)) return currentObject;
|
|
36
|
-
|
|
37
|
-
// We assert the type here because we know this branch handles PropertyNodes
|
|
38
|
-
const node = currentObject as Partial<PropertyNode<unknown[]>>;
|
|
39
|
-
const existingValue = Array.isArray(node.value) ? node.value : [];
|
|
40
|
-
|
|
41
|
-
const mappedArray = sourceValue.map((item, idx) =>
|
|
42
|
-
// When mapping over an array, recursively call with `skipMissingLeaves` set to `true`.
|
|
43
|
-
// This tells the function to skip optional keys inside these array objects.
|
|
44
|
-
createNestedProperty(
|
|
45
|
-
existingValue[idx] || {},
|
|
46
|
-
rest,
|
|
47
|
-
item,
|
|
48
|
-
displayData,
|
|
49
|
-
true
|
|
50
|
-
)
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
...node,
|
|
55
|
-
value: mappedArray,
|
|
56
|
-
name: node.name ?? buildName(displayData),
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
// Handles the case where the path key is a string
|
|
61
|
-
const handleStringKeyCase = (
|
|
62
|
-
currentObject: NodeOrStructure,
|
|
63
|
-
key: string,
|
|
64
|
-
rest: Path,
|
|
65
|
-
sourceValue: unknown,
|
|
66
|
-
displayData: DisplayData,
|
|
67
|
-
skipMissingLeaves: boolean
|
|
68
|
-
): NodeOrStructure => {
|
|
69
|
-
let nextSourceValue = sourceValue;
|
|
70
|
-
const isLeaf = rest.length === 0;
|
|
71
|
-
|
|
72
|
-
if (isObject(sourceValue)) {
|
|
73
|
-
// Check if any remaining string keys in the path exist in current sourceValue
|
|
74
|
-
// This handles nested object paths (unlike arrays which use null in the path)
|
|
75
|
-
const hasRestKey = rest.some(
|
|
76
|
-
(r) => typeof r === "string" && r in sourceValue
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
if (hasRestKey) {
|
|
80
|
-
return handleRestKey(currentObject, key, rest, sourceValue, displayData);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Skip processing when the key is not found within the claim object
|
|
84
|
-
if (!(key in sourceValue)) {
|
|
85
|
-
// If the flag is set (we're inside an array), skip the missing key completely.
|
|
86
|
-
if (skipMissingLeaves) {
|
|
87
|
-
return currentObject;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// If the flag is NOT set, create the empty placeholder
|
|
91
|
-
// so that its children can be attached later.
|
|
92
|
-
if (isLeaf) {
|
|
93
|
-
return {
|
|
94
|
-
...currentObject,
|
|
95
|
-
[key]: { value: {}, name: buildName(displayData) },
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
// Skip processing when the key is not found within the claim object
|
|
99
|
-
return currentObject;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
nextSourceValue = sourceValue[key];
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// base case
|
|
106
|
-
if (isLeaf) {
|
|
107
|
-
return {
|
|
108
|
-
...currentObject,
|
|
109
|
-
[key]: { value: nextSourceValue, name: buildName(displayData) },
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// recursive step
|
|
114
|
-
const nextObject =
|
|
115
|
-
(currentObject as Record<string, NodeOrStructure>)[key] || {};
|
|
116
|
-
|
|
117
|
-
return {
|
|
118
|
-
...currentObject,
|
|
119
|
-
[key]: createNestedProperty(
|
|
120
|
-
nextObject,
|
|
121
|
-
rest,
|
|
122
|
-
nextSourceValue,
|
|
123
|
-
displayData,
|
|
124
|
-
skipMissingLeaves
|
|
125
|
-
),
|
|
126
|
-
};
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
// Handles the case where the path key is a number
|
|
130
|
-
const handleNumberKeyCase = (
|
|
131
|
-
currentObject: NodeOrStructure,
|
|
132
|
-
key: number,
|
|
133
|
-
rest: Path,
|
|
134
|
-
sourceValue: unknown,
|
|
135
|
-
displayData: DisplayData
|
|
136
|
-
): NodeOrStructure => {
|
|
137
|
-
const newArray = Array.isArray(currentObject) ? [...currentObject] : [];
|
|
138
|
-
const nextValue = Array.isArray(sourceValue) ? sourceValue[key] : undefined;
|
|
139
|
-
|
|
140
|
-
newArray[key] = createNestedProperty(
|
|
141
|
-
newArray[key] || {},
|
|
142
|
-
rest,
|
|
143
|
-
nextValue,
|
|
144
|
-
displayData
|
|
145
|
-
);
|
|
146
|
-
return newArray;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Recursively constructs a nested object with descriptive properties from a path.
|
|
151
|
-
*
|
|
152
|
-
* @param currentObject - The object or array being built upon.
|
|
153
|
-
* @param path - The path segments to follow.
|
|
154
|
-
* @param sourceValue - The raw value to place at the end of the path.
|
|
155
|
-
* @param displayData - The data for generating localized names.
|
|
156
|
-
* @param skipMissingLeaves - If true, skips optional keys when mapping over arrays.
|
|
157
|
-
* @returns The new object or array structure.
|
|
158
|
-
*/
|
|
159
|
-
export const createNestedProperty = (
|
|
160
|
-
currentObject: NodeOrStructure,
|
|
161
|
-
path: Path,
|
|
162
|
-
sourceValue: unknown,
|
|
163
|
-
displayData: DisplayData,
|
|
164
|
-
skipMissingLeaves: boolean = false
|
|
165
|
-
): NodeOrStructure => {
|
|
166
|
-
const [key, ...rest] = path;
|
|
167
|
-
|
|
168
|
-
switch (true) {
|
|
169
|
-
case key === null:
|
|
170
|
-
return handleNullKeyCase(currentObject, rest, sourceValue, displayData);
|
|
171
|
-
|
|
172
|
-
case typeof key === "string":
|
|
173
|
-
return handleStringKeyCase(
|
|
174
|
-
currentObject,
|
|
175
|
-
key as string,
|
|
176
|
-
rest,
|
|
177
|
-
sourceValue,
|
|
178
|
-
displayData,
|
|
179
|
-
skipMissingLeaves
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
case typeof key === "number":
|
|
183
|
-
return handleNumberKeyCase(
|
|
184
|
-
currentObject,
|
|
185
|
-
key as number,
|
|
186
|
-
rest,
|
|
187
|
-
sourceValue,
|
|
188
|
-
displayData
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
default:
|
|
192
|
-
return currentObject;
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
// Handles the case where the next key in the path exists in the source object
|
|
197
|
-
const handleRestKey = (
|
|
198
|
-
currentObject: Record<string, any>,
|
|
199
|
-
key: string,
|
|
200
|
-
rest: Path,
|
|
201
|
-
sourceValue: Record<string, unknown>,
|
|
202
|
-
displayData: DisplayData
|
|
203
|
-
): NodeOrStructure => {
|
|
204
|
-
const currentNode = currentObject[key] ?? {};
|
|
205
|
-
const restKey = rest[0] as string;
|
|
206
|
-
const nextSourceValue = sourceValue[restKey];
|
|
207
|
-
if (typeof nextSourceValue === "undefined") {
|
|
208
|
-
return currentObject;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return {
|
|
212
|
-
...currentObject,
|
|
213
|
-
[key]: {
|
|
214
|
-
...currentNode,
|
|
215
|
-
value: createNestedProperty(
|
|
216
|
-
currentNode.value ?? {},
|
|
217
|
-
rest,
|
|
218
|
-
nextSourceValue,
|
|
219
|
-
displayData
|
|
220
|
-
),
|
|
221
|
-
},
|
|
222
|
-
};
|
|
223
|
-
};
|