babel-plugin-transform-typescript-metadata
Advanced tools
Comparing version 0.2.1 to 0.2.2
@@ -0,1 +1,22 @@ | ||
## [0.2.2](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/compare/v0.2.1...v0.2.2) (2019-03-27) | ||
### 🐛 Bug Fixes | ||
* Add InversifyJS function to make decorators compatible with babel ([4535adb](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/commit/4535adb)) | ||
* Handle unsupported kind of parameters with void zero ([a35f733](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/commit/a35f733)) | ||
* Omit value when it's a reference to self (class name) ([f755bc2](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/commit/f755bc2)) | ||
### 📚 Documentation | ||
* Add InversifyJS property injection doc ([b263fcd](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/commit/b263fcd)) | ||
* Make example DI code more realistic ([620182f](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/commit/620182f)) | ||
### 🏗 Chore | ||
* Add example code to test InversifyJS property injector ([48bd0bb](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/commit/48bd0bb)), closes [#2](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/issues/2) | ||
## [0.2.1](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/compare/v0.2.0...v0.2.1) (2019-03-24) | ||
@@ -2,0 +23,0 @@ |
@@ -5,5 +5,11 @@ import { types as t } from '@babel/core'; | ||
declare type Parameter = InferArray<t.ClassMethod['params']> | t.ClassProperty; | ||
export declare function serializeType(path: NodePath<any>, param: Parameter): SerializedType; | ||
export declare function serializeType(classPath: NodePath<t.ClassDeclaration>, param: Parameter): SerializedType; | ||
/** | ||
* Checks if node (this should be the result of `serializeReference`) member | ||
* expression or identifier is a reference to self (class name). | ||
* In this case, we just emit `Object` in order to avoid ReferenceError. | ||
*/ | ||
export declare function isClassType(className: string, node: t.Expression): boolean; | ||
declare type SerializedType = t.Identifier | t.UnaryExpression | t.ConditionalExpression; | ||
export {}; | ||
//# sourceMappingURL=serializeType.d.ts.map |
@@ -7,2 +7,3 @@ "use strict"; | ||
exports.serializeType = serializeType; | ||
exports.isClassType = isClassType; | ||
@@ -24,2 +25,3 @@ var _core = require("@babel/core"); | ||
function getTypedNode(param) { | ||
if (param == null) return null; | ||
if (param.type === 'ClassProperty') return param; | ||
@@ -32,3 +34,3 @@ if (param.type === 'Identifier') return param; | ||
function serializeType(path, param) { | ||
function serializeType(classPath, param) { | ||
const node = getTypedNode(param); | ||
@@ -38,6 +40,7 @@ if (node == null) return createVoidZero(); | ||
const annotation = node.typeAnnotation.typeAnnotation; | ||
return serializeTypeNode(annotation); | ||
const className = classPath.node.id ? classPath.node.id.name : ''; | ||
return serializeTypeNode(className, annotation); | ||
} | ||
function serializeTypeReferenceNode(node) { | ||
function serializeTypeReferenceNode(className, node) { | ||
/** | ||
@@ -52,2 +55,10 @@ * We need to save references to this type since it is going | ||
/** | ||
* We should omit references to self (class) since it will throw a | ||
* ReferenceError at runtime due to babel transpile output. | ||
*/ | ||
if (isClassType(className, reference)) { | ||
return _core.types.identifier('Object'); | ||
} | ||
/** | ||
* We don't know if type is just a type (interface, etc.) or a concrete | ||
@@ -59,7 +70,30 @@ * value (class, etc.). | ||
return _core.types.conditionalExpression(_core.types.binaryExpression('===', _core.types.unaryExpression('typeof', reference), _core.types.stringLiteral('undefined')), _core.types.identifier('Object'), _core.types.clone(reference)); | ||
} | ||
/** | ||
* Checks if node (this should be the result of `serializeReference`) member | ||
* expression or identifier is a reference to self (class name). | ||
* In this case, we just emit `Object` in order to avoid ReferenceError. | ||
*/ | ||
function isClassType(className, node) { | ||
switch (node.type) { | ||
case 'Identifier': | ||
return node.name === className; | ||
case 'MemberExpression': | ||
return isClassType(className, node.object); | ||
default: | ||
throw new Error(`The property expression at ${node.start} is not valid as a Type to be used in Reflect.metadata`); | ||
} | ||
} | ||
function serializeReference(typeName) { | ||
if (typeName.type === 'Identifier') return _core.types.identifier(typeName.name); | ||
if (typeName.type === 'Identifier') { | ||
return _core.types.identifier(typeName.name); | ||
} | ||
return _core.types.memberExpression(serializeReference(typeName.left), typeName.right); | ||
@@ -76,3 +110,3 @@ } | ||
*/ | ||
function serializeTypeNode(node) { | ||
function serializeTypeNode(className, node) { | ||
if (node === undefined) { | ||
@@ -90,3 +124,3 @@ return _core.types.identifier('Object'); | ||
case 'TSParenthesizedType': | ||
return serializeTypeNode(node.typeAnnotation); | ||
return serializeTypeNode(className, node.typeAnnotation); | ||
@@ -136,10 +170,10 @@ case 'TSFunctionType': | ||
case 'TSTypeReference': | ||
return serializeTypeReferenceNode(node); | ||
return serializeTypeReferenceNode(className, node); | ||
case 'TSIntersectionType': | ||
case 'TSUnionType': | ||
return serializeTypeList(node.types); | ||
return serializeTypeList(className, node.types); | ||
case 'TSConditionalType': | ||
return serializeTypeList([node.trueType, node.falseType]); | ||
return serializeTypeList(className, [node.trueType, node.falseType]); | ||
@@ -171,3 +205,3 @@ case 'TSTypeQuery': | ||
function serializeTypeList(types) { | ||
function serializeTypeList(className, types) { | ||
let serializedUnion; | ||
@@ -188,3 +222,3 @@ | ||
const serializedIndividual = serializeTypeNode(typeNode); | ||
const serializedIndividual = serializeTypeNode(className, typeNode); | ||
@@ -191,0 +225,0 @@ if (_core.types.isIdentifier(serializedIndividual) && serializedIndividual.name === 'Object') { |
{ | ||
"name": "babel-plugin-transform-typescript-metadata", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "Babel plugin to emit decorator metadata like typescript compiler", | ||
@@ -60,2 +60,3 @@ "main": "lib/plugin.js", | ||
"@babel/preset-typescript": "^7.3.3", | ||
"@babel/template": "^7.4.0", | ||
"@favoloso/conventional-changelog-emoji": "^0.9.0", | ||
@@ -62,0 +63,0 @@ "@types/jest": "^24.0.11", |
@@ -27,2 +27,3 @@ # babel-plugin-transform-typescript-metadata | ||
```ts | ||
import { Injectable, Inject } from 'some-di-library'; // Just an example | ||
import { MyService } from './MyService'; | ||
@@ -109,2 +110,33 @@ import { Configuration } from './Configuration'; | ||
### Usage with [InversifyJS](http://inversify.io) | ||
If you are using normal dependency injection letting Inversify **create your instances**, you should be fine with all kind of decorators. | ||
Instead, if you are using **property injection**, when [the container does not | ||
create the instances](https://github.com/inversify/InversifyJS/blob/master/wiki/property_injection.md#when-we-cannot-use-inversifyjs-to-create-an-instance-of-a-class), | ||
you would likely encounter errors since babel | ||
decorators are not exactly the same as TypeScript. | ||
You can fix it by _enhancing property decorators_ with the following function: | ||
```ts | ||
import getDecorators from 'inversify-inject-decorators'; | ||
// setup the container... | ||
let { lazyInject: originalLazyInject } = getDecorators(container); | ||
// Additional function to make properties decorators compatible with babel. | ||
function fixPropertyDecorator<T extends Function>(decorator: T): T { | ||
return ((...args: any[]) => ( | ||
target: any, | ||
propertyName: any, | ||
...decoratorArgs: any[] | ||
) => { | ||
decorator(...args)(target, propertyName, ...decoratorArgs); | ||
return Object.getOwnPropertyDescriptor(target, propertyName); | ||
}) as any; | ||
} | ||
export const lazyInject = fixPropertyDecorator(originalLazyInject); | ||
``` | ||
## Current Pitfalls | ||
@@ -111,0 +143,0 @@ |
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
26350
302
157
16