@theguild/federation-composition 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/cjs/specifications/link.js +40 -5
- package/cjs/subgraph/helpers.js +2 -2
- package/cjs/subgraph/state.js +8 -0
- package/cjs/subgraph/validation/rules/elements/provides.js +8 -6
- package/cjs/subgraph/validation/rules/elements/requires.js +9 -7
- package/cjs/subgraph/validation/validate-state.js +9 -3
- package/cjs/subgraph/validation/validate-subgraph.js +4 -2
- package/cjs/subgraph/validation/validation-context.js +10 -0
- package/cjs/supergraph/composition/directive.js +3 -0
- package/cjs/supergraph/composition/enum-type.js +3 -0
- package/cjs/supergraph/composition/input-object-type.js +3 -0
- package/cjs/supergraph/composition/interface-type.js +4 -0
- package/cjs/supergraph/composition/object-type.js +18 -20
- package/cjs/supergraph/composition/scalar-type.js +2 -0
- package/cjs/supergraph/composition/union-type.js +2 -0
- package/cjs/supergraph/state.js +24 -26
- package/cjs/supergraph/validation/rules/fields-of-the-same-type-rule.js +35 -0
- package/cjs/supergraph/validation/rules/invalid-field-sharing-rule.js +4 -1
- package/cjs/supergraph/validation/rules/satisfiablity/constants.js +4 -0
- package/cjs/supergraph/validation/rules/satisfiablity/edge.js +64 -0
- package/cjs/supergraph/validation/rules/satisfiablity/errors.js +44 -0
- package/cjs/supergraph/validation/rules/satisfiablity/fields.js +147 -0
- package/cjs/supergraph/validation/rules/satisfiablity/finder.js +267 -0
- package/cjs/supergraph/validation/rules/satisfiablity/graph.js +675 -0
- package/cjs/supergraph/validation/rules/satisfiablity/helpers.js +41 -0
- package/cjs/supergraph/validation/rules/satisfiablity/move-validator.js +337 -0
- package/cjs/supergraph/validation/rules/satisfiablity/moves.js +52 -0
- package/cjs/supergraph/validation/rules/satisfiablity/node.js +89 -0
- package/cjs/supergraph/validation/rules/satisfiablity/operation-path.js +70 -0
- package/cjs/supergraph/validation/rules/satisfiablity/supergraph.js +37 -0
- package/cjs/supergraph/validation/rules/satisfiablity/walker.js +306 -0
- package/cjs/supergraph/validation/rules/satisfiablity-rule.js +45 -1081
- package/cjs/supergraph/validation/validate-supergraph.js +1 -1
- package/cjs/utils/logger.js +127 -0
- package/esm/specifications/link.js +40 -5
- package/esm/subgraph/helpers.js +2 -2
- package/esm/subgraph/state.js +8 -0
- package/esm/subgraph/validation/rules/elements/provides.js +8 -6
- package/esm/subgraph/validation/rules/elements/requires.js +9 -7
- package/esm/subgraph/validation/validate-state.js +9 -3
- package/esm/subgraph/validation/validate-subgraph.js +4 -2
- package/esm/subgraph/validation/validation-context.js +11 -1
- package/esm/supergraph/composition/directive.js +3 -0
- package/esm/supergraph/composition/enum-type.js +3 -0
- package/esm/supergraph/composition/input-object-type.js +3 -0
- package/esm/supergraph/composition/interface-type.js +4 -0
- package/esm/supergraph/composition/object-type.js +18 -20
- package/esm/supergraph/composition/scalar-type.js +2 -0
- package/esm/supergraph/composition/union-type.js +2 -0
- package/esm/supergraph/state.js +24 -26
- package/esm/supergraph/validation/rules/fields-of-the-same-type-rule.js +35 -0
- package/esm/supergraph/validation/rules/invalid-field-sharing-rule.js +4 -1
- package/esm/supergraph/validation/rules/satisfiablity/constants.js +1 -0
- package/esm/supergraph/validation/rules/satisfiablity/edge.js +54 -0
- package/esm/supergraph/validation/rules/satisfiablity/errors.js +40 -0
- package/esm/supergraph/validation/rules/satisfiablity/fields.js +142 -0
- package/esm/supergraph/validation/rules/satisfiablity/finder.js +261 -0
- package/esm/supergraph/validation/rules/satisfiablity/graph.js +671 -0
- package/esm/supergraph/validation/rules/satisfiablity/helpers.js +35 -0
- package/esm/supergraph/validation/rules/satisfiablity/move-validator.js +333 -0
- package/esm/supergraph/validation/rules/satisfiablity/moves.js +46 -0
- package/esm/supergraph/validation/rules/satisfiablity/node.js +85 -0
- package/esm/supergraph/validation/rules/satisfiablity/operation-path.js +66 -0
- package/esm/supergraph/validation/rules/satisfiablity/supergraph.js +33 -0
- package/esm/supergraph/validation/rules/satisfiablity/walker.js +301 -0
- package/esm/supergraph/validation/rules/satisfiablity-rule.js +40 -1076
- package/esm/supergraph/validation/validate-supergraph.js +1 -1
- package/esm/utils/logger.js +119 -0
- package/package.json +2 -1
- package/typings/subgraph/state.d.cts +2 -0
- package/typings/subgraph/state.d.ts +2 -0
- package/typings/subgraph/validation/validate-state.d.cts +2 -1
- package/typings/subgraph/validation/validate-state.d.ts +2 -1
- package/typings/subgraph/validation/validation-context.d.cts +3 -0
- package/typings/subgraph/validation/validation-context.d.ts +3 -0
- package/typings/supergraph/composition/common.d.cts +2 -1
- package/typings/supergraph/composition/common.d.ts +2 -1
- package/typings/supergraph/composition/directive.d.cts +4 -0
- package/typings/supergraph/composition/directive.d.ts +4 -0
- package/typings/supergraph/composition/enum-type.d.cts +4 -0
- package/typings/supergraph/composition/enum-type.d.ts +4 -0
- package/typings/supergraph/composition/input-object-type.d.cts +4 -0
- package/typings/supergraph/composition/input-object-type.d.ts +4 -0
- package/typings/supergraph/composition/interface-type.d.cts +5 -0
- package/typings/supergraph/composition/interface-type.d.ts +5 -0
- package/typings/supergraph/composition/object-type.d.cts +5 -0
- package/typings/supergraph/composition/object-type.d.ts +5 -0
- package/typings/supergraph/composition/scalar-type.d.cts +3 -0
- package/typings/supergraph/composition/scalar-type.d.ts +3 -0
- package/typings/supergraph/composition/union-type.d.cts +3 -0
- package/typings/supergraph/composition/union-type.d.ts +3 -0
- package/typings/supergraph/state.d.cts +4 -4
- package/typings/supergraph/state.d.ts +4 -4
- package/typings/supergraph/validation/rules/satisfiablity/constants.d.cts +2 -0
- package/typings/supergraph/validation/rules/satisfiablity/constants.d.ts +2 -0
- package/typings/supergraph/validation/rules/satisfiablity/edge.d.cts +31 -0
- package/typings/supergraph/validation/rules/satisfiablity/edge.d.ts +31 -0
- package/typings/supergraph/validation/rules/satisfiablity/errors.d.cts +17 -0
- package/typings/supergraph/validation/rules/satisfiablity/errors.d.ts +17 -0
- package/typings/supergraph/validation/rules/satisfiablity/fields.d.cts +33 -0
- package/typings/supergraph/validation/rules/satisfiablity/fields.d.ts +33 -0
- package/typings/supergraph/validation/rules/satisfiablity/finder.d.cts +28 -0
- package/typings/supergraph/validation/rules/satisfiablity/finder.d.ts +28 -0
- package/typings/supergraph/validation/rules/satisfiablity/graph.d.cts +63 -0
- package/typings/supergraph/validation/rules/satisfiablity/graph.d.ts +63 -0
- package/typings/supergraph/validation/rules/satisfiablity/helpers.d.cts +7 -0
- package/typings/supergraph/validation/rules/satisfiablity/helpers.d.ts +7 -0
- package/typings/supergraph/validation/rules/satisfiablity/move-validator.d.cts +25 -0
- package/typings/supergraph/validation/rules/satisfiablity/move-validator.d.ts +25 -0
- package/typings/supergraph/validation/rules/satisfiablity/moves.d.cts +24 -0
- package/typings/supergraph/validation/rules/satisfiablity/moves.d.ts +24 -0
- package/typings/supergraph/validation/rules/satisfiablity/node.d.cts +31 -0
- package/typings/supergraph/validation/rules/satisfiablity/node.d.ts +31 -0
- package/typings/supergraph/validation/rules/satisfiablity/operation-path.d.cts +29 -0
- package/typings/supergraph/validation/rules/satisfiablity/operation-path.d.ts +29 -0
- package/typings/supergraph/validation/rules/satisfiablity/supergraph.d.cts +14 -0
- package/typings/supergraph/validation/rules/satisfiablity/supergraph.d.ts +14 -0
- package/typings/supergraph/validation/rules/satisfiablity/walker.d.cts +35 -0
- package/typings/supergraph/validation/rules/satisfiablity/walker.d.ts +35 -0
- package/typings/utils/logger.d.cts +33 -0
- package/typings/utils/logger.d.ts +33 -0
- package/cjs/utils/dependency-graph.js +0 -227
- package/esm/utils/dependency-graph.js +0 -222
- package/typings/utils/dependency-graph.d.cts +0 -31
- package/typings/utils/dependency-graph.d.ts +0 -31
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { OperationTypeNode } from 'graphql';
|
|
2
|
+
import type { SupergraphState } from '../../../state';
|
|
3
|
+
import { Step } from './operation-path';
|
|
4
|
+
export declare class Supergraph {
|
|
5
|
+
private supergraph;
|
|
6
|
+
private mergedGraph;
|
|
7
|
+
private fieldsResolver;
|
|
8
|
+
private moveRequirementChecker;
|
|
9
|
+
private logger;
|
|
10
|
+
constructor(supergraphState: SupergraphState);
|
|
11
|
+
validate(): import("./walker").WalkTracker[];
|
|
12
|
+
validateOperation(operation: OperationTypeNode, steps: Step[]): import("./walker").WalkTracker;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=supergraph.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { OperationTypeNode } from 'graphql';
|
|
2
|
+
import type { Logger } from '../../../../utils/logger';
|
|
3
|
+
import { type Edge } from './edge';
|
|
4
|
+
import { SatisfiabilityError } from './errors';
|
|
5
|
+
import type { Graph } from './graph';
|
|
6
|
+
import type { MoveValidator } from './move-validator';
|
|
7
|
+
import { OperationPath, type Step } from './operation-path';
|
|
8
|
+
export declare class WalkTracker {
|
|
9
|
+
superPath: OperationPath;
|
|
10
|
+
paths: OperationPath[];
|
|
11
|
+
private errors;
|
|
12
|
+
constructor(superPath: OperationPath, paths: OperationPath[]);
|
|
13
|
+
move(edge: Edge): WalkTracker;
|
|
14
|
+
addPath(path: OperationPath): void;
|
|
15
|
+
addError(error: SatisfiabilityError): void;
|
|
16
|
+
isPossible(): boolean;
|
|
17
|
+
givesEmptyResult(): boolean;
|
|
18
|
+
isEdgeVisited(edge: Edge): boolean;
|
|
19
|
+
listErrors(): SatisfiabilityError[];
|
|
20
|
+
}
|
|
21
|
+
export declare class Walker {
|
|
22
|
+
private moveChecker;
|
|
23
|
+
private supergraph;
|
|
24
|
+
private mergedGraph;
|
|
25
|
+
private logger;
|
|
26
|
+
private pathFinder;
|
|
27
|
+
constructor(logger: Logger, moveChecker: MoveValidator, supergraph: Graph, mergedGraph: Graph);
|
|
28
|
+
walkTrail(operationType: OperationTypeNode, steps: Step[]): WalkTracker;
|
|
29
|
+
walk(method?: 'bfs' | 'dfs'): WalkTracker[];
|
|
30
|
+
private nextStep;
|
|
31
|
+
private dfs;
|
|
32
|
+
private _dfs;
|
|
33
|
+
private bfs;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=walker.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { OperationTypeNode } from 'graphql';
|
|
2
|
+
import type { Logger } from '../../../../utils/logger';
|
|
3
|
+
import { type Edge } from './edge';
|
|
4
|
+
import { SatisfiabilityError } from './errors';
|
|
5
|
+
import type { Graph } from './graph';
|
|
6
|
+
import type { MoveValidator } from './move-validator';
|
|
7
|
+
import { OperationPath, type Step } from './operation-path';
|
|
8
|
+
export declare class WalkTracker {
|
|
9
|
+
superPath: OperationPath;
|
|
10
|
+
paths: OperationPath[];
|
|
11
|
+
private errors;
|
|
12
|
+
constructor(superPath: OperationPath, paths: OperationPath[]);
|
|
13
|
+
move(edge: Edge): WalkTracker;
|
|
14
|
+
addPath(path: OperationPath): void;
|
|
15
|
+
addError(error: SatisfiabilityError): void;
|
|
16
|
+
isPossible(): boolean;
|
|
17
|
+
givesEmptyResult(): boolean;
|
|
18
|
+
isEdgeVisited(edge: Edge): boolean;
|
|
19
|
+
listErrors(): SatisfiabilityError[];
|
|
20
|
+
}
|
|
21
|
+
export declare class Walker {
|
|
22
|
+
private moveChecker;
|
|
23
|
+
private supergraph;
|
|
24
|
+
private mergedGraph;
|
|
25
|
+
private logger;
|
|
26
|
+
private pathFinder;
|
|
27
|
+
constructor(logger: Logger, moveChecker: MoveValidator, supergraph: Graph, mergedGraph: Graph);
|
|
28
|
+
walkTrail(operationType: OperationTypeNode, steps: Step[]): WalkTracker;
|
|
29
|
+
walk(method?: 'bfs' | 'dfs'): WalkTracker[];
|
|
30
|
+
private nextStep;
|
|
31
|
+
private dfs;
|
|
32
|
+
private _dfs;
|
|
33
|
+
private bfs;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=walker.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
export declare class LoggerContext {
|
|
3
|
+
private indent;
|
|
4
|
+
private maxIdLength;
|
|
5
|
+
private idUpdateFns;
|
|
6
|
+
private logger;
|
|
7
|
+
private firstLoggerAt;
|
|
8
|
+
down(time: number): void;
|
|
9
|
+
up(time: number): number | undefined;
|
|
10
|
+
getTime(): number;
|
|
11
|
+
getIndent(): {
|
|
12
|
+
level: number;
|
|
13
|
+
str: string;
|
|
14
|
+
times: number[];
|
|
15
|
+
};
|
|
16
|
+
register(id: string, idUpdateFn: (len: number) => void): debug.Debugger;
|
|
17
|
+
private updateIndent;
|
|
18
|
+
}
|
|
19
|
+
export declare class Logger {
|
|
20
|
+
private id;
|
|
21
|
+
private context;
|
|
22
|
+
isEnabled: boolean;
|
|
23
|
+
private debug;
|
|
24
|
+
private idPrefix;
|
|
25
|
+
constructor(id: string, context: LoggerContext);
|
|
26
|
+
log(msg: string | (() => string), prefix?: string): void;
|
|
27
|
+
group(msg: string | (() => string)): void;
|
|
28
|
+
groupEnd(msg?: string | (() => string)): void;
|
|
29
|
+
create(id: string): Logger;
|
|
30
|
+
private _log;
|
|
31
|
+
private _updateIdPrefix;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
export declare class LoggerContext {
|
|
3
|
+
private indent;
|
|
4
|
+
private maxIdLength;
|
|
5
|
+
private idUpdateFns;
|
|
6
|
+
private logger;
|
|
7
|
+
private firstLoggerAt;
|
|
8
|
+
down(time: number): void;
|
|
9
|
+
up(time: number): number | undefined;
|
|
10
|
+
getTime(): number;
|
|
11
|
+
getIndent(): {
|
|
12
|
+
level: number;
|
|
13
|
+
str: string;
|
|
14
|
+
times: number[];
|
|
15
|
+
};
|
|
16
|
+
register(id: string, idUpdateFn: (len: number) => void): debug.Debugger;
|
|
17
|
+
private updateIndent;
|
|
18
|
+
}
|
|
19
|
+
export declare class Logger {
|
|
20
|
+
private id;
|
|
21
|
+
private context;
|
|
22
|
+
isEnabled: boolean;
|
|
23
|
+
private debug;
|
|
24
|
+
private idPrefix;
|
|
25
|
+
constructor(id: string, context: LoggerContext);
|
|
26
|
+
log(msg: string | (() => string), prefix?: string): void;
|
|
27
|
+
group(msg: string | (() => string)): void;
|
|
28
|
+
groupEnd(msg?: string | (() => string)): void;
|
|
29
|
+
create(id: string): Logger;
|
|
30
|
+
private _log;
|
|
31
|
+
private _updateIdPrefix;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DepGraphCycleError = exports.DepGraph = void 0;
|
|
4
|
-
function createDFS(edges, leavesOnly, result, circular) {
|
|
5
|
-
const visited = {};
|
|
6
|
-
return function (start) {
|
|
7
|
-
if (visited[start]) {
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
const inCurrentPath = {};
|
|
11
|
-
const currentPath = [];
|
|
12
|
-
const todo = [];
|
|
13
|
-
todo.push({ node: start, processed: false });
|
|
14
|
-
while (todo.length > 0) {
|
|
15
|
-
const current = todo[todo.length - 1];
|
|
16
|
-
const processed = current.processed;
|
|
17
|
-
const node = current.node;
|
|
18
|
-
if (!processed) {
|
|
19
|
-
if (visited[node]) {
|
|
20
|
-
todo.pop();
|
|
21
|
-
continue;
|
|
22
|
-
}
|
|
23
|
-
else if (inCurrentPath[node]) {
|
|
24
|
-
if (circular) {
|
|
25
|
-
todo.pop();
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
currentPath.push(node);
|
|
29
|
-
throw new DepGraphCycleError(currentPath);
|
|
30
|
-
}
|
|
31
|
-
inCurrentPath[node] = true;
|
|
32
|
-
currentPath.push(node);
|
|
33
|
-
const nodeEdges = edges[node];
|
|
34
|
-
for (let i = nodeEdges.length - 1; i >= 0; i--) {
|
|
35
|
-
todo.push({ node: nodeEdges[i], processed: false });
|
|
36
|
-
}
|
|
37
|
-
current.processed = true;
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
todo.pop();
|
|
41
|
-
currentPath.pop();
|
|
42
|
-
inCurrentPath[node] = false;
|
|
43
|
-
visited[node] = true;
|
|
44
|
-
if (!leavesOnly || edges[node].length === 0) {
|
|
45
|
-
result.push(node);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
class DepGraph {
|
|
52
|
-
nodes = {};
|
|
53
|
-
outgoingEdges = {};
|
|
54
|
-
incomingEdges = {};
|
|
55
|
-
circular;
|
|
56
|
-
constructor(opts) {
|
|
57
|
-
this.circular = opts?.circular ?? false;
|
|
58
|
-
}
|
|
59
|
-
size() {
|
|
60
|
-
return Object.keys(this.nodes).length;
|
|
61
|
-
}
|
|
62
|
-
addNode(name, data) {
|
|
63
|
-
if (!this.hasNode(name)) {
|
|
64
|
-
if (arguments.length === 2) {
|
|
65
|
-
this.nodes[name] = data;
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
this.nodes[name] = name;
|
|
69
|
-
}
|
|
70
|
-
this.outgoingEdges[name] = [];
|
|
71
|
-
this.incomingEdges[name] = [];
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
removeNode(name) {
|
|
75
|
-
if (this.hasNode(name)) {
|
|
76
|
-
delete this.nodes[name];
|
|
77
|
-
delete this.outgoingEdges[name];
|
|
78
|
-
delete this.incomingEdges[name];
|
|
79
|
-
[this.incomingEdges, this.outgoingEdges].forEach(edgeList => {
|
|
80
|
-
Object.keys(edgeList).forEach(key => {
|
|
81
|
-
const idx = edgeList[key].indexOf(name);
|
|
82
|
-
if (idx >= 0) {
|
|
83
|
-
edgeList[key].splice(idx, 1);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
hasNode(name) {
|
|
90
|
-
return this.nodes.hasOwnProperty(name);
|
|
91
|
-
}
|
|
92
|
-
getNodeData(name) {
|
|
93
|
-
if (this.hasNode(name)) {
|
|
94
|
-
return this.nodes[name];
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
throw new Error('Node does not exist: ' + name);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
setNodeData(name, data) {
|
|
101
|
-
if (this.hasNode(name)) {
|
|
102
|
-
this.nodes[name] = data;
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
throw new Error('Node does not exist: ' + name);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
addDependency(from, to) {
|
|
109
|
-
if (!this.hasNode(from)) {
|
|
110
|
-
throw new Error('Node does not exist: ' + from);
|
|
111
|
-
}
|
|
112
|
-
if (!this.hasNode(to)) {
|
|
113
|
-
throw new Error('Node does not exist: ' + to);
|
|
114
|
-
}
|
|
115
|
-
if (this.outgoingEdges[from].indexOf(to) === -1) {
|
|
116
|
-
this.outgoingEdges[from].push(to);
|
|
117
|
-
}
|
|
118
|
-
if (this.incomingEdges[to].indexOf(from) === -1) {
|
|
119
|
-
this.incomingEdges[to].push(from);
|
|
120
|
-
}
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
removeDependency(from, to) {
|
|
124
|
-
let idx;
|
|
125
|
-
if (this.hasNode(from)) {
|
|
126
|
-
idx = this.outgoingEdges[from].indexOf(to);
|
|
127
|
-
if (idx >= 0) {
|
|
128
|
-
this.outgoingEdges[from].splice(idx, 1);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (this.hasNode(to)) {
|
|
132
|
-
idx = this.incomingEdges[to].indexOf(from);
|
|
133
|
-
if (idx >= 0) {
|
|
134
|
-
this.incomingEdges[to].splice(idx, 1);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
directDependenciesOf(name) {
|
|
139
|
-
if (this.hasNode(name)) {
|
|
140
|
-
return this.outgoingEdges[name].slice(0);
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
throw new Error('Node does not exist: ' + name);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
directDependantsOf(name) {
|
|
147
|
-
if (this.hasNode(name)) {
|
|
148
|
-
return this.incomingEdges[name].slice(0);
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
throw new Error('Node does not exist: ' + name);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
dependenciesOf(name, leavesOnly) {
|
|
155
|
-
if (this.hasNode(name)) {
|
|
156
|
-
const result = [];
|
|
157
|
-
const DFS = createDFS(this.outgoingEdges, leavesOnly, result, this.circular);
|
|
158
|
-
DFS(name);
|
|
159
|
-
const idx = result.indexOf(name);
|
|
160
|
-
if (idx >= 0) {
|
|
161
|
-
result.splice(idx, 1);
|
|
162
|
-
}
|
|
163
|
-
return result;
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
throw new Error('Node does not exist: ' + name);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
dependantsOf(name, leavesOnly) {
|
|
170
|
-
if (this.hasNode(name)) {
|
|
171
|
-
const result = [];
|
|
172
|
-
const DFS = createDFS(this.incomingEdges, leavesOnly, result, this.circular);
|
|
173
|
-
DFS(name);
|
|
174
|
-
const idx = result.indexOf(name);
|
|
175
|
-
if (idx >= 0) {
|
|
176
|
-
result.splice(idx, 1);
|
|
177
|
-
}
|
|
178
|
-
return result;
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
throw new Error('Node does not exist: ' + name);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
overallOrder(leavesOnly) {
|
|
185
|
-
const result = [];
|
|
186
|
-
const keys = Object.keys(this.nodes);
|
|
187
|
-
if (keys.length === 0) {
|
|
188
|
-
return result;
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
if (!this.circular) {
|
|
192
|
-
const CycleDFS = createDFS(this.outgoingEdges, false, [], this.circular);
|
|
193
|
-
keys.forEach(function (n) {
|
|
194
|
-
CycleDFS(n);
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
const DFS = createDFS(this.outgoingEdges, leavesOnly, result, this.circular);
|
|
198
|
-
keys
|
|
199
|
-
.filter(node => this.incomingEdges[node].length === 0)
|
|
200
|
-
.forEach(n => {
|
|
201
|
-
DFS(n);
|
|
202
|
-
});
|
|
203
|
-
if (this.circular) {
|
|
204
|
-
keys
|
|
205
|
-
.filter(node => result.indexOf(node) === -1)
|
|
206
|
-
.forEach(function (n) {
|
|
207
|
-
DFS(n);
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
return result;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
entryNodes() {
|
|
214
|
-
return Object.keys(this.nodes).filter(node => this.incomingEdges[node].length === 0);
|
|
215
|
-
}
|
|
216
|
-
directDependentsOf = this.directDependantsOf;
|
|
217
|
-
dependentsOf = this.dependantsOf;
|
|
218
|
-
}
|
|
219
|
-
exports.DepGraph = DepGraph;
|
|
220
|
-
class DepGraphCycleError extends Error {
|
|
221
|
-
cyclePath;
|
|
222
|
-
constructor(cyclePath) {
|
|
223
|
-
super('Dependency Cycle Found: ' + cyclePath.join(' -> '));
|
|
224
|
-
this.cyclePath = cyclePath;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
exports.DepGraphCycleError = DepGraphCycleError;
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
function createDFS(edges, leavesOnly, result, circular) {
|
|
2
|
-
const visited = {};
|
|
3
|
-
return function (start) {
|
|
4
|
-
if (visited[start]) {
|
|
5
|
-
return;
|
|
6
|
-
}
|
|
7
|
-
const inCurrentPath = {};
|
|
8
|
-
const currentPath = [];
|
|
9
|
-
const todo = [];
|
|
10
|
-
todo.push({ node: start, processed: false });
|
|
11
|
-
while (todo.length > 0) {
|
|
12
|
-
const current = todo[todo.length - 1];
|
|
13
|
-
const processed = current.processed;
|
|
14
|
-
const node = current.node;
|
|
15
|
-
if (!processed) {
|
|
16
|
-
if (visited[node]) {
|
|
17
|
-
todo.pop();
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
else if (inCurrentPath[node]) {
|
|
21
|
-
if (circular) {
|
|
22
|
-
todo.pop();
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
currentPath.push(node);
|
|
26
|
-
throw new DepGraphCycleError(currentPath);
|
|
27
|
-
}
|
|
28
|
-
inCurrentPath[node] = true;
|
|
29
|
-
currentPath.push(node);
|
|
30
|
-
const nodeEdges = edges[node];
|
|
31
|
-
for (let i = nodeEdges.length - 1; i >= 0; i--) {
|
|
32
|
-
todo.push({ node: nodeEdges[i], processed: false });
|
|
33
|
-
}
|
|
34
|
-
current.processed = true;
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
todo.pop();
|
|
38
|
-
currentPath.pop();
|
|
39
|
-
inCurrentPath[node] = false;
|
|
40
|
-
visited[node] = true;
|
|
41
|
-
if (!leavesOnly || edges[node].length === 0) {
|
|
42
|
-
result.push(node);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
export class DepGraph {
|
|
49
|
-
nodes = {};
|
|
50
|
-
outgoingEdges = {};
|
|
51
|
-
incomingEdges = {};
|
|
52
|
-
circular;
|
|
53
|
-
constructor(opts) {
|
|
54
|
-
this.circular = opts?.circular ?? false;
|
|
55
|
-
}
|
|
56
|
-
size() {
|
|
57
|
-
return Object.keys(this.nodes).length;
|
|
58
|
-
}
|
|
59
|
-
addNode(name, data) {
|
|
60
|
-
if (!this.hasNode(name)) {
|
|
61
|
-
if (arguments.length === 2) {
|
|
62
|
-
this.nodes[name] = data;
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
this.nodes[name] = name;
|
|
66
|
-
}
|
|
67
|
-
this.outgoingEdges[name] = [];
|
|
68
|
-
this.incomingEdges[name] = [];
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
removeNode(name) {
|
|
72
|
-
if (this.hasNode(name)) {
|
|
73
|
-
delete this.nodes[name];
|
|
74
|
-
delete this.outgoingEdges[name];
|
|
75
|
-
delete this.incomingEdges[name];
|
|
76
|
-
[this.incomingEdges, this.outgoingEdges].forEach(edgeList => {
|
|
77
|
-
Object.keys(edgeList).forEach(key => {
|
|
78
|
-
const idx = edgeList[key].indexOf(name);
|
|
79
|
-
if (idx >= 0) {
|
|
80
|
-
edgeList[key].splice(idx, 1);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
hasNode(name) {
|
|
87
|
-
return this.nodes.hasOwnProperty(name);
|
|
88
|
-
}
|
|
89
|
-
getNodeData(name) {
|
|
90
|
-
if (this.hasNode(name)) {
|
|
91
|
-
return this.nodes[name];
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
throw new Error('Node does not exist: ' + name);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
setNodeData(name, data) {
|
|
98
|
-
if (this.hasNode(name)) {
|
|
99
|
-
this.nodes[name] = data;
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
throw new Error('Node does not exist: ' + name);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
addDependency(from, to) {
|
|
106
|
-
if (!this.hasNode(from)) {
|
|
107
|
-
throw new Error('Node does not exist: ' + from);
|
|
108
|
-
}
|
|
109
|
-
if (!this.hasNode(to)) {
|
|
110
|
-
throw new Error('Node does not exist: ' + to);
|
|
111
|
-
}
|
|
112
|
-
if (this.outgoingEdges[from].indexOf(to) === -1) {
|
|
113
|
-
this.outgoingEdges[from].push(to);
|
|
114
|
-
}
|
|
115
|
-
if (this.incomingEdges[to].indexOf(from) === -1) {
|
|
116
|
-
this.incomingEdges[to].push(from);
|
|
117
|
-
}
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
removeDependency(from, to) {
|
|
121
|
-
let idx;
|
|
122
|
-
if (this.hasNode(from)) {
|
|
123
|
-
idx = this.outgoingEdges[from].indexOf(to);
|
|
124
|
-
if (idx >= 0) {
|
|
125
|
-
this.outgoingEdges[from].splice(idx, 1);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
if (this.hasNode(to)) {
|
|
129
|
-
idx = this.incomingEdges[to].indexOf(from);
|
|
130
|
-
if (idx >= 0) {
|
|
131
|
-
this.incomingEdges[to].splice(idx, 1);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
directDependenciesOf(name) {
|
|
136
|
-
if (this.hasNode(name)) {
|
|
137
|
-
return this.outgoingEdges[name].slice(0);
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
throw new Error('Node does not exist: ' + name);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
directDependantsOf(name) {
|
|
144
|
-
if (this.hasNode(name)) {
|
|
145
|
-
return this.incomingEdges[name].slice(0);
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
throw new Error('Node does not exist: ' + name);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
dependenciesOf(name, leavesOnly) {
|
|
152
|
-
if (this.hasNode(name)) {
|
|
153
|
-
const result = [];
|
|
154
|
-
const DFS = createDFS(this.outgoingEdges, leavesOnly, result, this.circular);
|
|
155
|
-
DFS(name);
|
|
156
|
-
const idx = result.indexOf(name);
|
|
157
|
-
if (idx >= 0) {
|
|
158
|
-
result.splice(idx, 1);
|
|
159
|
-
}
|
|
160
|
-
return result;
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
throw new Error('Node does not exist: ' + name);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
dependantsOf(name, leavesOnly) {
|
|
167
|
-
if (this.hasNode(name)) {
|
|
168
|
-
const result = [];
|
|
169
|
-
const DFS = createDFS(this.incomingEdges, leavesOnly, result, this.circular);
|
|
170
|
-
DFS(name);
|
|
171
|
-
const idx = result.indexOf(name);
|
|
172
|
-
if (idx >= 0) {
|
|
173
|
-
result.splice(idx, 1);
|
|
174
|
-
}
|
|
175
|
-
return result;
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
throw new Error('Node does not exist: ' + name);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
overallOrder(leavesOnly) {
|
|
182
|
-
const result = [];
|
|
183
|
-
const keys = Object.keys(this.nodes);
|
|
184
|
-
if (keys.length === 0) {
|
|
185
|
-
return result;
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
if (!this.circular) {
|
|
189
|
-
const CycleDFS = createDFS(this.outgoingEdges, false, [], this.circular);
|
|
190
|
-
keys.forEach(function (n) {
|
|
191
|
-
CycleDFS(n);
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
const DFS = createDFS(this.outgoingEdges, leavesOnly, result, this.circular);
|
|
195
|
-
keys
|
|
196
|
-
.filter(node => this.incomingEdges[node].length === 0)
|
|
197
|
-
.forEach(n => {
|
|
198
|
-
DFS(n);
|
|
199
|
-
});
|
|
200
|
-
if (this.circular) {
|
|
201
|
-
keys
|
|
202
|
-
.filter(node => result.indexOf(node) === -1)
|
|
203
|
-
.forEach(function (n) {
|
|
204
|
-
DFS(n);
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
return result;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
entryNodes() {
|
|
211
|
-
return Object.keys(this.nodes).filter(node => this.incomingEdges[node].length === 0);
|
|
212
|
-
}
|
|
213
|
-
directDependentsOf = this.directDependantsOf;
|
|
214
|
-
dependentsOf = this.dependantsOf;
|
|
215
|
-
}
|
|
216
|
-
export class DepGraphCycleError extends Error {
|
|
217
|
-
cyclePath;
|
|
218
|
-
constructor(cyclePath) {
|
|
219
|
-
super('Dependency Cycle Found: ' + cyclePath.join(' -> '));
|
|
220
|
-
this.cyclePath = cyclePath;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export interface Options {
|
|
2
|
-
circular?: boolean;
|
|
3
|
-
}
|
|
4
|
-
export declare class DepGraph<T> {
|
|
5
|
-
private nodes;
|
|
6
|
-
private outgoingEdges;
|
|
7
|
-
private incomingEdges;
|
|
8
|
-
private circular;
|
|
9
|
-
constructor(opts?: Options);
|
|
10
|
-
size(): number;
|
|
11
|
-
addNode(name: string, data?: T): void;
|
|
12
|
-
removeNode(name: string): void;
|
|
13
|
-
hasNode(name: string): boolean;
|
|
14
|
-
getNodeData(name: string): string | T | undefined;
|
|
15
|
-
setNodeData(name: string, data?: T): void;
|
|
16
|
-
addDependency(from: string, to: string): boolean;
|
|
17
|
-
removeDependency(from: string, to: string): void;
|
|
18
|
-
directDependenciesOf(name: string): string[];
|
|
19
|
-
directDependantsOf(name: string): string[];
|
|
20
|
-
dependenciesOf(name: string, leavesOnly?: boolean): string[];
|
|
21
|
-
dependantsOf(name: string, leavesOnly?: boolean): string[];
|
|
22
|
-
overallOrder(leavesOnly?: boolean): string[];
|
|
23
|
-
entryNodes(): string[];
|
|
24
|
-
directDependentsOf: (name: string) => string[];
|
|
25
|
-
dependentsOf: (name: string, leavesOnly?: boolean) => string[];
|
|
26
|
-
}
|
|
27
|
-
export declare class DepGraphCycleError extends Error {
|
|
28
|
-
cyclePath: string[];
|
|
29
|
-
constructor(cyclePath: string[]);
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=dependency-graph.d.ts.map
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export interface Options {
|
|
2
|
-
circular?: boolean;
|
|
3
|
-
}
|
|
4
|
-
export declare class DepGraph<T> {
|
|
5
|
-
private nodes;
|
|
6
|
-
private outgoingEdges;
|
|
7
|
-
private incomingEdges;
|
|
8
|
-
private circular;
|
|
9
|
-
constructor(opts?: Options);
|
|
10
|
-
size(): number;
|
|
11
|
-
addNode(name: string, data?: T): void;
|
|
12
|
-
removeNode(name: string): void;
|
|
13
|
-
hasNode(name: string): boolean;
|
|
14
|
-
getNodeData(name: string): string | T | undefined;
|
|
15
|
-
setNodeData(name: string, data?: T): void;
|
|
16
|
-
addDependency(from: string, to: string): boolean;
|
|
17
|
-
removeDependency(from: string, to: string): void;
|
|
18
|
-
directDependenciesOf(name: string): string[];
|
|
19
|
-
directDependantsOf(name: string): string[];
|
|
20
|
-
dependenciesOf(name: string, leavesOnly?: boolean): string[];
|
|
21
|
-
dependantsOf(name: string, leavesOnly?: boolean): string[];
|
|
22
|
-
overallOrder(leavesOnly?: boolean): string[];
|
|
23
|
-
entryNodes(): string[];
|
|
24
|
-
directDependentsOf: (name: string) => string[];
|
|
25
|
-
dependentsOf: (name: string, leavesOnly?: boolean) => string[];
|
|
26
|
-
}
|
|
27
|
-
export declare class DepGraphCycleError extends Error {
|
|
28
|
-
cyclePath: string[];
|
|
29
|
-
constructor(cyclePath: string[]);
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=dependency-graph.d.ts.map
|