pkgviz 0.7.7 → 0.8.1
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +2 -1
- package/.next/build-manifest.json +15 -24
- package/.next/fallback-build-manifest.json +15 -0
- package/.next/images-manifest.json +14 -3
- package/.next/next-minimal-server.js.nft.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +52 -16
- package/.next/required-server-files.js +349 -0
- package/.next/required-server-files.json +106 -75
- package/.next/routes-manifest.json +16 -6
- package/.next/server/app/_global-error/page/app-paths-manifest.json +3 -0
- package/.next/server/app/_global-error/page/build-manifest.json +20 -0
- package/.next/server/app/_global-error/page/next-font-manifest.json +6 -0
- package/.next/server/app/_global-error/page/server-reference-manifest.json +4 -0
- package/.next/server/app/_global-error/page.js +9 -0
- package/.next/server/app/_global-error/page.js.map +5 -0
- package/.next/server/app/_global-error/page.js.nft.json +1 -0
- package/.next/server/app/_global-error/page_client-reference-manifest.js +3 -0
- package/.next/server/app/_global-error.html +1 -0
- package/.next/server/app/_global-error.meta +22 -0
- package/.next/server/app/_global-error.rsc +15 -0
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +20 -0
- package/.next/server/app/_global-error.segments/_full.segment.rsc +15 -0
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
- package/.next/server/app/_not-found/page/app-paths-manifest.json +3 -0
- package/.next/server/app/_not-found/page/build-manifest.json +20 -0
- package/.next/server/app/_not-found/page/next-font-manifest.json +11 -0
- package/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/_not-found/page/server-reference-manifest.json +4 -0
- package/.next/server/app/_not-found/page.js +13 -2
- package/.next/server/app/_not-found/page.js.map +5 -0
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +3 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.meta +19 -0
- package/.next/server/app/_not-found.rsc +18 -19
- package/.next/server/app/_not-found.segments/_full.segment.rsc +18 -0
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +24 -0
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -0
- package/.next/server/app/favicon.ico/route/app-paths-manifest.json +3 -0
- package/.next/server/app/favicon.ico/route/build-manifest.json +12 -0
- package/.next/server/app/favicon.ico/route.js +6 -1
- package/.next/server/app/favicon.ico/route.js.map +5 -0
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/server/app/page/app-paths-manifest.json +3 -0
- package/.next/server/app/page/build-manifest.json +20 -0
- package/.next/server/app/page/next-font-manifest.json +11 -0
- package/.next/server/app/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/page/server-reference-manifest.json +93 -0
- package/.next/server/app/page.js +16 -13
- package/.next/server/app/page.js.map +5 -0
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +3 -1
- package/.next/server/app-paths-manifest.json +2 -1
- package/.next/server/chunks/[externals]__0l8ei7u._.js +3 -0
- package/.next/server/chunks/[externals]__0l8ei7u._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__1to-yfd._.js +160 -0
- package/.next/server/chunks/[root-of-the-server]__1to-yfd._.js.map +1 -0
- package/.next/server/chunks/[turbopack]_runtime.js +807 -0
- package/.next/server/chunks/[turbopack]_runtime.js.map +10 -0
- package/.next/server/chunks/_next-internal_server_app_favicon_ico_route_actions_0g2jjls.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_favicon_ico_route_actions_0g2jjls.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0agsrep._.js +28 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0agsrep._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0f_e7c8._.js +33 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0f_e7c8._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0yqn68e._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0yqn68e._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__112mz-6._.js +14 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__112mz-6._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__11_76b7._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__11_76b7._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__12ovu0c._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__12ovu0c._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__16pmw__._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__16pmw__._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1f2jx51._.js +33 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1f2jx51._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1rn09vt._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1rn09vt._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__20e4gkp._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__20e4gkp._.js.map +1 -0
- package/.next/server/chunks/ssr/[turbopack]_runtime.js +807 -0
- package/.next/server/chunks/ssr/[turbopack]_runtime.js.map +10 -0
- package/.next/server/chunks/ssr/_1acy_2s._.js +158 -0
- package/.next/server/chunks/ssr/_1acy_2s._.js.map +1 -0
- package/.next/server/chunks/ssr/_1rh2tf9._.js +367 -0
- package/.next/server/chunks/ssr/_1rh2tf9._.js.map +1 -0
- package/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0zi5s8-.js +3 -0
- package/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0zi5s8-.js.map +1 -0
- package/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0pt47yr.js +3 -0
- package/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0pt47yr.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_01xbj_9._.js +33 -0
- package/.next/server/chunks/ssr/node_modules_01xbj_9._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_1c5ky4f._.js +3 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_1c5ky4f._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_1n3w9lb._.js +6 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_1n3w9lb._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j3._.js +3 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j3._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9.js +3 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0q-w892.js +3 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0q-w892.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js +3 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js.map +1 -0
- package/.next/server/chunks/ssr/src_app_loading_tsx_01g_-m0._.js +3 -0
- package/.next/server/chunks/ssr/src_app_loading_tsx_01g_-m0._.js.map +1 -0
- package/.next/server/middleware-build-manifest.js +24 -1
- package/.next/server/middleware-manifest.json +2 -2
- package/.next/server/next-font-manifest.js +1 -1
- package/.next/server/next-font-manifest.json +15 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages-manifest.json +2 -4
- package/.next/server/prefetch-hints.json +25 -0
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +94 -1
- package/.next/static/chunks/0_j-_aavigxqr.js +345 -0
- package/.next/static/chunks/19mx3mg6lkumu.js +1 -0
- package/.next/static/chunks/1las_6j17xa9p.js +1 -0
- package/.next/static/chunks/1xk6snnh6e5_j.css +3 -0
- package/.next/static/chunks/2-rtuqsgzmno4.js +22 -0
- package/.next/static/chunks/27t_qfc-3_lzs.js +1 -0
- package/.next/static/chunks/310vm2bl3xxpt.js +31 -0
- package/.next/static/chunks/3fntmmi971322.js +1 -0
- package/.next/static/chunks/turbopack-1b6uko1cu_h42.js +1 -0
- package/.next/static/media/4fa387ec64143e14-s.2tuy5pz7dlieh.woff2 +0 -0
- package/.next/static/media/53b9e256198e5412-s.390ncx5urfkfu.woff2 +0 -0
- package/.next/static/media/5ce348bf30bf5439-s.31988l_ccedte.woff2 +0 -0
- package/.next/static/media/6306c77e7c8268e4-s.2dbetqa9o8jxf.woff2 +0 -0
- package/.next/static/media/7178b3e590c64307-s.21jp631_3pja2.woff2 +0 -0
- package/.next/static/media/797e433ab948586e-s.p.0r6juujl39pe6.woff2 +0 -0
- package/.next/static/media/7d817b4c03b0c5f1-s.1uyisp29ctx0d.woff2 +0 -0
- package/.next/static/media/8a480f0b521d4e75-s.1qq4vpdcun5oj.woff2 +0 -0
- package/.next/static/media/bbc41e54d2fcbd21-s.1rgnod-3esatf.woff2 +0 -0
- package/.next/static/media/caa3a2e1cccd8315-s.p.0wgildi0cnwt9.woff2 +0 -0
- package/.next/static/media/favicon.2246eezznj2ab.ico +0 -0
- package/.next/static/media/fef07dbb0973bf53-s.3p2_lha1f2xer.woff2 +0 -0
- package/.next/static/qznDSVYlkQxVdRx-TE_Wk/_buildManifest.js +11 -0
- package/.next/static/qznDSVYlkQxVdRx-TE_Wk/_clientMiddlewareManifest.js +1 -0
- package/README.md +176 -4
- package/bin/pkgviz.ts +57 -29
- package/package.json +57 -36
- package/src/app/actions/audit.actions.ts +7 -49
- package/src/app/globals.css +0 -2
- package/src/app/layout.tsx +3 -2
- package/src/app/loading.tsx +8 -0
- package/src/app/page.tsx +16 -2
- package/src/app/utils/buildGraph.ts +99 -100
- package/src/app/utils/getParsedFileStructure.ts +128 -54
- package/src/app/utils/inspectParserLanguageAsync.ts +39 -0
- package/src/app/utils/markCyclicPackages.ts +45 -185
- package/src/app/utils/parser/cpp/parseCppFile.ts +68 -86
- package/src/app/utils/parser/delphi/parseFile.ts +36 -120
- package/src/app/utils/parser/java/findEntryPoint.ts +2 -1
- package/src/app/utils/parser/java/parseJavaFile.ts +33 -45
- package/src/app/utils/parser/kotlin/parseFile.ts +34 -87
- package/src/app/utils/parser/python/parseFile.ts +30 -100
- package/src/app/utils/parser/typescript/parseFile.ts +17 -52
- package/src/app/utils/selectParserLanguage.ts +39 -0
- package/src/cli/formatAuditRuleFailures.ts +21 -0
- package/src/cli/runAuditAsync.ts +41 -0
- package/src/components/Breadcrumb.tsx +5 -4
- package/src/components/ExportPanel.tsx +53 -0
- package/src/components/Header.tsx +1 -0
- package/src/components/Loader.tsx +8 -2
- package/src/components/ProjectLoadError.tsx +15 -0
- package/src/components/SettingsPanel.tsx +184 -0
- package/src/components/Switch.tsx +9 -17
- package/src/components/ThemeToggle.tsx +2 -1
- package/src/components/ToggleSwitch.tsx +36 -0
- package/src/components/sidebar/Sidebar.tsx +14 -0
- package/src/components/sidebar/SidebarBadge.tsx +25 -0
- package/src/components/sidebar/SidebarRow.tsx +14 -0
- package/src/components/sidebar/SidebarSection.tsx +16 -0
- package/src/components/sidebar/SidebarTabs.tsx +58 -0
- package/src/contexts/SettingsContext.tsx +19 -20
- package/src/features/audit/adapters/inbound/react/AuditRuleList.tsx +76 -0
- package/src/features/audit/adapters/inbound/react/AuditRulePanel.tsx +30 -0
- package/src/features/audit/adapters/inbound/react/CycleInspector.tsx +116 -0
- package/src/features/audit/adapters/inbound/react/CyclicDependenciesRuleDetails.tsx +124 -0
- package/src/features/audit/adapters/inbound/react/useCycleSelection.ts +47 -0
- package/src/features/audit/application/use-cases/createAuditFromSnapshot.ts +28 -0
- package/src/features/audit/application/use-cases/resolveSelectedCycleIds.ts +18 -0
- package/src/features/audit/composition/createAuditAsync.ts +11 -0
- package/src/features/audit/domain/evaluateAuditRules.ts +42 -0
- package/src/features/audit/domain/hasBlockingAuditRuleFailure.ts +6 -0
- package/src/features/audit/domain/resolveAuditConfiguration.ts +27 -0
- package/src/features/audit/utils/cycleVisualization.ts +86 -0
- package/src/features/dependency-analysis/adapters/outbound/dependency-graph/analyzeDependencyImportsAsync.ts +172 -0
- package/src/features/dependency-analysis/adapters/outbound/dependency-graph/analyzeTypeScriptImportsAsync.ts +6 -0
- package/src/features/graph-view/adapters/inbound/react/DependencyGraphView.tsx +184 -0
- package/src/features/graph-view/adapters/inbound/react/GraphZoomControls.tsx +48 -0
- package/src/features/graph-view/adapters/inbound/react/applyGraphInteractionPresentation.ts +35 -0
- package/src/features/graph-view/adapters/inbound/react/createGraphViewModel.ts +240 -0
- package/src/features/graph-view/adapters/inbound/react/createGraphViewStyles.ts +37 -0
- package/src/features/graph-view/adapters/inbound/react/useGraphFocus.ts +104 -0
- package/src/features/graph-view/adapters/inbound/react/useGraphInteractions.ts +50 -0
- package/src/features/graph-view/adapters/inbound/react/useGraphProjection.ts +71 -0
- package/src/features/graph-view/adapters/inbound/react/useGraphViewport.ts +48 -0
- package/src/features/graph-view/domain/getDependencyHighlightClasses.ts +39 -0
- package/src/features/graph-view/domain/reduceGraphInteraction.ts +23 -0
- package/src/features/graph-view/utils/createCompoundOpacityIndex.ts +38 -0
- package/src/features/graph-view/utils/projectVisibleGraph.ts +109 -0
- package/src/features/graph-view/utils/readNodeDefinitionId.ts +7 -0
- package/src/features/graph-view/utils/removeEmptyStructuralNodes.ts +27 -0
- package/src/features/project-analysis/adapters/outbound/filesystem/readProjectSnapshotAsync.ts +12 -0
- package/src/features/project-analysis/application/use-cases/createProjectSnapshotReader.ts +29 -0
- package/src/features/project-analysis/composition/loadProjectOverviewAsync.ts +14 -0
- package/src/features/project-analysis/composition/loadProjectSnapshotAsync.ts +12 -0
- package/src/features/project-tree/adapters/inbound/react/ProjectTreePanel.tsx +52 -0
- package/src/features/project-tree/adapters/inbound/react/useProjectTreeExpansion.ts +46 -0
- package/src/features/project-tree/application/use-cases/buildProjectTree.ts +61 -0
- package/src/features/project-tree/application/use-cases/resolveProjectTreeNavigation.ts +13 -0
- package/src/features/project-tree/utils/findProjectTreeNode.ts +14 -0
- package/src/features/project-tree/utils/findProjectTreeNodeByGraphPackage.ts +21 -0
- package/src/features/project-tree/utils/getProjectTreeAncestorIds.ts +26 -0
- package/src/features/settings/utils/readSettingsEnvironment.ts +53 -0
- package/src/i18n/en.ts +21 -2
- package/src/i18n/i18n.ts +2 -3
- package/src/layouts/breadthfirst/style.ts +1 -0
- package/src/layouts/circle/style.ts +1 -0
- package/src/layouts/concentric/style.ts +1 -0
- package/src/layouts/elk/layout.ts +1 -3
- package/src/layouts/elk/style.ts +1 -0
- package/src/layouts/getWeightBuckets.ts +3 -1
- package/src/layouts/grid/style.ts +1 -0
- package/src/layouts/index.ts +0 -4
- package/src/layouts/style.ts +172 -25
- package/src/screens/home/Home.tsx +73 -25
- package/src/screens/home/HomeGraph.tsx +43 -0
- package/src/screens/home/HomeSidebar.tsx +129 -0
- package/src/shared/types/index.ts +0 -9
- package/src/shared/utils/getProjectName.ts +4 -1
- package/src/shared/utils/parseProjectPath.ts +1 -0
- package/src/shared/utils/toPosix.ts +1 -1
- package/src/types/audit.ts +76 -0
- package/src/types/auditVisualization.ts +22 -0
- package/src/types/graphInteraction.ts +9 -0
- package/src/types/parserSelection.ts +11 -0
- package/src/types/projectAnalysis.ts +20 -0
- package/src/types/projectAnalysisActionResult.ts +2 -0
- package/src/types/projectTree.ts +7 -0
- package/src/utils/filter/filterByPackagePrefix.ts +25 -7
- package/src/utils/filter/filterEmptyPackages.ts +28 -29
- package/src/utils/filter/filterSubPackagesFromDepth.ts +20 -17
- package/src/utils/filter/filterVendorPackages.ts +1 -1
- package/src/utils/filter/isIntrinsicGraphNode.ts +8 -0
- package/src/utils/filter/toggleCompoundNodes.ts +41 -31
- package/src/utils/runProjectAnalysisActionAsync.ts +14 -0
- package/tsconfig.json +11 -3
- package/.next/app-build-manifest.json +0 -29
- package/.next/cache/.previewinfo +0 -1
- package/.next/cache/.rscinfo +0 -1
- package/.next/cache/.tsbuildinfo +0 -1
- package/.next/cache/chrome-devtools-workspace-uuid +0 -1
- package/.next/cache/eslint/.cache_6t30dc +0 -1
- package/.next/cache/webpack/client-production/0.pack +0 -4
- package/.next/cache/webpack/client-production/1.pack +0 -0
- package/.next/cache/webpack/client-production/10.pack +0 -0
- package/.next/cache/webpack/client-production/11.pack +0 -0
- package/.next/cache/webpack/client-production/12.pack +0 -0
- package/.next/cache/webpack/client-production/13.pack +0 -0
- package/.next/cache/webpack/client-production/14.pack +0 -0
- package/.next/cache/webpack/client-production/15.pack +0 -0
- package/.next/cache/webpack/client-production/16.pack +0 -0
- package/.next/cache/webpack/client-production/2.pack +0 -0
- package/.next/cache/webpack/client-production/3.pack +0 -0
- package/.next/cache/webpack/client-production/4.pack +0 -0
- package/.next/cache/webpack/client-production/5.pack +0 -0
- package/.next/cache/webpack/client-production/6.pack +0 -0
- package/.next/cache/webpack/client-production/7.pack +0 -0
- package/.next/cache/webpack/client-production/8.pack +0 -0
- package/.next/cache/webpack/client-production/9.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/1.pack +0 -0
- package/.next/cache/webpack/server-production/10.pack +0 -4
- package/.next/cache/webpack/server-production/11.pack +0 -0
- package/.next/cache/webpack/server-production/12.pack +0 -0
- package/.next/cache/webpack/server-production/13.pack +0 -0
- package/.next/cache/webpack/server-production/14.pack +0 -0
- package/.next/cache/webpack/server-production/15.pack +0 -0
- package/.next/cache/webpack/server-production/16.pack +0 -0
- package/.next/cache/webpack/server-production/17.pack +0 -0
- package/.next/cache/webpack/server-production/18.pack +0 -4
- package/.next/cache/webpack/server-production/2.pack +0 -0
- package/.next/cache/webpack/server-production/3.pack +0 -0
- package/.next/cache/webpack/server-production/4.pack +0 -0
- package/.next/cache/webpack/server-production/5.pack +0 -0
- package/.next/cache/webpack/server-production/6.pack +0 -0
- package/.next/cache/webpack/server-production/7.pack +0 -0
- package/.next/cache/webpack/server-production/8.pack +0 -0
- package/.next/cache/webpack/server-production/9.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/.next/diagnostics/build-diagnostics.json +0 -6
- package/.next/diagnostics/framework.json +0 -1
- package/.next/server/app/index.html +0 -1
- package/.next/server/app/index.meta +0 -7
- package/.next/server/app/index.rsc +0 -20
- package/.next/server/chunks/548.js +0 -6
- package/.next/server/chunks/610.js +0 -7
- package/.next/server/chunks/985.js +0 -22
- package/.next/server/middleware-react-loadable-manifest.js +0 -1
- package/.next/server/pages/_app.js +0 -1
- package/.next/server/pages/_app.js.nft.json +0 -1
- package/.next/server/pages/_document.js +0 -1
- package/.next/server/pages/_document.js.nft.json +0 -1
- package/.next/server/pages/_error.js +0 -19
- package/.next/server/pages/_error.js.nft.json +0 -1
- package/.next/server/webpack-runtime.js +0 -1
- package/.next/static/_YC2p40ZiYT2Gcw-h_tjC/_buildManifest.js +0 -1
- package/.next/static/chunks/4bd1b696-cf72ae8a39fa05aa.js +0 -1
- package/.next/static/chunks/680-55ad17895c8fb70b.js +0 -1
- package/.next/static/chunks/90542734-29e255269788f1bd.js +0 -1
- package/.next/static/chunks/91dbc596-b9cdccd3f5cba95d.js +0 -1
- package/.next/static/chunks/964-b440f7af22c41ca5.js +0 -1
- package/.next/static/chunks/app/_not-found/page-11e4fea8e290f304.js +0 -1
- package/.next/static/chunks/app/layout-8aae7fba5ed8afb3.js +0 -1
- package/.next/static/chunks/app/page-91450b1230da8bca.js +0 -1
- package/.next/static/chunks/framework-bc35dade6ff9684e.js +0 -1
- package/.next/static/chunks/main-9e86d333c1e02dd1.js +0 -1
- package/.next/static/chunks/main-app-69a9ff75ff3465ca.js +0 -1
- package/.next/static/chunks/pages/_app-0a0020ddd67f79cf.js +0 -1
- package/.next/static/chunks/pages/_error-03529f2c21436739.js +0 -1
- package/.next/static/chunks/webpack-7adfafc806738767.js +0 -1
- package/.next/static/css/ec31779168107a11.css +0 -3
- package/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- package/.next/trace +0 -2
- package/.next/types/app/layout.ts +0 -84
- package/.next/types/app/page.ts +0 -84
- package/.next/types/cache-life.d.ts +0 -141
- package/.next/types/package.json +0 -1
- package/src/app/actions/graph.actions.ts +0 -25
- package/src/app/utils/parser/cpp/extractCppPackageFromImport.ts +0 -18
- package/src/app/utils/parser/delphi/extractPackageFromImport.ts +0 -21
- package/src/app/utils/parser/java/extractJavaPackageFromImport.ts +0 -39
- package/src/app/utils/parser/java/getIntrinsicPackagesRecursive.ts +0 -33
- package/src/app/utils/parser/kotlin/extractPackageFromImport.ts +0 -19
- package/src/app/utils/parser/python/extractPythonPackageFromImport.ts +0 -18
- package/src/app/utils/parser/typescript/extractTypeScriptPackageFromImport.ts +0 -18
- package/src/components/Cytoscape.tsx +0 -23
- package/src/components/Setting.tsx +0 -17
- package/src/components/Settings.tsx +0 -189
- package/src/components/ZoomInput.tsx +0 -94
- package/src/components/useCytoscape.ts +0 -343
- package/src/layouts/getLayoutStyle.ts +0 -19
- package/src/shared/utils/detectLanguage.ts +0 -255
- package/src/shared/utils/getJsonAsync.ts +0 -13
- package/src/shared/utils/parseEnv.ts +0 -91
- package/src/store/useLocalStorage.ts +0 -29
- package/src/utils/hasChildren.ts +0 -7
- /package/.next/{react-loadable-manifest.json → server/app/_global-error/page/react-loadable-manifest.json} +0 -0
- /package/.next/static/chunks/{polyfills-42372ed130431b0a.js → 0cz1d0mv5g_q7.js} +0 -0
- /package/.next/static/{_YC2p40ZiYT2Gcw-h_tjC → qznDSVYlkQxVdRx-TE_Wk}/_ssgManifest.js +0 -0
|
@@ -1,48 +1,96 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import
|
|
2
|
+
import { useState } from 'react';
|
|
3
3
|
|
|
4
|
-
import { useEffect, useState } from 'react';
|
|
5
|
-
import { getGraphAction } from '@/app/actions/graph.actions';
|
|
6
4
|
import Breadcrumb from '@/components/Breadcrumb';
|
|
7
5
|
import Header from '@/components/Header';
|
|
8
|
-
import
|
|
9
|
-
import Settings from '@/components/Settings';
|
|
10
|
-
import { Cytoscape } from '@/components/Cytoscape';
|
|
6
|
+
import ProjectLoadError from '@/components/ProjectLoadError';
|
|
11
7
|
import { SettingsProvider } from '@/contexts/SettingsContext';
|
|
8
|
+
import { useCycleSelection } from '@/features/audit/adapters/inbound/react/useCycleSelection';
|
|
9
|
+
import { resolveProjectTreeNavigation } from '@/features/project-tree/application/use-cases/resolveProjectTreeNavigation';
|
|
10
|
+
import { findProjectTreeNodeByGraphPackage } from '@/features/project-tree/utils/findProjectTreeNodeByGraphPackage';
|
|
11
|
+
import { HomeGraph } from '@/screens/home/HomeGraph';
|
|
12
|
+
import { HomeSidebar } from '@/screens/home/HomeSidebar';
|
|
13
|
+
import type { Audit } from '@/types/audit';
|
|
14
|
+
import type { CycleInspection } from '@/types/auditVisualization';
|
|
15
|
+
import type { ProjectOverview } from '@/types/projectAnalysis';
|
|
16
|
+
import type { ProjectAnalysisActionResult } from '@/types/projectAnalysisActionResult';
|
|
17
|
+
import type { ProjectTreeNode } from '@/types/projectTree';
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
/*** Renders the PKGViz home screen and composes project navigation, diagnostics, and the graph. */
|
|
20
|
+
export default function HomeScreen({ project }: HomeScreenProps) {
|
|
14
21
|
const [currentPackage, setCurrentPackage] = useState<string>('');
|
|
15
|
-
const
|
|
22
|
+
const packageGraph = project.ok ? project.value.graph : null;
|
|
23
|
+
const projectTree = project.ok ? project.value.tree : [];
|
|
24
|
+
const [selectedTreeId, setSelectedTreeId] = useState<string | null>(null);
|
|
25
|
+
const auditEvaluation = project.ok ? project.value.evaluation : null;
|
|
26
|
+
const projectError = project.ok ? null : project.error;
|
|
27
|
+
const cycleSelection = useCycleSelection(auditEvaluation?.cyclicPackages ?? EMPTY_CYCLES);
|
|
28
|
+
const [cycleInspection, setCycleInspection] = useState<CycleInspection | null>(null);
|
|
16
29
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
/*** Navigates graph scope and mirrors the matching package selection in the project tree. */
|
|
31
|
+
const navigateToPackage = (path: string) => {
|
|
32
|
+
const packageName = normalizeGraphPackage(path);
|
|
33
|
+
const matchingTreeNode = findProjectTreeNodeByGraphPackage(projectTree, packageName);
|
|
34
|
+
setCurrentPackage(packageName);
|
|
35
|
+
setSelectedTreeId(matchingTreeNode?.id ?? null);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/*** Navigates only into packages with graph descendants; selecting a leaf keeps the current view. */
|
|
39
|
+
const selectProjectTreeNode = (node: ProjectTreeNode) => {
|
|
40
|
+
setSelectedTreeId(node.id);
|
|
41
|
+
setCurrentPackage(
|
|
42
|
+
resolveProjectTreeNavigation(
|
|
43
|
+
node,
|
|
44
|
+
packageGraph?.nodes.map(candidate => String(candidate.data.id ?? '')) ?? [],
|
|
45
|
+
currentPackage
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
};
|
|
22
49
|
|
|
23
50
|
return (
|
|
24
51
|
<>
|
|
25
52
|
<Header title="nav.packages">
|
|
26
|
-
<Breadcrumb
|
|
27
|
-
path={currentPackage.replace(/\./g, '/')}
|
|
28
|
-
onNavigate={(path: string) => setCurrentPackage(path.replace(/\//g, '.'))}
|
|
29
|
-
/>
|
|
53
|
+
<Breadcrumb path={currentPackage.replace(/\./g, '/')} onNavigate={navigateToPackage} />
|
|
30
54
|
</Header>
|
|
31
|
-
|
|
32
55
|
<SettingsProvider>
|
|
33
|
-
<main
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
56
|
+
<main
|
|
57
|
+
data-testid="main"
|
|
58
|
+
className="flex min-h-0 min-w-0 flex-1 flex-row overflow-hidden dark:bg-[#171717]"
|
|
59
|
+
>
|
|
60
|
+
<HomeSidebar
|
|
61
|
+
evaluation={auditEvaluation}
|
|
62
|
+
projectTree={projectTree}
|
|
63
|
+
selectedTreeId={selectedTreeId}
|
|
64
|
+
onProjectTreeSelect={selectProjectTreeNode}
|
|
65
|
+
cycleSelection={cycleSelection}
|
|
66
|
+
inspectedCycleId={cycleInspection?.id ?? null}
|
|
67
|
+
onCycleInspectionChange={setCycleInspection}
|
|
68
|
+
/>
|
|
69
|
+
{projectError ? (
|
|
70
|
+
<ProjectLoadError message={projectError} />
|
|
71
|
+
) : (
|
|
72
|
+
<HomeGraph
|
|
37
73
|
currentPackage={currentPackage}
|
|
38
|
-
|
|
74
|
+
cycleHighlights={cycleSelection.highlights}
|
|
75
|
+
cycleInspection={cycleInspection}
|
|
39
76
|
packageGraph={packageGraph}
|
|
77
|
+
setCurrentPackage={navigateToPackage}
|
|
78
|
+
onCloseInspection={() => setCycleInspection(null)}
|
|
40
79
|
/>
|
|
41
|
-
) : (
|
|
42
|
-
<Loader />
|
|
43
80
|
)}
|
|
44
81
|
</main>
|
|
45
82
|
</SettingsProvider>
|
|
46
83
|
</>
|
|
47
84
|
);
|
|
48
85
|
}
|
|
86
|
+
|
|
87
|
+
const EMPTY_CYCLES: NonNullable<Audit['evaluation']>['cyclicPackages'] = [];
|
|
88
|
+
|
|
89
|
+
interface HomeScreenProps {
|
|
90
|
+
readonly project: ProjectAnalysisActionResult<ProjectOverview>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/*** Normalizes graph navigation paths to the package-id representation used by Cytoscape. */
|
|
94
|
+
function normalizeGraphPackage(path: string): string {
|
|
95
|
+
return path.replaceAll('/', '.').replace(/^\.+|\.+$/g, '');
|
|
96
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type { ElementsDefinition } from 'cytoscape';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
import Loader from '@/components/Loader';
|
|
6
|
+
import { CycleInspector } from '@/features/audit/adapters/inbound/react/CycleInspector';
|
|
7
|
+
import { DependencyGraphView } from '@/features/graph-view/adapters/inbound/react/DependencyGraphView';
|
|
8
|
+
import type { CycleHighlight, CycleInspection } from '@/types/auditVisualization';
|
|
9
|
+
|
|
10
|
+
/*** Renders the graph surface together with its optional cycle inspector overlay. */
|
|
11
|
+
export function HomeGraph({
|
|
12
|
+
currentPackage,
|
|
13
|
+
cycleHighlights,
|
|
14
|
+
cycleInspection,
|
|
15
|
+
packageGraph,
|
|
16
|
+
setCurrentPackage,
|
|
17
|
+
onCloseInspection,
|
|
18
|
+
}: HomeGraphProps) {
|
|
19
|
+
if (!packageGraph) return <Loader />;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<DependencyGraphView
|
|
23
|
+
currentPackage={currentPackage}
|
|
24
|
+
setCurrentPackage={setCurrentPackage}
|
|
25
|
+
packageGraph={packageGraph}
|
|
26
|
+
cycleHighlights={cycleHighlights}
|
|
27
|
+
overlay={
|
|
28
|
+
cycleInspection === null ? null : (
|
|
29
|
+
<CycleInspector inspection={cycleInspection} onClose={onCloseInspection} />
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
/>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface HomeGraphProps {
|
|
37
|
+
readonly currentPackage: string;
|
|
38
|
+
readonly cycleHighlights: readonly CycleHighlight[];
|
|
39
|
+
readonly cycleInspection: CycleInspection | null;
|
|
40
|
+
readonly packageGraph: ElementsDefinition | null;
|
|
41
|
+
readonly setCurrentPackage: (path: string) => void;
|
|
42
|
+
readonly onCloseInspection: () => void;
|
|
43
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { ExportPanel } from '@/components/ExportPanel';
|
|
5
|
+
import { SettingsPanel } from '@/components/SettingsPanel';
|
|
6
|
+
import { Sidebar } from '@/components/sidebar/Sidebar';
|
|
7
|
+
import { SidebarTabs } from '@/components/sidebar/SidebarTabs';
|
|
8
|
+
import { AuditRulePanel } from '@/features/audit/adapters/inbound/react/AuditRulePanel';
|
|
9
|
+
import { ProjectTreePanel } from '@/features/project-tree/adapters/inbound/react/ProjectTreePanel';
|
|
10
|
+
import { t } from '@/i18n/i18n';
|
|
11
|
+
import type { Audit } from '@/types/audit';
|
|
12
|
+
import type { CycleInspection, CycleSelection } from '@/types/auditVisualization';
|
|
13
|
+
import type { ProjectTreeNode } from '@/types/projectTree';
|
|
14
|
+
|
|
15
|
+
/*** Composes Tree, Rules, and Export above persistent graph settings. */
|
|
16
|
+
export function HomeSidebar(props: HomeSidebarProps) {
|
|
17
|
+
const [activeTool, setActiveTool] = React.useState<string | null>('tree');
|
|
18
|
+
|
|
19
|
+
/*** Closes the evidence panel without changing the user's cycle visualization choices. */
|
|
20
|
+
const selectTool = (value: string) => {
|
|
21
|
+
if (activeTool === 'rules' && value !== 'rules') {
|
|
22
|
+
props.onCycleInspectionChange(null);
|
|
23
|
+
}
|
|
24
|
+
setActiveTool(value);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Sidebar>
|
|
29
|
+
<SidebarToolTabs
|
|
30
|
+
activeTool={activeTool}
|
|
31
|
+
evaluation={props.evaluation}
|
|
32
|
+
cycleSelection={props.cycleSelection}
|
|
33
|
+
inspectedCycleId={props.inspectedCycleId}
|
|
34
|
+
onCycleInspectionChange={props.onCycleInspectionChange}
|
|
35
|
+
onProjectTreeSelect={props.onProjectTreeSelect}
|
|
36
|
+
onValueChange={selectTool}
|
|
37
|
+
projectTree={props.projectTree}
|
|
38
|
+
selectedTreeId={props.selectedTreeId}
|
|
39
|
+
/>
|
|
40
|
+
<div className="shrink-0">
|
|
41
|
+
<SettingsPanel />
|
|
42
|
+
</div>
|
|
43
|
+
</Sidebar>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/*** Renders project-tree navigation together with secondary Rules and Export tools. */
|
|
48
|
+
function SidebarToolTabs({
|
|
49
|
+
activeTool,
|
|
50
|
+
evaluation,
|
|
51
|
+
cycleSelection,
|
|
52
|
+
inspectedCycleId,
|
|
53
|
+
onCycleInspectionChange,
|
|
54
|
+
onProjectTreeSelect,
|
|
55
|
+
onValueChange,
|
|
56
|
+
projectTree,
|
|
57
|
+
selectedTreeId,
|
|
58
|
+
}: SidebarToolTabsProps) {
|
|
59
|
+
const violatedRuleCount = evaluation?.rules.filter(rule => rule.status === 'failed').length ?? 0;
|
|
60
|
+
const findingCount =
|
|
61
|
+
evaluation?.rules
|
|
62
|
+
.filter(rule => rule.status === 'failed')
|
|
63
|
+
.reduce(
|
|
64
|
+
(count, rule) =>
|
|
65
|
+
count +
|
|
66
|
+
(rule.id === 'cyclic-dependencies'
|
|
67
|
+
? evaluation.cyclicPackages.length
|
|
68
|
+
: rule.details.length),
|
|
69
|
+
0
|
|
70
|
+
) ?? 0;
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<SidebarTabs
|
|
74
|
+
ariaLabel={t('sidebar.tools')}
|
|
75
|
+
value={activeTool}
|
|
76
|
+
onValueChange={onValueChange}
|
|
77
|
+
tabs={[
|
|
78
|
+
{
|
|
79
|
+
id: 'tree',
|
|
80
|
+
label: t('settings.tree'),
|
|
81
|
+
content: (
|
|
82
|
+
<ProjectTreePanel
|
|
83
|
+
nodes={projectTree}
|
|
84
|
+
selectedId={selectedTreeId}
|
|
85
|
+
onSelect={onProjectTreeSelect}
|
|
86
|
+
/>
|
|
87
|
+
),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: 'rules',
|
|
91
|
+
label: `${t('settings.rules')} · ${findingCount} ${t('audit.findings')}`,
|
|
92
|
+
disabled: violatedRuleCount === 0,
|
|
93
|
+
content:
|
|
94
|
+
evaluation === null ? null : (
|
|
95
|
+
<AuditRulePanel
|
|
96
|
+
evaluation={evaluation}
|
|
97
|
+
cycleSelection={cycleSelection}
|
|
98
|
+
inspectedCycleId={inspectedCycleId}
|
|
99
|
+
onCycleInspectionChange={onCycleInspectionChange}
|
|
100
|
+
/>
|
|
101
|
+
),
|
|
102
|
+
},
|
|
103
|
+
{ id: 'export', label: t('settings.export'), content: <ExportPanel /> },
|
|
104
|
+
]}
|
|
105
|
+
/>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface HomeSidebarProps {
|
|
110
|
+
readonly inspectedCycleId: string | null;
|
|
111
|
+
readonly evaluation: Audit['evaluation'] | null;
|
|
112
|
+
readonly projectTree: readonly ProjectTreeNode[];
|
|
113
|
+
readonly selectedTreeId: string | null;
|
|
114
|
+
readonly onProjectTreeSelect: (node: ProjectTreeNode) => void;
|
|
115
|
+
readonly cycleSelection: CycleSelection;
|
|
116
|
+
readonly onCycleInspectionChange: (inspection: CycleInspection | null) => void;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
interface SidebarToolTabsProps {
|
|
120
|
+
readonly inspectedCycleId: string | null;
|
|
121
|
+
readonly activeTool: string | null;
|
|
122
|
+
readonly evaluation: Audit['evaluation'] | null;
|
|
123
|
+
readonly cycleSelection: CycleSelection;
|
|
124
|
+
readonly onCycleInspectionChange: (inspection: CycleInspection | null) => void;
|
|
125
|
+
readonly onProjectTreeSelect: (node: ProjectTreeNode) => void;
|
|
126
|
+
readonly onValueChange: (value: string) => void;
|
|
127
|
+
readonly projectTree: readonly ProjectTreeNode[];
|
|
128
|
+
readonly selectedTreeId: string | null;
|
|
129
|
+
}
|
|
@@ -15,15 +15,6 @@ export enum Language {
|
|
|
15
15
|
Unknown = 'unknown',
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
/**
|
|
19
|
-
* Language Detection Result
|
|
20
|
-
*/
|
|
21
|
-
export interface LanguageDetectionResult {
|
|
22
|
-
language: Language;
|
|
23
|
-
confidence: number;
|
|
24
|
-
indicators: string[];
|
|
25
|
-
}
|
|
26
|
-
|
|
27
18
|
//////////////////////////////////////////////////////////////////////////
|
|
28
19
|
// Parser Types
|
|
29
20
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { parseProjectPath } from '@/shared/utils/parseProjectPath';
|
|
2
|
+
import { toPosix } from '@/shared/utils/toPosix';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
/*** Returns the project name for an explicit or configured project path. */
|
|
5
|
+
export const getProjectName = (projectPath: string = parseProjectPath()) =>
|
|
6
|
+
toPosix(projectPath).split('/').pop() || '{unknown}';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { toPosix } from '@/shared/utils/toPosix';
|
|
2
2
|
|
|
3
|
+
/*** Returns the configured project path in POSIX form. */
|
|
3
4
|
export const parseProjectPath = () => {
|
|
4
5
|
const projectPath = process.env.NEXT_PUBLIC_PROJECT_PATH;
|
|
5
6
|
if (!projectPath) throw new Error('Missing ENV: NEXT_PUBLIC_PROJECT_PATH');
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ParsedDirectory } from '@/shared/types';
|
|
2
|
+
import type { ParserSelection } from '@/types/parserSelection';
|
|
3
|
+
|
|
4
|
+
type AuditRuleMode = 'audit' | 'block' | 'off';
|
|
5
|
+
type AuditRulePolicy = 'advisory' | 'blocking';
|
|
6
|
+
type AuditRuleStatus = 'failed' | 'passed';
|
|
7
|
+
|
|
8
|
+
export interface AuditRuleConfiguration {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly mode: AuditRuleMode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AuditConfiguration {
|
|
14
|
+
readonly failOnRuleViolation: boolean;
|
|
15
|
+
readonly rules: readonly AuditRuleConfiguration[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ResolveAuditConfigurationInput {
|
|
19
|
+
readonly failOnRuleViolation?: boolean;
|
|
20
|
+
readonly rules?: readonly AuditRuleConfiguration[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ImportEvidence {
|
|
24
|
+
readonly filePath: string;
|
|
25
|
+
readonly fileClass: string;
|
|
26
|
+
readonly importName: string;
|
|
27
|
+
readonly isIntrinsic?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CycleEdgeEvidence {
|
|
31
|
+
readonly from: string;
|
|
32
|
+
readonly to: string;
|
|
33
|
+
readonly via: readonly ImportEvidence[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface PackageCycleDetail {
|
|
37
|
+
readonly packages: readonly string[];
|
|
38
|
+
readonly edges: readonly CycleEdgeEvidence[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface AuditRuleResult<TEvidence = unknown> {
|
|
42
|
+
readonly id: string;
|
|
43
|
+
readonly status: AuditRuleStatus;
|
|
44
|
+
readonly policy: AuditRulePolicy;
|
|
45
|
+
readonly message: string;
|
|
46
|
+
readonly details: readonly string[];
|
|
47
|
+
readonly evidence: TEvidence;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface CyclicDependenciesEvidence {
|
|
51
|
+
readonly cycles: readonly PackageCycleDetail[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface AuditEvaluation {
|
|
55
|
+
readonly cyclicPackages: readonly PackageCycleDetail[];
|
|
56
|
+
readonly rules: readonly AuditRuleResult[];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface AuditMeta {
|
|
60
|
+
readonly timeEnd: number;
|
|
61
|
+
readonly timeStart: number;
|
|
62
|
+
readonly language: ParserSelection;
|
|
63
|
+
readonly projectName: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface Audit {
|
|
67
|
+
readonly configuration: AuditConfiguration;
|
|
68
|
+
readonly evaluation: AuditEvaluation;
|
|
69
|
+
readonly meta: AuditMeta;
|
|
70
|
+
readonly files: ParsedDirectory;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface EvaluateAuditRulesInput {
|
|
74
|
+
readonly configuration: AuditConfiguration;
|
|
75
|
+
readonly cyclicPackages: readonly PackageCycleDetail[];
|
|
76
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PackageCycleDetail } from '@/types/audit';
|
|
2
|
+
|
|
3
|
+
export interface CycleHighlight {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly color: string;
|
|
6
|
+
readonly cycle: PackageCycleDetail;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface CycleInspection extends CycleHighlight {
|
|
10
|
+
readonly label: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface CycleFocus {
|
|
14
|
+
readonly currentPackage: string;
|
|
15
|
+
readonly packageDepth: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CycleSelection {
|
|
19
|
+
readonly highlights: readonly CycleHighlight[];
|
|
20
|
+
readonly selectedIds: readonly string[];
|
|
21
|
+
readonly setSelected: (id: string, selected: boolean) => void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface GraphInteractionState {
|
|
2
|
+
readonly hoveredNodeId: string | null;
|
|
3
|
+
readonly selectedNodeIds: readonly string[];
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface GraphInteractionEvent {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly type: 'pointer-enter' | 'pointer-leave' | 'select' | 'unselect';
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DetectedLanguage } from '@ankhorage/project-detector/types';
|
|
2
|
+
|
|
3
|
+
import type { Language } from '../shared/types';
|
|
4
|
+
|
|
5
|
+
/** pkgviz's parser choice, not a generic project's single language or a probability. */
|
|
6
|
+
export interface ParserSelection {
|
|
7
|
+
readonly language: Language;
|
|
8
|
+
readonly score: number;
|
|
9
|
+
readonly indicators: readonly string[];
|
|
10
|
+
readonly candidates: readonly DetectedLanguage[];
|
|
11
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ElementsDefinition } from 'cytoscape';
|
|
2
|
+
|
|
3
|
+
import type { ParsedDirectory } from '@/shared/types';
|
|
4
|
+
import type { Audit } from '@/types/audit';
|
|
5
|
+
import type { ParserSelection } from '@/types/parserSelection';
|
|
6
|
+
import type { ProjectTreeNode } from '@/types/projectTree';
|
|
7
|
+
|
|
8
|
+
export interface ProjectSnapshot {
|
|
9
|
+
readonly files: ParsedDirectory;
|
|
10
|
+
readonly graph: ElementsDefinition;
|
|
11
|
+
readonly language: ParserSelection;
|
|
12
|
+
readonly projectPath: string;
|
|
13
|
+
readonly timeStart: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ProjectOverview {
|
|
17
|
+
readonly graph: ElementsDefinition;
|
|
18
|
+
readonly tree: readonly ProjectTreeNode[];
|
|
19
|
+
readonly evaluation: Audit['evaluation'];
|
|
20
|
+
}
|
|
@@ -1,16 +1,34 @@
|
|
|
1
|
+
import { isIntrinsicGraphNode } from '@/utils/filter/isIntrinsicGraphNode';
|
|
2
|
+
|
|
3
|
+
/***
|
|
4
|
+
* Filters project descendants while retaining their adjacent external dependency endpoints.
|
|
5
|
+
* @performance Use endpoint sets to retain adjacent vendors without per-vendor edge scans.
|
|
6
|
+
*/
|
|
1
7
|
export function filterByPackagePrefix(
|
|
2
8
|
allElements: cytoscape.ElementsDefinition,
|
|
3
9
|
packagePrefix: string
|
|
4
10
|
): cytoscape.ElementsDefinition {
|
|
5
|
-
|
|
6
|
-
if (!
|
|
11
|
+
const normalizedPrefix = packagePrefix.replace(/\.+$/, '');
|
|
12
|
+
if (!normalizedPrefix) return allElements;
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
return (node
|
|
14
|
+
const descendantPrefix = normalizedPrefix + '.';
|
|
15
|
+
const projectNodes = allElements.nodes.filter(node => {
|
|
16
|
+
const id = node.data.id ?? '';
|
|
17
|
+
return isIntrinsicGraphNode(node) && id.startsWith(descendantPrefix);
|
|
12
18
|
});
|
|
13
|
-
|
|
19
|
+
const projectIds = new Set(projectNodes.map(node => node.data.id));
|
|
20
|
+
const connectedIds = new Set(
|
|
21
|
+
allElements.edges.flatMap(edge =>
|
|
22
|
+
projectIds.has(edge.data.source) || projectIds.has(edge.data.target)
|
|
23
|
+
? [edge.data.source, edge.data.target]
|
|
24
|
+
: []
|
|
25
|
+
)
|
|
26
|
+
);
|
|
27
|
+
const allowedNodes = allElements.nodes.filter(
|
|
28
|
+
node =>
|
|
29
|
+
projectIds.has(node.data.id) ||
|
|
30
|
+
(!isIntrinsicGraphNode(node) && connectedIds.has(String(node.data.id)))
|
|
31
|
+
);
|
|
14
32
|
const allowedNodeIds = new Set(allowedNodes.map(node => node.data.id));
|
|
15
33
|
const allowedEdges = allElements.edges.filter(
|
|
16
34
|
edge => allowedNodeIds.has(edge.data.source) && allowedNodeIds.has(edge.data.target)
|
|
@@ -1,36 +1,35 @@
|
|
|
1
|
-
import { ElementsDefinition } from 'cytoscape';
|
|
1
|
+
import type { ElementsDefinition } from 'cytoscape';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* Returns root package if only one inside, or '' (root folder)
|
|
5
|
-
*/
|
|
6
|
-
function getRootPackage(elements: ElementsDefinition) {
|
|
7
|
-
const rootPackages = elements.nodes.filter(n => {
|
|
8
|
-
return !n.data.id?.includes('.');
|
|
9
|
-
});
|
|
10
|
-
return rootPackages.length > 1 ? '' : (rootPackages[0].data.id as string);
|
|
11
|
-
}
|
|
3
|
+
import { isIntrinsicGraphNode } from '@/utils/filter/isIntrinsicGraphNode';
|
|
12
4
|
|
|
13
|
-
|
|
14
|
-
*
|
|
5
|
+
/***
|
|
6
|
+
* Skips a unique chain of structural project packages, stopping before real dependency endpoints.
|
|
7
|
+
* @performance Use full-graph indexes: navigation must not depend on depth projection or vendors.
|
|
8
|
+
* Preserve real isolated leaves and branching packages rather than silently filtering them away.
|
|
15
9
|
*/
|
|
16
10
|
export function filterEmptyPackages(currentPackage: string, elements: ElementsDefinition): string {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
if (childPackages.length === 1) {
|
|
29
|
-
currentPackage = childPackages[0];
|
|
30
|
-
} else {
|
|
31
|
-
break;
|
|
32
|
-
}
|
|
11
|
+
const children = new Map<string, string[]>();
|
|
12
|
+
for (const node of elements.nodes.filter(isIntrinsicGraphNode)) {
|
|
13
|
+
const id = String(node.data.id ?? '');
|
|
14
|
+
if (!id) continue;
|
|
15
|
+
const boundary = id.lastIndexOf('.');
|
|
16
|
+
const parent = boundary < 0 ? '' : id.slice(0, boundary);
|
|
17
|
+
const siblings = children.get(parent) ?? [];
|
|
18
|
+
siblings.push(id);
|
|
19
|
+
children.set(parent, siblings);
|
|
33
20
|
}
|
|
21
|
+
const connected = new Set(elements.edges.flatMap(edge => [edge.data.source, edge.data.target]));
|
|
22
|
+
return descend(currentPackage, children, connected);
|
|
23
|
+
}
|
|
34
24
|
|
|
35
|
-
|
|
25
|
+
/*** Descends only when the next package is a relationship-free structural container. */
|
|
26
|
+
function descend(
|
|
27
|
+
scope: string,
|
|
28
|
+
children: ReadonlyMap<string, readonly string[]>,
|
|
29
|
+
connected: ReadonlySet<string>
|
|
30
|
+
): string {
|
|
31
|
+
const candidates = children.get(scope) ?? [];
|
|
32
|
+
const next = candidates[0];
|
|
33
|
+
if (candidates.length !== 1 || !next || connected.has(next) || !children.has(next)) return scope;
|
|
34
|
+
return descend(next, children, connected);
|
|
36
35
|
}
|