@pablocm90/visual-review 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +80 -2
- package/dist/api-paths.d.ts +18 -0
- package/dist/api-paths.js +22 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +95 -0
- package/dist/config.d.ts +85 -0
- package/dist/config.js +150 -0
- package/dist/config.schema.json +98 -0
- package/dist/crate-graph.d.ts +8 -0
- package/dist/crate-graph.js +51 -0
- package/dist/crate-modules.d.ts +8 -0
- package/dist/crate-modules.js +103 -0
- package/dist/diff-graphs.d.ts +31 -0
- package/dist/diff-graphs.js +72 -0
- package/dist/graph.d.ts +24 -0
- package/dist/graph.js +9 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1 -0
- package/dist/linker.d.ts +32 -0
- package/dist/linker.js +1 -0
- package/dist/linkers/fetch-axum.d.ts +2 -0
- package/dist/linkers/fetch-axum.js +38 -0
- package/dist/notes.d.ts +37 -0
- package/dist/notes.js +82 -0
- package/dist/notes.schema.json +68 -0
- package/dist/on-path.d.ts +1 -0
- package/dist/on-path.js +16 -0
- package/dist/prune-reviews.d.ts +6 -0
- package/dist/prune-reviews.js +12 -0
- package/dist/pull-request.d.ts +17 -0
- package/dist/pull-request.js +41 -0
- package/dist/read-range.d.ts +29 -0
- package/dist/read-range.js +158 -0
- package/dist/reader.d.ts +30 -0
- package/dist/reader.js +1 -0
- package/dist/readers/rust.d.ts +2 -0
- package/dist/readers/rust.js +66 -0
- package/dist/readers/typescript.d.ts +2 -0
- package/dist/readers/typescript.js +124 -0
- package/dist/rust-syntax.d.ts +10 -0
- package/dist/rust-syntax.js +11 -0
- package/dist/rust-tests.d.ts +2 -0
- package/dist/rust-tests.js +24 -0
- package/dist/skipped.d.ts +7 -0
- package/dist/skipped.js +1 -0
- package/dist/sources-in.d.ts +5 -0
- package/dist/sources-in.js +7 -0
- package/dist/test-statements.d.ts +46 -0
- package/dist/test-statements.js +121 -0
- package/dist/viewer/review-data.d.ts +18 -0
- package/dist/viewer/review-data.js +1 -0
- package/dist/viewer/visible-diff.d.ts +16 -0
- package/dist/viewer/visible-diff.js +74 -0
- package/dist/viewer.html +52 -0
- package/dist/web-graph.d.ts +19 -0
- package/dist/web-graph.js +59 -0
- package/dist/working-tree.d.ts +1 -0
- package/dist/working-tree.js +19 -0
- package/package.json +65 -3
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Graph } from './graph.ts';
|
|
2
|
+
type SourceOptions = {
|
|
3
|
+
readonly stack: string;
|
|
4
|
+
readonly sourceRoot: string;
|
|
5
|
+
readonly source: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const fileId: ({ stack, sourceRoot, source }: SourceOptions) => string;
|
|
8
|
+
type StackOptions = {
|
|
9
|
+
readonly stack: string;
|
|
10
|
+
readonly directory: string;
|
|
11
|
+
readonly sourceRoot: string;
|
|
12
|
+
readonly boxes: ReadonlyArray<string>;
|
|
13
|
+
};
|
|
14
|
+
type WebGraphOptions = StackOptions & {
|
|
15
|
+
readonly cruiseJson: string;
|
|
16
|
+
readonly packages: ReadonlyMap<string, string>;
|
|
17
|
+
};
|
|
18
|
+
export declare const webGraph: ({ stack, directory, sourceRoot, boxes, cruiseJson, packages, }: WebGraphOptions) => Graph;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { join, matchesGlob } from 'node:path';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
const CruiseOutputSchema = z.object({
|
|
4
|
+
modules: z.array(z.object({
|
|
5
|
+
source: z.string(),
|
|
6
|
+
coreModule: z.boolean().optional(),
|
|
7
|
+
couldNotResolve: z.boolean().optional(),
|
|
8
|
+
dependencies: z.array(z.object({ module: z.string(), resolved: z.string() })),
|
|
9
|
+
})),
|
|
10
|
+
});
|
|
11
|
+
const prefixOf = (sourceRoot) => (sourceRoot === '.' ? '' : `${sourceRoot}/`);
|
|
12
|
+
const relativeTo = (sourceRoot, source) => source.slice(prefixOf(sourceRoot).length);
|
|
13
|
+
export const fileId = ({ stack, sourceRoot, source }) => `${stack}/file/${relativeTo(sourceRoot, source)}`;
|
|
14
|
+
const nodesOf = ({ stack, directory, sourceRoot, boxes, source, }) => {
|
|
15
|
+
const relative = relativeTo(sourceRoot, source);
|
|
16
|
+
const parts = relative.split('/');
|
|
17
|
+
const file = {
|
|
18
|
+
id: fileId({ stack, sourceRoot, source }),
|
|
19
|
+
kind: 'file',
|
|
20
|
+
path: join(directory, source),
|
|
21
|
+
};
|
|
22
|
+
if (parts.length === 1)
|
|
23
|
+
return [{ ...file, label: relative, parent: stack }];
|
|
24
|
+
const folders = parts.slice(0, -1).map((_, index) => parts.slice(0, index + 1).join('/'));
|
|
25
|
+
const [first = relative] = folders;
|
|
26
|
+
const label = folders.findLast(folder => boxes.some(box => matchesGlob(folder, box))) ?? first;
|
|
27
|
+
const module = {
|
|
28
|
+
id: `${stack}/module/${label}`,
|
|
29
|
+
kind: 'module',
|
|
30
|
+
label,
|
|
31
|
+
parent: stack,
|
|
32
|
+
path: join(directory, sourceRoot, label),
|
|
33
|
+
};
|
|
34
|
+
return [module, { ...file, label: relative.slice(label.length + 1), parent: module.id }];
|
|
35
|
+
};
|
|
36
|
+
const packageOf = (module) => module
|
|
37
|
+
.split('/')
|
|
38
|
+
.slice(0, module.startsWith('@') ? 2 : 1)
|
|
39
|
+
.join('/');
|
|
40
|
+
export const webGraph = ({ stack, directory, sourceRoot, boxes, cruiseJson, packages, }) => {
|
|
41
|
+
const { modules } = CruiseOutputSchema.parse(JSON.parse(cruiseJson));
|
|
42
|
+
const sources = modules.filter(({ source, coreModule, couldNotResolve }) => source.startsWith(prefixOf(sourceRoot)) && !coreModule && !couldNotResolve);
|
|
43
|
+
const sourcePaths = new Set(sources.map(({ source }) => source));
|
|
44
|
+
const nodes = new Map(sources
|
|
45
|
+
.flatMap(({ source }) => nodesOf({ stack, directory, sourceRoot, boxes, source }))
|
|
46
|
+
.map(node => [node.id, node]));
|
|
47
|
+
const targetsOf = (dependency) => {
|
|
48
|
+
if (sourcePaths.has(dependency.resolved))
|
|
49
|
+
return [fileId({ stack, sourceRoot, source: dependency.resolved })];
|
|
50
|
+
const sibling = packages.get(packageOf(dependency.module));
|
|
51
|
+
return sibling === undefined || sibling === stack ? [] : [sibling];
|
|
52
|
+
};
|
|
53
|
+
const edges = sources.flatMap(module => {
|
|
54
|
+
const from = fileId({ stack, sourceRoot, source: module.source });
|
|
55
|
+
return [...new Set(module.dependencies.flatMap(targetsOf))].map(to => ({ from, to }));
|
|
56
|
+
});
|
|
57
|
+
const stackNode = { id: stack, kind: 'stack', label: stack, path: '' };
|
|
58
|
+
return { nodes: [stackNode, ...nodes.values()], edges };
|
|
59
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const snapshotWorkingTree: (repo: string) => Promise<string>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
const run = promisify(execFile);
|
|
7
|
+
export const snapshotWorkingTree = async (repo) => {
|
|
8
|
+
const scratch = await mkdtemp(join(tmpdir(), 'visual-review-index-'));
|
|
9
|
+
const env = { ...process.env, GIT_INDEX_FILE: join(scratch, 'index') };
|
|
10
|
+
const git = async (...args) => (await run('git', ['-C', repo, ...args], { env })).stdout.trim();
|
|
11
|
+
try {
|
|
12
|
+
await git('add', '--all');
|
|
13
|
+
const tree = await git('write-tree');
|
|
14
|
+
return await git('commit-tree', tree, '-p', 'HEAD', '-m', 'visual-review: working tree');
|
|
15
|
+
}
|
|
16
|
+
finally {
|
|
17
|
+
await rm(scratch, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,68 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pablocm90/visual-review",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Structural review pages for pull requests, ranges and uncommitted work",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/pablocm90/visual-review.git"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": "^22.20.0 || >=24.8.0"
|
|
13
|
+
},
|
|
14
|
+
"os": [
|
|
15
|
+
"!win32"
|
|
16
|
+
],
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"visual-review": "dist/cli.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@babel/types": "^8.0.6",
|
|
31
|
+
"@biomejs/biome": "^2.5.15",
|
|
32
|
+
"@stryker-mutator/core": "^10.0.0",
|
|
33
|
+
"@stryker-mutator/vitest-runner": "^10.0.0",
|
|
34
|
+
"@testing-library/dom": "^10.4.2",
|
|
35
|
+
"@testing-library/react": "^16.3.3",
|
|
36
|
+
"@testing-library/user-event": "^14.6.8",
|
|
37
|
+
"@types/node": "^22.20.5",
|
|
38
|
+
"@types/react": "^19.3.0",
|
|
39
|
+
"@types/react-dom": "^19.3.0",
|
|
40
|
+
"@vitejs/plugin-react": "^6.1.2",
|
|
41
|
+
"elkjs": "^0.12.0",
|
|
42
|
+
"highlight.js": "11.12.0",
|
|
43
|
+
"jsdom": "^30.1.2",
|
|
44
|
+
"react": "^19.3.0",
|
|
45
|
+
"react-dom": "^19.3.0",
|
|
46
|
+
"typescript": "^7.0.2",
|
|
47
|
+
"vite": "^8.3.4",
|
|
48
|
+
"vite-plugin-singlefile": "^2.3.3",
|
|
49
|
+
"vitest": "^5.0.4"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@babel/parser": "^8.0.7",
|
|
53
|
+
"@swc/core": "^1.16.18",
|
|
54
|
+
"dependency-cruiser": "^18.6.0",
|
|
55
|
+
"jsonc-parser": "^3.3.1",
|
|
56
|
+
"tree-sitter-rust": "0.24.0",
|
|
57
|
+
"web-tree-sitter": "0.27.0",
|
|
58
|
+
"zod": "^4.6.7"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.build.json && vite build && node src/write-schemas.ts",
|
|
62
|
+
"check": "biome check .",
|
|
63
|
+
"typecheck": "tsc --noEmit",
|
|
64
|
+
"test": "vitest run",
|
|
65
|
+
"mutate": "stryker run",
|
|
66
|
+
"review": "vite build --logLevel silent && node src/cli.ts"
|
|
67
|
+
}
|
|
6
68
|
}
|