UNPKG

@opra/common

Version:
54 lines (53 loc) 2.15 kB
import { inheritPropertyInitializers, mergePrototype, } from '../../../helpers/index.js'; import { OpraSchema } from '../../../schema/index.js'; import { DATATYPE_METADATA } from '../../constants.js'; import { MappedType } from '../mapped-type.js'; import { getIsInheritedPredicateFn } from './get-is-inherited-predicate-fn.js'; export function createMappedClass(source, config, options) { const isInheritedPredicate = getIsInheritedPredicateFn(config.pick, config.omit); const sourceName = typeof source === 'string' ? source.charAt(0).toUpperCase() + source.substring(1) : source.name; const className = options?.name || sourceName + 'Mapped'; const MappedClass = { [className]: class { constructor() { if (typeof source === 'function') inheritPropertyInitializers(this, source, isInheritedPredicate); } }, }[className]; if (typeof source === 'function') mergePrototype(MappedClass.prototype, source.prototype); if (typeof source === 'function') { const m = Reflect.getOwnMetadata(DATATYPE_METADATA, source); if (!m) throw new TypeError(`Class "${source}" doesn't have datatype metadata information`); if (!(m.kind === OpraSchema.ComplexType.Kind || m.kind === OpraSchema.MappedType.Kind || m.kind === OpraSchema.MixinType.Kind)) { throw new TypeError(`Class "${source}" is not a ${OpraSchema.ComplexType.Kind}`); } } const metadata = { ...options, kind: 'MappedType', base: source, }; if (config.pick) metadata.pick = config.pick; if (config.omit) metadata.omit = config.omit; if (config.partial) metadata.partial = config.partial; if (config.required) metadata.required = config.required; Reflect.defineMetadata(DATATYPE_METADATA, metadata, MappedClass); if (typeof source === 'function') { MappedType._applyMixin(MappedClass, source, { ...config, isInheritedPredicate, }); } return MappedClass; }