UNPKG

@elsikora/nestjs-crud-automator

Version:

A library for automating the creation of CRUD operations in NestJS.

68 lines (65 loc) 3.21 kB
import { isDeepStrictEqual } from 'node:util'; import { ApiControllerGeneratedSecuritySnapshot } from './security-snapshot.class.js'; import { ErrorException } from '../../../../utility/error/exception.utility.js'; /** * Isolates generated mutation hydration from GET AFTER subscriber replacements and mutations. */ class ApiControllerGeneratedWriteHydrationContract { static assertUnchanged(rawItem, rawSnapshot, subscriberItem, subscriberSnapshot, subscriberResult, allowedRootAccessors) { this.assertDataGraph(rawItem, allowedRootAccessors); this.assertDataGraph(subscriberItem, allowedRootAccessors); if ((subscriberResult !== undefined && subscriberResult !== subscriberItem) || !isDeepStrictEqual(rawItem, rawSnapshot) || !isDeepStrictEqual(subscriberItem, subscriberSnapshot)) { throw ErrorException("Generated mutation GET subscriber changed the protected hydration entity"); } } static createSnapshot(item, allowedRootAccessors) { this.assertDataGraph(item, allowedRootAccessors); return ApiControllerGeneratedSecuritySnapshot.detach(item); } static assertDataGraph(value, allowedRootAccessors, visited = new WeakSet(), isRoot = true) { if (typeof value === "function") { throw ErrorException("Generated mutation hydration entity cannot contain function values"); } if (!value || typeof value !== "object" || visited.has(value)) { return; } visited.add(value); if (value instanceof ArrayBuffer || ArrayBuffer.isView(value) || value instanceof Date || value instanceof RegExp) { return; } if (value instanceof Promise || value instanceof WeakMap || value instanceof WeakSet) { throw ErrorException("Generated mutation hydration entity contains an unsupported mutable value"); } if (value instanceof Map) { for (const [key, item] of value) { this.assertDataGraph(key, allowedRootAccessors, visited, false); this.assertDataGraph(item, allowedRootAccessors, visited, false); } return; } if (value instanceof Set) { for (const item of value) { this.assertDataGraph(item, allowedRootAccessors, visited, false); } return; } for (const key of Reflect.ownKeys(value)) { if (Array.isArray(value) && key === "length") { continue; } const descriptor = Object.getOwnPropertyDescriptor(value, key); if (!descriptor) { continue; } if (!("value" in descriptor)) { if (isRoot && !descriptor.enumerable && allowedRootAccessors.has(key)) { continue; } throw ErrorException("Generated mutation hydration entity must contain data properties only"); } this.assertDataGraph(descriptor.value, allowedRootAccessors, visited, false); } } } export { ApiControllerGeneratedWriteHydrationContract }; //# sourceMappingURL=write-hydration-contract.class.js.map