@veraxhq/verax 0.1.0 → 0.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/README.md +123 -88
- package/bin/verax.js +11 -452
- package/package.json +14 -36
- package/src/cli/commands/default.js +523 -0
- package/src/cli/commands/doctor.js +165 -0
- package/src/cli/commands/inspect.js +109 -0
- package/src/cli/commands/run.js +402 -0
- package/src/cli/entry.js +196 -0
- package/src/cli/util/atomic-write.js +37 -0
- package/src/cli/util/detection-engine.js +296 -0
- package/src/cli/util/env-url.js +33 -0
- package/src/cli/util/errors.js +44 -0
- package/src/cli/util/events.js +34 -0
- package/src/cli/util/expectation-extractor.js +378 -0
- package/src/cli/util/findings-writer.js +31 -0
- package/src/cli/util/idgen.js +87 -0
- package/src/cli/util/learn-writer.js +39 -0
- package/src/cli/util/observation-engine.js +366 -0
- package/src/cli/util/observe-writer.js +25 -0
- package/src/cli/util/paths.js +29 -0
- package/src/cli/util/project-discovery.js +277 -0
- package/src/cli/util/project-writer.js +26 -0
- package/src/cli/util/redact.js +128 -0
- package/src/cli/util/run-id.js +30 -0
- package/src/cli/util/summary-writer.js +32 -0
- package/src/verax/cli/ci-summary.js +35 -0
- package/src/verax/cli/context-explanation.js +89 -0
- package/src/verax/cli/doctor.js +277 -0
- package/src/verax/cli/error-normalizer.js +154 -0
- package/src/verax/cli/explain-output.js +105 -0
- package/src/verax/cli/finding-explainer.js +130 -0
- package/src/verax/cli/init.js +237 -0
- package/src/verax/cli/run-overview.js +163 -0
- package/src/verax/cli/url-safety.js +101 -0
- package/src/verax/cli/wizard.js +98 -0
- package/src/verax/cli/zero-findings-explainer.js +57 -0
- package/src/verax/cli/zero-interaction-explainer.js +127 -0
- package/src/verax/core/action-classifier.js +86 -0
- package/src/verax/core/budget-engine.js +218 -0
- package/src/verax/core/canonical-outcomes.js +157 -0
- package/src/verax/core/decision-snapshot.js +335 -0
- package/src/verax/core/determinism-model.js +403 -0
- package/src/verax/core/incremental-store.js +237 -0
- package/src/verax/core/invariants.js +356 -0
- package/src/verax/core/promise-model.js +230 -0
- package/src/verax/core/replay-validator.js +350 -0
- package/src/verax/core/replay.js +222 -0
- package/src/verax/core/run-id.js +175 -0
- package/src/verax/core/run-manifest.js +99 -0
- package/src/verax/core/silence-impact.js +369 -0
- package/src/verax/core/silence-model.js +521 -0
- package/src/verax/detect/comparison.js +2 -34
- package/src/verax/detect/confidence-engine.js +764 -329
- package/src/verax/detect/detection-engine.js +293 -0
- package/src/verax/detect/evidence-index.js +177 -0
- package/src/verax/detect/expectation-model.js +194 -172
- package/src/verax/detect/explanation-helpers.js +187 -0
- package/src/verax/detect/finding-detector.js +450 -0
- package/src/verax/detect/findings-writer.js +44 -8
- package/src/verax/detect/flow-detector.js +366 -0
- package/src/verax/detect/index.js +172 -286
- package/src/verax/detect/interactive-findings.js +613 -0
- package/src/verax/detect/signal-mapper.js +308 -0
- package/src/verax/detect/verdict-engine.js +563 -0
- package/src/verax/evidence-index-writer.js +61 -0
- package/src/verax/index.js +90 -14
- package/src/verax/intel/effect-detector.js +368 -0
- package/src/verax/intel/handler-mapper.js +249 -0
- package/src/verax/intel/index.js +281 -0
- package/src/verax/intel/route-extractor.js +280 -0
- package/src/verax/intel/ts-program.js +256 -0
- package/src/verax/intel/vue-navigation-extractor.js +579 -0
- package/src/verax/intel/vue-router-extractor.js +323 -0
- package/src/verax/learn/action-contract-extractor.js +335 -101
- package/src/verax/learn/ast-contract-extractor.js +95 -5
- package/src/verax/learn/flow-extractor.js +172 -0
- package/src/verax/learn/manifest-writer.js +97 -47
- package/src/verax/learn/project-detector.js +40 -0
- package/src/verax/learn/route-extractor.js +27 -96
- package/src/verax/learn/state-extractor.js +212 -0
- package/src/verax/learn/static-extractor-navigation.js +114 -0
- package/src/verax/learn/static-extractor-validation.js +88 -0
- package/src/verax/learn/static-extractor.js +112 -4
- package/src/verax/learn/truth-assessor.js +24 -21
- package/src/verax/observe/aria-sensor.js +211 -0
- package/src/verax/observe/browser.js +10 -5
- package/src/verax/observe/console-sensor.js +1 -17
- package/src/verax/observe/domain-boundary.js +10 -1
- package/src/verax/observe/expectation-executor.js +512 -0
- package/src/verax/observe/flow-matcher.js +143 -0
- package/src/verax/observe/focus-sensor.js +196 -0
- package/src/verax/observe/human-driver.js +643 -275
- package/src/verax/observe/index.js +908 -27
- package/src/verax/observe/index.js.backup +1 -0
- package/src/verax/observe/interaction-discovery.js +365 -14
- package/src/verax/observe/interaction-runner.js +563 -198
- package/src/verax/observe/loading-sensor.js +139 -0
- package/src/verax/observe/navigation-sensor.js +255 -0
- package/src/verax/observe/network-sensor.js +55 -7
- package/src/verax/observe/observed-expectation-deriver.js +186 -0
- package/src/verax/observe/observed-expectation.js +305 -0
- package/src/verax/observe/page-frontier.js +234 -0
- package/src/verax/observe/settle.js +37 -17
- package/src/verax/observe/state-sensor.js +389 -0
- package/src/verax/observe/timing-sensor.js +228 -0
- package/src/verax/observe/traces-writer.js +61 -20
- package/src/verax/observe/ui-signal-sensor.js +136 -17
- package/src/verax/scan-summary-writer.js +77 -15
- package/src/verax/shared/artifact-manager.js +110 -8
- package/src/verax/shared/budget-profiles.js +136 -0
- package/src/verax/shared/ci-detection.js +39 -0
- package/src/verax/shared/config-loader.js +170 -0
- package/src/verax/shared/dynamic-route-utils.js +218 -0
- package/src/verax/shared/expectation-coverage.js +44 -0
- package/src/verax/shared/expectation-prover.js +81 -0
- package/src/verax/shared/expectation-tracker.js +201 -0
- package/src/verax/shared/expectations-writer.js +60 -0
- package/src/verax/shared/first-run.js +44 -0
- package/src/verax/shared/progress-reporter.js +171 -0
- package/src/verax/shared/retry-policy.js +14 -1
- package/src/verax/shared/root-artifacts.js +49 -0
- package/src/verax/shared/scan-budget.js +86 -0
- package/src/verax/shared/url-normalizer.js +162 -0
- package/src/verax/shared/zip-artifacts.js +65 -0
- package/src/verax/validate/context-validator.js +244 -0
- package/src/verax/validate/context-validator.js.bak +0 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CODE INTELLIGENCE v1 — Vue Router Route Extraction (AST-based)
|
|
3
|
+
*
|
|
4
|
+
* Extracts routes from Vue Router configuration using AST analysis.
|
|
5
|
+
* Includes dynamic routes with example paths.
|
|
6
|
+
*
|
|
7
|
+
* Supported patterns:
|
|
8
|
+
* - createRouter({ routes: [...] })
|
|
9
|
+
* - const routes = [...]
|
|
10
|
+
* - export const routes = [...]
|
|
11
|
+
* - export default { routes: [...] }
|
|
12
|
+
* - Dynamic routes: /users/:id → /users/1
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import ts from 'typescript';
|
|
16
|
+
import { resolve } from 'path';
|
|
17
|
+
import { existsSync, readFileSync } from 'fs';
|
|
18
|
+
import { parseFile, findNodes, getStringLiteral, getNodeLocation } from './ts-program.js';
|
|
19
|
+
import { normalizeDynamicRoute } from '../shared/dynamic-route-utils.js';
|
|
20
|
+
|
|
21
|
+
const INTERNAL_PATH_PATTERNS = [
|
|
22
|
+
/^\/admin/,
|
|
23
|
+
/^\/dashboard/,
|
|
24
|
+
/^\/account/,
|
|
25
|
+
/^\/settings/,
|
|
26
|
+
/\/internal/,
|
|
27
|
+
/\/private/
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
function isInternalRoute(path) {
|
|
31
|
+
return INTERNAL_PATH_PATTERNS.some(pattern => pattern.test(path));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Extract routes from Vue Router configuration.
|
|
36
|
+
*
|
|
37
|
+
* @param {string} projectRoot - Project root
|
|
38
|
+
* @param {Object} program - TypeScript program
|
|
39
|
+
* @returns {Array} - Array of route objects with sourceRef
|
|
40
|
+
*/
|
|
41
|
+
export function extractVueRoutes(projectRoot, program) {
|
|
42
|
+
const routes = [];
|
|
43
|
+
|
|
44
|
+
if (!program || !program.program) return routes;
|
|
45
|
+
|
|
46
|
+
// Look for router files in common locations
|
|
47
|
+
const routerFilePatterns = [
|
|
48
|
+
'src/router/index.ts',
|
|
49
|
+
'src/router/index.js',
|
|
50
|
+
'src/router.ts',
|
|
51
|
+
'src/router.js',
|
|
52
|
+
'router/index.ts',
|
|
53
|
+
'router/index.js',
|
|
54
|
+
'router.ts',
|
|
55
|
+
'router.js'
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
let routerFiles = [];
|
|
59
|
+
|
|
60
|
+
// First, try to find router files by pattern
|
|
61
|
+
for (const pattern of routerFilePatterns) {
|
|
62
|
+
const filePath = resolve(projectRoot, pattern);
|
|
63
|
+
if (existsSync(filePath)) {
|
|
64
|
+
routerFiles.push(filePath);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// If no router files found by pattern, search in source files
|
|
69
|
+
if (routerFiles.length === 0 && program.sourceFiles) {
|
|
70
|
+
for (const sourceFile of program.sourceFiles) {
|
|
71
|
+
// sourceFiles is an array of file paths (strings) from createTSProgram
|
|
72
|
+
const filePath = typeof sourceFile === 'string' ? sourceFile : sourceFile.fileName;
|
|
73
|
+
try {
|
|
74
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
75
|
+
if (content.includes('createRouter') ||
|
|
76
|
+
content.includes('routes:') ||
|
|
77
|
+
content.includes('const routes') ||
|
|
78
|
+
content.includes('export const routes')) {
|
|
79
|
+
routerFiles.push(filePath);
|
|
80
|
+
}
|
|
81
|
+
} catch (err) {
|
|
82
|
+
// Skip if file can't be read
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Extract routes from each router file
|
|
88
|
+
for (const filePath of routerFiles) {
|
|
89
|
+
const ast = parseFile(filePath, true);
|
|
90
|
+
if (!ast) continue;
|
|
91
|
+
|
|
92
|
+
const fileRoutes = extractRoutesFromAST(ast, projectRoot);
|
|
93
|
+
routes.push(...fileRoutes);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Deduplicate by path
|
|
97
|
+
const seen = new Set();
|
|
98
|
+
const uniqueRoutes = [];
|
|
99
|
+
for (const route of routes) {
|
|
100
|
+
const key = route.path;
|
|
101
|
+
if (!seen.has(key)) {
|
|
102
|
+
seen.add(key);
|
|
103
|
+
uniqueRoutes.push(route);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return uniqueRoutes;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Extract routes from AST.
|
|
112
|
+
*
|
|
113
|
+
* @param {ts.SourceFile} ast - Parsed source file
|
|
114
|
+
* @param {string} projectRoot - Project root
|
|
115
|
+
* @returns {Array} - Route objects
|
|
116
|
+
*/
|
|
117
|
+
function extractRoutesFromAST(ast, projectRoot) {
|
|
118
|
+
const routes = [];
|
|
119
|
+
|
|
120
|
+
// Find route array definitions
|
|
121
|
+
const routeArrays = findRouteArrays(ast);
|
|
122
|
+
|
|
123
|
+
for (const routeArray of routeArrays) {
|
|
124
|
+
const extracted = extractRoutesFromArray(routeArray, ast, projectRoot, '');
|
|
125
|
+
routes.push(...extracted);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return routes;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Find route array definitions in AST.
|
|
133
|
+
*
|
|
134
|
+
* @param {ts.SourceFile} ast - Source file
|
|
135
|
+
* @returns {Array} - Array literal nodes
|
|
136
|
+
*/
|
|
137
|
+
function findRouteArrays(ast) {
|
|
138
|
+
const arrays = [];
|
|
139
|
+
|
|
140
|
+
// Pattern 1: createRouter({ routes: [...] })
|
|
141
|
+
const createRouterCalls = findNodes(ast, node => {
|
|
142
|
+
if (!ts.isCallExpression(node)) return false;
|
|
143
|
+
const expr = node.expression;
|
|
144
|
+
if (!ts.isIdentifier(expr)) return false;
|
|
145
|
+
return expr.text === 'createRouter';
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
for (const call of createRouterCalls) {
|
|
149
|
+
if (call.arguments.length === 0) continue;
|
|
150
|
+
const arg = call.arguments[0];
|
|
151
|
+
if (!ts.isObjectLiteralExpression(arg)) continue;
|
|
152
|
+
|
|
153
|
+
for (const prop of arg.properties) {
|
|
154
|
+
if (!ts.isPropertyAssignment(prop)) continue;
|
|
155
|
+
const name = prop.name;
|
|
156
|
+
if (!ts.isIdentifier(name)) continue;
|
|
157
|
+
if (name.text !== 'routes') continue;
|
|
158
|
+
|
|
159
|
+
const init = prop.initializer;
|
|
160
|
+
if (ts.isArrayLiteralExpression(init)) {
|
|
161
|
+
arrays.push(init);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Pattern 2: const routes = [...] or export const routes = [...]
|
|
167
|
+
const routeVariables = findNodes(ast, node => {
|
|
168
|
+
if (!ts.isVariableDeclaration(node)) return false;
|
|
169
|
+
if (!ts.isIdentifier(node.name)) return false;
|
|
170
|
+
return node.name.text === 'routes';
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
for (const decl of routeVariables) {
|
|
174
|
+
if (decl.initializer && ts.isArrayLiteralExpression(decl.initializer)) {
|
|
175
|
+
arrays.push(decl.initializer);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Pattern 3: export default { routes: [...] }
|
|
180
|
+
const defaultExports = findNodes(ast, node => {
|
|
181
|
+
if (!ts.isExportAssignment(node)) return false;
|
|
182
|
+
return node.isExportEquals === false;
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
for (const exportNode of defaultExports) {
|
|
186
|
+
const expr = exportNode.expression;
|
|
187
|
+
if (!ts.isObjectLiteralExpression(expr)) continue;
|
|
188
|
+
|
|
189
|
+
for (const prop of expr.properties) {
|
|
190
|
+
if (!ts.isPropertyAssignment(prop)) continue;
|
|
191
|
+
const name = prop.name;
|
|
192
|
+
if (!ts.isIdentifier(name)) continue;
|
|
193
|
+
if (name.text !== 'routes') continue;
|
|
194
|
+
|
|
195
|
+
const init = prop.initializer;
|
|
196
|
+
if (ts.isArrayLiteralExpression(init)) {
|
|
197
|
+
arrays.push(init);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return arrays;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Extract routes from array literal.
|
|
207
|
+
*
|
|
208
|
+
* @param {ts.ArrayLiteralExpression} arrayNode - Array literal node
|
|
209
|
+
* @param {ts.SourceFile} ast - Source file
|
|
210
|
+
* @param {string} projectRoot - Project root
|
|
211
|
+
* @param {string} parentPath - Parent route path for nested routes
|
|
212
|
+
* @returns {Array} - Route objects
|
|
213
|
+
*/
|
|
214
|
+
function extractRoutesFromArray(arrayNode, ast, projectRoot, parentPath) {
|
|
215
|
+
const routes = [];
|
|
216
|
+
|
|
217
|
+
for (const element of arrayNode.elements) {
|
|
218
|
+
if (!ts.isObjectLiteralExpression(element)) continue;
|
|
219
|
+
|
|
220
|
+
const routeObj = extractRouteFromObject(element, ast, projectRoot, parentPath);
|
|
221
|
+
if (routeObj) {
|
|
222
|
+
routes.push(routeObj);
|
|
223
|
+
|
|
224
|
+
// Handle nested children
|
|
225
|
+
if (routeObj.children) {
|
|
226
|
+
for (const child of routeObj.children) {
|
|
227
|
+
routes.push(child);
|
|
228
|
+
}
|
|
229
|
+
delete routeObj.children;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return routes;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Extract route from object literal.
|
|
239
|
+
*
|
|
240
|
+
* @param {ts.ObjectLiteralExpression} objNode - Object literal node
|
|
241
|
+
* @param {ts.SourceFile} ast - Source file
|
|
242
|
+
* @param {string} projectRoot - Project root
|
|
243
|
+
* @param {string} parentPath - Parent route path
|
|
244
|
+
* @returns {Object|null} - Route object or null
|
|
245
|
+
*/
|
|
246
|
+
function extractRouteFromObject(objNode, ast, projectRoot, parentPath) {
|
|
247
|
+
let path = null;
|
|
248
|
+
let children = null;
|
|
249
|
+
|
|
250
|
+
for (const prop of objNode.properties) {
|
|
251
|
+
if (!ts.isPropertyAssignment(prop)) continue;
|
|
252
|
+
const name = prop.name;
|
|
253
|
+
if (!ts.isIdentifier(name)) continue;
|
|
254
|
+
|
|
255
|
+
if (name.text === 'path') {
|
|
256
|
+
const pathValue = getStringLiteral(prop.initializer);
|
|
257
|
+
if (pathValue) {
|
|
258
|
+
path = pathValue;
|
|
259
|
+
}
|
|
260
|
+
} else if (name.text === 'children') {
|
|
261
|
+
const init = prop.initializer;
|
|
262
|
+
if (ts.isArrayLiteralExpression(init)) {
|
|
263
|
+
children = init;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Skip if path is wildcard
|
|
269
|
+
if (!path || path.includes('*')) {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Build full path
|
|
274
|
+
let fullPath = path;
|
|
275
|
+
if (parentPath) {
|
|
276
|
+
if (path.startsWith('/')) {
|
|
277
|
+
fullPath = path;
|
|
278
|
+
} else {
|
|
279
|
+
// Relative path: join parent + child
|
|
280
|
+
const parentNormalized = parentPath.endsWith('/') ? parentPath.slice(0, -1) : parentPath;
|
|
281
|
+
fullPath = `${parentNormalized}/${path}`.replace(/\/+/g, '/');
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Normalize dynamic routes to example paths
|
|
286
|
+
const normalized = normalizeDynamicRoute(fullPath);
|
|
287
|
+
const location = getNodeLocation(ast, objNode, projectRoot);
|
|
288
|
+
|
|
289
|
+
let route;
|
|
290
|
+
if (normalized) {
|
|
291
|
+
// Dynamic route - use example path
|
|
292
|
+
route = {
|
|
293
|
+
path: normalized.examplePath,
|
|
294
|
+
originalPattern: normalized.originalPattern,
|
|
295
|
+
isDynamic: true,
|
|
296
|
+
exampleExecution: true,
|
|
297
|
+
sourceRef: location.sourceRef,
|
|
298
|
+
file: location.file,
|
|
299
|
+
line: location.line,
|
|
300
|
+
framework: 'vue-router',
|
|
301
|
+
public: !isInternalRoute(normalized.examplePath)
|
|
302
|
+
};
|
|
303
|
+
} else {
|
|
304
|
+
// Static route
|
|
305
|
+
route = {
|
|
306
|
+
path: fullPath,
|
|
307
|
+
sourceRef: location.sourceRef,
|
|
308
|
+
file: location.file,
|
|
309
|
+
line: location.line,
|
|
310
|
+
framework: 'vue-router',
|
|
311
|
+
public: !isInternalRoute(fullPath)
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Extract nested children
|
|
316
|
+
if (children) {
|
|
317
|
+
const parentPathForChildren = normalized ? normalized.examplePath : fullPath;
|
|
318
|
+
const childRoutes = extractRoutesFromArray(children, ast, projectRoot, parentPathForChildren);
|
|
319
|
+
route.children = childRoutes;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return route;
|
|
323
|
+
}
|