@route-intelligence/shared 2.1.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/dist/index.d.ts +288 -0
- package/dist/index.js +43 -0
- package/package.json +38 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
type RouteNodeType = 'route' | 'layout' | 'template' | 'loading' | 'error' | 'global-error' | 'not-found' | 'forbidden' | 'unauthorized' | 'middleware' | 'api-route' | 'redirect' | 'rewrite' | 'external-url';
|
|
2
|
+
type RouteEdgeType = 'navigation' | 'redirect' | 'permanent-redirect' | 'rewrite' | 'import' | 'layout-parent' | 'template-parent' | 'conditional-navigation' | 'middleware-match' | 'api-call' | 'prefetch' | 'intercepted-by' | 'dependency';
|
|
3
|
+
type ConditionKind = 'auth' | 'role' | 'permission' | 'feature-flag' | 'subscription' | 'locale' | 'env' | 'cookie' | 'header' | 'search-param' | 'query-param' | 'unknown';
|
|
4
|
+
type ConditionConfidence = 'certain' | 'inferred' | 'heuristic';
|
|
5
|
+
interface SourceLocation {
|
|
6
|
+
filePath: string;
|
|
7
|
+
line: number;
|
|
8
|
+
column: number;
|
|
9
|
+
endLine?: number;
|
|
10
|
+
endColumn?: number;
|
|
11
|
+
}
|
|
12
|
+
interface Condition {
|
|
13
|
+
kind: ConditionKind;
|
|
14
|
+
expression: string;
|
|
15
|
+
negated: boolean;
|
|
16
|
+
confidence: ConditionConfidence;
|
|
17
|
+
}
|
|
18
|
+
type DiagnosticSeverity = 'error' | 'warning' | 'info';
|
|
19
|
+
type DiagnosticRuleId = 'dead-route' | 'dead-layout' | 'broken-link' | 'broken-redirect' | 'redirect-cycle' | 'circular-navigation' | 'shadowed-route' | 'duplicate-route' | 'impossible-route' | 'middleware-gap' | 'missing-error-boundary' | 'missing-loading' | 'open-redirect';
|
|
20
|
+
interface Diagnostic {
|
|
21
|
+
ruleId: DiagnosticRuleId | string;
|
|
22
|
+
severity: DiagnosticSeverity;
|
|
23
|
+
message: string;
|
|
24
|
+
loc?: SourceLocation;
|
|
25
|
+
nodeId?: string;
|
|
26
|
+
edgeId?: string;
|
|
27
|
+
}
|
|
28
|
+
type NavigationSource = 'Link' | 'router.push' | 'router.replace' | 'router.prefetch' | 'router.back' | 'router.forward' | 'redirect' | 'permanentRedirect' | 'NextResponse.redirect' | 'NextResponse.rewrite' | 'window.location' | 'window.open' | 'history.pushState' | 'history.replaceState' | 'Navigate' | 'custom' | 'unknown';
|
|
29
|
+
type RuntimeKind = 'nodejs' | 'edge' | 'browser';
|
|
30
|
+
type RenderingKind = 'static' | 'dynamic' | 'isr' | 'streaming';
|
|
31
|
+
interface NodeAttributes {
|
|
32
|
+
type: RouteNodeType;
|
|
33
|
+
path: string;
|
|
34
|
+
filePath: string;
|
|
35
|
+
segment: string;
|
|
36
|
+
isDynamic: boolean;
|
|
37
|
+
isCatchAll: boolean;
|
|
38
|
+
isOptionalCatchAll: boolean;
|
|
39
|
+
isParallelSlot: boolean;
|
|
40
|
+
slotName?: string;
|
|
41
|
+
isIntercepted: boolean;
|
|
42
|
+
interceptLevel?: '.' | '..' | '(..)(..)' | '...';
|
|
43
|
+
isRouteGroup: boolean;
|
|
44
|
+
groupName?: string;
|
|
45
|
+
runtime: RuntimeKind;
|
|
46
|
+
rendering: RenderingKind;
|
|
47
|
+
isClientComponent: boolean;
|
|
48
|
+
isServerComponent: boolean;
|
|
49
|
+
isReachable: boolean;
|
|
50
|
+
isDead: boolean;
|
|
51
|
+
depth: number;
|
|
52
|
+
tags: string[];
|
|
53
|
+
conditions: Condition[];
|
|
54
|
+
diagnostics: Diagnostic[];
|
|
55
|
+
loc: SourceLocation;
|
|
56
|
+
}
|
|
57
|
+
interface EdgeAttributes {
|
|
58
|
+
type: RouteEdgeType;
|
|
59
|
+
method?: 'push' | 'replace';
|
|
60
|
+
isExternal: boolean;
|
|
61
|
+
source: NavigationSource;
|
|
62
|
+
conditions: Condition[];
|
|
63
|
+
loc: SourceLocation;
|
|
64
|
+
diagnostics: Diagnostic[];
|
|
65
|
+
}
|
|
66
|
+
interface SerializedNode {
|
|
67
|
+
id: string;
|
|
68
|
+
attributes: NodeAttributes;
|
|
69
|
+
}
|
|
70
|
+
interface SerializedEdge {
|
|
71
|
+
id: string;
|
|
72
|
+
source: string;
|
|
73
|
+
target: string;
|
|
74
|
+
attributes: EdgeAttributes;
|
|
75
|
+
}
|
|
76
|
+
interface SerializedGraph {
|
|
77
|
+
version: '1.0';
|
|
78
|
+
generatedAt: string;
|
|
79
|
+
root: string;
|
|
80
|
+
nodes: SerializedNode[];
|
|
81
|
+
edges: SerializedEdge[];
|
|
82
|
+
metadata?: GraphMetadata;
|
|
83
|
+
}
|
|
84
|
+
interface GraphMetadata {
|
|
85
|
+
pluginIds: string[];
|
|
86
|
+
totalRoutes: number;
|
|
87
|
+
totalLayouts: number;
|
|
88
|
+
totalApiRoutes: number;
|
|
89
|
+
deadRouteCount: number;
|
|
90
|
+
cycleCount: number;
|
|
91
|
+
maintainabilityScore?: number;
|
|
92
|
+
riskScore?: number;
|
|
93
|
+
}
|
|
94
|
+
declare function createDefaultNodeAttributes(overrides: Partial<NodeAttributes> & Pick<NodeAttributes, 'type' | 'path' | 'filePath'>): NodeAttributes;
|
|
95
|
+
declare function createDefaultEdgeAttributes(overrides: Partial<EdgeAttributes> & Pick<EdgeAttributes, 'type' | 'source'>): EdgeAttributes;
|
|
96
|
+
|
|
97
|
+
interface PluginCapabilities {
|
|
98
|
+
supportsAppRouter: boolean;
|
|
99
|
+
supportsPagesRouter: boolean;
|
|
100
|
+
supportsMiddleware: boolean;
|
|
101
|
+
supportsApiRoutes: boolean;
|
|
102
|
+
supportsI18n: boolean;
|
|
103
|
+
supportsIncrementalAnalysis: boolean;
|
|
104
|
+
}
|
|
105
|
+
interface PluginConfig {
|
|
106
|
+
[key: string]: unknown;
|
|
107
|
+
}
|
|
108
|
+
interface ProjectContext {
|
|
109
|
+
root: string;
|
|
110
|
+
config: AnalyzerConfig;
|
|
111
|
+
pluginConfig: PluginConfig;
|
|
112
|
+
}
|
|
113
|
+
interface AnalyzerConfig {
|
|
114
|
+
root: string;
|
|
115
|
+
plugins: FrameworkPlugin[];
|
|
116
|
+
include?: string[];
|
|
117
|
+
exclude?: string[];
|
|
118
|
+
cache?: {
|
|
119
|
+
enabled: boolean;
|
|
120
|
+
directory: string;
|
|
121
|
+
};
|
|
122
|
+
output?: {
|
|
123
|
+
formats: string[];
|
|
124
|
+
directory: string;
|
|
125
|
+
};
|
|
126
|
+
rules?: Record<string, 'error' | 'warn' | 'off'>;
|
|
127
|
+
}
|
|
128
|
+
type RawRouteType = 'route' | 'layout' | 'template' | 'loading' | 'error' | 'global-error' | 'not-found' | 'forbidden' | 'unauthorized' | 'middleware' | 'api-route';
|
|
129
|
+
interface RawRoute {
|
|
130
|
+
id: string;
|
|
131
|
+
type: RawRouteType;
|
|
132
|
+
filePath: string;
|
|
133
|
+
urlPath: string;
|
|
134
|
+
segment: string;
|
|
135
|
+
isDynamic: boolean;
|
|
136
|
+
isCatchAll: boolean;
|
|
137
|
+
isOptionalCatchAll: boolean;
|
|
138
|
+
isParallelSlot: boolean;
|
|
139
|
+
slotName?: string;
|
|
140
|
+
isIntercepted: boolean;
|
|
141
|
+
interceptLevel?: '.' | '..' | '(..)(..)' | '...';
|
|
142
|
+
isRouteGroup: boolean;
|
|
143
|
+
groupName?: string;
|
|
144
|
+
parentLayoutId?: string;
|
|
145
|
+
parentTemplateId?: string;
|
|
146
|
+
tags: string[];
|
|
147
|
+
}
|
|
148
|
+
type NavigationDestination = {
|
|
149
|
+
kind: 'static';
|
|
150
|
+
path: string;
|
|
151
|
+
} | {
|
|
152
|
+
kind: 'template-literal';
|
|
153
|
+
template: string;
|
|
154
|
+
params: string[];
|
|
155
|
+
} | {
|
|
156
|
+
kind: 'dynamic';
|
|
157
|
+
expression: string;
|
|
158
|
+
} | {
|
|
159
|
+
kind: 'external';
|
|
160
|
+
url: string;
|
|
161
|
+
};
|
|
162
|
+
interface NavigationCall {
|
|
163
|
+
callee: string;
|
|
164
|
+
destination: NavigationDestination;
|
|
165
|
+
method?: 'push' | 'replace';
|
|
166
|
+
conditions: Condition[];
|
|
167
|
+
loc: SourceLocation;
|
|
168
|
+
}
|
|
169
|
+
interface JSXLink {
|
|
170
|
+
componentName: string;
|
|
171
|
+
destination: NavigationDestination;
|
|
172
|
+
prefetch?: boolean;
|
|
173
|
+
conditions: Condition[];
|
|
174
|
+
loc: SourceLocation;
|
|
175
|
+
}
|
|
176
|
+
interface SemanticImport {
|
|
177
|
+
moduleSpecifier: string;
|
|
178
|
+
namedImports: string[];
|
|
179
|
+
defaultImport?: string;
|
|
180
|
+
loc: SourceLocation;
|
|
181
|
+
}
|
|
182
|
+
interface SemanticExport {
|
|
183
|
+
name: string;
|
|
184
|
+
isDefault: boolean;
|
|
185
|
+
loc: SourceLocation;
|
|
186
|
+
}
|
|
187
|
+
interface ComponentDeclaration {
|
|
188
|
+
name: string;
|
|
189
|
+
isDefault: boolean;
|
|
190
|
+
loc: SourceLocation;
|
|
191
|
+
}
|
|
192
|
+
interface ConditionalBlock {
|
|
193
|
+
expression: string;
|
|
194
|
+
conditions: Condition[];
|
|
195
|
+
loc: SourceLocation;
|
|
196
|
+
}
|
|
197
|
+
interface SemanticFile {
|
|
198
|
+
readonly path: string;
|
|
199
|
+
readonly isClientComponent: boolean;
|
|
200
|
+
readonly isServerComponent: boolean;
|
|
201
|
+
readonly exports: ReadonlyArray<SemanticExport>;
|
|
202
|
+
readonly imports: ReadonlyArray<SemanticImport>;
|
|
203
|
+
readonly components: ReadonlyArray<ComponentDeclaration>;
|
|
204
|
+
readonly navigationCalls: ReadonlyArray<NavigationCall>;
|
|
205
|
+
readonly jsxLinks: ReadonlyArray<JSXLink>;
|
|
206
|
+
readonly conditionalBlocks: ReadonlyArray<ConditionalBlock>;
|
|
207
|
+
/** Escape hatch for plugin-specific analysis — typed as unknown to avoid ts-morph in shared */
|
|
208
|
+
readonly sourceFile: unknown;
|
|
209
|
+
}
|
|
210
|
+
interface DiscoveredEdge {
|
|
211
|
+
sourceId: string;
|
|
212
|
+
targetId?: string;
|
|
213
|
+
targetPath?: string;
|
|
214
|
+
type: RouteEdgeType;
|
|
215
|
+
source: NavigationSource;
|
|
216
|
+
method?: 'push' | 'replace';
|
|
217
|
+
isExternal: boolean;
|
|
218
|
+
conditions: Condition[];
|
|
219
|
+
loc: SourceLocation;
|
|
220
|
+
}
|
|
221
|
+
interface FileAnalysisResult {
|
|
222
|
+
filePath: string;
|
|
223
|
+
edges: DiscoveredEdge[];
|
|
224
|
+
conditions: Condition[];
|
|
225
|
+
tags: string[];
|
|
226
|
+
diagnostics: Diagnostic[];
|
|
227
|
+
}
|
|
228
|
+
interface RouteGraphLike {
|
|
229
|
+
hasNode(id: string): boolean;
|
|
230
|
+
getNodePath(id: string): string | undefined;
|
|
231
|
+
findNodeByPath(path: string): string | undefined;
|
|
232
|
+
addNode(id: string, attributes: NodeAttributes): void;
|
|
233
|
+
addEdge(id: string, source: string, target: string, attributes: EdgeAttributes): void;
|
|
234
|
+
getAllNodeIds(): string[];
|
|
235
|
+
getAllEdges(): Array<{
|
|
236
|
+
id: string;
|
|
237
|
+
source: string;
|
|
238
|
+
target: string;
|
|
239
|
+
}>;
|
|
240
|
+
}
|
|
241
|
+
interface FrameworkPlugin {
|
|
242
|
+
readonly id: string;
|
|
243
|
+
readonly name: string;
|
|
244
|
+
readonly version: string;
|
|
245
|
+
readonly capabilities: PluginCapabilities;
|
|
246
|
+
detect(ctx: ProjectContext): Promise<boolean>;
|
|
247
|
+
configure(ctx: ProjectContext): Promise<PluginConfig>;
|
|
248
|
+
discoverRoutes(ctx: ProjectContext): AsyncIterable<RawRoute>;
|
|
249
|
+
analyzeFile(file: SemanticFile, ctx: AnalysisContext): Promise<FileAnalysisResult>;
|
|
250
|
+
enrichGraph(graph: RouteGraphLike, ctx: ProjectContext): Promise<void>;
|
|
251
|
+
runDiagnostics(graph: RouteGraphLike): Promise<Diagnostic[]>;
|
|
252
|
+
onFileChange?(event: FileChangeEvent, ctx: ProjectContext): Promise<InvalidationSet>;
|
|
253
|
+
}
|
|
254
|
+
interface AnalysisContext extends ProjectContext {
|
|
255
|
+
graph: RouteGraphLike;
|
|
256
|
+
routes: Map<string, RawRoute>;
|
|
257
|
+
}
|
|
258
|
+
interface FileChangeEvent {
|
|
259
|
+
type: 'add' | 'change' | 'unlink';
|
|
260
|
+
path: string;
|
|
261
|
+
}
|
|
262
|
+
interface InvalidationSet {
|
|
263
|
+
files: string[];
|
|
264
|
+
nodeIds: string[];
|
|
265
|
+
}
|
|
266
|
+
interface GraphPatch {
|
|
267
|
+
addedNodes: Array<{
|
|
268
|
+
id: string;
|
|
269
|
+
attributes: NodeAttributes;
|
|
270
|
+
}>;
|
|
271
|
+
removedNodeIds: string[];
|
|
272
|
+
addedEdges: Array<{
|
|
273
|
+
id: string;
|
|
274
|
+
source: string;
|
|
275
|
+
target: string;
|
|
276
|
+
attributes: EdgeAttributes;
|
|
277
|
+
}>;
|
|
278
|
+
removedEdgeIds: string[];
|
|
279
|
+
modifiedNodeIds: string[];
|
|
280
|
+
}
|
|
281
|
+
interface AnalysisResult {
|
|
282
|
+
graph: RouteGraphLike;
|
|
283
|
+
diagnostics: Diagnostic[];
|
|
284
|
+
metadata: GraphMetadata;
|
|
285
|
+
}
|
|
286
|
+
declare function defineConfig(config: AnalyzerConfig): AnalyzerConfig;
|
|
287
|
+
|
|
288
|
+
export { type AnalysisContext, type AnalysisResult, type AnalyzerConfig, type ComponentDeclaration, type Condition, type ConditionConfidence, type ConditionKind, type ConditionalBlock, type Diagnostic, type DiagnosticRuleId, type DiagnosticSeverity, type DiscoveredEdge, type EdgeAttributes, type FileAnalysisResult, type FileChangeEvent, type FrameworkPlugin, type GraphMetadata, type GraphPatch, type InvalidationSet, type JSXLink, type NavigationCall, type NavigationDestination, type NavigationSource, type NodeAttributes, type PluginCapabilities, type PluginConfig, type ProjectContext, type RawRoute, type RawRouteType, type RenderingKind, type RouteEdgeType, type RouteGraphLike, type RouteNodeType, type RuntimeKind, type SemanticExport, type SemanticFile, type SemanticImport, type SerializedEdge, type SerializedGraph, type SerializedNode, type SourceLocation, createDefaultEdgeAttributes, createDefaultNodeAttributes, defineConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// src/graph.types.ts
|
|
2
|
+
function createDefaultNodeAttributes(overrides) {
|
|
3
|
+
return {
|
|
4
|
+
segment: "",
|
|
5
|
+
isDynamic: false,
|
|
6
|
+
isCatchAll: false,
|
|
7
|
+
isOptionalCatchAll: false,
|
|
8
|
+
isParallelSlot: false,
|
|
9
|
+
isIntercepted: false,
|
|
10
|
+
isRouteGroup: false,
|
|
11
|
+
runtime: "nodejs",
|
|
12
|
+
rendering: "static",
|
|
13
|
+
isClientComponent: false,
|
|
14
|
+
isServerComponent: true,
|
|
15
|
+
isReachable: false,
|
|
16
|
+
isDead: false,
|
|
17
|
+
depth: 0,
|
|
18
|
+
tags: [],
|
|
19
|
+
conditions: [],
|
|
20
|
+
diagnostics: [],
|
|
21
|
+
loc: { filePath: overrides.filePath, line: 1, column: 1 },
|
|
22
|
+
...overrides
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function createDefaultEdgeAttributes(overrides) {
|
|
26
|
+
return {
|
|
27
|
+
isExternal: false,
|
|
28
|
+
conditions: [],
|
|
29
|
+
loc: { filePath: "", line: 0, column: 0 },
|
|
30
|
+
diagnostics: [],
|
|
31
|
+
...overrides
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/plugin.types.ts
|
|
36
|
+
function defineConfig(config) {
|
|
37
|
+
return config;
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
createDefaultEdgeAttributes,
|
|
41
|
+
createDefaultNodeAttributes,
|
|
42
|
+
defineConfig
|
|
43
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@route-intelligence/shared",
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Shared types and utilities for Route Intelligence",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"development": "./src/index.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
20
|
+
"dev": "tsup src/index.ts --format esm --dts --watch",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"test": "vitest run"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@route-intelligence/tsconfig": "*",
|
|
26
|
+
"@types/node": "^22.15.32",
|
|
27
|
+
"tsup": "^8.4.0",
|
|
28
|
+
"typescript": "^5.8.3",
|
|
29
|
+
"vitest": "^3.2.4"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
}
|
|
38
|
+
}
|