pkgviz 0.7.2 → 0.7.3

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.
Files changed (90) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +1 -1
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/cache/webpack/client-production/7.pack +0 -0
  5. package/.next/cache/webpack/client-production/8.pack +0 -0
  6. package/.next/cache/webpack/client-production/index.pack +0 -0
  7. package/.next/cache/webpack/client-production/index.pack.old +0 -0
  8. package/.next/cache/webpack/server-production/11.pack +0 -0
  9. package/.next/cache/webpack/server-production/12.pack +0 -0
  10. package/.next/cache/webpack/server-production/13.pack +0 -0
  11. package/.next/cache/webpack/server-production/index.pack +0 -0
  12. package/.next/cache/webpack/server-production/index.pack.old +0 -0
  13. package/.next/server/app/_not-found.html +1 -1
  14. package/.next/server/app/_not-found.rsc +1 -1
  15. package/.next/server/app/favicon.ico/route.js +1 -1
  16. package/.next/server/app/index.html +1 -1
  17. package/.next/server/app/index.rsc +1 -1
  18. package/.next/server/app-paths-manifest.json +1 -1
  19. package/.next/server/chunks/610.js +1 -1
  20. package/.next/server/pages/404.html +1 -1
  21. package/.next/server/pages/500.html +1 -1
  22. package/.next/trace +2 -2
  23. package/package.json +2 -3
  24. package/src/app/actions/graph.actions.ts +25 -0
  25. package/src/app/favicon.ico +0 -0
  26. package/src/app/globals.css +77 -0
  27. package/src/app/layout.tsx +30 -0
  28. package/src/app/page.tsx +5 -0
  29. package/src/app/utils/buildGraph.ts +119 -0
  30. package/src/app/utils/getParsedFileStructure.ts +225 -0
  31. package/src/app/utils/markCyclicPackages.ts +275 -0
  32. package/src/app/utils/parser/cpp/extractCppPackageFromImport.ts +18 -0
  33. package/src/app/utils/parser/cpp/parseCppFile.ts +150 -0
  34. package/src/app/utils/parser/delphi/extractPackageFromImport.ts +21 -0
  35. package/src/app/utils/parser/delphi/parseFile.ts +179 -0
  36. package/src/app/utils/parser/java/extractJavaPackageFromImport.ts +39 -0
  37. package/src/app/utils/parser/java/findEntryPoint.ts +24 -0
  38. package/src/app/utils/parser/java/getIntrinsicPackagesRecursive.ts +33 -0
  39. package/src/app/utils/parser/java/parseJavaFile.ts +114 -0
  40. package/src/app/utils/parser/kotlin/extractPackageFromImport.ts +19 -0
  41. package/src/app/utils/parser/kotlin/parseFile.ts +147 -0
  42. package/src/app/utils/parser/python/extractPythonPackageFromImport.ts +18 -0
  43. package/src/app/utils/parser/python/parseFile.ts +171 -0
  44. package/src/app/utils/parser/typescript/extractTypeScriptPackageFromImport.ts +18 -0
  45. package/src/app/utils/parser/typescript/parseFile.ts +130 -0
  46. package/src/components/Breadcrumb.tsx +34 -0
  47. package/src/components/Cytoscape.tsx +23 -0
  48. package/src/components/Header.tsx +28 -0
  49. package/src/components/Loader.tsx +10 -0
  50. package/src/components/Setting.tsx +17 -0
  51. package/src/components/Settings.tsx +189 -0
  52. package/src/components/Switch.tsx +31 -0
  53. package/src/components/ThemeToggle.tsx +25 -0
  54. package/src/components/ZoomInput.tsx +94 -0
  55. package/src/components/useCytoscape.ts +343 -0
  56. package/src/contexts/SettingsContext.tsx +88 -0
  57. package/src/i18n/en.ts +27 -0
  58. package/src/i18n/i18n.ts +12 -0
  59. package/src/layouts/breadthfirst/layout.ts +30 -0
  60. package/src/layouts/breadthfirst/style.ts +8 -0
  61. package/src/layouts/circle/layout.ts +11 -0
  62. package/src/layouts/circle/style.ts +18 -0
  63. package/src/layouts/concentric/layout.ts +10 -0
  64. package/src/layouts/concentric/style.ts +16 -0
  65. package/src/layouts/constants.ts +17 -0
  66. package/src/layouts/elk/layout.ts +55 -0
  67. package/src/layouts/elk/style.ts +14 -0
  68. package/src/layouts/getLayoutStyle.ts +19 -0
  69. package/src/layouts/getWeightBuckets.ts +58 -0
  70. package/src/layouts/grid/layout.ts +11 -0
  71. package/src/layouts/grid/style.ts +20 -0
  72. package/src/layouts/index.ts +14 -0
  73. package/src/layouts/style.ts +191 -0
  74. package/src/screens/home/Home.tsx +48 -0
  75. package/src/shared/constants/index.ts +7 -0
  76. package/src/shared/types/index.ts +68 -0
  77. package/src/shared/utils/detectLanguage.ts +255 -0
  78. package/src/shared/utils/getJsonAsync.ts +13 -0
  79. package/src/shared/utils/getProjectName.ts +3 -0
  80. package/src/shared/utils/parseEnv.ts +91 -0
  81. package/src/shared/utils/parseProjectPath.ts +8 -0
  82. package/src/store/useLocalStorage.ts +29 -0
  83. package/src/utils/filter/filterByPackagePrefix.ts +23 -0
  84. package/src/utils/filter/filterEmptyPackages.ts +36 -0
  85. package/src/utils/filter/filterSubPackagesFromDepth.ts +170 -0
  86. package/src/utils/filter/filterVendorPackages.ts +17 -0
  87. package/src/utils/filter/toggleCompoundNodes.ts +40 -0
  88. package/src/utils/hasChildren.ts +7 -0
  89. /package/.next/static/{VVBfFRai9p1x3oVXujjYO → cGbLRcmdy7k8HGus5vhzm}/_buildManifest.js +0 -0
  90. /package/.next/static/{VVBfFRai9p1x3oVXujjYO → cGbLRcmdy7k8HGus5vhzm}/_ssgManifest.js +0 -0
