@elsikora/nestjs-crud-automator
Version:
A library for automating the creation of CRUD operations in NestJS.
67 lines (64 loc) • 3.35 kB
JavaScript
import { isDeepStrictEqual } from 'node:util';
import { AuthorizationScopeMergeWhere } from '../../../../utility/authorization/scope-merge-where.utility.js';
import { InstanceChecker } from 'typeorm';
/**
* Merges subscriber WHERE criteria with a generated mandatory scope without
* repeatedly expanding an already-contained OR scope.
*/
class ApiControllerGeneratedScopeWhereContract {
static contains(candidateWhere, mandatoryWhere) {
if (!mandatoryWhere) {
return true;
}
if (!candidateWhere) {
return false;
}
const candidateBranches = Array.isArray(candidateWhere) ? candidateWhere : [candidateWhere];
const mandatoryBranches = Array.isArray(mandatoryWhere) ? mandatoryWhere : [mandatoryWhere];
return candidateBranches.length > 0 && mandatoryBranches.length > 0 && candidateBranches.every((candidateBranch) => mandatoryBranches.some((mandatoryBranch) => this.branchContains(candidateBranch, mandatoryBranch)));
}
static merge(candidateWhere, mandatoryWhere) {
const normalizedCandidate = AuthorizationScopeMergeWhere(undefined, candidateWhere);
return this.contains(normalizedCandidate, mandatoryWhere) ? normalizedCandidate : AuthorizationScopeMergeWhere(normalizedCandidate, mandatoryWhere);
}
static branchContains(candidate, mandatory) {
const candidateEntries = this.getOwnEnumerableDataEntries(candidate);
const mandatoryEntries = this.getOwnEnumerableDataEntries(mandatory);
if (!candidateEntries || !mandatoryEntries) {
return false;
}
const candidateValues = new Map(candidateEntries);
return mandatoryEntries.every(([key, mandatoryValue]) => candidateValues.has(key) && this.valueContains(candidateValues.get(key), mandatoryValue));
}
static getOwnEnumerableDataEntries(value) {
const entries = [];
for (const key of Reflect.ownKeys(value)) {
const descriptor = Object.getOwnPropertyDescriptor(value, key);
if (!descriptor?.enumerable || !("value" in descriptor)) {
return undefined;
}
entries.push([key, descriptor.value]);
}
return entries;
}
static isNestedWhere(value) {
return Boolean(value && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date) && !ArrayBuffer.isView(value) && !InstanceChecker.isFindOperator(value));
}
static valueContains(candidate, mandatory) {
if (Array.isArray(candidate) || Array.isArray(mandatory)) {
if (!Array.isArray(candidate) || !Array.isArray(mandatory)) {
return false;
}
return candidate.every((candidateBranch) => this.isNestedWhere(candidateBranch) && mandatory.some((mandatoryBranch) => this.isNestedWhere(mandatoryBranch) && this.branchContains(candidateBranch, mandatoryBranch)));
}
if (this.isNestedWhere(candidate)) {
return this.isNestedWhere(mandatory) && this.branchContains(candidate, mandatory);
}
if (this.isNestedWhere(mandatory)) {
return false;
}
return isDeepStrictEqual(candidate, mandatory);
}
}
export { ApiControllerGeneratedScopeWhereContract };
//# sourceMappingURL=scope-where-contract.class.js.map