@elench/testkit 0.1.64 → 0.1.65
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/lib/coverage/evidence.mjs +15 -3
- package/lib/coverage/evidence.test.mjs +13 -4
- package/lib/coverage/graph-builder.mjs +23 -24
- package/lib/coverage/next-ir-to-graph.mjs +240 -0
- package/node_modules/@elench/next-analysis/package.json +14 -0
- package/node_modules/@elench/next-analysis/src/api-routes.mjs +81 -0
- package/node_modules/@elench/next-analysis/src/api-routes.test.mjs +22 -0
- package/node_modules/@elench/next-analysis/src/app-root.mjs +7 -0
- package/node_modules/@elench/next-analysis/src/backend-links.mjs +31 -0
- package/node_modules/@elench/next-analysis/src/index.mjs +21 -0
- package/node_modules/@elench/next-analysis/src/pages.mjs +68 -0
- package/node_modules/@elench/next-analysis/src/project.mjs +94 -0
- package/node_modules/@elench/next-analysis/src/project.test.mjs +35 -0
- package/node_modules/@elench/next-analysis/src/route-tree.mjs +621 -0
- package/node_modules/@elench/next-analysis/src/routes.mjs +41 -0
- package/node_modules/@elench/next-analysis/src/routes.test.mjs +25 -0
- package/node_modules/@elench/next-analysis/src/server-actions.mjs +53 -0
- package/node_modules/@elench/next-analysis/src/server-actions.test.mjs +37 -0
- package/node_modules/@elench/next-analysis/src/shared.mjs +209 -0
- package/node_modules/@elench/next-analysis/src/swc.mjs +388 -0
- package/node_modules/@elench/testkit-bridge/package.json +2 -2
- package/node_modules/@elench/testkit-protocol/package.json +1 -1
- package/node_modules/@elench/ts-analysis/package.json +1 -1
- package/node_modules/@next/routing/README.md +91 -0
- package/node_modules/@next/routing/dist/__tests__/captures.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/conditions.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/dynamic-after-rewrites.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/i18n-resolve-routes.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/i18n.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/middleware.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/normalize-next-data.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/redirects.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/resolve-routes.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/rewrites.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/destination.d.ts +22 -0
- package/node_modules/@next/routing/dist/i18n.d.ts +48 -0
- package/node_modules/@next/routing/dist/index.d.ts +5 -0
- package/node_modules/@next/routing/dist/index.js +1 -0
- package/node_modules/@next/routing/dist/matchers.d.ts +12 -0
- package/node_modules/@next/routing/dist/middleware.d.ts +12 -0
- package/node_modules/@next/routing/dist/next-data.d.ts +10 -0
- package/node_modules/@next/routing/dist/resolve-routes.d.ts +2 -0
- package/node_modules/@next/routing/dist/types.d.ts +97 -0
- package/node_modules/@next/routing/package.json +39 -0
- package/node_modules/@swc/core/README.md +100 -0
- package/node_modules/@swc/core/Visitor.d.ts +218 -0
- package/node_modules/@swc/core/Visitor.js +1399 -0
- package/node_modules/@swc/core/binding.d.ts +59 -0
- package/node_modules/@swc/core/binding.js +368 -0
- package/node_modules/@swc/core/index.d.ts +120 -0
- package/node_modules/@swc/core/index.js +443 -0
- package/node_modules/@swc/core/package.json +120 -0
- package/node_modules/@swc/core/postinstall.js +148 -0
- package/node_modules/@swc/core/spack.d.ts +51 -0
- package/node_modules/@swc/core/spack.js +87 -0
- package/node_modules/@swc/core/util.d.ts +1 -0
- package/node_modules/@swc/core/util.js +104 -0
- package/node_modules/@swc/core-linux-x64-gnu/README.md +3 -0
- package/node_modules/@swc/core-linux-x64-gnu/package.json +46 -0
- package/node_modules/@swc/core-linux-x64-gnu/swc.linux-x64-gnu.node +0 -0
- package/node_modules/@swc/counter/CHANGELOG.md +7 -0
- package/node_modules/@swc/counter/README.md +7 -0
- package/node_modules/@swc/counter/index.js +1 -0
- package/node_modules/@swc/counter/package.json +27 -0
- package/node_modules/@swc/types/LICENSE +201 -0
- package/node_modules/@swc/types/README.md +4 -0
- package/node_modules/@swc/types/assumptions.d.ts +92 -0
- package/node_modules/@swc/types/assumptions.js +2 -0
- package/node_modules/@swc/types/index.d.ts +2049 -0
- package/node_modules/@swc/types/index.js +2 -0
- package/node_modules/@swc/types/package.json +40 -0
- package/package.json +6 -4
- package/lib/coverage/next-discovery.mjs +0 -205
- package/lib/coverage/next-static-analysis.mjs +0 -1045
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import nextRouting from "@next/routing";
|
|
4
|
+
import { findNextAppRoot } from "./app-root.mjs";
|
|
5
|
+
import { discoverApiRoutes } from "./api-routes.mjs";
|
|
6
|
+
import { discoverPages } from "./pages.mjs";
|
|
7
|
+
import { analyzeRouteTree } from "./route-tree.mjs";
|
|
8
|
+
import { discoverServerActions } from "./server-actions.mjs";
|
|
9
|
+
import { compareByPath, compareByRoute, createDiagnostic, normalizePath, readFileIfExists } from "./shared.mjs";
|
|
10
|
+
|
|
11
|
+
export function createNextAnalysisProject({ rootDir, buildDir = null, nextConfigPath = null } = {}) {
|
|
12
|
+
const { resolveRoutes } = nextRouting;
|
|
13
|
+
const absoluteRoot = path.resolve(rootDir || process.cwd());
|
|
14
|
+
const diagnostics = [];
|
|
15
|
+
const moduleCache = new Map();
|
|
16
|
+
const routeTreeCache = new Map();
|
|
17
|
+
const appRoot = findNextAppRoot(absoluteRoot);
|
|
18
|
+
|
|
19
|
+
const project = {
|
|
20
|
+
rootDir: absoluteRoot,
|
|
21
|
+
buildDir: buildDir ? path.resolve(absoluteRoot, buildDir) : null,
|
|
22
|
+
nextConfigPath: nextConfigPath ? path.resolve(absoluteRoot, nextConfigPath) : null,
|
|
23
|
+
findAppRoot() {
|
|
24
|
+
return appRoot;
|
|
25
|
+
},
|
|
26
|
+
readSourceFile(relativeFilePath) {
|
|
27
|
+
const absolutePath = path.join(absoluteRoot, relativeFilePath);
|
|
28
|
+
return readFileIfExists(absolutePath);
|
|
29
|
+
},
|
|
30
|
+
getDiagnostics() {
|
|
31
|
+
return [...diagnostics];
|
|
32
|
+
},
|
|
33
|
+
loadModule(relativeFilePath) {
|
|
34
|
+
return moduleCache.get(relativeFilePath) || null;
|
|
35
|
+
},
|
|
36
|
+
setModule(relativeFilePath, moduleInfo) {
|
|
37
|
+
moduleCache.set(relativeFilePath, moduleInfo);
|
|
38
|
+
},
|
|
39
|
+
discoverPages() {
|
|
40
|
+
if (!appRoot) {
|
|
41
|
+
diagnostics.push(createDiagnostic({
|
|
42
|
+
level: "warn",
|
|
43
|
+
code: "missing-app-root",
|
|
44
|
+
message: `No Next app root found under "${absoluteRoot}".`,
|
|
45
|
+
}));
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
return discoverPages({ rootDir: absoluteRoot, appRoot }).sort(compareByRoute);
|
|
49
|
+
},
|
|
50
|
+
discoverApiRoutes() {
|
|
51
|
+
if (!appRoot) return [];
|
|
52
|
+
return discoverApiRoutes({ rootDir: absoluteRoot, appRoot }).sort((left, right) => {
|
|
53
|
+
return left.requestPath.localeCompare(right.requestPath) || left.method.localeCompare(right.method);
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
discoverServerActions() {
|
|
57
|
+
if (!appRoot) return [];
|
|
58
|
+
return discoverServerActions({ rootDir: absoluteRoot, appRoot }).sort(compareByPath);
|
|
59
|
+
},
|
|
60
|
+
analyzeRouteTree(routeOrPageFile) {
|
|
61
|
+
if (!appRoot) return null;
|
|
62
|
+
const key = normalizePath(routeOrPageFile);
|
|
63
|
+
if (routeTreeCache.has(key)) return routeTreeCache.get(key);
|
|
64
|
+
const result = analyzeRouteTree({ project, routeOrPageFile, diagnostics });
|
|
65
|
+
routeTreeCache.set(key, result);
|
|
66
|
+
return result;
|
|
67
|
+
},
|
|
68
|
+
async loadBuildRouting() {
|
|
69
|
+
if (!project.buildDir || !fs.existsSync(project.buildDir)) return null;
|
|
70
|
+
return {
|
|
71
|
+
async resolve(url, pathnames = []) {
|
|
72
|
+
return resolveRoutes({
|
|
73
|
+
url: new URL(url),
|
|
74
|
+
basePath: "",
|
|
75
|
+
requestBody: null,
|
|
76
|
+
headers: new Headers(),
|
|
77
|
+
pathnames,
|
|
78
|
+
routes: {
|
|
79
|
+
beforeMiddleware: [],
|
|
80
|
+
beforeFiles: [],
|
|
81
|
+
afterFiles: [],
|
|
82
|
+
dynamicRoutes: [],
|
|
83
|
+
onMatch: [],
|
|
84
|
+
fallback: [],
|
|
85
|
+
},
|
|
86
|
+
invokeMiddleware: async () => ({}),
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return project;
|
|
94
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { createNextAnalysisProject } from "./index.mjs";
|
|
4
|
+
|
|
5
|
+
const fixtureRoot = path.resolve(
|
|
6
|
+
"/home/georgedlr/workspace/elench/testkit/test/fixtures/integration/next-route-tree-product"
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
describe("@elench/next-analysis project", () => {
|
|
10
|
+
it("discovers pages, api routes, and route trees from a Next fixture", () => {
|
|
11
|
+
const project = createNextAnalysisProject({ rootDir: fixtureRoot });
|
|
12
|
+
|
|
13
|
+
expect(project.findAppRoot()).toMatch(/src\/app$/u);
|
|
14
|
+
expect(project.discoverPages().map((page) => page.route)).toEqual(["/events", "/projects"]);
|
|
15
|
+
expect(project.discoverApiRoutes().map((route) => `${route.method} ${route.requestPath}`)).toEqual([
|
|
16
|
+
"GET /api/projects",
|
|
17
|
+
"POST /api/projects",
|
|
18
|
+
"GET /api/projects/[projectId]/events",
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
const routeTree = project.analyzeRouteTree("/projects");
|
|
22
|
+
expect(routeTree.reachableModules).toEqual(
|
|
23
|
+
expect.arrayContaining([
|
|
24
|
+
"src/app/(dashboard)/projects/page.tsx",
|
|
25
|
+
"src/components/project-context.tsx",
|
|
26
|
+
])
|
|
27
|
+
);
|
|
28
|
+
expect(routeTree.requests).toEqual(
|
|
29
|
+
expect.arrayContaining([
|
|
30
|
+
expect.objectContaining({ ownerKind: "page", method: "GET", path: "/api/projects" }),
|
|
31
|
+
expect.objectContaining({ ownerKind: "action", method: "POST", path: "/api/projects" }),
|
|
32
|
+
])
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
});
|