( value: T, properties: Array<keyof T> = [], depth = 2, )
| 84 | * while a value larger than 0 means that deeper levels of nesting will be protected as well. |
| 85 | */ |
| 86 | export function protectProperties<T>( |
| 87 | value: T, |
| 88 | properties: Array<keyof T> = [], |
| 89 | depth = 2, |
| 90 | ): boolean { |
| 91 | if (getDeletionMode() === 'off') { |
| 92 | return false; |
| 93 | } |
| 94 | |
| 95 | // Reflect.get may cause deprecation warnings, so we disable them temporarily |
| 96 | const originalEmitWarning = process.emitWarning; |
| 97 | |
| 98 | try { |
| 99 | // eslint-disable-next-line @typescript-eslint/no-empty-function |
| 100 | process.emitWarning = () => {}; |
| 101 | if ( |
| 102 | depth >= 0 && |
| 103 | canDeleteProperties(value) && |
| 104 | !Reflect.has(value, PROTECT_SYMBOL) |
| 105 | ) { |
| 106 | const result = Reflect.defineProperty(value, PROTECT_SYMBOL, { |
| 107 | configurable: true, |
| 108 | enumerable: false, |
| 109 | value: properties, |
| 110 | writable: true, |
| 111 | }); |
| 112 | for (const key of getProtectedKeys(value, properties)) { |
| 113 | try { |
| 114 | const nested = Reflect.get(value, key); |
| 115 | protectProperties(nested, [], depth - 1); |
| 116 | } catch { |
| 117 | // Reflect.get might fail in certain edge-cases |
| 118 | // Instead of failing the entire process, we will skip the property. |
| 119 | } |
| 120 | } |
| 121 | return result; |
| 122 | } |
| 123 | return false; |
| 124 | } finally { |
| 125 | process.emitWarning = originalEmitWarning; |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | /** |
| 130 | * Whether the given value has properties that can be deleted (regardless of protection). |
no test coverage detected