UNPKG

1.44 kBJavaScriptView Raw
1'use strict';
2
3/**
4 * Get path to the circular dependency.
5 * @param {String} parent
6 * @param {Object} unresolved
7 * @return {Array}
8 */
9function getPath(parent, unresolved) {
10 let parentVisited = false;
11
12 return Object.keys(unresolved).filter((module) => {
13 if (module === parent) {
14 parentVisited = true;
15 }
16 return parentVisited && unresolved[module];
17 });
18}
19
20/**
21 * A circular dependency is occurring when we see a software package
22 * more than once, unless that software package has all its dependencies resolved.
23 * @param {String} id
24 * @param {Object} modules
25 * @param {Object} circular
26 * @param {Object} resolved
27 * @param {Object} unresolved
28 */
29function resolver(id, modules, circular, resolved, unresolved) {
30 unresolved[id] = true;
31
32 if (modules[id]) {
33 modules[id].forEach((dependency) => {
34 if (!resolved[dependency]) {
35 if (unresolved[dependency]) {
36 circular.push(getPath(dependency, unresolved));
37 return;
38 }
39 resolver(dependency, modules, circular, resolved, unresolved);
40 }
41 });
42 }
43
44 resolved[id] = true;
45 unresolved[id] = false;
46}
47
48/**
49 * Finds all circular dependencies for the given modules.
50 * @param {Object} modules
51 * @return {Array}
52 */
53module.exports = function (modules) {
54 const circular = [];
55 const resolved = {};
56 const unresolved = {};
57
58 Object.keys(modules).forEach((id) => {
59 resolver(id, modules, circular, resolved, unresolved);
60 });
61
62 return circular;
63};