@dipscope/type-manager
Version:
Transform JSON strings or plain objects into JS class instances.
374 lines • 17.7 kB
JavaScript
import { DEFAULT_VALUE_RESOLVER } from './constants/default-value-resolver';
import { EMPTY_ARRAY } from './constants/empty-array';
import { EMPTY_MAP } from './constants/empty-map';
import { NULL_VALUE_RESOLVER } from './constants/null-value-resolver';
import { getReflectMetadata } from './functions/get-reflect-metadata';
import { Metadata } from './metadata';
import { PROPERTY_EXTENSION_METADATA_CTOR_SET_KEY } from './property-extension-metadata-ctor-set-key';
import { ResolvedPropertyState } from './property-states/resolved-property-state';
import { UnresolvedPropertyState } from './property-states/unresolved-property-state';
export class PropertyMetadata extends Metadata {
constructor(typeManager, typeFnMap, declaringTypeMetadata, propertyName, propertyOptions) {
super(typeManager, typeFnMap);
this.declaringTypeMetadata = declaringTypeMetadata;
this.propertyName = propertyName;
this.normalizedPropertyName = propertyName.toLocaleLowerCase();
this.reflectTypeFn = getReflectMetadata('design:type', declaringTypeMetadata.typeFn.prototype, propertyName);
this.propertyOptions = this.constructPropertyOptions(propertyOptions);
this.currentPropertyState = new UnresolvedPropertyState(this);
this.configure(propertyOptions);
return;
}
get propertyState() {
return this.currentPropertyState;
}
get alias() {
return this.currentPropertyState.alias;
}
get customValueMap() {
return this.currentPropertyState.customValueMap;
}
get serializedNullValue() {
return this.currentPropertyState.serializedNullValueResolver();
}
get serializedDefaultValue() {
return this.currentPropertyState.serializedDefaultValueResolver();
}
get deserializedNullValue() {
return this.currentPropertyState.deserializedNullValueResolver();
}
get deserializedDefaultValue() {
return this.currentPropertyState.deserializedDefaultValueResolver();
}
get serializedPropertyName() {
return this.currentPropertyState.serializedPropertyName;
}
get deserializedPropertyName() {
return this.currentPropertyState.deserializedPropertyName;
}
get deserializable() {
return this.currentPropertyState.deserializable;
}
get genericArguments() {
return this.currentPropertyState.genericArguments;
}
get genericMetadatas() {
return this.currentPropertyState.genericMetadatas;
}
get namingConvention() {
return this.currentPropertyState.namingConvention;
}
get referenceHandler() {
return this.currentPropertyState.referenceHandler;
}
get serializable() {
return this.currentPropertyState.serializable;
}
get serializer() {
return this.currentPropertyState.serializer;
}
get typeArgument() {
return this.currentPropertyState.typeArgument;
}
get typeMetadata() {
return this.currentPropertyState.typeMetadata;
}
get preserveNull() {
return this.currentPropertyState.preserveNull;
}
get useDefaultValue() {
return this.currentPropertyState.useDefaultValue;
}
get useImplicitConversion() {
return this.currentPropertyState.useImplicitConversion;
}
constructPropertyOptions(propertyOptions) {
if (propertyOptions.customValueMap === undefined) {
propertyOptions.customValueMap = new Map();
}
return propertyOptions;
}
configurePropertyExtensionMetadata(propertyExtensionMetadataCtor, propertyExtensionOptions) {
const propertyExtensionMetadataCtorSet = this.extractPropertyExtensionMetadataCtorSet();
if (!propertyExtensionMetadataCtorSet.has(propertyExtensionMetadataCtor)) {
propertyExtensionMetadataCtorSet.add(propertyExtensionMetadataCtor);
}
const initialPropertyExtensionOptions = propertyExtensionOptions !== null && propertyExtensionOptions !== void 0 ? propertyExtensionOptions : {};
const propertyExtensionMetadata = new propertyExtensionMetadataCtor(this, initialPropertyExtensionOptions);
return propertyExtensionMetadata;
}
extractPropertyExtensionMetadata(propertyExtensionMetadataCtor) {
const propertyExtensionMetadataCtorSet = this.extractPropertyExtensionMetadataCtorSet();
if (!propertyExtensionMetadataCtorSet.has(propertyExtensionMetadataCtor)) {
return undefined;
}
const initialPropertyExtensionOptions = {};
const propertyExtensionMetadata = new propertyExtensionMetadataCtor(this, initialPropertyExtensionOptions);
return propertyExtensionMetadata;
}
extractPropertyExtensionMetadataCtorSet() {
let customValueMap = this.propertyOptions.customValueMap;
if (customValueMap === undefined) {
customValueMap = new Map();
this.propertyOptions.customValueMap = customValueMap;
}
let propertyExtensionMetadataCtorSet = customValueMap.get(PROPERTY_EXTENSION_METADATA_CTOR_SET_KEY);
if (propertyExtensionMetadataCtorSet === undefined) {
propertyExtensionMetadataCtorSet = new Set();
customValueMap.set(PROPERTY_EXTENSION_METADATA_CTOR_SET_KEY, propertyExtensionMetadataCtorSet);
}
return propertyExtensionMetadataCtorSet;
}
resolvePropertyState() {
const propertyOptions = this.propertyOptions;
const propertyName = this.propertyName;
const alias = propertyOptions.alias;
const deserializedPropertyName = propertyName;
const typeArgument = propertyOptions.typeArgument === undefined
? this.reflectTypeFn
: propertyOptions.typeArgument;
const typeMetadata = this.resolveTypeMetadata(typeArgument);
const typeState = typeMetadata.typeState;
const customValueMap = this.resolveCustomValueMap(typeState);
const preserveNull = propertyOptions.preserveNull === undefined
? typeState.preserveNull
: propertyOptions.preserveNull;
const useDefaultValue = propertyOptions.useDefaultValue === undefined
? typeState.useDefaultValue
: propertyOptions.useDefaultValue;
const useImplicitConversion = propertyOptions.useImplicitConversion === undefined
? typeState.useImplicitConversion
: propertyOptions.useImplicitConversion;
const serializedDefaultValue = propertyOptions.defaultValue === undefined
? (propertyOptions.serializedDefaultValue === undefined ? typeState.serializedDefaultValue : propertyOptions.serializedDefaultValue)
: propertyOptions.defaultValue;
const serializedDefaultValueResolver = useDefaultValue
? (typeof serializedDefaultValue === 'function' ? serializedDefaultValue : () => serializedDefaultValue)
: DEFAULT_VALUE_RESOLVER;
const serializedNullValueResolver = preserveNull
? NULL_VALUE_RESOLVER
: serializedDefaultValueResolver;
const deserializedDefaultValue = propertyOptions.defaultValue === undefined
? (propertyOptions.deserializedDefaultValue === undefined ? typeState.deserializedDefaultValue : propertyOptions.deserializedDefaultValue)
: propertyOptions.defaultValue;
const deserializedDefaultValueResolver = useDefaultValue
? (typeof deserializedDefaultValue === 'function' ? deserializedDefaultValue : () => deserializedDefaultValue)
: DEFAULT_VALUE_RESOLVER;
const deserializedNullValueResolver = preserveNull
? NULL_VALUE_RESOLVER
: deserializedDefaultValueResolver;
const namingConvention = propertyOptions.namingConvention === undefined
? this.declaringTypeMetadata.typeState.namingConvention
: propertyOptions.namingConvention;
const serializedPropertyName = alias === undefined
? (namingConvention === undefined ? propertyName : namingConvention.convert(propertyName))
: alias;
const useDefaultSerialization = propertyOptions.serializable === undefined
&& propertyOptions.deserializable === undefined;
const serializable = useDefaultSerialization
|| propertyOptions.serializable === true;
const deserializable = useDefaultSerialization
|| propertyOptions.deserializable === true;
const genericArguments = propertyOptions.genericArguments === undefined
? EMPTY_ARRAY
: propertyOptions.genericArguments;
const genericMetadatas = this.resolveGenericMetadatas(genericArguments);
const referenceHandler = propertyOptions.referenceHandler === undefined
? typeState.referenceHandler
: propertyOptions.referenceHandler;
const serializer = propertyOptions.serializer === undefined
? typeState.serializer
: propertyOptions.serializer;
const resolvedPropertyState = new ResolvedPropertyState(this, alias, customValueMap, serializedNullValueResolver, serializedDefaultValueResolver, deserializedNullValueResolver, deserializedDefaultValueResolver, serializedPropertyName, deserializedPropertyName, serializable, deserializable, genericArguments, genericMetadatas, namingConvention, referenceHandler, serializer, typeArgument, typeMetadata, preserveNull, useDefaultValue, useImplicitConversion);
this.currentPropertyState = resolvedPropertyState;
return resolvedPropertyState;
}
unresolvePropertyState() {
const unresolvedPropertyState = new UnresolvedPropertyState(this);
this.currentPropertyState = unresolvedPropertyState;
return unresolvedPropertyState;
}
resolveCustomValueMap(typeState) {
const propertyOptions = this.propertyOptions;
const customValueMap = new Map();
if (propertyOptions.customValueMap === undefined) {
return customValueMap;
}
const typeCustomValueMap = typeState.customValueMap === undefined
? EMPTY_MAP
: typeState.customValueMap;
for (const [customKey, customValue] of propertyOptions.customValueMap) {
if (customValue === undefined) {
customValueMap.set(customKey, typeCustomValueMap.get(customKey));
continue;
}
customValueMap.set(customKey, customValue);
}
return customValueMap;
}
hasAlias(alias) {
this.propertyOptions.alias = alias;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
hasCustomValueMap(customValueMap) {
let currentCustomValueMap = this.propertyOptions.customValueMap;
if (currentCustomValueMap === undefined) {
currentCustomValueMap = new Map();
this.propertyOptions.customValueMap = currentCustomValueMap;
}
if (customValueMap !== undefined) {
if (currentCustomValueMap !== customValueMap) {
currentCustomValueMap.clear();
}
for (const [customKey, customValue] of customValueMap) {
currentCustomValueMap.set(customKey, customValue);
}
}
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
hasCustomValue(customKey, customValue) {
let customValueMap = this.propertyOptions.customValueMap;
if (customValueMap === undefined) {
customValueMap = new Map();
this.propertyOptions.customValueMap = customValueMap;
}
customValueMap.set(customKey, customValue);
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
extractCustomValue(customKey) {
let customValue = this.propertyState.customValueMap.get(customKey);
if (customValue === undefined && customKey.customValueResolver !== undefined) {
customValue = customKey.customValueResolver();
}
return customValue;
}
hasCustomOptions(customOptions) {
let customValueMap = this.propertyOptions.customValueMap;
if (customValueMap === undefined) {
customValueMap = new Map();
this.propertyOptions.customValueMap = customValueMap;
}
for (let i = 0; i < customOptions.length; i++) {
customValueMap.set(customOptions[i][0], customOptions[i][1]);
}
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
hasDefaultValue(defaultValue) {
this.propertyOptions.defaultValue = defaultValue;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
hasSerializedDefaultValue(serializedDefaultValue) {
this.propertyOptions.serializedDefaultValue = serializedDefaultValue;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
hasDeserializedDefaultValue(deserializedDefaultValue) {
this.propertyOptions.deserializedDefaultValue = deserializedDefaultValue;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
isDeserializable(deserializable = true) {
this.propertyOptions.deserializable = deserializable;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
isSerializable(serializable = true) {
this.propertyOptions.serializable = serializable;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
hasGenericArguments(genericArguments) {
this.propertyOptions.genericArguments = genericArguments;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
hasNamingConvention(namingConvention) {
this.propertyOptions.namingConvention = namingConvention;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
hasReferenceHandler(referenceHandler) {
this.propertyOptions.referenceHandler = referenceHandler;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
hasSerializer(serializer) {
this.propertyOptions.serializer = serializer;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
hasTypeArgument(typeArgument) {
this.propertyOptions.typeArgument = typeArgument !== null && typeArgument !== void 0 ? typeArgument : this.reflectTypeFn;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
shouldPreserveNull(preserveNull = true) {
this.propertyOptions.preserveNull = preserveNull;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
shouldUseDefaultValue(useDefaultValue = true) {
this.propertyOptions.useDefaultValue = useDefaultValue;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
shouldUseImplicitConversion(useImplicitConversion = true) {
this.propertyOptions.useImplicitConversion = useImplicitConversion;
this.currentPropertyState = new UnresolvedPropertyState(this);
return this;
}
configure(propertyOptions) {
if (propertyOptions.alias !== undefined) {
this.hasAlias(propertyOptions.alias);
}
if (propertyOptions.customValueMap !== undefined) {
this.hasCustomValueMap(propertyOptions.customValueMap);
}
if (propertyOptions.defaultValue !== undefined) {
this.hasDefaultValue(propertyOptions.defaultValue);
}
if (propertyOptions.serializedDefaultValue !== undefined) {
this.hasSerializedDefaultValue(propertyOptions.serializedDefaultValue);
}
if (propertyOptions.deserializedDefaultValue !== undefined) {
this.hasDeserializedDefaultValue(propertyOptions.deserializedDefaultValue);
}
if (propertyOptions.deserializable !== undefined) {
this.isDeserializable(propertyOptions.deserializable);
}
if (propertyOptions.genericArguments !== undefined) {
this.hasGenericArguments(propertyOptions.genericArguments);
}
if (propertyOptions.namingConvention !== undefined) {
this.hasNamingConvention(propertyOptions.namingConvention);
}
if (propertyOptions.referenceHandler !== undefined) {
this.hasReferenceHandler(propertyOptions.referenceHandler);
}
if (propertyOptions.serializable !== undefined) {
this.isSerializable(propertyOptions.serializable);
}
if (propertyOptions.serializer !== undefined) {
this.hasSerializer(propertyOptions.serializer);
}
if (propertyOptions.typeArgument !== undefined) {
this.hasTypeArgument(propertyOptions.typeArgument);
}
if (propertyOptions.preserveNull !== undefined) {
this.shouldPreserveNull(propertyOptions.preserveNull);
}
if (propertyOptions.useDefaultValue !== undefined) {
this.shouldUseDefaultValue(propertyOptions.useDefaultValue);
}
if (propertyOptions.useImplicitConversion !== undefined) {
this.shouldUseImplicitConversion(propertyOptions.useImplicitConversion);
}
return this;
}
}
//# sourceMappingURL=property-metadata.js.map