pkgviz 0.7.6 → 0.8.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/.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/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/2sswp23h6zh08.js +345 -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/rjdzHqzPw2GCNhDbjcu0-/_buildManifest.js +11 -0
- package/.next/static/rjdzHqzPw2GCNhDbjcu0-/_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 +94 -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/5HapMtlwNHlJNa0mJQNsK/_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/{5HapMtlwNHlJNa0mJQNsK → rjdzHqzPw2GCNhDbjcu0-}/_ssgManifest.js +0 -0
|
@@ -1,93 +1,47 @@
|
|
|
1
1
|
'use server';
|
|
2
|
-
import type { ParsedFile, MethodCall, MethodDefinition, ImportDefinition } from '@/shared/types';
|
|
3
|
-
|
|
4
|
-
import fs from 'node:fs';
|
|
5
2
|
import path from 'node:path';
|
|
6
|
-
import { extractPackageFromImport } from '@/app/utils/parser/kotlin/extractPackageFromImport';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Extracts package declaration from Kotlin content.
|
|
10
|
-
*/
|
|
11
|
-
function extractPackage(content: string): string {
|
|
12
|
-
const packageMatch = content.match(/^\s*package\s+([\w.]+)/m);
|
|
13
|
-
return packageMatch ? packageMatch[1] : '';
|
|
14
|
-
}
|
|
15
3
|
|
|
16
|
-
|
|
17
|
-
* Extracts import statements from Kotlin code.
|
|
18
|
-
*/
|
|
19
|
-
function extractImports(content: string): ImportDefinition[] {
|
|
20
|
-
const imports: ImportDefinition[] = [];
|
|
21
|
-
const importRegex = /^\s*import\s+([\w.]+(?:\.\*)?)/gm;
|
|
4
|
+
import { readTextFileWithinRoot } from '@ankhorage/utility/node/fs';
|
|
22
5
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const importPath = match[1];
|
|
26
|
-
const pkg = extractPackageFromImport(importPath);
|
|
27
|
-
|
|
28
|
-
// Check if it's an intrinsic/standard library import
|
|
29
|
-
const isIntrinsic =
|
|
30
|
-
importPath.startsWith('kotlin.') ||
|
|
31
|
-
importPath.startsWith('java.') ||
|
|
32
|
-
importPath.startsWith('javax.');
|
|
33
|
-
|
|
34
|
-
imports.push({
|
|
35
|
-
name: importPath,
|
|
36
|
-
pkg,
|
|
37
|
-
isIntrinsic,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
6
|
+
import type { ImportDefinition, MethodCall, MethodDefinition, ParsedFile } from '@/shared/types';
|
|
7
|
+
import { toPosix } from '@/shared/utils/toPosix';
|
|
40
8
|
|
|
41
|
-
|
|
9
|
+
/*** Extracts package declaration from Kotlin content. */
|
|
10
|
+
function extractPackage(content: string): string {
|
|
11
|
+
const packageMatch = /^\s*package\s+([\w.]+)/m.exec(content);
|
|
12
|
+
return packageMatch ? packageMatch[1] : '';
|
|
42
13
|
}
|
|
43
14
|
|
|
44
|
-
|
|
45
|
-
* Extracts class, object, data class, or sealed class name from Kotlin content.
|
|
46
|
-
*/
|
|
15
|
+
/*** Extracts class, object, data class, or sealed class name from Kotlin content. */
|
|
47
16
|
function extractClassName(content: string, fileName: string): string {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
17
|
+
const classMatch =
|
|
18
|
+
/(?:^|\n)\s*(?:data\s+|sealed\s+|abstract\s+|open\s+)?(?:class|object|interface)\s+([A-Za-z0-9_]+)/m.exec(
|
|
19
|
+
content
|
|
20
|
+
);
|
|
52
21
|
|
|
53
|
-
if (classMatch)
|
|
54
|
-
return classMatch[1];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Fallback to filename without extension
|
|
22
|
+
if (classMatch) return classMatch[1];
|
|
58
23
|
return path.basename(fileName, path.extname(fileName));
|
|
59
24
|
}
|
|
60
25
|
|
|
61
|
-
|
|
62
|
-
* Extracts method/function definitions from Kotlin content.
|
|
63
|
-
*/
|
|
26
|
+
/*** Extracts method/function definitions from Kotlin content. */
|
|
64
27
|
function extractMethodDefinitions(content: string): MethodDefinition[] {
|
|
65
28
|
const methods: MethodDefinition[] = [];
|
|
66
|
-
|
|
67
|
-
// Match function definitions: fun methodName(params): ReturnType or suspend fun methodName
|
|
68
29
|
const methodRegex =
|
|
69
30
|
/(?:^|\n)\s*(?:(private|protected|public|internal)\s+)?(?:suspend\s+)?fun\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*$$([^)]*)$$(?:\s*:\s*([^{=\n]+))?/gm;
|
|
70
31
|
|
|
71
32
|
let match;
|
|
72
33
|
while ((match = methodRegex.exec(content)) !== null) {
|
|
73
34
|
const visibility = (match[1] || 'public') as
|
|
74
|
-
| '
|
|
75
|
-
| 'protected'
|
|
76
|
-
| 'private'
|
|
77
|
-
| 'internal'
|
|
78
|
-
| 'default';
|
|
35
|
+
'public' | 'protected' | 'private' | 'internal' | 'default';
|
|
79
36
|
const name = match[2];
|
|
80
37
|
const paramsStr = match[3];
|
|
81
38
|
const returnType = match[4]?.trim() || 'Unit';
|
|
82
|
-
|
|
83
|
-
// Parse parameters
|
|
84
39
|
const params = paramsStr
|
|
85
40
|
.split(',')
|
|
86
41
|
.map(p => p.trim())
|
|
87
42
|
.filter(p => p)
|
|
88
43
|
.map(p => {
|
|
89
|
-
|
|
90
|
-
const paramMatch = p.match(/([a-zA-Z_][a-zA-Z0-9_]*)\s*:/);
|
|
44
|
+
const paramMatch = /([a-zA-Z_][a-zA-Z0-9_]*)\s*:/.exec(p);
|
|
91
45
|
return paramMatch ? paramMatch[1] : p;
|
|
92
46
|
});
|
|
93
47
|
|
|
@@ -102,46 +56,39 @@ function extractMethodDefinitions(content: string): MethodDefinition[] {
|
|
|
102
56
|
return methods;
|
|
103
57
|
}
|
|
104
58
|
|
|
105
|
-
|
|
106
|
-
* Extract method calls from Kotlin content.
|
|
107
|
-
*/
|
|
59
|
+
/*** Extracts method calls from Kotlin content. */
|
|
108
60
|
function extractMethodCalls(content: string): MethodCall[] {
|
|
109
61
|
const calls: MethodCall[] = [];
|
|
110
|
-
|
|
111
|
-
// Match: object.method( or variable.method(
|
|
112
62
|
const callRegex = /([a-zA-Z_][a-zA-Z0-9_]*)\.([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/g;
|
|
113
63
|
|
|
114
64
|
let match;
|
|
115
65
|
while ((match = callRegex.exec(content)) !== null) {
|
|
116
66
|
const callee = match[1];
|
|
117
67
|
const method = match[2];
|
|
118
|
-
|
|
119
68
|
calls.push({ callee, method });
|
|
120
69
|
}
|
|
121
70
|
|
|
122
71
|
return calls;
|
|
123
72
|
}
|
|
124
73
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
const calls = extractMethodCalls(content);
|
|
137
|
-
const relativePath = path.relative(projectRoot, fullPath);
|
|
74
|
+
/*** Parses Kotlin class/method/call metadata while consuming canonical dependency imports. */
|
|
75
|
+
export async function parseKotlinFile(
|
|
76
|
+
fullPath: string,
|
|
77
|
+
projectRoot: string,
|
|
78
|
+
imports: readonly ImportDefinition[]
|
|
79
|
+
): Promise<ParsedFile> {
|
|
80
|
+
const { content, path: resolvedPath } = readTextFileWithinRoot({
|
|
81
|
+
rootPath: projectRoot,
|
|
82
|
+
filePath: fullPath,
|
|
83
|
+
});
|
|
84
|
+
const fileName = path.basename(resolvedPath);
|
|
138
85
|
|
|
139
86
|
return {
|
|
140
|
-
className,
|
|
141
|
-
package:
|
|
142
|
-
imports,
|
|
143
|
-
methods,
|
|
144
|
-
calls,
|
|
145
|
-
path:
|
|
87
|
+
className: extractClassName(content, fileName),
|
|
88
|
+
package: extractPackage(content),
|
|
89
|
+
imports: [...imports],
|
|
90
|
+
methods: extractMethodDefinitions(content),
|
|
91
|
+
calls: extractMethodCalls(content),
|
|
92
|
+
path: toPosix(path.relative(projectRoot, resolvedPath)),
|
|
146
93
|
};
|
|
147
94
|
}
|
|
@@ -1,89 +1,29 @@
|
|
|
1
1
|
'use server';
|
|
2
|
-
import type { ParsedFile, MethodCall, MethodDefinition, ImportDefinition } from '@/shared/types';
|
|
3
|
-
|
|
4
|
-
import fs from 'node:fs';
|
|
5
2
|
import path from 'node:path';
|
|
6
|
-
import { extractPythonPackageFromImport } from '@/app/utils/parser/python/extractPythonPackageFromImport';
|
|
7
3
|
|
|
8
|
-
|
|
9
|
-
* Extracts module path from Python __init__.py structure.
|
|
10
|
-
*/
|
|
11
|
-
function extractModulePath(filePath: string, projectRoot: string): string {
|
|
12
|
-
const relativePath = path.relative(projectRoot, filePath);
|
|
13
|
-
const parts = relativePath.split(path.sep);
|
|
4
|
+
import { readTextFileWithinRoot } from '@ankhorage/utility/node/fs';
|
|
14
5
|
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
import type { ImportDefinition, MethodCall, MethodDefinition, ParsedFile } from '@/shared/types';
|
|
7
|
+
import { toPosix } from '@/shared/utils/toPosix';
|
|
17
8
|
|
|
18
|
-
|
|
9
|
+
/*** Extracts module path from Python source structure. */
|
|
10
|
+
function extractModulePath(filePath: string, projectRoot: string): string {
|
|
11
|
+
const relativePath = toPosix(path.relative(projectRoot, filePath));
|
|
12
|
+
const parts = relativePath.split('/');
|
|
13
|
+
parts.pop();
|
|
19
14
|
return parts.join('.');
|
|
20
15
|
}
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
* Extracts import statements from Python code.
|
|
24
|
-
*/
|
|
25
|
-
function extractImports(content: string): ImportDefinition[] {
|
|
26
|
-
const imports: ImportDefinition[] = [];
|
|
27
|
-
|
|
28
|
-
// Match: import module
|
|
29
|
-
// Match: import module as alias
|
|
30
|
-
// Match: from module import something
|
|
31
|
-
const importRegex =
|
|
32
|
-
/(?:^|\n)\s*(?:from\s+([\w.]+)\s+)?import\s+([\w\s,*]+?)(?:\s+as\s+\w+)?(?:\s|$|#)/gm;
|
|
33
|
-
|
|
34
|
-
let match;
|
|
35
|
-
while ((match = importRegex.exec(content)) !== null) {
|
|
36
|
-
const fromModule = match[1];
|
|
37
|
-
const importedItems = match[2];
|
|
38
|
-
|
|
39
|
-
if (fromModule) {
|
|
40
|
-
// from X import Y
|
|
41
|
-
const pkg = extractPythonPackageFromImport(fromModule);
|
|
42
|
-
const isIntrinsic = fromModule.startsWith('.');
|
|
43
|
-
|
|
44
|
-
imports.push({
|
|
45
|
-
name: fromModule,
|
|
46
|
-
pkg,
|
|
47
|
-
isIntrinsic,
|
|
48
|
-
});
|
|
49
|
-
} else {
|
|
50
|
-
// import X, Y, Z
|
|
51
|
-
const mods = importedItems.split(',').map(m => m.trim());
|
|
52
|
-
for (const mod of mods) {
|
|
53
|
-
const pkg = extractPythonPackageFromImport(mod);
|
|
54
|
-
imports.push({
|
|
55
|
-
name: mod,
|
|
56
|
-
pkg,
|
|
57
|
-
isIntrinsic: false,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return imports;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Extracts the class name from Python content.
|
|
68
|
-
*/
|
|
17
|
+
/*** Extracts the class name from Python content. */
|
|
69
18
|
function extractClassName(content: string, fileName: string): string {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (classMatch) {
|
|
73
|
-
return classMatch[1];
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Fallback to filename without extension
|
|
19
|
+
const classMatch = /^class\s+([A-Za-z0-9_]+)/m.exec(content);
|
|
20
|
+
if (classMatch) return classMatch[1];
|
|
77
21
|
return path.basename(fileName, path.extname(fileName));
|
|
78
22
|
}
|
|
79
23
|
|
|
80
|
-
|
|
81
|
-
* Extracts method/function definitions from Python content.
|
|
82
|
-
*/
|
|
24
|
+
/*** Extracts method/function definitions from Python content. */
|
|
83
25
|
function extractMethodDefinitions(content: string): MethodDefinition[] {
|
|
84
26
|
const methods: MethodDefinition[] = [];
|
|
85
|
-
|
|
86
|
-
// Match function definitions: def method_name(params): or async def method_name(params):
|
|
87
27
|
const methodRegex =
|
|
88
28
|
/(?:^|\n)\s*(async\s+)?def\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*$$([^)]*)$$\s*(?:->([^:]+))?:/gm;
|
|
89
29
|
|
|
@@ -92,14 +32,11 @@ function extractMethodDefinitions(content: string): MethodDefinition[] {
|
|
|
92
32
|
const name = match[2];
|
|
93
33
|
const paramsStr = match[3];
|
|
94
34
|
const returnType = match[4]?.trim() || 'None';
|
|
95
|
-
|
|
96
|
-
// Parse parameters
|
|
97
35
|
const params = paramsStr
|
|
98
36
|
.split(',')
|
|
99
37
|
.map(p => p.trim())
|
|
100
38
|
.filter(p => p && p !== 'self' && p !== 'cls');
|
|
101
39
|
|
|
102
|
-
// Determine visibility (Python convention: _ prefix = protected, __ prefix = private)
|
|
103
40
|
let visibility: 'public' | 'protected' | 'private' | 'default' = 'public';
|
|
104
41
|
if (name.startsWith('__') && !name.endsWith('__')) {
|
|
105
42
|
visibility = 'private';
|
|
@@ -118,13 +55,9 @@ function extractMethodDefinitions(content: string): MethodDefinition[] {
|
|
|
118
55
|
return methods;
|
|
119
56
|
}
|
|
120
57
|
|
|
121
|
-
|
|
122
|
-
* Extract method calls from Python content.
|
|
123
|
-
*/
|
|
58
|
+
/*** Extracts method calls from Python content. */
|
|
124
59
|
function extractMethodCalls(content: string): MethodCall[] {
|
|
125
60
|
const calls: MethodCall[] = [];
|
|
126
|
-
|
|
127
|
-
// Match: object.method( or self.method(
|
|
128
61
|
const callRegex = /([a-zA-Z_][a-zA-Z0-9_]*)\.([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/g;
|
|
129
62
|
|
|
130
63
|
let match;
|
|
@@ -132,7 +65,6 @@ function extractMethodCalls(content: string): MethodCall[] {
|
|
|
132
65
|
const callee = match[1];
|
|
133
66
|
const method = match[2];
|
|
134
67
|
|
|
135
|
-
// Skip common built-in methods to reduce noise
|
|
136
68
|
if (
|
|
137
69
|
['append', 'extend', 'pop', 'remove', 'join', 'split', 'strip'].includes(method) &&
|
|
138
70
|
['str', 'list', 'dict', 'set'].includes(callee)
|
|
@@ -146,26 +78,24 @@ function extractMethodCalls(content: string): MethodCall[] {
|
|
|
146
78
|
return calls;
|
|
147
79
|
}
|
|
148
80
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
const calls = extractMethodCalls(content);
|
|
161
|
-
const relativePath = path.relative(projectRoot, fullPath);
|
|
81
|
+
/*** Parses Python metadata while consuming canonical dependency imports. */
|
|
82
|
+
export async function parsePythonFile(
|
|
83
|
+
fullPath: string,
|
|
84
|
+
projectRoot: string,
|
|
85
|
+
imports: readonly ImportDefinition[]
|
|
86
|
+
): Promise<ParsedFile> {
|
|
87
|
+
const { content, path: resolvedPath } = readTextFileWithinRoot({
|
|
88
|
+
rootPath: projectRoot,
|
|
89
|
+
filePath: fullPath,
|
|
90
|
+
});
|
|
91
|
+
const fileName = path.basename(resolvedPath);
|
|
162
92
|
|
|
163
93
|
return {
|
|
164
|
-
className,
|
|
165
|
-
package:
|
|
166
|
-
imports,
|
|
167
|
-
methods,
|
|
168
|
-
calls,
|
|
169
|
-
path:
|
|
94
|
+
className: extractClassName(content, fileName),
|
|
95
|
+
package: extractModulePath(resolvedPath, projectRoot),
|
|
96
|
+
imports: [...imports],
|
|
97
|
+
methods: extractMethodDefinitions(content),
|
|
98
|
+
calls: extractMethodCalls(content),
|
|
99
|
+
path: toPosix(path.relative(projectRoot, resolvedPath)),
|
|
170
100
|
};
|
|
171
101
|
}
|
|
@@ -1,57 +1,16 @@
|
|
|
1
|
-
import type { ParsedFile, MethodCall, MethodDefinition, ImportDefinition } from '@/shared/types';
|
|
2
|
-
|
|
3
1
|
import fs from 'node:fs/promises';
|
|
4
|
-
import { basename, relative
|
|
5
|
-
import ts from 'typescript';
|
|
6
|
-
import { extractTypeScriptPackageFromImport } from '@/app/utils/parser/typescript/extractTypeScriptPackageFromImport';
|
|
7
|
-
import { toPosix } from '@/shared/utils/toPosix';
|
|
8
|
-
import { parseProjectPath } from '@/shared/utils/parseProjectPath';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Extracts import statements from TypeScript code.
|
|
12
|
-
*/
|
|
13
|
-
function extractImports(content: string, filename: string): ImportDefinition[] {
|
|
14
|
-
const sourceFile = ts.createSourceFile('temp.ts', content, ts.ScriptTarget.Latest, true);
|
|
15
|
-
const imports: ImportDefinition[] = [];
|
|
16
|
-
|
|
17
|
-
sourceFile.forEachChild(node => {
|
|
18
|
-
if (!ts.isImportDeclaration(node)) return;
|
|
19
|
-
|
|
20
|
-
const fullPath = toPosix(filename).split('/').slice(0, -1).join('/');
|
|
21
|
-
const moduleSpecifier = (node.moduleSpecifier as ts.StringLiteral).text;
|
|
22
|
-
|
|
23
|
-
function resolveImportPath(curDir: string, specifier: string) {
|
|
24
|
-
const root = parseProjectPath();
|
|
2
|
+
import { basename, relative } from 'node:path';
|
|
25
3
|
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
isIntrinsic: true,
|
|
29
|
-
resolvedPath: resolve(curDir, specifier).slice(root.length + 1),
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
if (specifier.startsWith('@/'))
|
|
33
|
-
return {
|
|
34
|
-
isIntrinsic: true,
|
|
35
|
-
resolvedPath: specifier.replace(/^@/, 'src'),
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
return { isIntrinsic: false, resolvedPath: specifier };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const { resolvedPath, isIntrinsic } = resolveImportPath(fullPath, moduleSpecifier);
|
|
42
|
-
|
|
43
|
-
const pkg = extractTypeScriptPackageFromImport(resolvedPath);
|
|
44
|
-
imports.push({ name: pkg, pkg, isIntrinsic });
|
|
45
|
-
});
|
|
4
|
+
import ts from 'typescript';
|
|
46
5
|
|
|
47
|
-
|
|
48
|
-
}
|
|
6
|
+
import type { ImportDefinition, MethodCall, MethodDefinition, ParsedFile } from '@/shared/types';
|
|
7
|
+
import { toPosix } from '@/shared/utils/toPosix';
|
|
49
8
|
|
|
50
|
-
|
|
9
|
+
/***
|
|
51
10
|
* Extracts the class name from the content and filename fallback.
|
|
52
11
|
*/
|
|
53
12
|
function extractClassName(content: string, fileName: string): string {
|
|
54
|
-
const classMatch =
|
|
13
|
+
const classMatch = /class\s+(\w+)/.exec(content);
|
|
55
14
|
if (classMatch) {
|
|
56
15
|
return classMatch[1];
|
|
57
16
|
}
|
|
@@ -59,13 +18,14 @@ function extractClassName(content: string, fileName: string): string {
|
|
|
59
18
|
return basename(fileName, '.ts');
|
|
60
19
|
}
|
|
61
20
|
|
|
62
|
-
|
|
21
|
+
/***
|
|
63
22
|
* Extracts method definitions from TypeScript content.
|
|
64
23
|
*/
|
|
65
24
|
function extractMethodDefinitions(content: string): MethodDefinition[] {
|
|
66
25
|
const sourceFile = ts.createSourceFile('temp.ts', content, ts.ScriptTarget.Latest, true);
|
|
67
26
|
const methods: MethodDefinition[] = [];
|
|
68
27
|
|
|
28
|
+
/*** Visits syntax nodes while collecting parser metadata. */
|
|
69
29
|
function visit(node: ts.Node) {
|
|
70
30
|
if (ts.isMethodDeclaration(node) && node.name) {
|
|
71
31
|
const name = node.name.getText();
|
|
@@ -88,13 +48,14 @@ function extractMethodDefinitions(content: string): MethodDefinition[] {
|
|
|
88
48
|
return methods;
|
|
89
49
|
}
|
|
90
50
|
|
|
91
|
-
|
|
51
|
+
/***
|
|
92
52
|
* Extracts method calls from TypeScript content.
|
|
93
53
|
*/
|
|
94
54
|
function extractMethodCalls(content: string): MethodCall[] {
|
|
95
55
|
const sourceFile = ts.createSourceFile('temp.ts', content, ts.ScriptTarget.Latest, true);
|
|
96
56
|
const calls: MethodCall[] = [];
|
|
97
57
|
|
|
58
|
+
/*** Visits syntax nodes while collecting parser metadata. */
|
|
98
59
|
function visit(node: ts.Node) {
|
|
99
60
|
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
100
61
|
const callee = node.expression.expression.getText();
|
|
@@ -109,10 +70,14 @@ function extractMethodCalls(content: string): MethodCall[] {
|
|
|
109
70
|
return calls;
|
|
110
71
|
}
|
|
111
72
|
|
|
112
|
-
|
|
73
|
+
/***
|
|
113
74
|
* Parses a TypeScript file and returns metadata useful for diagram generation.
|
|
114
75
|
*/
|
|
115
|
-
export async function parseFile(
|
|
76
|
+
export async function parseFile(
|
|
77
|
+
fullPath: string,
|
|
78
|
+
projectRoot: string,
|
|
79
|
+
imports: readonly ImportDefinition[]
|
|
80
|
+
): Promise<ParsedFile> {
|
|
116
81
|
const posixFullPath = toPosix(fullPath);
|
|
117
82
|
const content = await fs.readFile(posixFullPath, 'utf-8');
|
|
118
83
|
const relativePath = toPosix(relative(projectRoot, posixFullPath));
|
|
@@ -121,7 +86,7 @@ export async function parseFile(fullPath: string, projectRoot: string): Promise<
|
|
|
121
86
|
|
|
122
87
|
return {
|
|
123
88
|
className: extractClassName(content, fullPath),
|
|
124
|
-
imports:
|
|
89
|
+
imports: [...imports],
|
|
125
90
|
methods: extractMethodDefinitions(content),
|
|
126
91
|
calls: extractMethodCalls(content),
|
|
127
92
|
package: segmentedPath.join('.'),
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ProjectDetection } from '@ankhorage/project-detector/types';
|
|
2
|
+
|
|
3
|
+
import { Language } from '../../shared/types';
|
|
4
|
+
import type { ParserSelection } from '../../types/parserSelection';
|
|
5
|
+
|
|
6
|
+
/*** Select a supported parser by evidence strength, evidence count, then stable parser order. */
|
|
7
|
+
export function selectParserLanguage(detection: ProjectDetection): ParserSelection {
|
|
8
|
+
const supported = [
|
|
9
|
+
Language.TypeScript,
|
|
10
|
+
Language.Java,
|
|
11
|
+
Language.Cpp,
|
|
12
|
+
Language.Python,
|
|
13
|
+
Language.Delphi,
|
|
14
|
+
Language.Kotlin,
|
|
15
|
+
];
|
|
16
|
+
const candidates = supported
|
|
17
|
+
.flatMap(language => {
|
|
18
|
+
const detected = detection.languages.find(candidate => candidate.id === language);
|
|
19
|
+
return detected ? [{ language, detected }] : [];
|
|
20
|
+
})
|
|
21
|
+
.sort(
|
|
22
|
+
(left, right) =>
|
|
23
|
+
right.detected.score - left.detected.score ||
|
|
24
|
+
right.detected.evidence.length - left.detected.evidence.length ||
|
|
25
|
+
supported.indexOf(left.language) - supported.indexOf(right.language)
|
|
26
|
+
);
|
|
27
|
+
const selected = candidates[0];
|
|
28
|
+
if (!selected) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`No supported parser detected. Found: ${detection.languages.map(language => language.id).join(', ') || 'unknown'}. Supported: ${supported.join(', ')}.`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
language: selected.language,
|
|
35
|
+
score: selected.detected.score,
|
|
36
|
+
indicators: selected.detected.evidence,
|
|
37
|
+
candidates: detection.languages,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AuditRuleResult } from '@/types/audit';
|
|
2
|
+
|
|
3
|
+
/*** Formats blocking audit-rule failures for terminal and CI output. */
|
|
4
|
+
export function formatAuditRuleFailures(
|
|
5
|
+
results: readonly AuditRuleResult[],
|
|
6
|
+
artifactPath: string
|
|
7
|
+
): string {
|
|
8
|
+
const failures = results.filter(
|
|
9
|
+
result => result.policy === 'blocking' && result.status === 'failed'
|
|
10
|
+
);
|
|
11
|
+
const ruleLines = failures.flatMap(result => {
|
|
12
|
+
const details =
|
|
13
|
+
result.details.length > 0
|
|
14
|
+
? result.details.map(detail => ` ${detail}`)
|
|
15
|
+
: [` ${result.message}`];
|
|
16
|
+
|
|
17
|
+
return [`✗ ${result.id}`, ...details, ''];
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return ['PKGViz audit failed', '', ...ruleLines, `Audit: ${artifactPath}`].join('\n');
|
|
21
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { resolveFileSystemPathWithinRoot, writeFileWithinRoot } from '@ankhorage/utility/node/fs';
|
|
2
|
+
|
|
3
|
+
import { createAuditAsync } from '@/features/audit/composition/createAuditAsync';
|
|
4
|
+
import { hasBlockingAuditRuleFailure } from '@/features/audit/domain/hasBlockingAuditRuleFailure';
|
|
5
|
+
import type { Audit, ResolveAuditConfigurationInput } from '@/types/audit';
|
|
6
|
+
|
|
7
|
+
/*** Creates, writes, and evaluates an audit while retaining the artifact on rule failure. */
|
|
8
|
+
export async function runAuditAsync(input: RunAuditInput): Promise<RunAuditResult> {
|
|
9
|
+
const audit = await createAuditAsync(input.projectPath, input.configuration);
|
|
10
|
+
const body = input.pretty ? JSON.stringify(audit, null, 2) : JSON.stringify(audit);
|
|
11
|
+
|
|
12
|
+
await writeFileWithinRoot({
|
|
13
|
+
rootPath: input.projectPath,
|
|
14
|
+
filePath: input.outputPath,
|
|
15
|
+
body: new TextEncoder().encode(body),
|
|
16
|
+
exclusive: false,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const artifactPath = resolveFileSystemPathWithinRoot(input.projectPath, input.outputPath);
|
|
20
|
+
const shouldFail =
|
|
21
|
+
audit.configuration.failOnRuleViolation && hasBlockingAuditRuleFailure(audit.evaluation.rules);
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
audit,
|
|
25
|
+
artifactPath,
|
|
26
|
+
exitCode: shouldFail ? 2 : 0,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface RunAuditInput {
|
|
31
|
+
readonly projectPath: string;
|
|
32
|
+
readonly outputPath: string;
|
|
33
|
+
readonly pretty: boolean;
|
|
34
|
+
readonly configuration?: ResolveAuditConfigurationInput;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface RunAuditResult {
|
|
38
|
+
readonly audit: Audit;
|
|
39
|
+
readonly artifactPath: string;
|
|
40
|
+
readonly exitCode: 0 | 2;
|
|
41
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
import { ChevronRight, Home } from 'lucide-react';
|
|
4
3
|
import Link from 'next/link';
|
|
4
|
+
import React from 'react';
|
|
5
5
|
|
|
6
|
+
/*** Renders package navigation breadcrumbs without empty path segments. */
|
|
6
7
|
export default function Breadcrumb({ path, onNavigate }: BreadcrumbProps) {
|
|
7
|
-
const parts = path.split('/')
|
|
8
|
+
const parts = path.split('/').filter(Boolean);
|
|
8
9
|
|
|
9
10
|
return (
|
|
10
11
|
<nav className="flex items-center space-x-1 text-sm">
|
|
@@ -13,10 +14,10 @@ export default function Breadcrumb({ path, onNavigate }: BreadcrumbProps) {
|
|
|
13
14
|
</Link>
|
|
14
15
|
|
|
15
16
|
{parts.map((part, index) => {
|
|
16
|
-
const currentPath = parts.
|
|
17
|
+
const currentPath = parts.slice(0, index + 1).join('/');
|
|
17
18
|
|
|
18
19
|
return (
|
|
19
|
-
<div key={
|
|
20
|
+
<div key={currentPath} className="flex items-center">
|
|
20
21
|
<ChevronRight className="h-4 w-4 text-foreground opacity-20" />
|
|
21
22
|
<Link href="#" onClick={() => onNavigate(currentPath)} className="ml-1 text-foreground">
|
|
22
23
|
{part}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { DownloadIcon } from 'lucide-react';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
import { downloadAuditJsonAction, downloadAuditXmlAction } from '@/app/actions/audit.actions';
|
|
6
|
+
import { SidebarRow } from '@/components/sidebar/SidebarRow';
|
|
7
|
+
|
|
8
|
+
/*** Renders secondary audit-export actions inside the Export sidebar tab. */
|
|
9
|
+
export function ExportPanel() {
|
|
10
|
+
return (
|
|
11
|
+
<div className="pt-3">
|
|
12
|
+
<SidebarRow>
|
|
13
|
+
<ExportButton
|
|
14
|
+
format="JSON"
|
|
15
|
+
mimeType="application/json"
|
|
16
|
+
onExport={downloadAuditJsonAction}
|
|
17
|
+
/>
|
|
18
|
+
</SidebarRow>
|
|
19
|
+
<SidebarRow>
|
|
20
|
+
<ExportButton format="XML" mimeType="application/xml" onExport={downloadAuditXmlAction} />
|
|
21
|
+
</SidebarRow>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/*** Downloads one serialized audit format. */
|
|
27
|
+
function ExportButton({ format, mimeType, onExport }: ExportButtonProps) {
|
|
28
|
+
return (
|
|
29
|
+
<button
|
|
30
|
+
type="button"
|
|
31
|
+
onClick={async () => {
|
|
32
|
+
const { data, filename } = await onExport();
|
|
33
|
+
const blob = new Blob([data], { type: mimeType });
|
|
34
|
+
const url = URL.createObjectURL(blob);
|
|
35
|
+
const anchor = document.createElement('a');
|
|
36
|
+
anchor.href = url;
|
|
37
|
+
anchor.download = filename;
|
|
38
|
+
anchor.click();
|
|
39
|
+
URL.revokeObjectURL(url);
|
|
40
|
+
}}
|
|
41
|
+
className="flex cursor-pointer items-center text-xs hover:text-blue-600 dark:hover:text-blue-400"
|
|
42
|
+
>
|
|
43
|
+
<DownloadIcon size={10} className="mr-1.5" />
|
|
44
|
+
<span>{format}</span>
|
|
45
|
+
</button>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface ExportButtonProps {
|
|
50
|
+
readonly format: string;
|
|
51
|
+
readonly mimeType: string;
|
|
52
|
+
readonly onExport: () => Promise<{ data: string; filename: string }>;
|
|
53
|
+
}
|
|
@@ -4,6 +4,7 @@ import ThemeToggle from '@/components/ThemeToggle';
|
|
|
4
4
|
import { t } from '@/i18n/i18n';
|
|
5
5
|
import { getProjectName } from '@/shared/utils/getProjectName';
|
|
6
6
|
|
|
7
|
+
/*** Renders the application header. */
|
|
7
8
|
export default function Header({ children, title }: HeaderProps) {
|
|
8
9
|
const projectName = getProjectName();
|
|
9
10
|
|