babel-plugin-transform-typescript-metadata
Advanced tools
Comparing version 0.2.2 to 0.3.0
@@ -0,1 +1,19 @@ | ||
# [0.3.0](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/compare/v0.2.2...v0.3.0) (2020-03-05) | ||
### ✨ Features | ||
* Add support for TSBigIntKeyword ([358a689](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/commit/358a689)) | ||
* Move param dec to class ([1371f6b](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/commit/1371f6b)) | ||
### 🐛 Bug Fixes | ||
* Restored [@babel](https://github.com/babel)/core types to allow TSC checking ([55ff485](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/commit/55ff485)) | ||
### 🏗 Chore | ||
* Update release-it to v11+ ([e61386f](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/commit/e61386f)) | ||
## [0.2.2](https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/compare/v0.2.1...v0.2.2) (2019-03-27) | ||
@@ -2,0 +20,0 @@ |
@@ -12,2 +12,6 @@ "use strict"; | ||
function createMetadataDesignDecorator(design, typeArg) { | ||
return _core.types.decorator(_core.types.callExpression(_core.types.memberExpression(_core.types.identifier('Reflect'), _core.types.identifier('metadata')), [_core.types.stringLiteral(design), typeArg])); | ||
} | ||
function metadataVisitor(classPath, path) { | ||
@@ -21,3 +25,7 @@ const field = path.node; | ||
if (!decorators || decorators.length === 0) return; | ||
decorators.push(_core.types.decorator(_core.types.callExpression(_core.types.memberExpression(_core.types.identifier('Reflect'), _core.types.identifier('metadata')), [_core.types.stringLiteral('design:paramtypes'), _core.types.arrayExpression(field.params.map(param => (0, _serializeType.serializeType)(classPath, param)))]))); | ||
decorators.push(createMetadataDesignDecorator('design:type', _core.types.identifier('Function'))); | ||
decorators.push(createMetadataDesignDecorator('design:paramtypes', _core.types.arrayExpression(field.params.map(param => (0, _serializeType.serializeType)(classPath, param))))); // Hint: `design:returntype` could also be implemented here, although this seems | ||
// quite complicated to achieve without the TypeScript compiler. | ||
// See https://github.com/microsoft/TypeScript/blob/f807b57356a8c7e476fedc11ad98c9b02a9a0e81/src/compiler/transformers/ts.ts#L1315 | ||
break; | ||
@@ -28,5 +36,5 @@ | ||
if (!field.typeAnnotation || field.typeAnnotation.type !== 'TSTypeAnnotation') return; | ||
field.decorators.push(_core.types.decorator(_core.types.callExpression(_core.types.memberExpression(_core.types.identifier('Reflect'), _core.types.identifier('metadata')), [_core.types.stringLiteral('design:type'), (0, _serializeType.serializeType)(classPath, field)]))); | ||
field.decorators.push(createMetadataDesignDecorator('design:type', (0, _serializeType.serializeType)(classPath, field))); | ||
break; | ||
} | ||
} |
@@ -156,2 +156,4 @@ "use strict"; | ||
case 'TSNumberKeyword': | ||
case 'TSBigIntKeyword': | ||
// Still not in ``@babel/core` typings | ||
return _core.types.identifier('Number'); | ||
@@ -158,0 +160,0 @@ |
@@ -10,2 +10,24 @@ "use strict"; | ||
/** | ||
* Helper function to create a field/class decorator from a parameter decorator. | ||
* Field/class decorators get three arguments: the class, the name of the method | ||
* (or 'undefined' in the case of the constructor) and the position index of the | ||
* parameter in the argument list. | ||
* Some of this information, the index, is only available at transform time, and | ||
* has to be stored. The other arguments are part of the decorator signature and | ||
* will be passed to the decorator anyway. But the decorator has to be called | ||
* with all three arguments at runtime, so this creates a function wrapper, which | ||
* takes the target and the key, and adds the index to it. | ||
* | ||
* Inject() becomes function(target, key) { return Inject()(target, key, 0) } | ||
* | ||
* @param paramIndex the index of the parameter inside the function call | ||
* @param decoratorExpression the decorator expression, the return object of SomeParameterDecorator() | ||
* @param isConstructor indicates if the key should be set to 'undefined' | ||
*/ | ||
function createParamDecorator(paramIndex, decoratorExpression, isConstructor = false) { | ||
return _core.types.decorator(_core.types.functionExpression(null, // anonymous function | ||
[_core.types.identifier('target'), _core.types.identifier('key')], _core.types.blockStatement([_core.types.returnStatement(_core.types.callExpression(decoratorExpression, [_core.types.identifier('target'), _core.types.identifier(isConstructor ? 'undefined' : 'key'), _core.types.numericLiteral(paramIndex)]))]))); | ||
} | ||
function parameterVisitor(classPath, path) { | ||
@@ -16,3 +38,2 @@ if (path.type !== 'ClassMethod') return; | ||
const methodPath = path; | ||
const methodName = path.node.key.name; | ||
const params = methodPath.get('params') || []; | ||
@@ -24,13 +45,19 @@ params.slice().forEach(function (param) { | ||
(param.node.decorators || []).slice().forEach(function (decorator) { | ||
const className = classPath.node.id.name; | ||
if (methodPath.node.kind === 'constructor') { | ||
resultantDecorator = createParamDecorator(param.key, decorator.expression, true); | ||
if (methodPath.node.kind === 'constructor') { | ||
resultantDecorator = _core.types.callExpression(decorator.expression, [_core.types.identifier(className), _core.types.identifier('undefined'), _core.types.numericLiteral(param.key)]); | ||
if (!classPath.node.decorators) { | ||
classPath.node.decorators = []; | ||
} | ||
classPath.node.decorators.push(resultantDecorator); | ||
} else { | ||
resultantDecorator = _core.types.callExpression(decorator.expression, [_core.types.identifier(`${className}.prototype`), _core.types.stringLiteral(methodName), _core.types.numericLiteral(param.key)]); | ||
} | ||
resultantDecorator = createParamDecorator(param.key, decorator.expression, false); | ||
const expression = _core.types.expressionStatement(resultantDecorator); | ||
if (!methodPath.node.decorators) { | ||
methodPath.node.decorators = []; | ||
} | ||
classPath.insertAfter(expression); | ||
methodPath.node.decorators.push(resultantDecorator); | ||
} | ||
}); | ||
@@ -37,0 +64,0 @@ |
{ | ||
"name": "babel-plugin-transform-typescript-metadata", | ||
"version": "0.2.2", | ||
"version": "0.3.0", | ||
"description": "Babel plugin to emit decorator metadata like typescript compiler", | ||
@@ -44,6 +44,7 @@ "main": "lib/plugin.js", | ||
}, | ||
"increment": "conventional:@favoloso/emoji", | ||
"scripts": { | ||
"changelog": "./node_modules/.bin/conventional-changelog -p @favoloso/emoji | tail -n +3", | ||
"beforeStage": "./node_modules/.bin/conventional-changelog -p @favoloso/emoji -i CHANGELOG.md -s" | ||
"plugins": { | ||
"@release-it/conventional-changelog": { | ||
"preset": "@favoloso/emoji", | ||
"infile": "CHANGELOG.md" | ||
} | ||
} | ||
@@ -55,18 +56,20 @@ }, | ||
"devDependencies": { | ||
"@babel/cli": "^7.2.3", | ||
"@babel/core": "^7.4.0", | ||
"@babel/plugin-proposal-class-properties": "^7.4.0", | ||
"@babel/plugin-proposal-decorators": "^7.4.0", | ||
"@babel/preset-env": "^7.4.2", | ||
"@babel/preset-typescript": "^7.3.3", | ||
"@babel/template": "^7.4.0", | ||
"@favoloso/conventional-changelog-emoji": "^0.9.0", | ||
"@types/jest": "^24.0.11", | ||
"babel-test": "^0.1.6", | ||
"conventional-changelog-cli": "^2.0.12", | ||
"husky": "^1.3.1", | ||
"jest": "^24.5.0", | ||
"jest-file-snapshot": "^0.3.6", | ||
"release-it": "^10.3.1", | ||
"typescript": "^3.3.4000" | ||
"@babel/cli": "^7.6.4", | ||
"@babel/core": "^7.6.4", | ||
"@babel/plugin-proposal-class-properties": "^7.5.5", | ||
"@babel/plugin-proposal-decorators": "^7.6.0", | ||
"@babel/preset-env": "^7.6.3", | ||
"@babel/preset-typescript": "^7.6.0", | ||
"@babel/template": "^7.6.0", | ||
"@babel/types": "^7.6.3", | ||
"@favoloso/conventional-changelog-emoji": "^0.10.0", | ||
"@release-it/conventional-changelog": "^1.1.0", | ||
"@types/jest": "^24.0.19", | ||
"babel-test": "^0.2.3", | ||
"conventional-changelog-cli": "^2.0.25", | ||
"husky": "^4.2.3", | ||
"jest": "^24.9.0", | ||
"jest-file-snapshot": "^0.3.7", | ||
"release-it": "^12.6.3", | ||
"typescript": "^3.6.4" | ||
}, | ||
@@ -73,0 +76,0 @@ "dependencies": { |
@@ -145,13 +145,2 @@ # babel-plugin-transform-typescript-metadata | ||
following: `typeof Type === 'undefined' ? Object : Type`. The code has the | ||
advantage of not throwing If you know a better | ||
way to do this, let me know! | ||
- Parameter decorators are emitted right _after_ the `ClassDeclaration` node, | ||
like: | ||
```js | ||
let A = (/* ... */) | ||
Inject()(A.prototype, 'methodName', 1); | ||
``` | ||
I'm not sure if this can cause issue with scoping, if you get in troubles with | ||
this kind of decorators, please open an issue. | ||
advantage of not throwing. If you know a better way to do this, let me know! |
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
28599
334
18
146