UNPKG

ember-source

Version:

A JavaScript framework for creating ambitious web applications

149 lines (137 loc) 5.36 kB
import '../@glimmer/global-context/index.js'; import './debug-to-string-BsFOvUtQ.js'; import { isDevelopingApp } from '@embroider/macros'; import { track } from '../@glimmer/validator/index.js'; import { v as valueForRef } from './reference-B6HMX4y0.js'; const CUSTOM_TAG_FOR = new WeakMap(); function getCustomTagFor(obj) { return CUSTOM_TAG_FOR.get(obj); } function setCustomTagFor(obj, customTagFn) { CUSTOM_TAG_FOR.set(obj, customTagFn); } function convertToInt(prop) { if (typeof prop === 'symbol') return null; const num = Number(prop); if (isNaN(num)) return null; return num % 1 === 0 ? num : null; } function tagForNamedArg(namedArgs, key) { return track(() => { if (key in namedArgs) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme valueForRef(namedArgs[key]); } }); } function tagForPositionalArg(positionalArgs, key) { return track(() => { if (key === '[]') { // consume all of the tags in the positional array positionalArgs.forEach(valueForRef); } const parsed = convertToInt(key); if (parsed !== null && parsed < positionalArgs.length) { // consume the tag of the referenced index // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme valueForRef(positionalArgs[parsed]); } }); } // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- @fixme class NamedArgsProxy { // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- @fixme constructor(named) { this.named = named; } // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- @fixme get(_target, prop) { const ref = this.named[prop]; if (ref !== undefined) { return valueForRef(ref); } } // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- @fixme has(_target, prop) { return prop in this.named; } ownKeys() { return Object.keys(this.named); } isExtensible() { return false; } // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- @fixme getOwnPropertyDescriptor(_target, prop) { if (isDevelopingApp() && !(prop in this.named)) { throw new Error(`args proxies do not have real property descriptors, so you should never need to call getOwnPropertyDescriptor yourself. This code exists for enumerability, such as in for-in loops and Object.keys(). Attempted to get the descriptor for \`${String(prop)}\``); } return { enumerable: true, configurable: true }; } } class PositionalArgsProxy { constructor(positional) { this.positional = positional; } get(target, prop) { let { positional } = this; if (prop === 'length') { return positional.length; } const parsed = convertToInt(prop); if (parsed !== null && parsed < positional.length) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme return valueForRef(positional[parsed]); } // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access return target[prop]; } isExtensible() { return false; } has(_target, prop) { const parsed = convertToInt(prop); return parsed !== null && parsed < this.positional.length; } } const argsProxyFor = (capturedArgs, type) => { const { named, positional } = capturedArgs; let getNamedTag = (_obj, key) => tagForNamedArg(named, key); let getPositionalTag = (_obj, key) => tagForPositionalArg(positional, key); const namedHandler = new NamedArgsProxy(named); const positionalHandler = new PositionalArgsProxy(positional); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const namedTarget = Object.create(null); const positionalTarget = []; if (isDevelopingApp()) { const setHandler = function (_target, prop) { throw new Error(`You attempted to set ${String(prop)} on the arguments of a component, helper, or modifier. Arguments are immutable and cannot be updated directly; they always represent the values that are passed down. If you want to set default values, you should use a getter and local tracked state instead.`); }; const forInDebugHandler = () => { throw new Error(`Object.keys() was called on the positional arguments array for a ${type}, which is not supported. This function is a low-level function that should not need to be called for positional argument arrays. You may be attempting to iterate over the array using for...in instead of for...of.`); }; namedHandler.set = setHandler; positionalHandler.set = setHandler; positionalHandler.ownKeys = forInDebugHandler; } // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const namedProxy = new Proxy(namedTarget, namedHandler); const positionalProxy = new Proxy(positionalTarget, positionalHandler); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument setCustomTagFor(namedProxy, getNamedTag); setCustomTagFor(positionalProxy, getPositionalTag); return { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment named: namedProxy, positional: positionalProxy }; }; export { argsProxyFor as a, getCustomTagFor as g, setCustomTagFor as s };