Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 15x 15x 15x 15x 15x 65x 65x 65x 7x 35x 35x 35x 30x 5x 35x 35x 35x 35x 35x 80x 80x 20x 20x 60x 35x 15x 15x 15x 12x 12x 6x 6x 6x 6x 6x 6x | import type {CompactExtendOp, OPCODE_EXTEND} from '../codec/compact/types'; import {AbstractOp} from './AbstractOp'; import type {OperationExtend} from '../types'; import {find, isArrayReference, isObjectReference, type Path, formatJsonPointer} from '@jsonjoy.com/json-pointer'; import {OPCODE} from '../constants'; import type {IMessagePackEncoder} from '@jsonjoy.com/json-pack/lib/msgpack'; const {isArray} = Array; /** * @category JSON Patch Extended */ export class OpExtend extends AbstractOp<'extend'> { constructor( path: Path, public readonly props: Record<string, unknown>, public readonly deleteNull: boolean, ) { super(path); } public op() { return 'extend' as const; } public code() { return OPCODE.extend; } public apply(doc: unknown) { const ref = find(doc, this.path); Iif (isArrayReference(ref)) { Iif (ref.val !== undefined) { ref.obj[ref.key] = this.extend(ref.val); } } else if (isObjectReference(ref)) { ref.obj[ref.key] = this.extend(ref.val); } else { doc = this.extend(doc); } return {doc}; } private extend<T>(value: T): T { Iif (isArray(value)) return value; Iif (typeof value !== 'object') return value; Iif (!value) return value; for (const [key, v] of Object.entries(this.props)) { Iif (key === '__proto__') throw new Error('NO_PROTO'); if (v === null && this.deleteNull) { delete (value as any)[key]; continue; } (value as any)[key] = v; } return value; } public toJson(parent?: AbstractOp): OperationExtend { const op: OperationExtend = { op: 'extend', path: formatJsonPointer(this.path), props: this.props, }; if (this.deleteNull) op.deleteNull = this.deleteNull; return op; } public toCompact(parent: undefined | AbstractOp, verbose: boolean): CompactExtendOp { const opcode: OPCODE_EXTEND = verbose ? 'extend' : OPCODE.extend; return this.deleteNull ? [opcode, this.path, this.props, 1] : [opcode, this.path, this.props]; } public encode(encoder: IMessagePackEncoder, parent?: AbstractOp) { const {deleteNull} = this; encoder.encodeArrayHeader(deleteNull ? 4 : 3); encoder.writer.u8(OPCODE.extend); encoder.encodeArray(this.path as unknown[]); encoder.encodeObject(this.props); if (deleteNull) encoder.writer.u8(1); } } |