@automapper/classes
Advanced tools
Comparing version 8.7.6 to 8.7.7
29
index.js
@@ -10,10 +10,7 @@ import { isDateConstructor, isPrimitiveConstructor, defaultStrategyInitializerOptions, AutoMapperLogger } from '@automapper/core'; | ||
var _a; | ||
let metadataList = (((_a = model.constructor) === null || _a === void 0 ? void 0 : _a.prototype) ? Reflect.getMetadata(AUTOMAP_PROPERTIES_METADATA_KEY, model.constructor.prototype) || [] : []).concat(Reflect.getMetadata(AUTOMAP_PROPERTIES_METADATA_KEY, model) || []); | ||
const metadataFactoryFn = model[AUTOMAPPER_METADATA_FACTORY_KEY]; | ||
if (metadataFactoryFn) { | ||
metadataList = metadataList.concat(metadataFactoryFn() || []); | ||
} | ||
return metadataList.reduce((result, [propertyKey, { | ||
@@ -28,7 +25,5 @@ type, | ||
const trueMeta = isArray ? meta[0] : meta; | ||
if (!isDateConstructor(trueMeta) && !isPrimitiveConstructor(trueMeta)) { | ||
result[1].push(trueMeta); | ||
} | ||
result[0].push([propertyKey, { | ||
@@ -55,21 +50,15 @@ type: () => trueMeta, | ||
mapper, | ||
get applyMetadata() { | ||
return applyMetadata(this); | ||
}, | ||
retrieveMetadata(...identifiers) { | ||
const metadataMap = new Map(); | ||
for (let i = 0, length = identifiers.length; i < length; i++) { | ||
const identifier = identifiers[i]; | ||
if (metadataTracker.has(identifier)) { | ||
continue; | ||
} | ||
const [metadataList, nestedConstructors] = getMetadataList(identifier); | ||
metadataMap.set(identifier, metadataList); | ||
metadataTracker.add(identifier); | ||
if (nestedConstructors.length) { | ||
@@ -82,6 +71,4 @@ const nestedConstructorsMetadataMap = this.retrieveMetadata(...nestedConstructors); | ||
} | ||
return metadataMap; | ||
}, | ||
preMap, | ||
@@ -96,12 +83,10 @@ postMap | ||
const existingMetadataList = Reflect.getMetadata(AUTOMAP_PROPERTIES_METADATA_KEY, target.constructor) || []; | ||
if (!options.type) { | ||
const designTypeMeta = Reflect.getMetadata('design:type', target, propertyKey); // only store design:type metadata if it's not Array or Object | ||
const designTypeMeta = Reflect.getMetadata('design:type', target, propertyKey); | ||
// only store design:type metadata if it's not Array or Object | ||
if (designTypeMeta && designTypeMeta !== Array && designTypeMeta !== Object) { | ||
options.type = () => designTypeMeta; | ||
} | ||
} // if typeFn is still null/undefined, fail fast; | ||
} | ||
// if typeFn is still null/undefined, fail fast; | ||
if (options.type == null) { | ||
@@ -115,6 +100,4 @@ if (AutoMapperLogger.warn) { | ||
} | ||
return; | ||
} | ||
if (!options.isGetterOnly) { | ||
@@ -127,7 +110,5 @@ // paramtypes gives information about the setter. | ||
} | ||
Reflect.defineMetadata(AUTOMAP_PROPERTIES_METADATA_KEY, [...existingMetadataList, [propertyKey, options]], target.constructor); | ||
}; | ||
} | ||
function getAutoMapOptions(typeFnOrOptions) { | ||
@@ -141,3 +122,2 @@ if (typeFnOrOptions === undefined) { | ||
} | ||
if (typeof typeFnOrOptions === 'function') { | ||
@@ -150,3 +130,2 @@ return { | ||
} | ||
return typeFnOrOptions; | ||
@@ -153,0 +132,0 @@ } |
import { getMetadataList, AUTOMAP_PROPERTIES_METADATA_KEY } from '@automapper/classes'; | ||
import { AutoMapperLogger } from '@automapper/core'; | ||
function inheritAutoMapMetadata(parentClass, // eslint-disable-next-line @typescript-eslint/ban-types | ||
function inheritAutoMapMetadata(parentClass, | ||
// eslint-disable-next-line @typescript-eslint/ban-types | ||
targetClass, isPropertyInherited = () => true) { | ||
try { | ||
const [parentClassMetadataList] = getMetadataList(parentClass); | ||
if (!parentClassMetadataList.length) { | ||
return; | ||
} | ||
const [existingMetadataList] = getMetadataList(targetClass); | ||
@@ -37,3 +36,2 @@ Reflect.defineMetadata(AUTOMAP_PROPERTIES_METADATA_KEY, [...existingMetadataList, ...parentClassMetadataList.filter(([propertyKey]) => isPropertyInherited(propertyKey))], targetClass); | ||
const isInheritedPredicate = propertyKey => keys.includes(propertyKey); | ||
class PickClassType { | ||
@@ -43,5 +41,3 @@ constructor() { | ||
} | ||
} | ||
inheritAutoMapMetadata(classRef, PickClassType, isInheritedPredicate); | ||
@@ -53,3 +49,2 @@ return PickClassType; | ||
const isInheritedPredicate = propertyKey => !keys.includes(propertyKey); | ||
class OmitClassType { | ||
@@ -59,5 +54,3 @@ constructor() { | ||
} | ||
} | ||
inheritAutoMapMetadata(classRef, OmitClassType, isInheritedPredicate); | ||
@@ -73,5 +66,3 @@ return OmitClassType; | ||
} | ||
} | ||
inheritAutoMapMetadata(classARef, IntersectionClassType); | ||
@@ -78,0 +69,0 @@ inheritAutoMapMetadata(classBRef, IntersectionClassType); |
{ | ||
"name": "@automapper/classes/mapped-types", | ||
"version": "8.7.6", | ||
"version": "8.7.7", | ||
"type": "module", | ||
@@ -17,4 +17,4 @@ "exports": { | ||
"peerDependencies": { | ||
"@automapper/core": "8.7.6", | ||
"@automapper/classes": "8.7.6" | ||
"@automapper/core": "8.7.7", | ||
"@automapper/classes": "8.7.7" | ||
}, | ||
@@ -21,0 +21,0 @@ "repository": { |
{ | ||
"name": "@automapper/classes", | ||
"version": "8.7.6", | ||
"version": "8.7.7", | ||
"type": "module", | ||
"peerDependencies": { | ||
"@automapper/core": "8.7.6", | ||
"@automapper/core": "8.7.7", | ||
"reflect-metadata": "~0.1.13" | ||
@@ -8,0 +8,0 @@ }, |
@@ -23,9 +23,6 @@ import { AUTOMAPPER_METADATA_FACTORY_KEY } from '@automapper/classes'; | ||
var _a, _b; | ||
const symbol = type.getSymbol() || type.aliasSymbol; | ||
if (!symbol) { | ||
return false; | ||
} | ||
return symbol.getName() === 'Array' && (((_a = type.typeArguments) === null || _a === void 0 ? void 0 : _a.length) === 1 || ((_b = type.aliasTypeArguments) === null || _b === void 0 ? void 0 : _b.length) === 1); | ||
@@ -40,10 +37,7 @@ } | ||
} | ||
if (hasFlag(type, TypeFlags.EnumLiteral) && !type.isUnion()) return false; | ||
const symbol = type.getSymbol(); | ||
if (symbol == null) { | ||
return false; | ||
} | ||
const { | ||
@@ -59,3 +53,2 @@ valueDeclaration | ||
var _a, _b; | ||
const isEnum = isEnumType(type); | ||
@@ -70,3 +63,2 @@ const valueDeclaration = (_a = type.getSymbol()) === null || _a === void 0 ? void 0 : _a.valueDeclaration; | ||
var _a, _b; | ||
const isEnum = isEnumType(type); | ||
@@ -84,3 +76,2 @@ const valueDeclaration = (_a = type.getSymbol()) === null || _a === void 0 ? void 0 : _a.valueDeclaration; | ||
const isDecoratorFactory = decorator.expression.kind === SyntaxKind.CallExpression; | ||
if (isDecoratorFactory) { | ||
@@ -90,10 +81,7 @@ const callExpression = decorator.expression; | ||
const identifier = expression; | ||
if (isDynamicallyAdded(identifier)) { | ||
return undefined; | ||
} | ||
return getIdentifierFromExpression(expression).getText(); | ||
} | ||
return getIdentifierFromExpression(decorator.expression).getText(); | ||
@@ -105,3 +93,2 @@ } | ||
} | ||
return expression; | ||
@@ -111,7 +98,5 @@ } | ||
const identifier = getNameFromExpression(expression); | ||
if (identifier && identifier.kind !== SyntaxKind.Identifier) { | ||
throw new Error(); | ||
} | ||
return identifier; | ||
@@ -123,3 +108,2 @@ } | ||
} | ||
const compilerNode = !enclosingNode ? undefined : enclosingNode; | ||
@@ -139,23 +123,17 @@ return typeChecker.typeToString(type, compilerNode, typeFormatFlags); | ||
} | ||
if (isBoolean(type)) { | ||
return [Boolean.name, isArray]; | ||
} | ||
if (isNumber(type) || isNumberEnum(type)) { | ||
return [Number.name, isArray]; | ||
} | ||
if (isString(type) || isStringEnum(type)) { | ||
return [String.name, isArray]; | ||
} | ||
if (isDate(type)) { | ||
return [Date.name, isArray]; | ||
} | ||
if (type.isClass() || type.aliasSymbol) { | ||
return [getText(type, typeChecker), isArray]; | ||
} | ||
return [undefined, isArray]; | ||
@@ -165,9 +143,6 @@ } | ||
var _a; | ||
let importPath = (_a = /\("([^)]).+(")/.exec(typeReference)) === null || _a === void 0 ? void 0 : _a[0]; | ||
if (!importPath) { | ||
return undefined; | ||
} | ||
importPath = importPath.slice(2, importPath.length - 1); | ||
@@ -186,7 +161,5 @@ let relativePath = posix.relative(dirname(fileName), importPath); | ||
} | ||
static visit(sourceFile, context, program) { | ||
const typeChecker = program.getTypeChecker(); | ||
ModelVisitor.isCommonJS = context.getCompilerOptions().module === ModuleKind.CommonJS; | ||
function nodeVisitorFactory(ctx, sf) { | ||
@@ -198,7 +171,6 @@ const nodeVisitor = node => { | ||
return node; | ||
} // if this is a class node, traverse all properties in this class | ||
} | ||
// if this is a class node, traverse all properties in this class | ||
// after traverse finishes, we add the metadata factory method to the class | ||
// because all nodes' metadata should have been saved | ||
if (isClassDeclaration(node)) { | ||
@@ -208,28 +180,23 @@ // visit each property/methods/nodes/comments in the class | ||
return ModelVisitor.addMetadataFactory(node, ctx.factory); | ||
} // if the node is property or a getter | ||
} | ||
// if the node is property or a getter | ||
// foo: string | ||
// get foo(): string {} | ||
if (isPropertyDeclaration(node) || isGetAccessorDeclaration(node)) { | ||
const decorators = node.decorators; | ||
const existingAutoMapDecorator = getDecoratorOrUndefinedByNames([AUTOMAPPER_DECORATOR_NAME], ctx.factory, decorators); // if the property already has AutoMap decorator on it, skip | ||
const existingAutoMapDecorator = getDecoratorOrUndefinedByNames([AUTOMAPPER_DECORATOR_NAME], ctx.factory, decorators); | ||
// if the property already has AutoMap decorator on it, skip | ||
if (existingAutoMapDecorator) { | ||
return node; | ||
} | ||
const isPropertyStaticOrPrivate = (node.modifiers || []).some(modifier => modifier.kind === SyntaxKind.StaticKeyword || modifier.kind === SyntaxKind.PrivateKeyword); // if this property is static or private, skip because | ||
const isPropertyStaticOrPrivate = (node.modifiers || []).some(modifier => modifier.kind === SyntaxKind.StaticKeyword || modifier.kind === SyntaxKind.PrivateKeyword); | ||
// if this property is static or private, skip because | ||
// we shouldn't/can't access this property when mapping | ||
if (isPropertyStaticOrPrivate) { | ||
return node; | ||
} // Check jsDoc for ignore tag | ||
} | ||
// Check jsDoc for ignore tag | ||
const jsDocKey = JSDOC_KEY; | ||
if (node[jsDocKey]) { | ||
const ignoreTag = getAllJSDocTags(node[jsDocKey], tag => tag.tagName.escapedText === AUTOMAP_IGNORE_TAG); | ||
if (ignoreTag) { | ||
@@ -239,34 +206,26 @@ return node; | ||
} | ||
return ModelVisitor.inspectNode(ctx.factory, node, typeChecker, sf); | ||
} // visit each node in the file | ||
} | ||
// visit each node in the file | ||
return visitEachChild(node, nodeVisitor, ctx); | ||
}; | ||
return nodeVisitor; | ||
} | ||
const visitedSourceFile = visitNode(sourceFile, nodeVisitorFactory(context, sourceFile)); // if the target is CommonJS, keep as is | ||
const visitedSourceFile = visitNode(sourceFile, nodeVisitorFactory(context, sourceFile)); | ||
// if the target is CommonJS, keep as is | ||
if (ModelVisitor.isCommonJS) { | ||
return visitedSourceFile; | ||
} // if the target is not CommonJS, we need to re-map the imports | ||
} | ||
// if the target is not CommonJS, we need to re-map the imports | ||
return context.factory.updateSourceFile(visitedSourceFile, [...ModelVisitor.importsMap.values()].concat((visitedSourceFile.statements || []).filter(statement => statement.kind !== SyntaxKind.ImportDeclaration)), visitedSourceFile.isDeclarationFile, visitedSourceFile.referencedFiles, visitedSourceFile.typeReferenceDirectives, visitedSourceFile.hasNoDefaultLib, visitedSourceFile.libReferenceDirectives); | ||
} | ||
static addMetadataFactory(classNode, factory) { | ||
const classMetadata = this.getClassMetadata(classNode); // return early, no class metadata | ||
const classMetadata = this.getClassMetadata(classNode); | ||
// return early, no class metadata | ||
if (!classMetadata) { | ||
return classNode; | ||
} // add the factory static method at the end of the class | ||
} | ||
// add the factory static method at the end of the class | ||
return factory.updateClassDeclaration(classNode, classNode.decorators, classNode.modifiers, classNode.name, classNode.typeParameters, classNode.heritageClauses, [...classNode.members, this.createMetadataFactoryMethod(factory, classMetadata)]); | ||
} | ||
static createMetadataFactoryMethod(factory, metadata) { | ||
@@ -283,3 +242,2 @@ /** | ||
} | ||
return expressions; | ||
@@ -292,25 +250,21 @@ }, []), true); | ||
*/ | ||
return factory.createMethodDeclaration(undefined, [factory.createModifier(SyntaxKind.StaticKeyword)], undefined, factory.createIdentifier(AUTOMAPPER_METADATA_FACTORY_KEY), undefined, undefined, [], undefined, factory.createBlock([factory.createReturnStatement(metadataAsReturnBlock)], true)); | ||
} | ||
static addMetadata(node, metadata, // { type, depth } | ||
static addMetadata(node, metadata, | ||
// { type, depth } | ||
sourceFile) { | ||
var _a, _b; | ||
const hostClass = node.parent; | ||
const className = (_a = hostClass.name) === null || _a === void 0 ? void 0 : _a.getText(); // cannot find the class of this property, skip | ||
const className = (_a = hostClass.name) === null || _a === void 0 ? void 0 : _a.getText(); | ||
// cannot find the class of this property, skip | ||
if (!className) { | ||
return node; | ||
} | ||
const existingMetadata = this.metadataMap.get(className) || {}; | ||
const propertyName = (_b = node.name) === null || _b === void 0 ? void 0 : _b.getText(sourceFile); // defensive, no name for this property, skip | ||
const propertyName = (_b = node.name) === null || _b === void 0 ? void 0 : _b.getText(sourceFile); | ||
// defensive, no name for this property, skip | ||
// or this property name is computed like: object[computed] | ||
if (!propertyName || node.name && node.name.kind === SyntaxKind.ComputedPropertyName) { | ||
return node; | ||
} | ||
this.metadataMap.set(className, Object.assign(Object.assign({}, existingMetadata), { | ||
@@ -321,32 +275,26 @@ [propertyName]: metadata | ||
} | ||
static inspectNode(factory, node, typeChecker, sourceFile) { | ||
// try getting type from typeChecker | ||
let type = typeChecker.getTypeAtLocation(node); | ||
const typeNode = node.type; // no type for property node, skip | ||
if (!type || !typeNode) return node; // union with undefined or null like string | null, ?: string | ||
const typeNode = node.type; | ||
// no type for property node, skip | ||
if (!type || !typeNode) return node; | ||
// union with undefined or null like string | null, ?: string | ||
if (isNullableUnionType(type)) { | ||
type = type.getNonNullableType(); | ||
} // typeReference is [the type, if the type is array or not] | ||
} | ||
// typeReference is [the type, if the type is array or not] | ||
const typeReference = getTypeReference(type, typeNode, typeChecker); | ||
if (!typeReference[0]) { | ||
const typeReferenceFromNodeType = this.tryGetTypeReferenceFromNodeType(node); | ||
if (typeReferenceFromNodeType) { | ||
typeReference[0] = typeReferenceFromNodeType; | ||
} | ||
} // failed to infer type, skip | ||
if (!typeReference[0]) return node; // if typeReference includes an import statement, extract the correct import symbol | ||
} | ||
// failed to infer type, skip | ||
if (!typeReference[0]) return node; | ||
// if typeReference includes an import statement, extract the correct import symbol | ||
if (typeReference[0].includes('import')) { | ||
if (ModelVisitor.isCommonJS) { | ||
const replacedImportPath = replaceImportPath(typeReference[0], sourceFile.fileName); | ||
if (replacedImportPath) { | ||
@@ -357,3 +305,2 @@ typeReference[0] = replacedImportPath; | ||
const typeName = typeReference[0].split('.').pop(); | ||
if (typeName) { | ||
@@ -364,6 +311,4 @@ typeReference[0] = typeName; | ||
} | ||
return this.addMetadata(node, this.createMetadataObjectLiteral(factory, typeReference), sourceFile); | ||
} | ||
static createMetadataObjectLiteral(factory, [type, isArray]) { | ||
@@ -373,3 +318,2 @@ // result should be: { type: () => typeReference | [typeReference], depth: 1 } | ||
} | ||
static getClassMetadata(classNode) { | ||
@@ -379,16 +323,11 @@ if (!classNode.name) { | ||
} | ||
return this.metadataMap.get(classNode.name.getText()); | ||
} | ||
static tryGetTypeReferenceFromNodeType(node) { | ||
var _a; | ||
return (_a = node.type.typeName) === null || _a === void 0 ? void 0 : _a.escapedText; | ||
} | ||
static cloneImportDeclaration(factory, importDeclaration) { | ||
return factory.createImportDeclaration(importDeclaration.decorators, importDeclaration.modifiers, importDeclaration.importClause, importDeclaration.moduleSpecifier); | ||
} | ||
} | ||
@@ -413,7 +352,5 @@ ModelVisitor.metadataMap = new Map(); | ||
} | ||
return sourceFile; | ||
}; | ||
} | ||
}; | ||
@@ -420,0 +357,0 @@ } |
{ | ||
"name": "@automapper/classes/transformer-plugin", | ||
"version": "8.7.6", | ||
"version": "8.7.7", | ||
"type": "module", | ||
@@ -17,4 +17,4 @@ "exports": { | ||
"peerDependencies": { | ||
"@automapper/core": "8.7.6", | ||
"@automapper/classes": "8.7.6" | ||
"@automapper/core": "8.7.7", | ||
"@automapper/classes": "8.7.7" | ||
}, | ||
@@ -21,0 +21,0 @@ "repository": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1180
70640