( oldValue: Schema.Json, newValue: Schema.Json, path: string, patches: Array<JsonPatchOperation> )
| 184 | } |
| 185 | |
| 186 | function getLoop( |
| 187 | oldValue: Schema.Json, |
| 188 | newValue: Schema.Json, |
| 189 | path: string, |
| 190 | patches: Array<JsonPatchOperation> |
| 191 | ): void { |
| 192 | if (Object.is(oldValue, newValue)) return |
| 193 | if (Array.isArray(oldValue) && Array.isArray(newValue)) { |
| 194 | const len1 = oldValue.length |
| 195 | const len2 = newValue.length |
| 196 | |
| 197 | // Compare shared prefix by index |
| 198 | const shared = Math.min(len1, len2) |
| 199 | for (let i = 0; i < shared; i++) { |
| 200 | getLoop(oldValue[i], newValue[i], `${path}/${i}`, patches) |
| 201 | } |
| 202 | |
| 203 | // Remove from end to start so later indices do not shift. |
| 204 | for (let i = len1 - 1; i >= len2; i--) { |
| 205 | patches.push({ op: "remove", path: `${path}/${i}` }) |
| 206 | } |
| 207 | |
| 208 | // Add from beginning to end. |
| 209 | for (let i = len1; i < len2; i++) { |
| 210 | patches.push({ op: "add", path: `${path}/${i}`, value: newValue[i] }) |
| 211 | } |
| 212 | |
| 213 | return |
| 214 | } |
| 215 | |
| 216 | if (isJsonObject(oldValue) && isJsonObject(newValue)) { |
| 217 | const keys1 = Object.keys(oldValue) |
| 218 | const keys2 = Object.keys(newValue) |
| 219 | const allKeys = Array.from(new Set([...keys1, ...keys2])).sort() |
| 220 | |
| 221 | for (const key of allKeys) { |
| 222 | const keyPath = `${path}/${escapeToken(key)}` |
| 223 | const hasKey1 = Object.hasOwn(oldValue, key) |
| 224 | const hasKey2 = Object.hasOwn(newValue, key) |
| 225 | |
| 226 | if (hasKey1 && hasKey2) { |
| 227 | getLoop(oldValue[key], newValue[key], keyPath, patches) |
| 228 | } else if (!hasKey1 && hasKey2) { |
| 229 | patches.push({ op: "add", path: keyPath, value: newValue[key] }) |
| 230 | } else { |
| 231 | patches.push({ op: "remove", path: keyPath }) |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | return |
| 236 | } |
| 237 | |
| 238 | patches.push({ op: "replace", path, value: newValue }) |
| 239 | } |
| 240 | |
| 241 | /** |
| 242 | * Applies a JSON Patch to a JSON document. |
no test coverage detected