UNPKG

3.65 kBJavaScriptView Raw
1/**
2 * disallow DI of specified services
3 *
4 * Some services should be used only in a specific AngularJS service (Ajax-based service for example), in order to follow the separation of concerns paradigm.
5 * The second parameter specifies the services.
6 * The third parameter can be a list of angular objects (controller, factory, etc.).
7 * Or second parameter can be an object, where keys are angular object names and value is a list of services (like {controller: ['$http'], factory: ['$q']})
8 *
9 * @linkDescription disallow DI of specified services for other angular components (`$http` for controllers, filters and directives)
10 * @version 0.1.0
11 * @category bestPractice
12 * @sinceAngularVersion 1.x
13 */
14'use strict';
15
16const utils = require('./utils/utils');
17
18module.exports = {
19 meta: {
20 schema: [{
21 type: ['array', 'object']
22 }, {
23 type: 'array'
24 }]
25 },
26 create: function(context) {
27 let angularObjectList = ['controller', 'filter', 'directive'];
28 let badServices = [];
29 let map;
30 let message = 'REST API calls should be implemented in a specific service';
31
32 function isArray(item) {
33 return Object.prototype.toString.call(item) === '[object Array]';
34 }
35
36 function isObject(item) {
37 return Object.prototype.toString.call(item) === '[object Object]';
38 }
39
40 if (context.options[0] === undefined) {
41 badServices = [/\$http/, /\$resource/, /Restangular/, /\$q/, /\$filter/];
42 }
43
44 if (isArray(context.options[0])) {
45 badServices = context.options[0];
46 }
47
48 if (isArray(context.options[1])) {
49 angularObjectList = context.options[1];
50 }
51
52 if (isObject(context.options[0])) {
53 map = context.options[0];
54
55 let result = [];
56 let prop;
57
58 for (prop in map) {
59 if (map.hasOwnProperty(prop)) {
60 result.push(prop);
61 }
62 }
63
64 angularObjectList = result;
65 }
66
67 function isSetBedService(serviceName, angularObjectName) {
68 if (map) {
69 return map[angularObjectName].find(object => utils.convertPrefixToRegex(object).test(serviceName));
70 }
71 return badServices.find(object => utils.convertPrefixToRegex(object).test(serviceName));
72 }
73
74 return {
75
76 CallExpression: function(node) {
77 let callee = node.callee;
78
79 if (utils.isAngularComponent(node) && callee.type === 'MemberExpression' && angularObjectList.indexOf(callee.property.name) >= 0) {
80 if (utils.isFunctionType(node.arguments[1])) {
81 node.arguments[1].params.forEach(function(service) {
82 if (service.type === 'Identifier' && isSetBedService(service.name, callee.property.name)) {
83 context.report(node, message + ' (' + service.name + ' in ' + callee.property.name + ')', {});
84 }
85 });
86 }
87
88 if (utils.isArrayType(node.arguments[1])) {
89 node.arguments[1].elements.forEach(function(service) {
90 if (service.type === 'Literal' && isSetBedService(service.value, callee.property.name)) {
91 context.report(node, message + ' (' + service.value + ' in ' + callee.property.name + ')', {});
92 }
93 });
94 }
95 }
96 }
97 };
98 }
99};