@opra/common
Version:
Opra common package
54 lines (53 loc) • 2.15 kB
JavaScript
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;
}