UNPKG

element-vir

Version:

Heroic. Reactive. Declarative. Type safe. Web components without compromise.

70 lines (69 loc) 2.33 kB
import { AssertionError, check } from '@augment-vir/assert'; import { getObjectTypedKeys, wrapInTry } from '@augment-vir/common'; const expectedStaticProperties = getObjectTypedKeys({ assign: '', assignedInputs: '', cssVars: '', elementOptions: '', events: '', hostClasses: '', init: '', InputsType: '', render: '', slotNames: '', testIds: '', StateType: '', styles: '', tagName: '', UpdateStateType: '', }); /** `assignedInputs` is only populated by the template transforms, so it is legitimately unset. */ const staticPropertiesAllowedToBeUndefined = ['assignedInputs']; /** * The type-only statics (such as `InputsType`) are getters that throw, so their descriptors must be * inspected instead of their values. */ function findStaticDescriptor(input, key) { const ownDescriptor = Object.getOwnPropertyDescriptor(input, key); if (ownDescriptor) { return ownDescriptor; } const parent = Object.getPrototypeOf(input); return parent == undefined ? undefined : findStaticDescriptor(parent, key); } /** * Asserts that the given input is a declarative element definition. * * @category Util * @see {@link isDeclarativeElementDefinition} */ export function assertDeclarativeElementDefinition(input, failMessage) { if (!check.isFunction(input)) { throw new AssertionError('Input is not a declarative element constructor', failMessage); } expectedStaticProperties.forEach((expectedProperty) => { const descriptor = findStaticDescriptor(input, expectedProperty); if (!descriptor) { throw new AssertionError(`missing prop '${expectedProperty}'`, failMessage); } else if (!descriptor.get && descriptor.value === undefined && !staticPropertiesAllowedToBeUndefined.includes(expectedProperty)) { throw new AssertionError(`undefined prop '${expectedProperty}'`, failMessage); } }); } /** * Checks that the given input is a declarative element definition. * * @category Util * @see {@link assertDeclarativeElementDefinition} */ export function isDeclarativeElementDefinition(input) { return wrapInTry(() => { assertDeclarativeElementDefinition(input); return true; }, { fallbackValue: false, }); }