next-route-graph 1.0.2 → 1.2.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/CHANGELOG.md +95 -0
- package/CONTRIBUTING.md +74 -0
- package/README.md +169 -134
- package/SECURITY.md +19 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +126 -44
- package/dist/core/analyzer.d.ts +16 -0
- package/dist/core/analyzer.d.ts.map +1 -0
- package/dist/core/analyzer.js +113 -29
- package/dist/core/detector.d.ts +19 -0
- package/dist/core/detector.d.ts.map +1 -0
- package/dist/core/detector.js +31 -3
- package/dist/core/inspect.d.ts +6 -0
- package/dist/core/inspect.d.ts.map +1 -0
- package/dist/core/inspect.js +21 -0
- package/dist/core/linter.d.ts +11 -0
- package/dist/core/linter.d.ts.map +1 -0
- package/dist/core/linter.js +194 -0
- package/dist/core/parser.d.ts +95 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +242 -15
- package/dist/core/scanner.d.ts +12 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +32 -6
- package/dist/errors/index.d.ts +35 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +65 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/preview.d.ts +4 -0
- package/dist/preview.d.ts.map +1 -0
- package/dist/preview.js +25 -0
- package/dist/render/dot.d.ts +13 -0
- package/dist/render/dot.d.ts.map +1 -0
- package/dist/render/dot.js +66 -0
- package/dist/render/flat.d.ts +13 -0
- package/dist/render/flat.d.ts.map +1 -0
- package/dist/render/flat.js +14 -2
- package/dist/render/graph.d.ts +13 -0
- package/dist/render/graph.d.ts.map +1 -0
- package/dist/render/graph.js +53 -0
- package/dist/render/html.d.ts +8 -0
- package/dist/render/html.d.ts.map +1 -0
- package/dist/render/html.js +718 -0
- package/dist/render/index.d.ts +20 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +37 -0
- package/dist/render/json.d.ts +13 -0
- package/dist/render/json.d.ts.map +1 -0
- package/dist/render/json.js +12 -14
- package/dist/render/markdown.d.ts +13 -0
- package/dist/render/markdown.d.ts.map +1 -0
- package/dist/render/markdown.js +59 -0
- package/dist/render/mermaid.d.ts +13 -0
- package/dist/render/mermaid.d.ts.map +1 -0
- package/dist/render/mermaid.js +64 -0
- package/dist/render/renderer.interface.d.ts +8 -0
- package/dist/render/renderer.interface.d.ts.map +1 -0
- package/dist/render/renderer.interface.js +1 -0
- package/dist/render/svg.d.ts +8 -0
- package/dist/render/svg.d.ts.map +1 -0
- package/dist/render/svg.js +76 -0
- package/dist/render/tree.d.ts +13 -0
- package/dist/render/tree.d.ts.map +1 -0
- package/dist/render/tree.js +57 -7
- package/dist/types/index.d.ts +132 -0
- package/dist/types/index.d.ts.map +1 -0
- package/docs/ARCHITECTURE.md +71 -0
- package/docs/NEW_FEATURES.md +16 -0
- package/docs/adr/0001-offline-reports-and-shared-route-graph.md +29 -0
- package/docs/route-report.png +0 -0
- package/package.json +71 -52
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
`next-route-graph` scans App Router source files without importing the target project's code. The CLI and SDK share the same analysis pipeline. Renderers consume plain analysis data and return strings; file writes, HTTP serving, and exit policy belong outside that pipeline.
|
|
4
|
+
|
|
5
|
+
```mermaid
|
|
6
|
+
flowchart TD
|
|
7
|
+
CLI[CLI: options, output, exit policy] --> Inspect[inspectProject]
|
|
8
|
+
SDK[TypeScript SDK] --> Inspect
|
|
9
|
+
Inspect --> Detect[Detect App Router root]
|
|
10
|
+
Detect --> Scan[Discover source files]
|
|
11
|
+
Scan --> Analyze[Analyze convention files]
|
|
12
|
+
Analyze --> Parse[Comment-aware text parser]
|
|
13
|
+
Analyze --> Lint[Route diagnostics]
|
|
14
|
+
Analyze --> Result[AnalysisResult]
|
|
15
|
+
Result --> Filter[Optional immutable endpoint filter]
|
|
16
|
+
Filter --> Render[OutputRenderer]
|
|
17
|
+
Render --> Text[Tree / Flat / JSON / Markdown]
|
|
18
|
+
Render --> Graph[Shared URL graph]
|
|
19
|
+
Graph --> Visual[SVG / Mermaid / DOT / HTML]
|
|
20
|
+
Render --> CLI
|
|
21
|
+
CLI --> Files[File or stdout]
|
|
22
|
+
CLI --> Preview[Loopback HTTP preview]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Boundaries
|
|
26
|
+
|
|
27
|
+
| Module | Responsibility |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| `core/detector.ts` | Select `app/`, `src/app/`, or a direct App Router directory; report missing or ambiguous roots. |
|
|
30
|
+
| `core/scanner.ts` | Walk supported source files. Skip private, hidden, dependency, and build directories; do not traverse symlinks. |
|
|
31
|
+
| `core/parser.ts` | Recognize convention files, directives, declared methods, and literal config. Resolve URL paths, including interception relative to URL segments. It is a text parser, not an AST. |
|
|
32
|
+
| `core/analyzer.ts` | Read each convention file once, construct endpoint entries, index layout files, attach outer-to-inner layout chains, compute counts, and run lint. |
|
|
33
|
+
| `core/inspect.ts` | Compose detection → scan → analysis for the CLI and SDK; provide immutable filtering and full scan timing. |
|
|
34
|
+
| `core/linter.ts` | Return diagnostics, never choose process exit codes. Partition collision checks by parallel branch and exclude intercepted variants from ordinary URL collision checks. |
|
|
35
|
+
| `render/graph.ts` | Build a URL trie including non-endpoint segments; retain every source at shared URLs. Provide shared markup escaping for HTML/XML. |
|
|
36
|
+
| `render/*` | Convert `AnalysisResult` into text, SVG, or HTML. No filesystem writes, network calls, or process exits. |
|
|
37
|
+
| `preview.ts` | Serve only an in-memory HTML report on `127.0.0.1`, with GET/HEAD, no filesystem access, and explicit listen errors. |
|
|
38
|
+
| `cli.ts` | Validate output selection and port; choose format, destination, and CI policy; report errors to stderr. |
|
|
39
|
+
|
|
40
|
+
## Data contracts
|
|
41
|
+
|
|
42
|
+
`DiscoveredFile` has an absolute path for reads and a normalized App Router-relative path for output. `RouteEntry` represents an endpoint source, not a unique URL: parallel views and intercepted variants can share a public path. `RouteFile` describes convention files in the endpoint's filesystem directory. `layoutChain` records the layouts found in ancestor directories.
|
|
43
|
+
|
|
44
|
+
`AnalysisResult` contains project identity, endpoint entries, summary counts, scan duration, and lint results. JSON exports preserve that shape. `filterRoutes()` returns a new result, recalculates endpoint-related counts, and retains project-wide convention totals and diagnostics. Strict validation always uses the full scan.
|
|
45
|
+
|
|
46
|
+
`RouteGraphNode` represents a URL segment. Its `routes` array retains every endpoint source at that path; an empty array means a grouping segment. Nodes have unique export-local IDs, a parent ID, depth, and normalized path. SVG, Mermaid, and DOT use this same model. These edges represent URL ancestry, not layout or import relationships.
|
|
47
|
+
|
|
48
|
+
## Complexity and failure handling
|
|
49
|
+
|
|
50
|
+
Scanning and source extraction scale with discovered files and bytes read. Layout lookup uses a directory index and walks only each endpoint's ancestors, rather than searching every file at every depth. Graph construction creates nodes for URL prefixes and sorts siblings for deterministic traversal. Source reads remain sequential to bound open files and memory; no concurrency framework or cache is needed for a one-shot local scan.
|
|
51
|
+
|
|
52
|
+
Detection, directory reads, and convention-file reads raise typed errors with codes and hints. Read failures abort analysis: silently substituting an empty source would turn missing metadata into misleading findings. Renderers do not catch these errors or mutate process state. Unknown renderer formats throw rather than silently producing a terminal tree.
|
|
53
|
+
|
|
54
|
+
CLI reports are written before strict lint exit policy runs, so failing CI jobs can retain artifacts. Preview validates strict policy before starting, so a failed check never leaves a server alive. Operational notices use stderr; successful exports go to stdout or a file.
|
|
55
|
+
|
|
56
|
+
## Offline report and security
|
|
57
|
+
|
|
58
|
+
The report contains a pre-rendered SVG, route table, health diagnostics, and encoded JSON for interaction. HTML/XML text and attributes are escaped; `<` is Unicode-escaped in embedded JSON to prevent script termination. Browser interactions create text nodes instead of interpolating source data into HTML. A content security policy blocks network dependencies. Browser script and styles are inline so reports work from disk.
|
|
59
|
+
|
|
60
|
+
CSV cells are quoted and formula-leading values receive a leading apostrophe. Downloads use local Blob URLs. Clipboard failure opens the selectable source instead. The preview serves a static snapshot with no cache, no directory listing, and no arbitrary file routes.
|
|
61
|
+
|
|
62
|
+
The report exposes filenames, endpoint names, and detected metadata, not file bodies. Its purpose is architecture inspection, not vulnerability detection or runtime verification.
|
|
63
|
+
|
|
64
|
+
## Verification
|
|
65
|
+
|
|
66
|
+
- Node's test runner covers parsing, scanning, linting, renderers, source escaping, immutable filtering, the built SDK, CLI file exports, strict policy, and HTTP preview behavior.
|
|
67
|
+
- `npm test` builds production artifacts first, so CLI and consumer tests cannot accidentally validate an old `dist/`.
|
|
68
|
+
- Playwright is development-only. Browser tests open local HTML offline and exercise keyboard selection, duplicate endpoint details, search, filters, all downloads, SVG XML validity, hostile source data, formula-safe CSV, and mobile overflow.
|
|
69
|
+
- CI tests the CLI on Windows and Linux and runs browser checks on Linux. No Next.js runtime is required.
|
|
70
|
+
|
|
71
|
+
See [ADR 0001](adr/0001-offline-reports-and-shared-route-graph.md) for the rendering trade-off and [README limitations](../README.md#scope-and-limitations) for the analysis boundary.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Improvement evidence
|
|
2
|
+
|
|
3
|
+
The purpose of this work is a more useful route inspector, not a larger feature count. GitRoll scores must be measured by GitRoll after a rescan; this document makes no predicted score claims.
|
|
4
|
+
|
|
5
|
+
| Area | Concrete improvement | Evidence |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| Architecture | One scan entry point for CLI and SDK; output and preview stay outside analysis; indexed layout lookup. | `src/core/inspect.ts`, `src/core/analyzer.ts`, workflow and consumer tests. |
|
|
8
|
+
| Interoperability | Rendered SVG, offline HTML, existing documentation/machine formats, and a shared graph exposed to SDK consumers. | `src/render/graph.ts`, `src/render/svg.ts`, export and browser tests. |
|
|
9
|
+
| Useful exploration | Select endpoint sources and layout chains; search/filter routes; inspect project health; download results. | `src/render/html.ts`, `tests/browser/report.test.mjs`. |
|
|
10
|
+
| Correctness | Interception target resolution, valid parallel variants, API-only layouts, case-sensitive paths, dynamic-prefix collisions, explicit read failures. | `tests/report_workflow.test.ts` plus existing parser/linter fixtures. |
|
|
11
|
+
| Safety | Escaped source data, restrictive report CSP, spreadsheet-safe CSV, loopback-only preview. | Hostile-input browser checks, markup checks, HTTP integration tests. |
|
|
12
|
+
| Documentation | Working examples, exit-code contract, explicit static-analysis limitations, architecture boundaries, and an implemented ADR. | README, architecture guide, ADR, CI workflow. |
|
|
13
|
+
|
|
14
|
+
The SVG URL graph is deliberately simple. It includes missing parent segments and keeps all endpoint sources without adding a graph runtime, CDN, database, plugin framework, watch daemon, or a replacement Next.js compiler. Mermaid/DOT remain useful source exports; HTML renders a native SVG instead of pretending those source blocks are visual previews.
|
|
15
|
+
|
|
16
|
+
Run `npm run typecheck`, `npm test`, and `npm run test:browser` to reproduce the checks. Browser setup and artifact generation are documented in the [README](../README.md#development).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# ADR 0001: Offline SVG reports with a shared URL graph
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-11-10
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
The CLI exports Mermaid and DOT source, but users also need a diagram that is already rendered and a report they can inspect without running a graph tool. A list of route cards does not convey nesting. Duplicate public URLs can represent valid parallel or intercepted sources and must remain inspectable.
|
|
9
|
+
|
|
10
|
+
## Decision
|
|
11
|
+
|
|
12
|
+
Build one URL hierarchy from `RouteEntry[]`, including URL segments without endpoints. Keep an array of endpoint sources on each node. Use the model for SVG, Mermaid, and DOT; embed SVG directly in the offline HTML report. Provide source/layout details beside the diagram, a filterable route table, full-project health checks, and one export selector.
|
|
13
|
+
|
|
14
|
+
Keep analysis independent of transport: renderers return strings; the CLI writes files or starts a small loopback HTTP server. Reuse the same `inspectProject()` pipeline in the CLI and SDK. Retain existing low-level APIs.
|
|
15
|
+
|
|
16
|
+
## Alternatives
|
|
17
|
+
|
|
18
|
+
- Bundle Mermaid and Graphviz renderers: more JavaScript and maintenance for a graph that can be drawn directly with SVG.
|
|
19
|
+
- Load a CDN: breaks offline reports and introduces network and privacy requirements.
|
|
20
|
+
- Add a graph application/framework: unnecessary for URL ancestry, selection, and basic filtering.
|
|
21
|
+
- Keep only source exports: useful for pipelines, but does not meet the need for a rendered artifact.
|
|
22
|
+
|
|
23
|
+
## Consequences
|
|
24
|
+
|
|
25
|
+
No new runtime dependency is required. SVG works in browsers, documents, and design tools, and the HTML remains a portable single file. Missing segments and parallel sources use consistent semantics across visual formats.
|
|
26
|
+
|
|
27
|
+
The map is a scrollable hierarchy rather than a force-directed canvas; it does not attempt drag layouts, runtime navigation, import analysis, or continuous watching. Large reports grow with endpoint count. The source parser remains heuristic and documented as such; adding a compiler dependency would require demonstrated parsing needs and its own decision.
|
|
28
|
+
|
|
29
|
+
Playwright is a development-only dependency to verify the actual offline browser behavior and downloads. Unit and integration tests continue using Node's built-in runner.
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,52 +1,71 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "next-route-graph",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "
|
|
5
|
-
"type": "module",
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
},
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "next-route-graph",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Inspect, lint, and visualize the structure of a Next.js App Router project from the terminal or SDK",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"next-route-graph": "dist/cli.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"docs",
|
|
21
|
+
"CHANGELOG.md",
|
|
22
|
+
"CONTRIBUTING.md",
|
|
23
|
+
"SECURITY.md"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"dev": "tsx src/cli.ts",
|
|
30
|
+
"build": "tsc -p tsconfig.build.json",
|
|
31
|
+
"typecheck": "tsc --noEmit",
|
|
32
|
+
"pretest": "npm run build",
|
|
33
|
+
"test": "tsx --test tests/run.mjs",
|
|
34
|
+
"pretest:browser": "npm run build",
|
|
35
|
+
"test:browser": "node --test tests/browser/report.test.mjs",
|
|
36
|
+
"prepublishOnly": "npm run typecheck && npm test"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"nextjs",
|
|
40
|
+
"app-router",
|
|
41
|
+
"routes",
|
|
42
|
+
"cli",
|
|
43
|
+
"visualization",
|
|
44
|
+
"route-map",
|
|
45
|
+
"mermaid",
|
|
46
|
+
"linter",
|
|
47
|
+
"typescript"
|
|
48
|
+
],
|
|
49
|
+
"author": {
|
|
50
|
+
"name": "Nima Soltanian",
|
|
51
|
+
"url": "https://github.com/Nima-sltn"
|
|
52
|
+
},
|
|
53
|
+
"license": "MIT",
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "https://github.com/Nima-sltn/next-route-graph.git"
|
|
57
|
+
},
|
|
58
|
+
"bugs": {
|
|
59
|
+
"url": "https://github.com/Nima-sltn/next-route-graph/issues"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"commander": "^12.1.0",
|
|
63
|
+
"picocolors": "^1.1.0"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/node": "^20.19.43",
|
|
67
|
+
"playwright": "^1.62.1",
|
|
68
|
+
"tsx": "^4.7.0",
|
|
69
|
+
"typescript": "^5.3.3"
|
|
70
|
+
}
|
|
71
|
+
}
|