UNPKG

2.9 kBJavaScriptView Raw
1'use strict';
2
3const tree = require('./tree');
4const cyclic = require('./cyclic');
5const graph = require('./graph');
6const log = require('./log');
7
8const defaultConfig = {
9 baseDir: null,
10 excludeRegExp: false,
11 fileExtensions: ['js'],
12 includeNpm: false,
13 requireConfig: null,
14 webpackConfig: null,
15 layout: 'dot',
16 fontName: 'Arial',
17 fontSize: '14px',
18 backgroundColor: '#000000',
19 nodeColor: '#c6c5fe',
20 noDependencyColor: '#cfffac',
21 cyclicNodeColor: '#ff6c60',
22 edgeColor: '#757575',
23 graphVizOptions: false,
24 graphVizPath: false,
25 dependencyFilter: false
26};
27
28class Madge {
29 /**
30 * Class constructor.
31 * @constructor
32 * @api public
33 * @param {String|Array|Object} path
34 * @param {Object} config
35 * @return {Promise}
36 */
37 constructor(path, config) {
38 this.skipped = [];
39
40 if (!path) {
41 throw new Error('path argument not provided');
42 }
43
44 this.config = Object.assign({}, defaultConfig, config);
45
46 if (typeof path === 'object' && !Array.isArray(path)) {
47 this.tree = path;
48 log('using predefined tree %o', path);
49 return Promise.resolve(this);
50 }
51
52 if (typeof path === 'string') {
53 path = [path];
54 }
55
56 return tree(path, this.config).then((res) => {
57 this.tree = res.tree;
58 this.skipped = res.skipped;
59 return this;
60 });
61 }
62
63 /**
64 * Return the module dependency graph as an object.
65 * @api public
66 * @return {Object}
67 */
68 obj() {
69 return this.tree;
70 }
71
72 /**
73 * Return produced warnings.
74 * @api public
75 * @return {Array}
76 */
77 warnings() {
78 return {
79 skipped: this.skipped
80 };
81 }
82
83 /**
84 * Return the modules that has circular dependencies.
85 * @api public
86 * @return {Object}
87 */
88 circular() {
89 return cyclic(this.tree);
90 }
91
92 /**
93 * Return a list of modules that depends on the given module.
94 * @api public
95 * @param {String} id
96 * @return {Array}
97 */
98 depends(id) {
99 const tree = this.obj();
100
101 return Object
102 .keys(tree)
103 .filter((dep) => tree[dep].indexOf(id) >= 0);
104 }
105
106 /**
107 * Return a list of modules that no one is depending on.
108 * @api public
109 * @return {Array}
110 */
111 orphans() {
112 const tree = this.obj();
113 const map = {};
114
115 Object
116 .keys(tree)
117 .forEach((dep) => {
118 tree[dep].forEach((id) => {
119 map[id] = true;
120 });
121 });
122
123 return Object
124 .keys(tree)
125 .filter((dep) => !map[dep]);
126 }
127
128 /**
129 * Return the module dependency graph as DOT output.
130 * @api public
131 * @return {Promise}
132 */
133 dot() {
134 return graph.dot(this.obj(), this.config);
135 }
136
137 /**
138 * Write dependency graph to image.
139 * @api public
140 * @param {String} imagePath
141 * @return {Promise}
142 */
143 image(imagePath) {
144 if (!imagePath) {
145 return Promise.reject(new Error('imagePath not provided'));
146 }
147
148 return graph.image(this.obj(), this.circular(), imagePath, this.config);
149 }
150}
151
152/**
153 * Expose API.
154 * @param {String|Array} path
155 * @param {Object} config
156 * @return {Promise}
157 */
158module.exports = (path, config) => new Madge(path, config);