diff --git a/.gitignore b/.gitignore index d28f9a65..67f5dafe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.idea node_modules dist *.log* diff --git a/package.json b/package.json index a2b2460b..488af7e8 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "acorn": "^8.8.2", "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-parameter-decorator": "^1.0.16", + "babel-plugin-transform-typescript-metadata": "^0.3.2", "changelogen": "^0.4.1", "config": "^3.3.9", "create-require": "^1.1.1", @@ -63,11 +64,13 @@ "pirates": "^4.0.5", "pkg-types": "^1.0.2", "prettier": "^2.8.4", + "reflect-metadata": "^0.1.13", "semver": "^7.3.8", "terser-webpack-plugin": "^5.3.6", "ts-loader": "^9.4.2", "tslib": "^2.5.0", "typescript": "^4.9.5", + "vite": "^4.1.2", "vitest": "^0.28.5", "webpack": "^5.75.0", "webpack-cli": "^5.0.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 561f5061..7d9ac843 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,7 @@ specifiers: acorn: ^8.8.2 babel-plugin-dynamic-import-node: ^2.3.3 babel-plugin-parameter-decorator: ^1.0.16 + babel-plugin-transform-typescript-metadata: ^0.3.2 changelogen: ^0.4.1 config: ^3.3.9 create-require: ^1.1.1 @@ -41,11 +42,13 @@ specifiers: pirates: ^4.0.5 pkg-types: ^1.0.2 prettier: ^2.8.4 + reflect-metadata: ^0.1.13 semver: ^7.3.8 terser-webpack-plugin: ^5.3.6 ts-loader: ^9.4.2 tslib: ^2.5.0 typescript: ^4.9.5 + vite: ^4.1.2 vitest: ^0.28.5 webpack: ^5.75.0 webpack-cli: ^5.0.1 @@ -73,6 +76,7 @@ devDependencies: acorn: 8.8.2 babel-plugin-dynamic-import-node: 2.3.3 babel-plugin-parameter-decorator: 1.0.16 + babel-plugin-transform-typescript-metadata: 0.3.2 changelogen: 0.4.1 config: 3.3.9 create-require: 1.1.1 @@ -91,11 +95,13 @@ devDependencies: pirates: 4.0.5 pkg-types: 1.0.2 prettier: 2.8.4 + reflect-metadata: 0.1.13 semver: 7.3.8 terser-webpack-plugin: 5.3.6_webpack@5.75.0 ts-loader: 9.4.2_hhrrucqyg4eysmfpujvov2ym5u tslib: 2.5.0 typescript: 4.9.5 + vite: 4.1.2_@types+node@18.13.0 vitest: 0.28.5 webpack: 5.75.0_webpack-cli@5.0.1 webpack-cli: 5.0.1_webpack@5.75.0 @@ -1428,6 +1434,12 @@ packages: resolution: {integrity: sha512-yUT2WPTUg1JaPmRGRSF557m1HJ9vdFQInRWOkiOyO5a9HhqlXffJu+fQ2xd5+qU/35ICMrrk9eWKsHCairKA9w==} dev: true + /babel-plugin-transform-typescript-metadata/0.3.2: + resolution: {integrity: sha512-mWEvCQTgXQf48yDqgN7CH50waTyYBeP2Lpqx4nNWab9sxEpdXVeKgfj1qYI2/TgUPQtNFZ85i3PemRtnXVYYJg==} + dependencies: + '@babel/helper-plugin-utils': 7.20.2 + dev: true + /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true @@ -3506,6 +3518,10 @@ packages: resolve: 1.22.1 dev: true + /reflect-metadata/0.1.13: + resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} + dev: true + /regexp-tree/0.1.24: resolution: {integrity: sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==} hasBin: true @@ -4086,7 +4102,7 @@ packages: picocolors: 1.0.0 source-map: 0.6.1 source-map-support: 0.5.21 - vite: 4.1.1_@types+node@18.13.0 + vite: 4.1.2_@types+node@18.13.0 transitivePeerDependencies: - '@types/node' - less @@ -4097,8 +4113,8 @@ packages: - terser dev: true - /vite/4.1.1_@types+node@18.13.0: - resolution: {integrity: sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==} + /vite/4.1.2_@types+node@18.13.0: + resolution: {integrity: sha512-MWDb9Rfy3DI8omDQySbMK93nQqStwbsQWejXRY2EBzEWKmLAXWb1mkI9Yw2IJrc+oCvPCI1Os5xSSIBYY6DEAw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -4174,7 +4190,7 @@ packages: tinybench: 2.3.1 tinypool: 0.3.1 tinyspy: 1.1.1 - vite: 4.1.1_@types+node@18.13.0 + vite: 4.1.2_@types+node@18.13.0 vite-node: 0.28.5_@types+node@18.13.0 why-is-node-running: 2.2.2 transitivePeerDependencies: diff --git a/src/babel.ts b/src/babel.ts index 339b0b57..751b7e7b 100644 --- a/src/babel.ts +++ b/src/babel.ts @@ -33,11 +33,11 @@ export default function transform(opts: TransformOptions): TRANSFORM_RESULT { require("@babel/plugin-transform-typescript"), { allowDeclareFields: true }, ]); - // `unshift` because this plugin must come before `@babel/plugin-syntax-class-properties` - _opts.plugins.unshift([ - require("@babel/plugin-proposal-decorators"), - { legacy: true }, - ]); + // `unshift` because these plugin must come before `@babel/plugin-syntax-class-properties` + _opts.plugins.unshift( + [require("babel-plugin-transform-typescript-metadata")], + [require("@babel/plugin-proposal-decorators"), { legacy: true }] + ); _opts.plugins.push(require("babel-plugin-parameter-decorator")); _opts.plugins.push(require("@babel/plugin-syntax-import-assertions")); } diff --git a/test/__snapshots__/fixtures.test.ts.snap b/test/__snapshots__/fixtures.test.ts.snap index 7a847364..fdb36b45 100644 --- a/test/__snapshots__/fixtures.test.ts.snap +++ b/test/__snapshots__/fixtures.test.ts.snap @@ -106,9 +106,14 @@ Logical nullish assignment: 50 20" `; exports[`fixtures > typescript > stdout 1`] = ` -"{ +"Decorator metadata keys: design:type +Decorator called with 3 arguments. +Decorator called with 3 arguments. +Decorator called with 3 arguments. +Decorator called with 1 arguments. +{ file: '/test.ts', dir: '', resolve: '/test.ts' -} undefined" +} undefined [class DecoratedClass]" `; diff --git a/test/fixtures/typescript/decorators.ts b/test/fixtures/typescript/decorators.ts index 92d04084..720bd01d 100644 --- a/test/fixtures/typescript/decorators.ts +++ b/test/fixtures/typescript/decorators.ts @@ -1,11 +1,21 @@ +import "reflect-metadata"; function decorator(...args: any) { - console.log("Decorator called with arguments:", args); + console.log("Decorator called with " + args.length + " arguments."); +} + +function anotherDecorator() { + return function (object: any, propertyName: any) { + console.log( + "Decorator metadata keys: " + + Reflect.getMetadataKeys(object, propertyName) + ); + }; } @decorator export default class DecoratedClass { - @decorator - decoratedProperty = null; + @anotherDecorator() + decoratedProperty: string; @decorator get decoratedAccessor() { @@ -16,4 +26,8 @@ export default class DecoratedClass { decoratedFunction(@decorator decoratedParameter: any) { return decoratedParameter; } + + constructor() { + this.decoratedProperty = "foo"; + } } diff --git a/test/fixtures/typescript/index.ts b/test/fixtures/typescript/index.ts index 747ef96f..689bc0ff 100644 --- a/test/fixtures/typescript/index.ts +++ b/test/fixtures/typescript/index.ts @@ -1,4 +1,5 @@ import test, { FeedService } from "./test"; +import Clazz from "./decorators"; export type { Test } from "./types"; -console.log(test(), FeedService); +console.log(test(), FeedService, Clazz);