diff options
| author | Shipwreckt <me@shipwreckt.co.uk> | 2025-10-31 20:02:14 +0000 |
|---|---|---|
| committer | Shipwreckt <me@shipwreckt.co.uk> | 2025-10-31 20:02:14 +0000 |
| commit | 7a52ddeba2a68388b544f529d2d92104420f77b0 (patch) | |
| tree | 15ddd47457a2cb4a96060747437d36474e4f6b4e /node_modules/@11ty/eleventy/src/Data/ComputedDataProxy.js | |
| parent | 53d6ae2b5568437afa5e4995580a3fb679b7b91b (diff) | |
Changed from static to 11ty!
Diffstat (limited to 'node_modules/@11ty/eleventy/src/Data/ComputedDataProxy.js')
| -rw-r--r-- | node_modules/@11ty/eleventy/src/Data/ComputedDataProxy.js | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/node_modules/@11ty/eleventy/src/Data/ComputedDataProxy.js b/node_modules/@11ty/eleventy/src/Data/ComputedDataProxy.js new file mode 100644 index 0000000..2415355 --- /dev/null +++ b/node_modules/@11ty/eleventy/src/Data/ComputedDataProxy.js @@ -0,0 +1,131 @@ +import lodash from "@11ty/lodash-custom"; +import { isPlainObject } from "@11ty/eleventy-utils"; + +const { set: lodashSet, get: lodashGet } = lodash; + +/* Calculates computed data using Proxies */ +class ComputedDataProxy { + constructor(computedKeys) { + if (Array.isArray(computedKeys)) { + this.computedKeys = new Set(computedKeys); + } else { + this.computedKeys = computedKeys; + } + } + + isArrayOrPlainObject(data) { + return Array.isArray(data) || isPlainObject(data); + } + + getProxyData(data, keyRef) { + // WARNING: SIDE EFFECTS + // Set defaults for keys not already set on parent data + + // TODO should make another effort to get rid of this, + // See the ProxyWrap util for more proxy handlers that will likely fix this + let undefinedValue = "__11TY_UNDEFINED__"; + if (this.computedKeys) { + for (let key of this.computedKeys) { + if (lodashGet(data, key, undefinedValue) === undefinedValue) { + lodashSet(data, key, ""); + } + } + } + + let proxyData = this._getProxyData(data, keyRef); + return proxyData; + } + + _getProxyForObject(dataObj, keyRef, parentKey = "") { + return new Proxy( + {}, + { + get: (obj, key) => { + if (typeof key !== "string") { + return obj[key]; + } + + let newKey = `${parentKey ? `${parentKey}.` : ""}${key}`; + + // Issue #1137 + // Special case for Collections, always return an Array for collection keys + // so they it works fine with Array methods like `filter`, `map`, etc + if (newKey === "collections") { + keyRef.add(newKey); + return new Proxy( + {}, + { + get: (target, key) => { + if (typeof key === "string") { + keyRef.add(`collections.${key}`); + return []; + } + return target[key]; + }, + }, + ); + } + + let newData = this._getProxyData(dataObj[key], keyRef, newKey); + if (!this.isArrayOrPlainObject(newData)) { + keyRef.add(newKey); + } + return newData; + }, + }, + ); + } + + _getProxyForArray(dataArr, keyRef, parentKey = "") { + return new Proxy(new Array(dataArr.length), { + get: (obj, key) => { + if (Array.prototype.hasOwnProperty(key)) { + // remove `filter`, `constructor`, `map`, etc + keyRef.add(parentKey); + return obj[key]; + } + + // Hm, this needs to be better + if (key === "then") { + keyRef.add(parentKey); + return; + } + + let newKey = `${parentKey}[${key}]`; + let newData = this._getProxyData(dataArr[key], keyRef, newKey); + if (!this.isArrayOrPlainObject(newData)) { + keyRef.add(newKey); + } + return newData; + }, + }); + } + + _getProxyData(data, keyRef, parentKey = "") { + if (isPlainObject(data)) { + return this._getProxyForObject(data, keyRef, parentKey); + } else if (Array.isArray(data)) { + return this._getProxyForArray(data, keyRef, parentKey); + } + + // everything else! + return data; + } + + async findVarsUsed(fn, data = {}) { + let keyRef = new Set(); + + // careful, logging proxyData will mess with test results! + let proxyData = this.getProxyData(data, keyRef); + + // squelch console logs for this fake proxy data pass 😅 + // let savedLog = console.log; + // console.log = () => {}; + await fn(proxyData); + // console.log = savedLog; + + return Array.from(keyRef); + } +} + +export default ComputedDataProxy; |