@@ -0,0 +1,55 @@
1
+ import cytoscape from 'cytoscape';
2
+ import elk from 'cytoscape-elk';
3
+ cytoscape.use(elk as cytoscape.Ext);
4
+
5
+ type ElkLayoutOptions = cytoscape.BaseLayoutOptions &
6
+ cytoscape.AnimatedLayoutOptions & {
7
+ readonly name: 'elk';
8
+ readonly animate: boolean;
9
+ readonly animateFilter: (node: cytoscape.NodeSingular, i: number) => boolean;
10
+ readonly animationDuration: number;
11
+ readonly animationEasing: string | undefined;
12
+ readonly fit: boolean;
13
+ readonly nodeDimensionsIncludeLabels: boolean;
14
+ readonly nodeLayoutOptions?: (node: cytoscape.NodeSingular) => Record<string, unknown> | void;
15
+ readonly elk: Record<string, unknown>;
16
+ readonly priority: (edge: cytoscape.EdgeSingular) => number | null;
17
+ readonly padding?: number;
18
+ };
19
+
20
+ /***
21
+ * @url https://eclipse.dev/elk/reference/algorithms/org-eclipse-elk-layered.html
22
+ */
23
+ export const layout: ElkLayoutOptions = {
24
+ name: 'elk',
25
+
26
+ /***
27
+ * @url http://www.eclipse.org/elk/reference.html
28
+ * @info Drop prefix from options name, e.g. org.eclipse.elk.direction becomes elk.direction
29
+ * @info Enums use the name of the enum as string Direction.DOWN becomes elk.direction: 'DOWN'
30
+ */
31
+ elk: {
32
+ algorithm: 'layered',
33
+ 'elk.direction': 'DOWN',
34
+ 'elk.hierarchyHandling': 'INCLUDE_CHILDREN',
35
+ },
36
+ animate: true, // Whether to transition the node positions
37
+ animateFilter: function (/* node, i */) {
38
+ return true;
39
+ }, // Whether to animate specific nodes when animation is on; non-animated nodes immediately go to their final positions
40
+ animationDuration: 500, // Duration of animation in ms if enabled
41
+ animationEasing: undefined, // Easing of animation if enabled
42
+
43
+ fit: true, // Whether to fit
44
+ nodeDimensionsIncludeLabels: false, // Boolean which changes whether label dimensions are included when calculating node dimensions
45
+ nodeLayoutOptions: undefined, // Per-node options function
46
+ // padding: 20, // Padding on fit
47
+ transform: function (_node, pos) {
48
+ return pos;
49
+ }, // A function that applies a transform to the final node position
50
+ ready: undefined, // Callback on layoutready
51
+ stop: undefined, // Callback on layoutstop
52
+ priority: function (/* edge */) {
53
+ return null;
54
+ }, // Edges with a non-nil value are skipped when geedy edge cycle breaking is enabled
55
+ };
@@ -0,0 +1,14 @@
1
+ import type { StylesheetJson } from 'cytoscape';
2
+
3
+ export function getStyle() {
4
+ const style: StylesheetJson = [
5
+ {
6
+ selector: 'node',
7
+ style: {
8
+ 'edge-distances': 'intersection', // 'node-position',
9
+ },
10
+ },
11
+ ];
12
+
13
+ return style;
14
+ }
@@ -0,0 +1,19 @@
1
+ import type { LayoutOptions } from 'cytoscape';
2
+
3
+ import { getStyle as getBreadthfirstStyle } from '@/layouts/breadthfirst/style';
4
+ import { getStyle as getCircleStyle } from '@/layouts/circle/style';
5
+ import { getStyle as getConcentricStyle } from '@/layouts/concentric/style';
6
+ import { getStyle as getGridStyle } from '@/layouts/grid/style';
7
+
8
+ export function getLayoutStyle(cytoscapeLayout: LayoutOptions['name']) {
9
+ switch (cytoscapeLayout) {
10
+ case 'breadthfirst':
11
+ return getBreadthfirstStyle();
12
+ case 'circle':
13
+ return getCircleStyle();
14
+ case 'concentric':
15
+ return getConcentricStyle();
16
+ case 'grid':
17
+ return getGridStyle();
18
+ }
19
+ }
@@ -0,0 +1,58 @@
1
+ import type { ElementsDefinition } from 'cytoscape';
2
+
3
+ export function getWeightBuckets(
4
+ categoryCount: number,
5
+ algorithm: 'linear' | 'log' | 'quantile' = 'linear',
6
+ filteredElements: ElementsDefinition
7
+ ) {
8
+ if (!filteredElements) return { thresholds: [], counts: [] };
9
+
10
+ const weights = filteredElements.edges.map(e => Number(e.data.weight));
11
+ const max = getMaxEdgeWeight(filteredElements);
12
+
13
+ const thresholds: number[] = [];
14
+ const counts = new Array(categoryCount).fill(0);
15
+
16
+ if (algorithm === 'linear') {
17
+ for (let i = 1; i < categoryCount; i++) {
18
+ thresholds.push((i * max) / categoryCount);
19
+ }
20
+ thresholds.push(max);
21
+ } else if (algorithm === 'log') {
22
+ const logMax = Math.log(max);
23
+ for (let i = 1; i < categoryCount; i++) {
24
+ thresholds.push(Math.exp((i * logMax) / categoryCount));
25
+ }
26
+ thresholds.push(max);
27
+ } else if (algorithm === 'quantile') {
28
+ const sorted = [...weights].sort((a, b) => a - b);
29
+ for (let i = 1; i < categoryCount; i++) {
30
+ const qIndex = Math.floor((i * sorted.length) / categoryCount);
31
+ thresholds.push(sorted[qIndex]);
32
+ }
33
+ thresholds.push(max);
34
+ }
35
+
36
+ // Count how many weights fall into each bucket
37
+ weights.forEach(w => {
38
+ for (let i = 0; i < thresholds.length; i++) {
39
+ if (w <= thresholds[i]) {
40
+ counts[i]++;
41
+ break;
42
+ }
43
+ }
44
+ });
45
+
46
+ return {
47
+ thresholds: thresholds.map(Math.round),
48
+ counts,
49
+ };
50
+ }
51
+
52
+ export function getMaxEdgeWeight(filteredElements: ElementsDefinition) {
53
+ return (
54
+ filteredElements?.edges.reduce((max, edge) => {
55
+ return edge.data.weight > max ? edge.data.weight : max;
56
+ }, 0) ?? 0
57
+ );
58
+ }
@@ -0,0 +1,11 @@
1
+ import type { GridLayoutOptions, NodeSingular } from 'cytoscape';
2
+
3
+ export const layout: GridLayoutOptions = {
4
+ name: 'grid',
5
+ // fit: true,
6
+ // padding: 30, // Add some space around the graph
7
+ avoidOverlap: true,
8
+
9
+ // Sort nodes alphabetically by their ID
10
+ sort: (a: NodeSingular, b: NodeSingular) => a.data('id').localeCompare(b.data('id')),
11
+ };
@@ -0,0 +1,20 @@
1
+ import type { StylesheetJson } from 'cytoscape';
2
+
3
+ export function getStyle() {
4
+ const style: StylesheetJson = [
5
+ {
6
+ selector: 'node',
7
+ style: {
8
+ shape: 'rectangle',
9
+ },
10
+ },
11
+ {
12
+ selector: 'edge',
13
+ style: {
14
+ 'text-margin-x': 0, // Reset text margins for straight lines
15
+ 'text-margin-y': 0,
16
+ },
17
+ },
18
+ ];
19
+ return style;
20
+ }
@@ -0,0 +1,14 @@
1
+ export { layout as breadthfirstLayout } from '@/layouts/breadthfirst/layout';
2
+ export { getStyle as getBreadthfirstStyle } from '@/layouts/breadthfirst/style';
3
+
4
+ export { layout as circleLayout } from '@/layouts/circle/layout';
5
+ export { getStyle as getCircleStyle } from '@/layouts/circle/style';
6
+
7
+ export { layout as concentricLayout } from '@/layouts/concentric/layout';
8
+ export { getStyle as getConcentricStyle } from '@/layouts/concentric/style';
9
+
10
+ export { layout as elkLayout } from '@/layouts/elk/layout';
11
+ export { getStyle as getElkStyle } from '@/layouts/elk/style';
12
+
13
+ export { layout as gridLayout } from '@/layouts/grid/layout';
14
+ export { getStyle as getGridStyle } from '@/layouts/grid/style';
@@ -0,0 +1,191 @@
1
+ import type { ElementsDefinition, NodeSingular, StylesheetJson } from 'cytoscape';
2
+
3
+ import { getWeightBuckets } from '@/layouts/getWeightBuckets';
4
+
5
+ export type ThemeKey = 'dark' | 'light';
6
+
7
+ const palette = {
8
+ light: {
9
+ canvasBg: '#ffffff',
10
+ // edge: '#9E9E9E',
11
+ edge: '#000',
12
+ weightXs: '#000',
13
+ weightMd: '#000',
14
+ weightXl: '#000',
15
+
16
+ nodeBg: '#E8F1FF',
17
+ nodeBorder: '#0B5FFF',
18
+ nodeBorderVendor: '#E2D5FF',
19
+ nodeBgVendor: '#D1C4FF',
20
+ nodeText: '#0B5FFF',
21
+
22
+ selectedFill: '#0B5FFF',
23
+ selectedFillVendor: '#a025aa',
24
+ selectedRing: '#0B5FFF',
25
+ selectedText: '#FFF',
26
+ },
27
+ dark: {
28
+ canvasBg: '#171717',
29
+ edge: '#707070',
30
+ weightXs: '#5A5A5A',
31
+ weightMd: '#8A8A8A',
32
+ weightXl: '#C0C0C0',
33
+
34
+ nodeBg: '#1E2533',
35
+ nodeBgVendor: '#241431',
36
+ nodeBorder: '#2A3A4A',
37
+ nodeBorderVendor: '#351542',
38
+ nodeText: '#E8F0FF',
39
+
40
+ selectedFill: '#2E6FFF',
41
+ selectedFillVendor: '#4E25AA',
42
+ selectedRing: '#BBD3FF',
43
+ selectedText: '#FFFFFF',
44
+ },
45
+ } as const;
46
+
47
+ export const getCanvasBg = (theme: ThemeKey) => palette[theme].canvasBg;
48
+
49
+ export function getStyle(filteredElements: ElementsDefinition, theme: ThemeKey): StylesheetJson {
50
+ const colors = palette[theme];
51
+ const { thresholds } = getWeightBuckets(3, 'linear', filteredElements);
52
+
53
+ return [
54
+ {
55
+ selector: 'node',
56
+ style: {
57
+ shape: 'bottom-round-rectangle',
58
+ 'background-color': colors.nodeBg,
59
+ 'border-color': colors.nodeBorder,
60
+ color: colors.nodeText,
61
+ label: 'data(name)',
62
+ 'text-valign': 'center',
63
+ 'text-halign': 'center',
64
+ width: (node: NodeSingular) => {
65
+ return node.data('name').length * 7;
66
+ },
67
+ height: (node: NodeSingular) => {
68
+ return node.height() / 2 + 10;
69
+ },
70
+ padding: '8px 8px',
71
+ 'border-width': 1,
72
+ 'font-size': '14px',
73
+ 'overlay-opacity': 0, // avoid gray overlay
74
+ },
75
+ },
76
+ {
77
+ selector: 'node.isVendor',
78
+ style: {
79
+ 'background-color': colors.nodeBgVendor,
80
+ },
81
+ },
82
+ { selector: 'node.packageCycle', style: { 'border-color': '#d80303', 'border-width': 3 } },
83
+ { selector: 'node.isParent', style: { 'font-weight': 'bold' } },
84
+ {
85
+ selector: 'node:selected',
86
+ style: {
87
+ 'background-color': colors.selectedFill,
88
+ 'border-color': colors.selectedRing,
89
+ 'border-width': 3,
90
+ color: colors.selectedText,
91
+ 'background-opacity': 1,
92
+ opacity: 1,
93
+ 'overlay-opacity': 0,
94
+ },
95
+ },
96
+ {
97
+ selector: 'node.isVendor:selected',
98
+ style: { 'background-color': colors.selectedFillVendor },
99
+ },
100
+ {
101
+ selector: 'node:parent, node:parent:selected',
102
+ style: {
103
+ 'background-opacity': 0.3,
104
+ 'background-color': colors.selectedFill,
105
+ color: colors.nodeText,
106
+ 'border-width': 2,
107
+ 'border-color': colors.nodeBorder,
108
+ 'text-valign': 'top',
109
+ 'text-margin-y': -5,
110
+ padding: '10px',
111
+ 'padding-top': '20px',
112
+ 'text-halign': 'center',
113
+ 'font-size': 14,
114
+ 'font-weight': 'bold',
115
+ 'font-style': 'italic',
116
+ label: 'data(name)',
117
+ },
118
+ },
119
+ {
120
+ selector: 'node:parent.isVendor, node:parent.isVendor:selected',
121
+ style: {
122
+ 'background-color': colors.nodeBgVendor,
123
+ 'border-color': colors.nodeBorderVendor,
124
+ },
125
+ },
126
+ {
127
+ selector: 'edge',
128
+ style: {
129
+ 'arrow-scale': 1,
130
+ 'target-arrow-color': colors.edge,
131
+ 'target-arrow-shape': 'chevron',
132
+ 'target-arrow-fill': 'filled',
133
+ 'line-color': colors.edge,
134
+ 'curve-style': 'straight',
135
+ opacity: 1,
136
+ 'line-opacity': 1,
137
+ },
138
+ },
139
+ {
140
+ selector: 'edge.hushed',
141
+ style: {
142
+ opacity: 0.04,
143
+ },
144
+ },
145
+ {
146
+ selector: 'edge.highlight-outgoer, edge.highlight-incomer, edge.highlight-dependency',
147
+ style: {
148
+ opacity: 1,
149
+ 'line-opacity': 1,
150
+ width: 4,
151
+ 'line-color': colors.weightXl,
152
+ 'target-arrow-color': colors.weightXl,
153
+ 'source-arrow-color': colors.weightXl,
154
+ },
155
+ },
156
+ { selector: 'edge[weight <= 1]', style: { label: '' } },
157
+ {
158
+ selector: `edge[weight > 1][weight <= ${thresholds[0]}]`,
159
+ style: {
160
+ width: 1,
161
+ 'line-color': colors.weightXs,
162
+ 'target-arrow-color': colors.weightXs,
163
+ },
164
+ },
165
+ {
166
+ selector: `edge[weight > ${thresholds[0]}][weight <= ${thresholds[1]}]`,
167
+ style: {
168
+ width: 4,
169
+ 'arrow-scale': 2,
170
+ 'line-color': colors.weightMd,
171
+ 'target-arrow-color': colors.weightMd,
172
+ },
173
+ },
174
+ {
175
+ selector: `edge[weight > ${thresholds[1]}]`,
176
+ style: {
177
+ width: 8,
178
+ 'line-color': colors.weightXl,
179
+ 'target-arrow-color': colors.weightXl,
180
+ },
181
+ },
182
+ {
183
+ selector: 'edge.packageCycle',
184
+ style: { 'line-color': '#d80303', 'target-arrow-color': '#d80303' },
185
+ },
186
+ {
187
+ selector: 'edge.packageCycle',
188
+ style: { 'line-color': '#d80303', 'target-arrow-color': '#d80303' },
189
+ },
190
+ ];
191
+ }
@@ -0,0 +1,48 @@
1
+ 'use client';
2
+ import type { ElementsDefinition } from 'cytoscape';
3
+
4
+ import { useEffect, useState } from 'react';
5
+ import { getGraphAction } from '@/app/actions/graph.actions';
6
+ import Breadcrumb from '@/components/Breadcrumb';
7
+ import Header from '@/components/Header';
8
+ import Loader from '@/components/Loader';
9
+ import Settings from '@/components/Settings';
10
+ import { Cytoscape } from '@/components/Cytoscape';
11
+ import { SettingsProvider } from '@/contexts/SettingsContext';
12
+
13
+ export default function HomeScreen() {
14
+ const [currentPackage, setCurrentPackage] = useState<string>('');
15
+ const [packageGraph, setPackageGraph] = useState<ElementsDefinition | null>(null);
16
+
17
+ useEffect(() => {
18
+ if (!packageGraph) {
19
+ getGraphAction().then(setPackageGraph);
20
+ }
21
+ }, [packageGraph]);
22
+
23
+ return (
24
+ <>
25
+ <Header title="nav.packages">
26
+ <Breadcrumb
27
+ path={currentPackage.replace(/\./g, '/')}
28
+ onNavigate={(path: string) => setCurrentPackage(path.replace(/\//g, '.'))}
29
+ />
30
+ </Header>
31
+
32
+ <SettingsProvider>
33
+ <main data-testid="main" className="flex flex-1 flex-row dark:bg-[#171717]">
34
+ <Settings />
35
+ {packageGraph ? (
36
+ <Cytoscape
37
+ currentPackage={currentPackage}
38
+ setCurrentPackage={setCurrentPackage}
39
+ packageGraph={packageGraph}
40
+ />
41
+ ) : (
42
+ <Loader />
43
+ )}
44
+ </main>
45
+ </SettingsProvider>
46
+ </>
47
+ );
48
+ }
@@ -0,0 +1,7 @@
1
+ ////////////////////////////////////////////////////////////////////////////
2
+ // Shared Constants
3
+
4
+ /**
5
+ * Java source root directory
6
+ */
7
+ export const JAVA_ROOT = 'src/main/java';
@@ -0,0 +1,68 @@
1
+ ///////////////////////////////////////////////////////////////////////////
2
+ // Language Detection Types
3
+
4
+ /**
5
+ * List of supported coding languages
6
+ */
7
+ export enum Language {
8
+ Cpp = 'cpp',
9
+ Delphi = 'delphi',
10
+ JavaScript = 'javascript',
11
+ Kotlin = 'kotlin',
12
+ Python = 'python',
13
+ TypeScript = 'typescript',
14
+ Java = 'java',
15
+ Unknown = 'unknown',
16
+ }
17
+
18
+ /**
19
+ * Language Detection Result
20
+ */
21
+ export interface LanguageDetectionResult {
22
+ language: Language;
23
+ confidence: number;
24
+ indicators: string[];
25
+ }
26
+
27
+ //////////////////////////////////////////////////////////////////////////
28
+ // Parser Types
29
+
30
+ export interface ParsedFile {
31
+ readonly calls: MethodCall[];
32
+ readonly className: string;
33
+ readonly imports: ImportDefinition[];
34
+ readonly methods: MethodDefinition[];
35
+ readonly package: string;
36
+ readonly path: string; // Relative path from project root
37
+ }
38
+
39
+ export interface ParsedDirectory {
40
+ [k: string]: ParsedDirectory | ParsedFile;
41
+ }
42
+
43
+ /**
44
+ * Method Definition
45
+ */
46
+ export interface MethodDefinition {
47
+ readonly name: string;
48
+ readonly returnType: string;
49
+ readonly parameters: string[];
50
+ readonly visibility: 'public' | 'protected' | 'private' | 'default';
51
+ }
52
+
53
+ /**
54
+ * Method Call
55
+ */
56
+ export interface MethodCall {
57
+ readonly callee: string;
58
+ readonly method: string;
59
+ }
60
+
61
+ /**
62
+ * Import Definition
63
+ */
64
+ export interface ImportDefinition {
65
+ readonly name: string;
66
+ readonly pkg: string;
67
+ readonly isIntrinsic?: boolean;
68
+ }