UNPKG

@dipscope/type-manager

Version:

Transform JSON strings or plain objects into JS class instances.

374 lines 17.7 kB
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