├── .babelrc
├── .npmignore
├── .gitignore
├── example
├── .babelrc
└── src
│ ├── ExampleService.js
│ ├── ExampleController.js
│ ├── ExampleDirective.js
│ └── index.js
├── .eslintrc
├── package.json
├── README.md
├── LICENSE
└── src
└── index.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015"]
3 | }
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | src
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | .idea
3 | logs
4 | *.log
5 |
6 | # Dependency directory
7 | node_modules
8 | lib
9 |
--------------------------------------------------------------------------------
/example/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015"],
3 | "plugins": [
4 | "transform-class-properties",
5 | "syntax-decorators",
6 | "ng-annotate"
7 | ]
8 | }
--------------------------------------------------------------------------------
/example/src/ExampleService.js:
--------------------------------------------------------------------------------
1 | @Inject('$http')
2 | class ExampleService {
3 |
4 | getData() {
5 | return this.$http.get('...');
6 | }
7 | }
8 |
9 | export default ExampleService;
10 |
--------------------------------------------------------------------------------
/example/src/ExampleController.js:
--------------------------------------------------------------------------------
1 |
2 | @Inject('$exService')
3 | export class ExampleController {
4 |
5 | constructor() {
6 | this.data = '';
7 | }
8 |
9 | load() {
10 | this.$exService
11 | .getData()
12 | .then(data => {
13 | this.data = data;
14 | });
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "rules": {
4 | "strict": 0,
5 | "quotes": [2, "single"],
6 | "no-underscore-dangle": 0,
7 | "no-use-before-define": 0,
8 | "no-new-func": 0,
9 | "no-console": 0,
10 | "no-var": 1,
11 | "new-cap": 0
12 | },
13 | "env": {
14 | "es6": true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/example/src/ExampleDirective.js:
--------------------------------------------------------------------------------
1 |
2 | class ExampleDirective {
3 |
4 | restrict = 'E';
5 | controller = 'ExampleController';
6 | controllerAs = '$exCtrl';
7 | template = `
8 |
9 | {{$exCtrl.data}}
10 | `;
11 |
12 | }
13 |
14 | export default ExampleDirective;
15 |
--------------------------------------------------------------------------------
/example/src/index.js:
--------------------------------------------------------------------------------
1 | import ExampleDirective from './ExampleDirective';
2 | import ExampleController from './ExampleController';
3 | import ExampleService from './ExampleService';
4 |
5 | angular
6 | .module('example', [])
7 | .controller('ExampleController', ExampleController)
8 | .directive('exDirective', ExampleDirective)
9 | .service('$exService', ExampleService);
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "babel-plugin-ng-annotate",
3 | "version": "0.3.2",
4 | "description": "Babel Plugin for AngularJS dependency injection annotations.",
5 | "dependencies": {
6 | "babel-plugin-syntax-decorators": "^6.5.0",
7 | "babel-plugin-transform-class-properties": "^6.6.0",
8 | "babel-preset-es2015": "^6.6.0",
9 | "babel-runtime": "^6.3.13"
10 | },
11 | "author": "Maciej Chmielarski ",
12 | "license": "MIT",
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/mchmielarski/babel-plugin-ng-annotate.git"
16 | },
17 | "main": "lib/index.js",
18 | "scripts": {
19 | "build": "babel src --out-dir lib"
20 | },
21 | "keywords": [
22 | "babel",
23 | "babel-plugin",
24 | "angular",
25 | "annotate"
26 | ],
27 | "devDependencies": {
28 | "babel-cli": "^6.6.5"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # babel-plugin-ng-annotate - babel 6.x
2 |
3 | ## How to install
4 |
5 | ```
6 | $ npm install --save-dev babel-plugin-ng-annotate
7 | ```
8 |
9 | Note: this library depends on the [syntax decorators](https://www.npmjs.com/package/babel-plugin-syntax-decorators) plugin for parsing. Simply `$ npm install --save-dev babel-plugin-syntax-decorators` and follow the setup instructions below.
10 |
11 | ## How to setup
12 |
13 | #### .babelrc
14 | ```js
15 | {
16 | "presets": ["es2015"],
17 | "plugins": ["syntax-decorators", "ng-annotate"]
18 | }
19 | ```
20 |
21 |
22 | ## How to use
23 |
24 | ```js
25 | @Inject('service1', 'service2', 'service3')
26 | class MyController {
27 |
28 | constructor() {
29 | this.service1();
30 | }
31 |
32 | method() {
33 | this.service2();
34 | }
35 |
36 | anotherMethod() {
37 | this.service3();
38 | }
39 | }
40 |
41 | angular.controller('MyController', MyController);
42 | ```
43 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Maciej Chmielarski
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 |
23 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export default function ({ types: t }) {
2 | return {
3 | visitor: {
4 | ClassDeclaration(path) {
5 | if (!path.node.decorators) {
6 | return;
7 | }
8 | const inject = path.node.decorators.find(decorator => decorator.expression.callee.name === 'Inject');
9 |
10 | if (!inject) {
11 | return;
12 | }
13 | path.node.decorators = path.node.decorators.splice(path.node.decorators.indexOf(inject), 1);
14 |
15 | const toInject = inject.expression.arguments.map(arg => arg.value);
16 | let ctor = path.node.body.body.find(el => el.kind === 'constructor');
17 | let toParam;
18 |
19 | if (!ctor) {
20 | ctor = t.classMethod(
21 | 'constructor',
22 | t.identifier('constructor'),
23 | [],
24 | t.blockStatement([])
25 | );
26 | if (path.node.superClass) {
27 | ctor.body.body.unshift(
28 | t.expressionStatement(t.callExpression(t.super(), []))
29 | );
30 | }
31 | path.node.body.body.unshift(ctor);
32 | toParam = toInject;
33 | } else {
34 | toParam = toInject.filter(param => !ctor.params.find(p => p.name === param));
35 | }
36 |
37 | toParam.forEach(i => {
38 | let fCmd;
39 | let sup;
40 | if (Array.isArray(ctor.body.body)) {
41 | fCmd = ctor.body.body[0];
42 | } else {
43 | fCmd = ctor.body.body;
44 | }
45 | if (fCmd && fCmd.expression && fCmd.expression.callee && fCmd.expression.callee.type === 'Super') {
46 | sup = ctor.body.body.shift();
47 | }
48 |
49 | ctor.body.body.unshift(
50 | t.expressionStatement(
51 | t.assignmentExpression(
52 | '=',
53 | t.memberExpression(t.thisExpression(), t.identifier(i)),
54 | t.identifier(i)
55 | )
56 | )
57 | );
58 |
59 | if (sup) {
60 | ctor.body.body.unshift(sup);
61 | }
62 | })
63 |
64 | ctor.params = ctor.params.concat(toParam.map(i => t.identifier(i)));
65 |
66 | const injectExp = t.expressionStatement(t.assignmentExpression(
67 | '=',
68 | t.memberExpression(
69 | t.identifier(path.node.id.name),
70 | t.identifier('$inject')),
71 | t.arrayExpression(toInject.map(d => t.stringLiteral(d)))
72 | ));
73 |
74 | if (path.parentPath.type === 'ExportNamedDeclaration') {
75 | path.parentPath.insertAfter(injectExp);
76 | } else {
77 | path.insertAfter(injectExp);
78 | }
79 | }
80 | }
81 | };
82 | };
83 |
--------------------------------------------------------------------------------