├── .babelrc
├── .gitignore
├── .idea
├── babel-plugin-mobx-async-action.iml
├── encodings.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── package.json
├── src
└── index.js
└── test
├── fixtures
├── handle-async-await-generator
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
├── handle-base-case
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
├── handle-custom-import
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
├── handle-custom-package
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
├── handle-mobx-imported-as-namespace-but-action-used-separately
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
├── handle-mobx-imported-as-namespace
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
├── handle-typescript-and-class-expression
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
├── handle-when-function-has-extra-wrapper
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
├── transform-typescript-decorated-methods
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
├── transform-typescript-decorated-with-metadata
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
├── work-with-latest-preset-and-typescript
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
└── work-with-latest-preset
│ ├── .babelrc
│ ├── actual.js
│ └── expected.js
└── index.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-0"]
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | lib
4 | package-lock.json
5 | /.idea
6 |
--------------------------------------------------------------------------------
/.idea/babel-plugin-mobx-async-action.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | src
4 | package-lock.json
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - v8
4 | - v9
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Artur Eshenbrener
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # babel-plugin-mobx-async-action
2 |
3 | [](https://www.npmjs.com/babel-plugin-mobx-async-action/)
4 |
5 | [](https://travis-ci.com/Strate/babel-plugin-mobx-async-action)
6 |
7 | Converts all async actions to mobx's 4 `flow` utility call.
8 |
9 | * [Use other package](#toc-mobx-package)
10 | * [Use with Typescript](#toc-use-with-typescript)
11 |
12 |
13 | ## Example
14 |
15 | **In**
16 |
17 | ```js
18 | import { action } from "mobx";
19 |
20 | action(async function doSome() {
21 | const response = await fetch("/api/list")
22 | this.items = await response.json();
23 | });
24 | ```
25 |
26 | **Out**
27 |
28 | ```js
29 | "use strict";
30 |
31 | import { action } from "mobx";
32 | import { flow as _flow } from "mobx";
33 |
34 | action((() => {
35 | var _ref = _flow(function* () {
36 | const response = yield fetch("/api/list");
37 | this.items = yield response.json();
38 | });
39 |
40 | function doSome() {
41 | return _ref.apply(this, arguments);
42 | }
43 |
44 | return doSome;
45 | })());
46 | ```
47 |
48 | ## Motivation
49 |
50 | Motivation to use flow() well described in official mobx documentation: https://mobx.js.org/best/actions.html#flows
51 | However, it is much useful to write pure async/await actions, especially if original code written in typescript: generator
52 | functions can not be covered by types, especially results of `yield` calls. So, let write actions as before, but let
53 | babel and this plugin do all the rest.
54 |
55 | ## Caveats
56 |
57 | Plugin support only ES6 imports. Only this imports are supported:
58 | ```
59 | import {action} from "mobx";
60 | ```
61 | ```
62 | import {action as actionAlias} from "mobx";
63 | ```
64 | ```
65 | import * as mobx from "mobx";
66 | ```
67 | ```
68 | import * as mobxAlias from "mobx";
69 | ```
70 | ```
71 | import * as mobx from "my-mobx-alias"
72 | ```
73 | For example, this cases are **not supported**:
74 | ```
75 | const mobx = require("mobx")
76 | ```
77 | ```
78 | const {action} = require("mobx")
79 | ```
80 | ```
81 | import * as mobx from "mobx";
82 | const {action} = mobx;
83 | action(function() {});
84 | ```
85 |
86 |
87 | ## Installation
88 |
89 | ```sh
90 | $ npm install babel-plugin-mobx-async-action
91 | ```
92 |
93 | ## Usage
94 |
95 | ### Via `.babelrc` (Recommended)
96 |
97 | **.babelrc**
98 |
99 | ```json
100 | {
101 | "plugins": ["mobx-async-action"]
102 | }
103 | ```
104 |
105 | ### Via CLI
106 |
107 | ```sh
108 | $ babel --plugins mobx-async-action script.js
109 | ```
110 |
111 | ### Via Node API
112 |
113 | ```javascript
114 | require("babel-core").transform("code", {
115 | plugins: ["mobx-async-action"]
116 | });
117 | ```
118 |
119 |
120 | ## Use other package.
121 |
122 | If you use wrapper for "mobx" package, you can pass it's name to plugin:
123 |
124 | #### .babelrc
125 |
126 | ```json5
127 | {
128 | "plugins": [
129 | ["mobx-async-action", {
130 | "mobx-package": "mobx-custom"
131 | }]
132 | ]
133 | }
134 | ```
135 |
136 | ## Use with typescript.
137 |
138 | This plugin could handle decorators code, emitted from typescript, such as:
139 |
140 | ```js
141 | import * as tslib_1 from "tslib";
142 | import { action } from "mobx";
143 | export default class Class2 {
144 | async method() {
145 | await 123
146 | await 321
147 | }
148 | }
149 | tslib_1.__decorate([
150 | action
151 | ], Class2.prototype, "method", null);
152 | ```
153 |
154 | To get this code worked, you should enable [importHelpers](https://www.typescriptlang.org/docs/handbook/compiler-options.html)
155 | compiler option, and get [tslib](https://www.npmjs.com/package/tslib) package installed. Also, typescript
156 | should emit es6 modules, so, you should target your compiler to es2015+. That's all,
157 | plugin detect import from "tslib" and handle typescript decorators.
158 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "babel-plugin-mobx-async-action",
3 | "version": "0.0.6",
4 | "description": "",
5 | "license": "MIT",
6 | "repository": "Strate/babel-plugin-mobx-async-action",
7 | "author": "Strate ",
8 | "main": "lib/index.js",
9 | "dependencies": {
10 | "babel-helper-remap-async-to-generator": "^6"
11 | },
12 | "devDependencies": {
13 | "babel-cli": "^6.4.5",
14 | "babel-plugin-transform-decorators-legacy": "^1.3.4",
15 | "babel-preset-es2015": "^6.3.13",
16 | "babel-preset-stage-0": "^6.3.13",
17 | "mocha": "^2.2.5"
18 | },
19 | "scripts": {
20 | "clean": "rm -rf lib",
21 | "build": "babel src -d lib",
22 | "test": "mocha --compilers js:babel-register",
23 | "test:watch": "npm run test -- --watch",
24 | "prepublish": "npm run clean && npm run build"
25 | },
26 | "keywords": [
27 | "mobx",
28 | "utils",
29 | "babel-plugin"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import remapAsyncToGenerator from "babel-helper-remap-async-to-generator";
2 |
3 | export default function (babel) {
4 | const {types: t} = babel;
5 |
6 | /**
7 | * t.isFunctionExpression() || t.isArrowFunctionExpression()
8 | */
9 | function isAnyFunctionExpression() {
10 | return t.isFunctionExpression.apply(t, arguments) ||
11 | t.isArrowFunctionExpression.apply(t, arguments) ||
12 | t.isClassMethod.apply(t, arguments)
13 | ;
14 | }
15 |
16 | function isAction(node, actionIdentifier, mobxNamespaceIdentifier) {
17 | return (actionIdentifier && t.isIdentifier(node, {name: actionIdentifier})) ||
18 | (
19 | t.isMemberExpression(node) &&
20 | t.isIdentifier(node.object, {name: 'action'}) &&
21 | t.isIdentifier(node.property, {name: "bound"})
22 | ) ||
23 | (
24 | mobxNamespaceIdentifier &&
25 | t.isMemberExpression(node) &&
26 | t.isIdentifier(node.object, {name: mobxNamespaceIdentifier}) &&
27 | t.isIdentifier(node.property, {name: "action"})
28 | )
29 | }
30 |
31 | function convertToFlow(path, state) {
32 | if (
33 | isAnyFunctionExpression(path.node) &&
34 | path.node.async &&
35 | t.isBlockStatement(path.get('body').node)
36 | ) {
37 | remapAsyncToGenerator(path, state.file, {
38 | wrapAsync: state.addImport(state.mobxPackage, "flow")
39 | });
40 | }
41 | }
42 |
43 | const traverseSibling = {
44 | CallExpression(path, state) {
45 | const node = path.node;
46 | const actionIdentifier = this.actionIdentifier;
47 | const mobxNamespaceIdentifier = this.mobxNamespaceIdentifier;
48 | const mobxPackage = this.mobxPackage;
49 | if (isAction(node.callee, actionIdentifier, mobxNamespaceIdentifier)) {
50 | if (node.arguments.length === 1) {
51 | convertToFlow(path.get('arguments.0'), state)
52 | path.skip();
53 | } else if (node.arguments.length === 2) {
54 | convertToFlow(path.get('arguments.1'), state)
55 | path.skip();
56 | }
57 | }
58 | },
59 |
60 | ["ClassMethod|ClassProperty"](path, state) {
61 | const actionIdentifier = this.actionIdentifier;
62 | const mobxNamespaceIdentifier = this.mobxNamespaceIdentifier;
63 | const mobxPackage = this.mobxPackage;
64 | const explicitClasses = this.classes;
65 | const classDeclaration = path.findParent(p => p.isClassDeclaration() || p.isClassExpression())
66 | // If there is an explicit classes with actions, handle them separately
67 | if (
68 | explicitClasses &&
69 | t.isIdentifier(classDeclaration.node.id) &&
70 | void 0 !== explicitClasses[classDeclaration.node.id.name] &&
71 | t.isClassMethod(path.node) &&
72 | t.isIdentifier(path.node.key) &&
73 | (
74 | // all code inside constructor should be handled as action too, because it could contain other action creations
75 | path.node.key.name === "constructor" ||
76 | void 0 !== explicitClasses[classDeclaration.node.id.name][path.node.key.name]
77 | )
78 | ) {
79 | if (path.node.key.name === "constructor") {
80 | path.get('body').get('body').forEach(cPath => {
81 | if (cPath.isExpressionStatement()) {
82 | const exprPath = cPath.get('expression')
83 | if (exprPath.isAssignmentExpression() && exprPath.get('operator').node === '=') {
84 | const leftPath = exprPath.get('left')
85 | const rightPath = exprPath.get('right')
86 | if (
87 | leftPath.isMemberExpression() &&
88 | leftPath.get('object').isThisExpression() &&
89 | leftPath.get('property').isIdentifier() &&
90 | leftPath.get('property').node.name in explicitClasses[classDeclaration.node.id.name] &&
91 | (rightPath.isArrowFunctionExpression() || rightPath.isFunctionExpression())
92 | ) {
93 | convertToFlow(rightPath, state)
94 | }
95 | }
96 | }
97 | })
98 | } else {
99 | convertToFlow(path, state)
100 | }
101 | path.skip();
102 | } else if (path.node.decorators) {
103 | for (const {expression} of path.node.decorators) {
104 | if (
105 | isAction(expression, actionIdentifier, mobxNamespaceIdentifier) ||
106 | (t.isCallExpression(expression) && isAction(expression.callee, actionIdentifier, mobxNamespaceIdentifier))
107 | ) {
108 | if (t.isClassMethod(path.node)) {
109 | convertToFlow(path, state)
110 | path.skip();
111 | } else if (t.isClassProperty(path.node)) {
112 | convertToFlow(path.get('value'), state)
113 | path.skip();
114 | }
115 | }
116 | }
117 | }
118 | },
119 | };
120 |
121 | return {
122 | name: "mobx-async-action-transform",
123 | visitor: {
124 | Program(path, state) {
125 | let actionIdentifier;
126 | let mobxNamespaceIdentifier;
127 | let tslibNamespaceIdentifier;
128 | const mobxPackage = state.opts && state.opts["mobx-package"] || "mobx"
129 | path.traverse({
130 | ImportDeclaration(path) {
131 | if (path.node.source.value === mobxPackage) {
132 | for (const specifier of path.node.specifiers) {
133 | if (t.isImportNamespaceSpecifier(specifier) || (specifier.imported.name === "action")) {
134 | if (t.isImportNamespaceSpecifier(specifier)) {
135 | mobxNamespaceIdentifier = specifier.local.name;
136 | } else if (specifier.imported.name === "action") {
137 | actionIdentifier = specifier.local.name;
138 | }
139 | }
140 | }
141 | }
142 | if (path.node.source.value === "tslib") {
143 | for (const specifier of path.node.specifiers) {
144 | if (t.isImportNamespaceSpecifier(specifier)) {
145 | tslibNamespaceIdentifier = specifier.local.name
146 | }
147 | }
148 | }
149 | }
150 | })
151 | const context = {...state, actionIdentifier, mobxNamespaceIdentifier, mobxPackage, addImport: state.addImport}
152 | path.traverse(traverseSibling, context)
153 | const toTraverse = [];
154 | /**
155 | * Lookup for typescript decorators, and handle them separately
156 | */
157 | path.traverse({
158 | CallExpression(path) {
159 | const node = path.node
160 | if (
161 | t.isMemberExpression(node.callee) &&
162 | t.isIdentifier(node.callee.object, {name: tslibNamespaceIdentifier}) &&
163 | t.isIdentifier(node.callee.property, {name: "__decorate"}) &&
164 | node.arguments.length === 4 &&
165 | t.isArrayExpression(node.arguments[0]) &&
166 | (
167 | node.arguments[0].elements.some(e =>
168 | (
169 | t.isIdentifier(e, {name: actionIdentifier})
170 | ) ||
171 | (
172 | t.isMemberExpression(e) &&
173 | t.isIdentifier(e.object, {name: mobxNamespaceIdentifier}) &&
174 | t.isIdentifier(e.property, {name: "action"})
175 | ) || (
176 | t.isCallExpression(e) &&
177 | t.isIdentifier(e.callee, {name: actionIdentifier})
178 | ) || (
179 | t.isCallExpression(e) &&
180 | t.isMemberExpression(e.callee) &&
181 | t.isIdentifier(e.callee.object, {name: mobxNamespaceIdentifier}) &&
182 | t.isIdentifier(e.callee.property, {name: "action"})
183 | )
184 | )
185 | ) &&
186 | t.isMemberExpression(node.arguments[1]) &&
187 | t.isIdentifier(node.arguments[1].property, {name: "prototype"}) &&
188 | t.isStringLiteral(node.arguments[2])
189 | ) {
190 | const className = node.arguments[1].object.name
191 | const methodName = node.arguments[2].value
192 | const traversePath = path.getStatementParent().parentPath
193 | const existsTraverseRequest = toTraverse.find(e => e.path === traversePath)
194 | if (!existsTraverseRequest) {
195 | toTraverse.push({
196 | path: traversePath,
197 | classes: {
198 | [className]: {[methodName]: methodName}
199 | }
200 | })
201 | } else {
202 | const existsClassRequest = existsTraverseRequest.classes[className]
203 | if (!existsClassRequest) {
204 | existsTraverseRequest.classes[className] = {[methodName]: methodName}
205 | } else {
206 | existsTraverseRequest.classes[className][methodName] = methodName
207 | }
208 | }
209 | }
210 | }
211 | })
212 | toTraverse.forEach(({path, classes}) => path.traverse(traverseSibling, {...context, classes}))
213 | },
214 | }
215 | };
216 | }
217 |
--------------------------------------------------------------------------------
/test/fixtures/handle-async-await-generator/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOpts":{
3 | "plugins":["decorators", "classProperties"]
4 | },
5 | "plugins": [
6 | "../../../src"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixtures/handle-async-await-generator/actual.js:
--------------------------------------------------------------------------------
1 | import {action} from "mobx";
2 |
3 | function a1() {
4 | }
5 |
6 | action(function* doSome() {
7 | yield 1;
8 | yield 2;
9 | });
10 |
11 | action(async function doSomeSpecial() {
12 | await 1;
13 | await 2;
14 | })
15 |
16 | action(async () => {
17 | await 1;
18 | await 2;
19 | });
20 |
21 | action(async () => {
22 | const a = [
23 | await 1,
24 | await 2,
25 | ]
26 | });
27 |
28 | class SomeClass {
29 | @action
30 | generatorMethod = function* () {
31 | yield 1;
32 | yield 2;
33 | }
34 | @action("named")
35 | generatorMethod2 = function* () {
36 | yield 1;
37 | yield 2;
38 | }
39 |
40 | @action
41 | async method() {
42 | await 1;
43 | await 2;
44 | }
45 |
46 | @action("named")
47 | async method1() {
48 | await 1;
49 | await 2;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/test/fixtures/handle-async-await-generator/expected.js:
--------------------------------------------------------------------------------
1 | import { flow as _flow } from "mobx";
2 | import { action } from "mobx";
3 |
4 | function a1() {}
5 |
6 | action(function* doSome() {
7 | yield 1;
8 | yield 2;
9 | });
10 |
11 | action((() => {
12 | var _ref = _flow(function* () {
13 | yield 1;
14 | yield 2;
15 | });
16 |
17 | function doSomeSpecial() {
18 | return _ref.apply(this, arguments);
19 | }
20 |
21 | return doSomeSpecial;
22 | })());
23 |
24 | action(_flow(function* () {
25 | yield 1;
26 | yield 2;
27 | }));
28 |
29 | action(_flow(function* () {
30 | const a = [yield 1, yield 2];
31 | }));
32 |
33 | class SomeClass {
34 | @action
35 | generatorMethod = function* () {
36 | yield 1;
37 | yield 2;
38 | };
39 |
40 | @action("named")
41 | generatorMethod2 = function* () {
42 | yield 1;
43 | yield 2;
44 | };
45 |
46 | @action
47 | method() {
48 | return _flow(function* () {
49 | yield 1;
50 | yield 2;
51 | })();
52 | }
53 |
54 | @action("named")
55 | method1() {
56 | return _flow(function* () {
57 | yield 1;
58 | yield 2;
59 | })();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/test/fixtures/handle-base-case/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOpts":{
3 | "plugins":["decorators", "classProperties"]
4 | },
5 | "plugins": [
6 | "../../../src"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixtures/handle-base-case/actual.js:
--------------------------------------------------------------------------------
1 | import {action} from "mobx";
2 |
3 | function a1() {
4 | }
5 |
6 | action(async function doSome() {
7 | const response = fetch("/api/list")
8 | this.items = await response.json();
9 | });
10 |
11 | action(async function doSome() {
12 | await 123
13 | });
14 |
15 | action.bound(async function doSome() {
16 | await 123
17 | });
18 |
19 | action("named", async function doSome() {
20 | await 123
21 | });
22 |
23 | action.bound("named", async function doSome() {
24 | await 123
25 | });
26 |
27 | action("named", async function doSome() {
28 | await 123
29 | });
30 |
31 | class SomeAsyncClass {
32 | @action("named")
33 | m3 = async function () {
34 | await 123
35 | await 321
36 | };
37 | m4 = action(async function () {
38 | await 123
39 | await 321
40 | });
41 | @action
42 | m5 = async () => {
43 | };
44 | m6 = action(async () => {
45 | await 123
46 | await 321
47 | });
48 | @action
49 | m7 = blabla;
50 |
51 | @action
52 | async m1() {
53 | await 123
54 | await 321
55 | }
56 |
57 | @action.bound
58 | async m1() {
59 | await 123
60 | await 321
61 | }
62 |
63 | @action("name")
64 | async m2() {
65 | await 123
66 | await 321
67 | }
68 | }
69 |
70 | class SomeSyncClass {
71 | @action("named")
72 | m3 = function () {
73 | 123;
74 | this;
75 | };
76 | m4 = action(function () {
77 | 123;
78 | this;
79 | });
80 | @action
81 | m5 = () => {
82 | };
83 | m6 = action(() => {
84 | 123;
85 | this;
86 | });
87 | @action
88 | m7 = blabla;
89 |
90 | @action
91 | m1() {
92 | 123;
93 | this;
94 | }
95 |
96 | @action.bound
97 | m1() {
98 | 123;
99 | this;
100 | }
101 |
102 | @action("name")
103 | m2() {
104 | 123;
105 | this;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/test/fixtures/handle-base-case/expected.js:
--------------------------------------------------------------------------------
1 | import { flow as _flow } from "mobx";
2 | import { action } from "mobx";
3 |
4 | function a1() {}
5 |
6 | action((() => {
7 | var _ref = _flow(function* () {
8 | const response = fetch("/api/list");
9 | this.items = yield response.json();
10 | });
11 |
12 | function doSome() {
13 | return _ref.apply(this, arguments);
14 | }
15 |
16 | return doSome;
17 | })());
18 |
19 | action((() => {
20 | var _ref2 = _flow(function* () {
21 | yield 123;
22 | });
23 |
24 | function doSome() {
25 | return _ref2.apply(this, arguments);
26 | }
27 |
28 | return doSome;
29 | })());
30 |
31 | action.bound((() => {
32 | var _ref3 = _flow(function* () {
33 | yield 123;
34 | });
35 |
36 | function doSome() {
37 | return _ref3.apply(this, arguments);
38 | }
39 |
40 | return doSome;
41 | })());
42 |
43 | action("named", (() => {
44 | var _ref4 = _flow(function* () {
45 | yield 123;
46 | });
47 |
48 | function doSome() {
49 | return _ref4.apply(this, arguments);
50 | }
51 |
52 | return doSome;
53 | })());
54 |
55 | action.bound("named", (() => {
56 | var _ref5 = _flow(function* () {
57 | yield 123;
58 | });
59 |
60 | function doSome() {
61 | return _ref5.apply(this, arguments);
62 | }
63 |
64 | return doSome;
65 | })());
66 |
67 | action("named", (() => {
68 | var _ref6 = _flow(function* () {
69 | yield 123;
70 | });
71 |
72 | function doSome() {
73 | return _ref6.apply(this, arguments);
74 | }
75 |
76 | return doSome;
77 | })());
78 |
79 | class SomeAsyncClass {
80 | @action("named")
81 | m3 = _flow(function* () {
82 | yield 123;
83 | yield 321;
84 | });
85 | m4 = action(_flow(function* () {
86 | yield 123;
87 | yield 321;
88 | }));
89 |
90 | @action
91 | m5 = _flow(function* () {});
92 | m6 = action(_flow(function* () {
93 | yield 123;
94 | yield 321;
95 | }));
96 |
97 | @action
98 | m7 = blabla;
99 |
100 | @action
101 | m1() {
102 | return _flow(function* () {
103 | yield 123;
104 | yield 321;
105 | })();
106 | }
107 |
108 | @action.bound
109 | m1() {
110 | return _flow(function* () {
111 | yield 123;
112 | yield 321;
113 | })();
114 | }
115 |
116 | @action("name")
117 | m2() {
118 | return _flow(function* () {
119 | yield 123;
120 | yield 321;
121 | })();
122 | }
123 | }
124 |
125 | class SomeSyncClass {
126 | @action("named")
127 | m3 = function () {
128 | 123;
129 | this;
130 | };
131 | m4 = action(function () {
132 | 123;
133 | this;
134 | });
135 |
136 | @action
137 | m5 = () => {};
138 | m6 = action(() => {
139 | 123;
140 | this;
141 | });
142 |
143 | @action
144 | m7 = blabla;
145 |
146 | @action
147 | m1() {
148 | 123;
149 | this;
150 | }
151 |
152 | @action.bound
153 | m1() {
154 | 123;
155 | this;
156 | }
157 |
158 | @action("name")
159 | m2() {
160 | 123;
161 | this;
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/test/fixtures/handle-custom-import/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOpts":{
3 | "plugins":["decorators", "classProperties"]
4 | },
5 | "plugins": [
6 | "../../../src"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixtures/handle-custom-import/actual.js:
--------------------------------------------------------------------------------
1 | import {action as otherName} from "mobx";
2 |
3 | otherName(async function () {
4 | await 123
5 | await 321
6 | });
7 |
--------------------------------------------------------------------------------
/test/fixtures/handle-custom-import/expected.js:
--------------------------------------------------------------------------------
1 | import { flow as _flow } from "mobx";
2 | import { action as otherName } from "mobx";
3 |
4 | otherName(_flow(function* () {
5 | yield 123;
6 | yield 321;
7 | }));
8 |
--------------------------------------------------------------------------------
/test/fixtures/handle-custom-package/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOpts":{
3 | "plugins":["decorators", "classProperties"]
4 | },
5 | "plugins": [
6 | ["../../../src", {
7 | "mobx-package": "mobx-custom"
8 | }]
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/test/fixtures/handle-custom-package/actual.js:
--------------------------------------------------------------------------------
1 | import {action as otherName} from "mobx-custom";
2 |
3 | otherName(async function () {
4 | await 123
5 | await 321
6 | });
7 |
--------------------------------------------------------------------------------
/test/fixtures/handle-custom-package/expected.js:
--------------------------------------------------------------------------------
1 | import { flow as _flow } from "mobx-custom";
2 | import { action as otherName } from "mobx-custom";
3 |
4 | otherName(_flow(function* () {
5 | yield 123;
6 | yield 321;
7 | }));
8 |
--------------------------------------------------------------------------------
/test/fixtures/handle-mobx-imported-as-namespace-but-action-used-separately/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOpts":{
3 | "plugins":["decorators", "classProperties"]
4 | },
5 | "plugins": [
6 | "../../../src"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixtures/handle-mobx-imported-as-namespace-but-action-used-separately/actual.js:
--------------------------------------------------------------------------------
1 | import * as mobx from "mobx";
2 | import {action} from "mobx";
3 |
4 | action(async function () {
5 | await 123
6 | });
7 |
8 | mobx.action(async function () {
9 | await 123
10 | });
11 |
--------------------------------------------------------------------------------
/test/fixtures/handle-mobx-imported-as-namespace-but-action-used-separately/expected.js:
--------------------------------------------------------------------------------
1 | import { flow as _flow } from "mobx";
2 | import * as mobx from "mobx";
3 | import { action } from "mobx";
4 |
5 | action(_flow(function* () {
6 | yield 123;
7 | }));
8 |
9 | mobx.action(_flow(function* () {
10 | yield 123;
11 | }));
12 |
--------------------------------------------------------------------------------
/test/fixtures/handle-mobx-imported-as-namespace/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOpts":{
3 | "plugins":["decorators", "classProperties"]
4 | },
5 | "plugins": [
6 | "../../../src"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixtures/handle-mobx-imported-as-namespace/actual.js:
--------------------------------------------------------------------------------
1 | import * as mobxNamespace from "mobx";
2 |
3 | function a1() {
4 | }
5 |
6 | mobxNamespace.action(async function doSome() {
7 | await 123
8 | });
9 |
10 | mobxNamespace.action.bound(async function doSome() {
11 | await 123
12 | });
13 |
14 | mobxNamespace.action("named", async function doSome() {
15 | await 123
16 | });
17 |
18 | mobxNamespace.action.bound("named", async function doSome() {
19 | await 123
20 | });
21 |
22 | mobxNamespace.action("named", async function doSome() {
23 | await 123
24 | });
25 |
26 | class SomeAsyncClass {
27 | @mobxNamespace.action("named")
28 | m3 = async function () {
29 | await 123
30 | await 321
31 | };
32 | m4 = mobxNamespace.action(async function () {
33 | await 123
34 | await 321
35 | });
36 | @mobxNamespace.action
37 | m5 = async () => {
38 | };
39 | m6 = mobxNamespace.action(async () => {
40 | await 123
41 | await 321
42 | });
43 | @mobxNamespace.action
44 | m7 = blabla;
45 |
46 | @mobxNamespace.action
47 | async m1() {
48 | await 123
49 | await 321
50 | }
51 |
52 | @mobxNamespace.action.bound
53 | async m1() {
54 | await 123
55 | await 321
56 | }
57 |
58 | @mobxNamespace.action("name")
59 | async m2() {
60 | await 123
61 | await 321
62 | }
63 | }
64 |
65 | class SomeSyncClass {
66 | @mobxNamespace.action("named")
67 | m3 = function () {
68 | 123;
69 | this;
70 | };
71 | m4 = mobxNamespace.action(function () {
72 | 123;
73 | this;
74 | });
75 | @mobxNamespace.action
76 | m5 = () => {
77 | };
78 | m6 = mobxNamespace.action(() => {
79 | 123;
80 | this;
81 | });
82 | @mobxNamespace.action
83 | m7 = blabla;
84 |
85 | @mobxNamespace.action
86 | m1() {
87 | 123;
88 | this;
89 | }
90 |
91 | @mobxNamespace.action.bound
92 | m1() {
93 | 123;
94 | this;
95 | }
96 |
97 | @mobxNamespace.action("name")
98 | m2() {
99 | 123;
100 | this;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/test/fixtures/handle-mobx-imported-as-namespace/expected.js:
--------------------------------------------------------------------------------
1 | import { flow as _flow } from "mobx";
2 | import * as mobxNamespace from "mobx";
3 |
4 | function a1() {}
5 |
6 | mobxNamespace.action((() => {
7 | var _ref = _flow(function* () {
8 | yield 123;
9 | });
10 |
11 | function doSome() {
12 | return _ref.apply(this, arguments);
13 | }
14 |
15 | return doSome;
16 | })());
17 |
18 | mobxNamespace.action.bound(async function doSome() {
19 | await 123;
20 | });
21 |
22 | mobxNamespace.action("named", (() => {
23 | var _ref2 = _flow(function* () {
24 | yield 123;
25 | });
26 |
27 | function doSome() {
28 | return _ref2.apply(this, arguments);
29 | }
30 |
31 | return doSome;
32 | })());
33 |
34 | mobxNamespace.action.bound("named", async function doSome() {
35 | await 123;
36 | });
37 |
38 | mobxNamespace.action("named", (() => {
39 | var _ref3 = _flow(function* () {
40 | yield 123;
41 | });
42 |
43 | function doSome() {
44 | return _ref3.apply(this, arguments);
45 | }
46 |
47 | return doSome;
48 | })());
49 |
50 | class SomeAsyncClass {
51 | @mobxNamespace.action("named")
52 | m3 = _flow(function* () {
53 | yield 123;
54 | yield 321;
55 | });
56 | m4 = mobxNamespace.action(_flow(function* () {
57 | yield 123;
58 | yield 321;
59 | }));
60 |
61 | @mobxNamespace.action
62 | m5 = _flow(function* () {});
63 | m6 = mobxNamespace.action(_flow(function* () {
64 | yield 123;
65 | yield 321;
66 | }));
67 |
68 | @mobxNamespace.action
69 | m7 = blabla;
70 |
71 | @mobxNamespace.action
72 | m1() {
73 | return _flow(function* () {
74 | yield 123;
75 | yield 321;
76 | })();
77 | }
78 |
79 | @mobxNamespace.action.bound
80 | async m1() {
81 | await 123;
82 | await 321;
83 | }
84 |
85 | @mobxNamespace.action("name")
86 | m2() {
87 | return _flow(function* () {
88 | yield 123;
89 | yield 321;
90 | })();
91 | }
92 | }
93 |
94 | class SomeSyncClass {
95 | @mobxNamespace.action("named")
96 | m3 = function () {
97 | 123;
98 | this;
99 | };
100 | m4 = mobxNamespace.action(function () {
101 | 123;
102 | this;
103 | });
104 |
105 | @mobxNamespace.action
106 | m5 = () => {};
107 | m6 = mobxNamespace.action(() => {
108 | 123;
109 | this;
110 | });
111 |
112 | @mobxNamespace.action
113 | m7 = blabla;
114 |
115 | @mobxNamespace.action
116 | m1() {
117 | 123;
118 | this;
119 | }
120 |
121 | @mobxNamespace.action.bound
122 | m1() {
123 | 123;
124 | this;
125 | }
126 |
127 | @mobxNamespace.action("name")
128 | m2() {
129 | 123;
130 | this;
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/test/fixtures/handle-typescript-and-class-expression/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOpts":{
3 | "plugins":["decorators", "classProperties"]
4 | },
5 | "plugins": [
6 | "../../../src"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixtures/handle-typescript-and-class-expression/actual.js:
--------------------------------------------------------------------------------
1 | import * as tslib_1 from "tslib";
2 | import {action} from "mobx";
3 | import * as mobx from "mobx";
4 |
5 | let Class1 = class Class1 {
6 | constructor() {
7 | this.method1 = async () => {
8 | await 123
9 | await 321
10 | };
11 | this.method2 = async () => {
12 | await 123
13 | await 321
14 | }
15 | }
16 |
17 | async method() {
18 | await 123
19 | await 321
20 | }
21 |
22 | method2() {
23 | let Class2 = class Class2 {
24 | async method() {
25 | await 123
26 | await 321
27 | }
28 | }
29 |
30 | tslib_1.__decorate([
31 | action
32 | ], Class2.prototype, "method", null);
33 | return Class2;
34 | }
35 |
36 | @action
37 | async method3() {
38 | await 1
39 | let Class2 = class Class2 {
40 | async method() {
41 | await 123
42 | await 321
43 | }
44 | }
45 |
46 | tslib_1.__decorate([
47 | action
48 | ], Class2.prototype, "method", null);
49 | return Class2;
50 | }
51 | }
52 |
53 | tslib_1.__decorate([
54 | mobx.action
55 | ], Class1.prototype, "method", null);
56 | tslib_1.__decorate([
57 | action
58 | ], Class1.prototype, "method1", void 0);
59 | export default class Class2 {
60 | async method() {
61 | await 123
62 | await 321
63 | }
64 | }
65 | tslib_1.__decorate([
66 | action
67 | ], Class2.prototype, "method", null);
68 |
--------------------------------------------------------------------------------
/test/fixtures/handle-typescript-and-class-expression/expected.js:
--------------------------------------------------------------------------------
1 | import { flow as _flow } from "mobx";
2 | import * as tslib_1 from "tslib";
3 | import { action } from "mobx";
4 | import * as mobx from "mobx";
5 |
6 | let Class1 = class Class1 {
7 | constructor() {
8 | this.method1 = _flow(function* () {
9 | yield 123;
10 | yield 321;
11 | });
12 | this.method2 = async () => {
13 | await 123;
14 | await 321;
15 | };
16 | }
17 |
18 | method() {
19 | return _flow(function* () {
20 | yield 123;
21 | yield 321;
22 | })();
23 | }
24 |
25 | method2() {
26 | let Class2 = class Class2 {
27 | method() {
28 | return _flow(function* () {
29 | yield 123;
30 | yield 321;
31 | })();
32 | }
33 | };
34 |
35 | tslib_1.__decorate([action], Class2.prototype, "method", null);
36 | return Class2;
37 | }
38 |
39 | @action
40 | method3() {
41 | return _flow(function* () {
42 | yield 1;
43 | let Class2 = class Class2 {
44 | method() {
45 | return _flow(function* () {
46 | yield 123;
47 | yield 321;
48 | })();
49 | }
50 | };
51 |
52 | tslib_1.__decorate([action], Class2.prototype, "method", null);
53 | return Class2;
54 | })();
55 | }
56 | };
57 |
58 | tslib_1.__decorate([mobx.action], Class1.prototype, "method", null);
59 | tslib_1.__decorate([action], Class1.prototype, "method1", void 0);
60 | export default class Class2 {
61 | method() {
62 | return _flow(function* () {
63 | yield 123;
64 | yield 321;
65 | })();
66 | }
67 | }
68 | tslib_1.__decorate([action], Class2.prototype, "method", null);
69 |
--------------------------------------------------------------------------------
/test/fixtures/handle-when-function-has-extra-wrapper/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOpts":{
3 | "plugins":["decorators", "classProperties"]
4 | },
5 | "plugins": [
6 | "../../../src"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixtures/handle-when-function-has-extra-wrapper/actual.js:
--------------------------------------------------------------------------------
1 | import {action} from "mobx";
2 |
3 | action(other(deep(wrapper(async function () {
4 | await 123
5 | }))))
6 |
--------------------------------------------------------------------------------
/test/fixtures/handle-when-function-has-extra-wrapper/expected.js:
--------------------------------------------------------------------------------
1 | import { action } from "mobx";
2 |
3 | action(other(deep(wrapper(async function () {
4 | await 123;
5 | }))));
6 |
--------------------------------------------------------------------------------
/test/fixtures/transform-typescript-decorated-methods/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOpts":{
3 | "plugins":["decorators", "classProperties"]
4 | },
5 | "plugins": [
6 | "../../../src"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixtures/transform-typescript-decorated-methods/actual.js:
--------------------------------------------------------------------------------
1 | import * as tslib_1 from "tslib";
2 | import {action} from "mobx";
3 | import * as mobx from "mobx";
4 |
5 | class Class1 {
6 | constructor() {
7 | this.method1 = async () => {
8 | await 123
9 | await 321
10 | };
11 | this.method2 = async () => {
12 | await 123
13 | await 321
14 | }
15 | }
16 |
17 | async method() {
18 | await 123
19 | await 321
20 | }
21 |
22 | method2() {
23 | class Class2 {
24 | async method() {
25 | await 123
26 | await 321
27 | }
28 | }
29 |
30 | tslib_1.__decorate([
31 | action
32 | ], Class2.prototype, "method", null);
33 | return Class2;
34 | }
35 |
36 | @action
37 | async method3() {
38 | await 1
39 | class Class2 {
40 | async method() {
41 | await 123
42 | await 321
43 | }
44 | }
45 |
46 | tslib_1.__decorate([
47 | action
48 | ], Class2.prototype, "method", null);
49 | return Class2;
50 | }
51 | }
52 |
53 | tslib_1.__decorate([
54 | mobx.action
55 | ], Class1.prototype, "method", null);
56 | tslib_1.__decorate([
57 | action
58 | ], Class1.prototype, "method1", void 0);
59 | export default class Class2 {
60 | async method() {
61 | await 123
62 | await 321
63 | }
64 | }
65 | tslib_1.__decorate([
66 | action
67 | ], Class2.prototype, "method", null);
68 |
--------------------------------------------------------------------------------
/test/fixtures/transform-typescript-decorated-methods/expected.js:
--------------------------------------------------------------------------------
1 | import { flow as _flow } from "mobx";
2 | import * as tslib_1 from "tslib";
3 | import { action } from "mobx";
4 | import * as mobx from "mobx";
5 |
6 | class Class1 {
7 | constructor() {
8 | this.method1 = _flow(function* () {
9 | yield 123;
10 | yield 321;
11 | });
12 | this.method2 = async () => {
13 | await 123;
14 | await 321;
15 | };
16 | }
17 |
18 | method() {
19 | return _flow(function* () {
20 | yield 123;
21 | yield 321;
22 | })();
23 | }
24 |
25 | method2() {
26 | class Class2 {
27 | method() {
28 | return _flow(function* () {
29 | yield 123;
30 | yield 321;
31 | })();
32 | }
33 | }
34 |
35 | tslib_1.__decorate([action], Class2.prototype, "method", null);
36 | return Class2;
37 | }
38 |
39 | @action
40 | method3() {
41 | return _flow(function* () {
42 | yield 1;
43 | class Class2 {
44 | method() {
45 | return _flow(function* () {
46 | yield 123;
47 | yield 321;
48 | })();
49 | }
50 | }
51 |
52 | tslib_1.__decorate([action], Class2.prototype, "method", null);
53 | return Class2;
54 | })();
55 | }
56 | }
57 |
58 | tslib_1.__decorate([mobx.action], Class1.prototype, "method", null);
59 | tslib_1.__decorate([action], Class1.prototype, "method1", void 0);
60 | export default class Class2 {
61 | method() {
62 | return _flow(function* () {
63 | yield 123;
64 | yield 321;
65 | })();
66 | }
67 | }
68 | tslib_1.__decorate([action], Class2.prototype, "method", null);
69 |
--------------------------------------------------------------------------------
/test/fixtures/transform-typescript-decorated-with-metadata/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOpts":{
3 | "plugins":["decorators", "classProperties"]
4 | },
5 | "plugins": [
6 | "../../../src"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixtures/transform-typescript-decorated-with-metadata/actual.js:
--------------------------------------------------------------------------------
1 | import * as tslib_1 from "tslib";
2 | import {action} from "mobx";
3 |
4 | export default class Class2 {
5 | async method() {
6 | await 123
7 | await 321
8 | }
9 | }
10 | tslib_1.__decorate([
11 | action,
12 | tslib_1.__metadata("design:type", Function),
13 | tslib_1.__metadata("design:paramtypes", []),
14 | tslib_1.__metadata("design:returntype", Promise)
15 | ], Class2.prototype, "method", null);
16 |
--------------------------------------------------------------------------------
/test/fixtures/transform-typescript-decorated-with-metadata/expected.js:
--------------------------------------------------------------------------------
1 | import { flow as _flow } from "mobx";
2 | import * as tslib_1 from "tslib";
3 | import { action } from "mobx";
4 |
5 | export default class Class2 {
6 | method() {
7 | return _flow(function* () {
8 | yield 123;
9 | yield 321;
10 | })();
11 | }
12 | }
13 | tslib_1.__decorate([action, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", []), tslib_1.__metadata("design:returntype", Promise)], Class2.prototype, "method", null);
14 |
--------------------------------------------------------------------------------
/test/fixtures/work-with-latest-preset-and-typescript/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "../../../src",
4 | "transform-decorators-legacy"
5 | ],
6 | "presets": [
7 | "es2015",
8 | "stage-2"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/test/fixtures/work-with-latest-preset-and-typescript/actual.js:
--------------------------------------------------------------------------------
1 | import * as tslib_1 from "tslib";
2 | import {action} from "mobx";
3 | import * as mobx from "mobx";
4 |
5 | class Class1 {
6 | constructor() {
7 | this.method1 = async () => {
8 | await 123
9 | await 321
10 | };
11 | this.method2 = async () => {
12 | await 123
13 | await 321
14 | }
15 | }
16 |
17 | async method() {
18 | await 123
19 | await 321
20 | }
21 |
22 | method2() {
23 | class Class2 {
24 | async method() {
25 | await 123
26 | await 321
27 | }
28 | }
29 |
30 | tslib_1.__decorate([
31 | action
32 | ], Class2.prototype, "method", null);
33 | return Class2;
34 | }
35 |
36 | @action
37 | async method3() {
38 | class Class2 {
39 | async method() {
40 | await 123
41 | await 321
42 | }
43 | }
44 |
45 | tslib_1.__decorate([
46 | action
47 | ], Class2.prototype, "method", null);
48 | return Class2;
49 | }
50 | }
51 |
52 | tslib_1.__decorate([
53 | mobx.action
54 | ], Class1.prototype, "method", null);
55 | tslib_1.__decorate([
56 | action
57 | ], Class1.prototype, "method1", void 0);
58 | export default class Class2 {
59 | async method() {
60 | await 123
61 | await 321
62 | }
63 | }
64 | tslib_1.__decorate([
65 | action
66 | ], Class2.prototype, "method", null);
67 |
--------------------------------------------------------------------------------
/test/fixtures/work-with-latest-preset-and-typescript/expected.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = undefined;
7 |
8 | var _mobx = require("mobx");
9 |
10 | var mobx = _interopRequireWildcard(_mobx);
11 |
12 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
13 |
14 | var _desc, _value, _class;
15 |
16 | var _tslib = require("tslib");
17 |
18 | var tslib_1 = _interopRequireWildcard(_tslib);
19 |
20 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
21 |
22 | function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
23 |
24 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
25 |
26 | function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
27 | var desc = {};
28 | Object['ke' + 'ys'](descriptor).forEach(function (key) {
29 | desc[key] = descriptor[key];
30 | });
31 | desc.enumerable = !!desc.enumerable;
32 | desc.configurable = !!desc.configurable;
33 |
34 | if ('value' in desc || desc.initializer) {
35 | desc.writable = true;
36 | }
37 |
38 | desc = decorators.slice().reverse().reduce(function (desc, decorator) {
39 | return decorator(target, property, desc) || desc;
40 | }, desc);
41 |
42 | if (context && desc.initializer !== void 0) {
43 | desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
44 | desc.initializer = undefined;
45 | }
46 |
47 | if (desc.initializer === void 0) {
48 | Object['define' + 'Property'](target, property, desc);
49 | desc = null;
50 | }
51 |
52 | return desc;
53 | }
54 |
55 | var Class1 = (_class = function () {
56 | function Class1() {
57 | var _this = this;
58 |
59 | _classCallCheck(this, Class1);
60 |
61 | this.method1 = (0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
62 | return regeneratorRuntime.wrap(function _callee$(_context) {
63 | while (1) {
64 | switch (_context.prev = _context.next) {
65 | case 0:
66 | _context.next = 2;
67 | return 123;
68 |
69 | case 2:
70 | _context.next = 4;
71 | return 321;
72 |
73 | case 4:
74 | case "end":
75 | return _context.stop();
76 | }
77 | }
78 | }, _callee, _this);
79 | }));
80 | this.method2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
81 | return regeneratorRuntime.wrap(function _callee2$(_context2) {
82 | while (1) {
83 | switch (_context2.prev = _context2.next) {
84 | case 0:
85 | _context2.next = 2;
86 | return 123;
87 |
88 | case 2:
89 | _context2.next = 4;
90 | return 321;
91 |
92 | case 4:
93 | case "end":
94 | return _context2.stop();
95 | }
96 | }
97 | }, _callee2, _this);
98 | }));
99 | }
100 |
101 | _createClass(Class1, [{
102 | key: "method",
103 | value: function method() {
104 | var _this2 = this;
105 |
106 | return (0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
107 | return regeneratorRuntime.wrap(function _callee3$(_context3) {
108 | while (1) {
109 | switch (_context3.prev = _context3.next) {
110 | case 0:
111 | _context3.next = 2;
112 | return 123;
113 |
114 | case 2:
115 | _context3.next = 4;
116 | return 321;
117 |
118 | case 4:
119 | case "end":
120 | return _context3.stop();
121 | }
122 | }
123 | }, _callee3, _this2);
124 | }))();
125 | }
126 | }, {
127 | key: "method2",
128 | value: function method2() {
129 | var Class2 = function () {
130 | function Class2() {
131 | _classCallCheck(this, Class2);
132 | }
133 |
134 | _createClass(Class2, [{
135 | key: "method",
136 | value: function method() {
137 | var _this3 = this;
138 |
139 | return (0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
140 | return regeneratorRuntime.wrap(function _callee4$(_context4) {
141 | while (1) {
142 | switch (_context4.prev = _context4.next) {
143 | case 0:
144 | _context4.next = 2;
145 | return 123;
146 |
147 | case 2:
148 | _context4.next = 4;
149 | return 321;
150 |
151 | case 4:
152 | case "end":
153 | return _context4.stop();
154 | }
155 | }
156 | }, _callee4, _this3);
157 | }))();
158 | }
159 | }]);
160 |
161 | return Class2;
162 | }();
163 |
164 | tslib_1.__decorate([_mobx.action], Class2.prototype, "method", null);
165 | return Class2;
166 | }
167 | }, {
168 | key: "method3",
169 | value: function method3() {
170 | var _this5 = this;
171 |
172 | return (0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {
173 | var Class2;
174 | return regeneratorRuntime.wrap(function _callee6$(_context6) {
175 | while (1) {
176 | switch (_context6.prev = _context6.next) {
177 | case 0:
178 | Class2 = function () {
179 | function Class2() {
180 | _classCallCheck(this, Class2);
181 | }
182 |
183 | _createClass(Class2, [{
184 | key: "method",
185 | value: function method() {
186 | var _this4 = this;
187 |
188 | return (0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {
189 | return regeneratorRuntime.wrap(function _callee5$(_context5) {
190 | while (1) {
191 | switch (_context5.prev = _context5.next) {
192 | case 0:
193 | _context5.next = 2;
194 | return 123;
195 |
196 | case 2:
197 | _context5.next = 4;
198 | return 321;
199 |
200 | case 4:
201 | case "end":
202 | return _context5.stop();
203 | }
204 | }
205 | }, _callee5, _this4);
206 | }))();
207 | }
208 | }]);
209 |
210 | return Class2;
211 | }();
212 |
213 | tslib_1.__decorate([_mobx.action], Class2.prototype, "method", null);
214 | return _context6.abrupt("return", Class2);
215 |
216 | case 3:
217 | case "end":
218 | return _context6.stop();
219 | }
220 | }
221 | }, _callee6, _this5);
222 | }))();
223 | }
224 | }]);
225 |
226 | return Class1;
227 | }(), (_applyDecoratedDescriptor(_class.prototype, "method3", [_mobx.action], Object.getOwnPropertyDescriptor(_class.prototype, "method3"), _class.prototype)), _class);
228 |
229 |
230 | tslib_1.__decorate([mobx.action], Class1.prototype, "method", null);
231 | tslib_1.__decorate([_mobx.action], Class1.prototype, "method1", void 0);
232 |
233 | var Class2 = function () {
234 | function Class2() {
235 | _classCallCheck(this, Class2);
236 | }
237 |
238 | _createClass(Class2, [{
239 | key: "method",
240 | value: function method() {
241 | var _this6 = this;
242 |
243 | return (0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee7() {
244 | return regeneratorRuntime.wrap(function _callee7$(_context7) {
245 | while (1) {
246 | switch (_context7.prev = _context7.next) {
247 | case 0:
248 | _context7.next = 2;
249 | return 123;
250 |
251 | case 2:
252 | _context7.next = 4;
253 | return 321;
254 |
255 | case 4:
256 | case "end":
257 | return _context7.stop();
258 | }
259 | }
260 | }, _callee7, _this6);
261 | }))();
262 | }
263 | }]);
264 |
265 | return Class2;
266 | }();
267 |
268 | exports.default = Class2;
269 |
270 | tslib_1.__decorate([_mobx.action], Class2.prototype, "method", null);
271 |
--------------------------------------------------------------------------------
/test/fixtures/work-with-latest-preset/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "../../../src",
4 | "transform-decorators-legacy"
5 | ],
6 | "presets": [
7 | "es2015",
8 | "stage-2"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/test/fixtures/work-with-latest-preset/actual.js:
--------------------------------------------------------------------------------
1 | import {action} from "mobx";
2 |
3 | function a1() {
4 | }
5 |
6 | action(function* doSome() {
7 | yield 1;
8 | yield 2;
9 | });
10 |
11 | action(async function doSomeSpecial() {
12 | await 1;
13 | await 2;
14 | })
15 |
16 | action(async () => {
17 | await 1;
18 | await 2;
19 | });
20 |
21 | action(async () => {
22 | const a = [
23 | await 1,
24 | await 2,
25 | ]
26 | });
27 |
28 | class SomeClass {
29 | @action
30 | generatorMethod = function* () {
31 | yield 1;
32 | yield 2;
33 | }
34 | @action("named")
35 | generatorMethod2 = function* () {
36 | yield 1;
37 | yield 2;
38 | }
39 |
40 | @action
41 | async method() {
42 | await 1;
43 | await 2;
44 | }
45 |
46 | @action("named")
47 | async method1() {
48 | await 1;
49 | await 2;
50 | }
51 |
52 | @action
53 | method2 = async () => {
54 | await 1
55 | await 2
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/test/fixtures/work-with-latest-preset/expected.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _mobx = require("mobx");
4 |
5 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
6 |
7 | var _dec, _dec2, _desc, _value, _class, _descriptor, _descriptor2, _descriptor3;
8 |
9 | function _initDefineProp(target, property, descriptor, context) {
10 | if (!descriptor) return;
11 | Object.defineProperty(target, property, {
12 | enumerable: descriptor.enumerable,
13 | configurable: descriptor.configurable,
14 | writable: descriptor.writable,
15 | value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
16 | });
17 | }
18 |
19 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20 |
21 | function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
22 | var desc = {};
23 | Object['ke' + 'ys'](descriptor).forEach(function (key) {
24 | desc[key] = descriptor[key];
25 | });
26 | desc.enumerable = !!desc.enumerable;
27 | desc.configurable = !!desc.configurable;
28 |
29 | if ('value' in desc || desc.initializer) {
30 | desc.writable = true;
31 | }
32 |
33 | desc = decorators.slice().reverse().reduce(function (desc, decorator) {
34 | return decorator(target, property, desc) || desc;
35 | }, desc);
36 |
37 | if (context && desc.initializer !== void 0) {
38 | desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
39 | desc.initializer = undefined;
40 | }
41 |
42 | if (desc.initializer === void 0) {
43 | Object['define' + 'Property'](target, property, desc);
44 | desc = null;
45 | }
46 |
47 | return desc;
48 | }
49 |
50 | function _initializerWarningHelper(descriptor, context) {
51 | throw new Error('Decorating class property failed. Please ensure that transform-class-properties is enabled.');
52 | }
53 |
54 | function a1() {}
55 |
56 | (0, _mobx.action)( /*#__PURE__*/regeneratorRuntime.mark(function doSome() {
57 | return regeneratorRuntime.wrap(function doSome$(_context) {
58 | while (1) {
59 | switch (_context.prev = _context.next) {
60 | case 0:
61 | _context.next = 2;
62 | return 1;
63 |
64 | case 2:
65 | _context.next = 4;
66 | return 2;
67 |
68 | case 4:
69 | case "end":
70 | return _context.stop();
71 | }
72 | }
73 | }, doSome, this);
74 | }));
75 |
76 | (0, _mobx.action)(function () {
77 | var _ref = (0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
78 | return regeneratorRuntime.wrap(function _callee$(_context2) {
79 | while (1) {
80 | switch (_context2.prev = _context2.next) {
81 | case 0:
82 | _context2.next = 2;
83 | return 1;
84 |
85 | case 2:
86 | _context2.next = 4;
87 | return 2;
88 |
89 | case 4:
90 | case "end":
91 | return _context2.stop();
92 | }
93 | }
94 | }, _callee, this);
95 | }));
96 |
97 | function doSomeSpecial() {
98 | return _ref.apply(this, arguments);
99 | }
100 |
101 | return doSomeSpecial;
102 | }());
103 |
104 | (0, _mobx.action)((0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
105 | return regeneratorRuntime.wrap(function _callee2$(_context3) {
106 | while (1) {
107 | switch (_context3.prev = _context3.next) {
108 | case 0:
109 | _context3.next = 2;
110 | return 1;
111 |
112 | case 2:
113 | _context3.next = 4;
114 | return 2;
115 |
116 | case 4:
117 | case "end":
118 | return _context3.stop();
119 | }
120 | }
121 | }, _callee2, undefined);
122 | })));
123 |
124 | (0, _mobx.action)((0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
125 | var a;
126 | return regeneratorRuntime.wrap(function _callee3$(_context4) {
127 | while (1) {
128 | switch (_context4.prev = _context4.next) {
129 | case 0:
130 | _context4.next = 2;
131 | return 1;
132 |
133 | case 2:
134 | _context4.t0 = _context4.sent;
135 | _context4.next = 5;
136 | return 2;
137 |
138 | case 5:
139 | _context4.t1 = _context4.sent;
140 | a = [_context4.t0, _context4.t1];
141 |
142 | case 7:
143 | case "end":
144 | return _context4.stop();
145 | }
146 | }
147 | }, _callee3, undefined);
148 | })));
149 |
150 | var SomeClass = (_dec = (0, _mobx.action)("named"), _dec2 = (0, _mobx.action)("named"), (_class = function () {
151 | function SomeClass() {
152 | _classCallCheck(this, SomeClass);
153 |
154 | _initDefineProp(this, "generatorMethod", _descriptor, this);
155 |
156 | _initDefineProp(this, "generatorMethod2", _descriptor2, this);
157 |
158 | _initDefineProp(this, "method2", _descriptor3, this);
159 | }
160 |
161 | _createClass(SomeClass, [{
162 | key: "method",
163 | value: function method() {
164 | var _this = this;
165 |
166 | return (0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
167 | return regeneratorRuntime.wrap(function _callee4$(_context5) {
168 | while (1) {
169 | switch (_context5.prev = _context5.next) {
170 | case 0:
171 | _context5.next = 2;
172 | return 1;
173 |
174 | case 2:
175 | _context5.next = 4;
176 | return 2;
177 |
178 | case 4:
179 | case "end":
180 | return _context5.stop();
181 | }
182 | }
183 | }, _callee4, _this);
184 | }))();
185 | }
186 | }, {
187 | key: "method1",
188 | value: function method1() {
189 | var _this2 = this;
190 |
191 | return (0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {
192 | return regeneratorRuntime.wrap(function _callee5$(_context6) {
193 | while (1) {
194 | switch (_context6.prev = _context6.next) {
195 | case 0:
196 | _context6.next = 2;
197 | return 1;
198 |
199 | case 2:
200 | _context6.next = 4;
201 | return 2;
202 |
203 | case 4:
204 | case "end":
205 | return _context6.stop();
206 | }
207 | }
208 | }, _callee5, _this2);
209 | }))();
210 | }
211 | }]);
212 |
213 | return SomeClass;
214 | }(), (_descriptor = _applyDecoratedDescriptor(_class.prototype, "generatorMethod", [_mobx.action], {
215 | enumerable: true,
216 | initializer: function initializer() {
217 | return (/*#__PURE__*/regeneratorRuntime.mark(function _callee6() {
218 | return regeneratorRuntime.wrap(function _callee6$(_context7) {
219 | while (1) {
220 | switch (_context7.prev = _context7.next) {
221 | case 0:
222 | _context7.next = 2;
223 | return 1;
224 |
225 | case 2:
226 | _context7.next = 4;
227 | return 2;
228 |
229 | case 4:
230 | case "end":
231 | return _context7.stop();
232 | }
233 | }
234 | }, _callee6, this);
235 | })
236 | );
237 | }
238 | }), _descriptor2 = _applyDecoratedDescriptor(_class.prototype, "generatorMethod2", [_dec], {
239 | enumerable: true,
240 | initializer: function initializer() {
241 | return (/*#__PURE__*/regeneratorRuntime.mark(function _callee7() {
242 | return regeneratorRuntime.wrap(function _callee7$(_context8) {
243 | while (1) {
244 | switch (_context8.prev = _context8.next) {
245 | case 0:
246 | _context8.next = 2;
247 | return 1;
248 |
249 | case 2:
250 | _context8.next = 4;
251 | return 2;
252 |
253 | case 4:
254 | case "end":
255 | return _context8.stop();
256 | }
257 | }
258 | }, _callee7, this);
259 | })
260 | );
261 | }
262 | }), _applyDecoratedDescriptor(_class.prototype, "method", [_mobx.action], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "method1", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "method1"), _class.prototype), _descriptor3 = _applyDecoratedDescriptor(_class.prototype, "method2", [_mobx.action], {
263 | enumerable: true,
264 | initializer: function initializer() {
265 | var _this3 = this;
266 |
267 | return (0, _mobx.flow)( /*#__PURE__*/regeneratorRuntime.mark(function _callee8() {
268 | return regeneratorRuntime.wrap(function _callee8$(_context9) {
269 | while (1) {
270 | switch (_context9.prev = _context9.next) {
271 | case 0:
272 | _context9.next = 2;
273 | return 1;
274 |
275 | case 2:
276 | _context9.next = 4;
277 | return 2;
278 |
279 | case 4:
280 | case "end":
281 | return _context9.stop();
282 | }
283 | }
284 | }, _callee8, _this3);
285 | }));
286 | }
287 | })), _class));
288 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fs from 'fs';
3 | import assert from 'assert';
4 | import { transformFileSync } from 'babel-core';
5 | import plugin from '../src';
6 |
7 | function trim(str) {
8 | return str.replace(/^\s+|\s+$/, '');
9 | }
10 |
11 | describe('', () => {
12 | const fixturesDir = path.join(__dirname, 'fixtures');
13 | fs.readdirSync(fixturesDir).map((caseName) => {
14 | it(`should ${caseName.split('-').join(' ')}`, () => {
15 | const fixtureDir = path.join(fixturesDir, caseName);
16 | const actualPath = path.join(fixtureDir, 'actual.js');
17 | const actual = transformFileSync(actualPath).code;
18 |
19 | const expected = fs.readFileSync(
20 | path.join(fixtureDir, 'expected.js')
21 | ).toString();
22 |
23 | // console.log(path.join(fixtureDir, 'expected.js'))
24 | // console.log(actual)
25 |
26 | assert.equal(trim(actual), trim(expected));
27 | });
28 | });
29 | });
30 |
--------------------------------------------------------------------------------