* Recursively removes a field or a set of fields from an object based on a given path. * * @param {string} path - The path specifying the field(s) to remove. You can use dot notation * to traverse nested objects and use a wildcard (*) to match multiple subfields. * @param {object} object - The
(path, object)
| 71 | * @param {object} object - The object from which the field(s) will be removed. |
| 72 | */ |
| 73 | function removeObjectField(path, object) { |
| 74 | if (!object || typeof path !== "string") return; |
| 75 | |
| 76 | const pathList = path.split("."); |
| 77 | const lastKey = pathList.pop(); |
| 78 | let currentObj = object; |
| 79 | |
| 80 | const forbiddenKeys = new Set(["__proto__", "constructor", "prototype"]); |
| 81 | |
| 82 | for (const rawKey of pathList) { |
| 83 | if (typeof rawKey !== "string") continue; |
| 84 | if (forbiddenKeys.has(rawKey)) return; |
| 85 | |
| 86 | const key = rawKey; |
| 87 | |
| 88 | if (key === "*") { |
| 89 | if (typeof currentObj !== "object" || currentObj === null) continue; |
| 90 | |
| 91 | const nextPath = [...pathList.slice(pathList.indexOf(key) + 1), lastKey].join("."); |
| 92 | for (const child of Object.values(currentObj)) { |
| 93 | if (child && typeof child === "object") { |
| 94 | removeObjectField(nextPath, child); |
| 95 | } |
| 96 | } |
| 97 | return; |
| 98 | } |
| 99 | |
| 100 | const nextValue = Reflect.get(currentObj, key); |
| 101 | if (typeof nextValue === "object" && nextValue !== null && Reflect.has(currentObj, key)) { |
| 102 | currentObj = nextValue; |
| 103 | } else { |
| 104 | return; |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | if (lastKey === "*") { |
| 109 | if (typeof currentObj === "object" && currentObj !== null) { |
| 110 | for (const key of Object.keys(currentObj)) { |
| 111 | if (!forbiddenKeys.has(key)) Reflect.deleteProperty(currentObj, key); |
| 112 | } |
| 113 | } |
| 114 | } else if (!forbiddenKeys.has(lastKey) && Reflect.has(currentObj, lastKey)) { |
| 115 | Reflect.deleteProperty(currentObj, lastKey); |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | module.exports = { |
| 120 | removeObjectField, |
no test coverage detected