UNPKG

@drip_sync/drip

Version:

Scalable incremental sync for MongoDB aggregation pipelines

64 lines (63 loc) 2.67 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.InvalidUpdateDescription = void 0; exports.applyUpdateDescription = applyUpdateDescription; const zod_1 = __importDefault(require("zod")); class InvalidUpdateDescription extends Error { } exports.InvalidUpdateDescription = InvalidUpdateDescription; function applyUpdateDescription(old, updateDescription) { if (Object.keys(updateDescription).length === 0) { // No update return old; } // Copy the given object by one level const res = { ...old }; for (const [k, v_] of Object.entries(updateDescription)) { const vParsed = zod_1.default.record(zod_1.default.string(), zod_1.default.unknown()).safeParse(v_); if (!vParsed.success) { throw new InvalidUpdateDescription(`Expected object, got ${typeof v_}`); } const v = vParsed.data; switch (k) { case "d": for (const nestedKey of Object.keys(v)) { delete res[nestedKey]; } break; case "t": for (const [nestedKey, newSize] of Object.entries(v)) { const arr = res[nestedKey]; if (!Array.isArray(arr)) { throw new InvalidUpdateDescription(`Expected array, got ${typeof arr}`); } if (typeof newSize !== "number") { throw new InvalidUpdateDescription(`Expected number, got ${typeof newSize}`); } res[nestedKey] = arr.slice(0, newSize); } break; case "i": Object.assign(res, v); break; default: { // Must be an embedded change if (!k.startsWith("s")) { throw new InvalidUpdateDescription(`Unexpected key: "${k}"`); } const nestedFieldName = k.slice(1); const nestedFieldParsed = zod_1.default .record(zod_1.default.string(), zod_1.default.unknown()) .safeParse(res[nestedFieldName]); if (!nestedFieldParsed.success) { throw new InvalidUpdateDescription(`Expected nested object, got ${typeof res[nestedFieldName]}`); } res[nestedFieldName] = applyUpdateDescription(nestedFieldParsed.data, v); } } } return res; }