UNPKG

@trap_stevo/rolestack

Version:

Unify access logic across your applications with a single, elegant stack for roles. Define, query, and evolve roles on the fly.

206 lines (205 loc) 6.98 kB
"use strict"; function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); } function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); } function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); } function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); } function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; } function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } var _roles = /*#__PURE__*/new WeakMap(); var _normalizeName = /*#__PURE__*/new WeakMap(); var _validator = /*#__PURE__*/new WeakMap(); var _RoleStack_brand = /*#__PURE__*/new WeakSet(); class RoleStack { constructor(opts) { _classPrivateMethodInitSpec(this, _RoleStack_brand); _classPrivateFieldInitSpec(this, _roles, new Map()); _classPrivateFieldInitSpec(this, _normalizeName, void 0); _classPrivateFieldInitSpec(this, _validator, void 0); _classPrivateFieldSet(_normalizeName, this, opts?.normalizeName || (n => { if (typeof n !== "string") { return String(n ?? ""); } const t = n.trim(); return t ? t.toLowerCase() : ""; })); _classPrivateFieldSet(_validator, this, typeof opts?.validator === "function" ? opts.validator : null); if (Array.isArray(opts?.initial)) { for (const item of opts.initial) { this.set(item.name, item.data); } } } set(name, data) { const k = _assertClassBrand(_RoleStack_brand, this, _key).call(this, name); if (!k) { return null; } _assertClassBrand(_RoleStack_brand, this, _assertValid).call(this, name, data); _classPrivateFieldGet(_roles, this).set(k, _deepClone.call(RoleStack, data)); return this.get(name); } register(name, data) { const k = _assertClassBrand(_RoleStack_brand, this, _key).call(this, name); if (!k) { return null; } if (_classPrivateFieldGet(_roles, this).has(k)) { console.log(`Role "${name}" already exists.`); return null; } return this.set(name, data); } upsert(name, patch, options) { const k = _assertClassBrand(_RoleStack_brand, this, _key).call(this, name); if (!k) { return null; } const current = _classPrivateFieldGet(_roles, this).get(k); let next; if (typeof patch === "function") { next = patch(_deepClone.call(RoleStack, current)); } else if (current) { next = options?.merge ? options.merge(_deepClone.call(RoleStack, current), _deepClone.call(RoleStack, patch)) : { ...current, ...patch }; } else { next = _deepClone.call(RoleStack, patch); } return this.set(name, next); } get(name) { const k = _assertClassBrand(_RoleStack_brand, this, _key).call(this, name); if (!k) { return null; } const val = _classPrivateFieldGet(_roles, this).get(k); return val === undefined ? null : _deepClone.call(RoleStack, val); } remove(name) { const k = _assertClassBrand(_RoleStack_brand, this, _key).call(this, name); if (!k || !_classPrivateFieldGet(_roles, this).delete(k)) { console.log(`Role "${name}" not found.`); } } contains(name) { return !!_assertClassBrand(_RoleStack_brand, this, _key).call(this, name) && _classPrivateFieldGet(_roles, this).has(_assertClassBrand(_RoleStack_brand, this, _key).call(this, name)); } list() { return [..._classPrivateFieldGet(_roles, this).entries()].map(([name, data]) => ({ name, data: _deepClone.call(RoleStack, data) })); } toJSON() { return this.list(); } static fromJSON(data, opts) { return new RoleStack({ ...opts, initial: data }); } getField(name, fieldPath) { const data = this.get(name); if (data == null) return undefined; const pathArr = String(fieldPath).split(".").map(s => s.trim()).filter(Boolean); return _getPath.call(RoleStack, data, pathArr); } setField(name, fieldPath, value) { const k = _assertClassBrand(_RoleStack_brand, this, _key).call(this, name); if (!k || !_classPrivateFieldGet(_roles, this).has(k)) { console.log(`Role "${name}" not found.`); return null; } const data = _deepClone.call(RoleStack, _classPrivateFieldGet(_roles, this).get(k)); const pathArr = String(fieldPath).split(".").map(s => s.trim()).filter(Boolean); _setPath.call(RoleStack, data, pathArr, value); _assertClassBrand(_RoleStack_brand, this, _assertValid).call(this, name, data); _classPrivateFieldGet(_roles, this).set(k, data); return this.get(name); } query(fieldPath, value, opts) { const cmp = typeof opts?.equals === "function" ? opts.equals : _deepEqual; const paths = String(fieldPath).split(".").map(s => s.trim()).filter(Boolean); const out = []; for (const [name, data] of _classPrivateFieldGet(_roles, this).entries()) { const v = _getPath.call(RoleStack, data, paths); if (cmp(v, value)) { out.push({ name, data: _deepClone.call(RoleStack, data) }); } } return out; } queryWhere(fieldPath, predicate) { const paths = String(fieldPath).split(".").map(s => s.trim()).filter(Boolean); const out = []; for (const [name, data] of _classPrivateFieldGet(_roles, this).entries()) { const v = _getPath.call(RoleStack, data, paths); if (predicate(v, name, data)) { out.push({ name, data: _deepClone.call(RoleStack, data) }); } } return out; } } function _key(name) { return _classPrivateFieldGet(_normalizeName, this).call(this, name); } function _assertValid(name, data) { if (_classPrivateFieldGet(_validator, this)) _classPrivateFieldGet(_validator, this).call(this, name, data); } function _deepClone(v) { return v === undefined ? undefined : JSON.parse(JSON.stringify(v)); } function _getPath(obj, paths) { let cur = obj; for (const key of paths) { if (cur == null) { return undefined; } cur = cur[key]; } return cur; } function _setPath(obj, paths, value) { if (paths.length === 0) { return value; } let cur = obj; for (let i = 0; i < paths.length - 1; i++) { const key = paths[i]; if (cur[key] == null || typeof cur[key] !== "object" || Array.isArray(cur[key])) { cur[key] = {}; } cur = cur[key]; } cur[paths[paths.length - 1]] = value; return obj; } function _deepEqual(a, b) { if (a === b) { return true; } if (typeof a !== typeof b) { return false; } if (a && b && typeof a === "object") { try { return JSON.stringify(a) === JSON.stringify(b); } catch { return false; } } return false; } ; module.exports = { RoleStack };