1 | 'use strict';
|
2 |
|
3 | const tree = require('./tree');
|
4 | const cyclic = require('./cyclic');
|
5 | const graph = require('./graph');
|
6 | const log = require('./log');
|
7 |
|
8 | const defaultConfig = {
|
9 | baseDir: null,
|
10 | excludeRegExp: false,
|
11 | fileExtensions: ['js'],
|
12 | includeNpm: false,
|
13 | requireConfig: null,
|
14 | webpackConfig: null,
|
15 | tsConfig: null,
|
16 | rankdir: 'LR',
|
17 | layout: 'dot',
|
18 | fontName: 'Arial',
|
19 | fontSize: '14px',
|
20 | backgroundColor: '#111111',
|
21 | nodeColor: '#c6c5fe',
|
22 | nodeShape: 'box',
|
23 | nodeStyle: 'rounded',
|
24 | noDependencyColor: '#cfffac',
|
25 | cyclicNodeColor: '#ff6c60',
|
26 | edgeColor: '#757575',
|
27 | graphVizOptions: false,
|
28 | graphVizPath: false,
|
29 | dependencyFilter: false
|
30 | };
|
31 |
|
32 | class Madge {
|
33 | |
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | constructor(path, config) {
|
42 | this.skipped = [];
|
43 |
|
44 | if (!path) {
|
45 | throw new Error('path argument not provided');
|
46 | }
|
47 |
|
48 | this.config = Object.assign({}, defaultConfig, config);
|
49 |
|
50 | if (typeof path === 'object' && !Array.isArray(path)) {
|
51 | this.tree = path;
|
52 | log('using predefined tree %o', path);
|
53 | return Promise.resolve(this);
|
54 | }
|
55 |
|
56 | if (typeof path === 'string') {
|
57 | path = [path];
|
58 | }
|
59 |
|
60 | return tree(path, this.config).then((res) => {
|
61 | this.tree = res.tree;
|
62 | this.skipped = res.skipped;
|
63 | return this;
|
64 | });
|
65 | }
|
66 |
|
67 | |
68 |
|
69 |
|
70 |
|
71 |
|
72 | obj() {
|
73 | return this.tree;
|
74 | }
|
75 |
|
76 | |
77 |
|
78 |
|
79 |
|
80 |
|
81 | warnings() {
|
82 | return {
|
83 | skipped: this.skipped
|
84 | };
|
85 | }
|
86 |
|
87 | |
88 |
|
89 |
|
90 |
|
91 |
|
92 | circular() {
|
93 | return cyclic(this.tree);
|
94 | }
|
95 |
|
96 | |
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 | depends(id) {
|
103 | const tree = this.obj();
|
104 |
|
105 | return Object
|
106 | .keys(tree)
|
107 | .filter((dep) => tree[dep].indexOf(id) >= 0);
|
108 | }
|
109 |
|
110 | |
111 |
|
112 |
|
113 |
|
114 |
|
115 | orphans() {
|
116 | const tree = this.obj();
|
117 | const map = {};
|
118 |
|
119 | Object
|
120 | .keys(tree)
|
121 | .forEach((dep) => {
|
122 | tree[dep].forEach((id) => {
|
123 | map[id] = true;
|
124 | });
|
125 | });
|
126 |
|
127 | return Object
|
128 | .keys(tree)
|
129 | .filter((dep) => !map[dep]);
|
130 | }
|
131 |
|
132 | |
133 |
|
134 |
|
135 |
|
136 |
|
137 | leaves() {
|
138 | const tree = this.obj();
|
139 | return Object.keys(tree).filter((key) => !tree[key].length);
|
140 | }
|
141 |
|
142 | |
143 |
|
144 |
|
145 |
|
146 |
|
147 | dot() {
|
148 | return graph.dot(this.obj(), this.circular(), this.config);
|
149 | }
|
150 |
|
151 | |
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 | image(imagePath) {
|
158 | if (!imagePath) {
|
159 | return Promise.reject(new Error('imagePath not provided'));
|
160 | }
|
161 |
|
162 | return graph.image(this.obj(), this.circular(), imagePath, this.config);
|
163 | }
|
164 |
|
165 | |
166 |
|
167 |
|
168 |
|
169 |
|
170 | svg() {
|
171 | return graph.svg(this.obj(), this.circular(), this.config);
|
172 | }
|
173 | }
|
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 | module.exports = (path, config) => new Madge(path, config);
|