@youtyan/code-viewer 0.1.15 → 0.1.17
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 +34 -8
- package/dist/code-viewer.js +2235 -0
- package/package.json +23 -18
- package/web/app.js +514 -5
- package/web/style.css +44 -3
- package/web-src/routes.ts +0 -148
- package/web-src/server/cache.ts +0 -64
- package/web-src/server/dev-assets.ts +0 -37
- package/web-src/server/dev.ts +0 -100
- package/web-src/server/git.ts +0 -483
- package/web-src/server/preview.ts +0 -985
- package/web-src/server/range.ts +0 -8
- package/web-src/server/runtime.d.ts +0 -51
- package/web-src/server/search.ts +0 -104
- package/web-src/types.ts +0 -136
package/web-src/server/range.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
declare const Bun: {
|
|
2
|
-
spawn(args: string[], opts?: Record<string, unknown>): {
|
|
3
|
-
kill(signal?: string): void;
|
|
4
|
-
exited: Promise<number>;
|
|
5
|
-
};
|
|
6
|
-
spawnSync(args: string[], opts?: Record<string, unknown>): {
|
|
7
|
-
exitCode: number;
|
|
8
|
-
stdout: Uint8Array;
|
|
9
|
-
stderr: Uint8Array;
|
|
10
|
-
};
|
|
11
|
-
serve(opts: {
|
|
12
|
-
hostname?: string;
|
|
13
|
-
port?: number;
|
|
14
|
-
fetch(req: Request): Response | Promise<Response>;
|
|
15
|
-
}): { port: number };
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
declare const process: {
|
|
19
|
-
argv: string[];
|
|
20
|
-
env: Record<string, string | undefined>;
|
|
21
|
-
cwd(): string;
|
|
22
|
-
platform: 'darwin' | 'win32' | string;
|
|
23
|
-
on(event: 'SIGINT' | 'SIGTERM', listener: () => void): void;
|
|
24
|
-
exit(code?: number): never;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
interface ImportMeta {
|
|
28
|
-
dir: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
declare module 'node:fs' {
|
|
32
|
-
export function existsSync(path: string): boolean;
|
|
33
|
-
export function readdirSync(path: string): string[];
|
|
34
|
-
export function readFileSync(path: string): Buffer;
|
|
35
|
-
export function readFileSync(path: string, encoding: BufferEncoding): string;
|
|
36
|
-
export function realpathSync(path: string): string;
|
|
37
|
-
export function statSync(path: string): { mtimeMs: number };
|
|
38
|
-
export function watch(
|
|
39
|
-
path: string,
|
|
40
|
-
options: { persistent?: boolean },
|
|
41
|
-
listener: (eventType: string, filename: string | Buffer | null) => void,
|
|
42
|
-
): unknown;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
declare module 'node:path' {
|
|
46
|
-
export function basename(path: string): string;
|
|
47
|
-
export function extname(path: string): string;
|
|
48
|
-
export function join(...parts: string[]): string;
|
|
49
|
-
export function normalize(path: string): string;
|
|
50
|
-
export function relative(from: string, to: string): string;
|
|
51
|
-
}
|
package/web-src/server/search.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import type { FileSearchListResponse, GrepMatch } from '../types';
|
|
2
|
-
import type { GitTreeEntry } from './git';
|
|
3
|
-
|
|
4
|
-
export const GREP_DEFAULT_MAX = 200;
|
|
5
|
-
export const GREP_ABSOLUTE_MAX = 500;
|
|
6
|
-
export const GREP_MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
7
|
-
export const FILE_SEARCH_ABSOLUTE_MAX = 50000;
|
|
8
|
-
|
|
9
|
-
export function normalizeGrepMax(value: string | null): number {
|
|
10
|
-
const parsed = Number(value || '');
|
|
11
|
-
if (!Number.isInteger(parsed) || parsed <= 0) return GREP_DEFAULT_MAX;
|
|
12
|
-
return Math.min(parsed, GREP_ABSOLUTE_MAX);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function isSkippableSearchPath(path: string, omitDirNames: string[] = []): boolean {
|
|
16
|
-
const omitDirs = new Set(omitDirNames.map(name => name.toLowerCase()));
|
|
17
|
-
return path.split(/[\\/]+/).some(part => {
|
|
18
|
-
const lower = part.toLowerCase();
|
|
19
|
-
return lower === '.git' || omitDirs.has(lower);
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function fixedStringLineMatches(path: string, text: string, query: string, max: number): GrepMatch[] {
|
|
24
|
-
const needle = query.toLowerCase();
|
|
25
|
-
if (!needle) return [];
|
|
26
|
-
const matches: GrepMatch[] = [];
|
|
27
|
-
const lines = text.split('\n');
|
|
28
|
-
for (let i = 0; i < lines.length && matches.length < max; i++) {
|
|
29
|
-
const line = lines[i];
|
|
30
|
-
const column = line.toLowerCase().indexOf(needle);
|
|
31
|
-
if (column < 0) continue;
|
|
32
|
-
matches.push({
|
|
33
|
-
path,
|
|
34
|
-
line: i + 1,
|
|
35
|
-
column: column + 1,
|
|
36
|
-
preview: line.slice(0, 500),
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
return matches;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function buildFileSearchList(ref: string, generation: number, entries: GitTreeEntry[]): FileSearchListResponse {
|
|
43
|
-
const files = entries
|
|
44
|
-
.filter((entry): entry is GitTreeEntry & { type: 'blob' | 'commit' } => entry.type === 'blob' || entry.type === 'commit')
|
|
45
|
-
.slice(0, FILE_SEARCH_ABSOLUTE_MAX)
|
|
46
|
-
.map(entry => ({ path: entry.path, type: entry.type }));
|
|
47
|
-
return {
|
|
48
|
-
ref,
|
|
49
|
-
generation,
|
|
50
|
-
files,
|
|
51
|
-
truncated: entries.length > FILE_SEARCH_ABSOLUTE_MAX,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function buildRgArgs(query: string, max: number, paths: string[], regex = false, omitDirNames: string[] = []): string[] {
|
|
56
|
-
const safePaths = paths.length ? paths : ['.'];
|
|
57
|
-
const omitGlobs = omitDirNames.flatMap(name => ['--glob', `!${name}/**`, '--glob', `!**/${name}/**`]);
|
|
58
|
-
const args = [
|
|
59
|
-
'rg',
|
|
60
|
-
'--no-config',
|
|
61
|
-
'--line-number',
|
|
62
|
-
'--column',
|
|
63
|
-
'--no-heading',
|
|
64
|
-
'--color',
|
|
65
|
-
'never',
|
|
66
|
-
'--smart-case',
|
|
67
|
-
'--max-count',
|
|
68
|
-
String(max),
|
|
69
|
-
'--max-filesize',
|
|
70
|
-
'2M',
|
|
71
|
-
...omitGlobs,
|
|
72
|
-
'-e',
|
|
73
|
-
query,
|
|
74
|
-
'--',
|
|
75
|
-
...safePaths,
|
|
76
|
-
];
|
|
77
|
-
if (!regex) args.splice(8, 0, '--fixed-strings');
|
|
78
|
-
return args;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export function parseRgOutput(stdout: string, max: number, omitDirNames: string[] = []): GrepMatch[] {
|
|
82
|
-
const matches: GrepMatch[] = [];
|
|
83
|
-
for (const line of stdout.split('\n')) {
|
|
84
|
-
if (!line || matches.length >= max) continue;
|
|
85
|
-
const parsed = /^(.*):(\d+):(\d+):(.*)$/.exec(line);
|
|
86
|
-
if (!parsed) continue;
|
|
87
|
-
const path = parsed[1];
|
|
88
|
-
const lineNo = Number(parsed[2]);
|
|
89
|
-
const column = Number(parsed[3]);
|
|
90
|
-
const preview = parsed[4];
|
|
91
|
-
if (!path || !lineNo || !column || isSkippableSearchPath(path, omitDirNames)) continue;
|
|
92
|
-
matches.push({ path, line: lineNo, column, preview: preview.slice(0, 500) });
|
|
93
|
-
}
|
|
94
|
-
return matches;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function parseGitGrepOutput(stdout: string, ref: string, max: number, omitDirNames: string[] = []): GrepMatch[] {
|
|
98
|
-
const prefix = ref + ':';
|
|
99
|
-
const normalized = stdout
|
|
100
|
-
.split('\n')
|
|
101
|
-
.map(line => line.startsWith(prefix) ? line.slice(prefix.length) : line)
|
|
102
|
-
.join('\n');
|
|
103
|
-
return parseRgOutput(normalized, max, omitDirNames);
|
|
104
|
-
}
|
package/web-src/types.ts
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import type { GdpExpandLogic } from './expand-logic';
|
|
2
|
-
|
|
3
|
-
export type FileMeta = {
|
|
4
|
-
order?: number;
|
|
5
|
-
key?: string;
|
|
6
|
-
path: string;
|
|
7
|
-
old_path?: string;
|
|
8
|
-
display_path?: string;
|
|
9
|
-
status?: string;
|
|
10
|
-
additions?: number;
|
|
11
|
-
deletions?: number;
|
|
12
|
-
binary?: boolean;
|
|
13
|
-
media_kind?: string | null;
|
|
14
|
-
size_class?: string;
|
|
15
|
-
force_layout?: string;
|
|
16
|
-
highlight?: boolean;
|
|
17
|
-
load_url: string;
|
|
18
|
-
preview_url?: string | null;
|
|
19
|
-
estimated_height_px?: number;
|
|
20
|
-
untracked?: boolean;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export type DiffMeta = {
|
|
24
|
-
files: FileMeta[];
|
|
25
|
-
totals?: {
|
|
26
|
-
files: number;
|
|
27
|
-
additions: number;
|
|
28
|
-
deletions: number;
|
|
29
|
-
};
|
|
30
|
-
range?: string;
|
|
31
|
-
branch?: string;
|
|
32
|
-
project?: string;
|
|
33
|
-
generation?: number;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export type RepoTreeEntry = {
|
|
37
|
-
name: string;
|
|
38
|
-
path: string;
|
|
39
|
-
type: 'tree' | 'blob' | 'commit';
|
|
40
|
-
children_omitted?: true;
|
|
41
|
-
children_omitted_reason?: 'heavy' | 'internal' | 'truncated';
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export type RepoTreeResponse = {
|
|
45
|
-
ref: string;
|
|
46
|
-
path: string;
|
|
47
|
-
project: string;
|
|
48
|
-
branch?: string;
|
|
49
|
-
upload_enabled?: boolean;
|
|
50
|
-
entries: RepoTreeEntry[];
|
|
51
|
-
readme?: {
|
|
52
|
-
path: string;
|
|
53
|
-
text: string;
|
|
54
|
-
} | null;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export type SettingsResponse = {
|
|
58
|
-
project: string;
|
|
59
|
-
scope: {
|
|
60
|
-
omit_dirs_effective: string[];
|
|
61
|
-
omit_dirs_built_in: string[];
|
|
62
|
-
max_entries: number;
|
|
63
|
-
};
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export type FileSearchListResponse = {
|
|
67
|
-
ref: string;
|
|
68
|
-
generation: number;
|
|
69
|
-
files: {
|
|
70
|
-
path: string;
|
|
71
|
-
type: 'blob' | 'commit';
|
|
72
|
-
}[];
|
|
73
|
-
truncated: boolean;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
export type GrepMatch = {
|
|
77
|
-
path: string;
|
|
78
|
-
line: number;
|
|
79
|
-
column: number;
|
|
80
|
-
preview: string;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export type GrepResponse = {
|
|
84
|
-
ref: string;
|
|
85
|
-
engine: 'rg' | 'git' | 'fallback';
|
|
86
|
-
truncated: boolean;
|
|
87
|
-
matches: GrepMatch[];
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export type FileDiffResponse = {
|
|
91
|
-
path: string;
|
|
92
|
-
old_path?: string;
|
|
93
|
-
status?: string;
|
|
94
|
-
mode?: string;
|
|
95
|
-
diff: string;
|
|
96
|
-
hunk_count?: number;
|
|
97
|
-
rendered_hunk_count?: number;
|
|
98
|
-
truncated?: boolean;
|
|
99
|
-
binary?: boolean;
|
|
100
|
-
generation?: number;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export type FileRangeResponse = {
|
|
104
|
-
path: string;
|
|
105
|
-
ref: string;
|
|
106
|
-
start: number;
|
|
107
|
-
end: number;
|
|
108
|
-
lines: string[];
|
|
109
|
-
total: number;
|
|
110
|
-
generation?: number;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
export type DiffCardElement = HTMLElement & {
|
|
114
|
-
_diffData?: FileDiffResponse | null;
|
|
115
|
-
_file?: FileMeta | null;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
export type RefResponse = {
|
|
119
|
-
branches?: string[];
|
|
120
|
-
tags?: string[];
|
|
121
|
-
commits?: string[];
|
|
122
|
-
current?: string;
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
declare global {
|
|
126
|
-
interface Window {
|
|
127
|
-
Diff2HtmlUI: any;
|
|
128
|
-
hljs: any;
|
|
129
|
-
GdpExpandLogic: typeof GdpExpandLogic;
|
|
130
|
-
_lastMeta?: DiffMeta;
|
|
131
|
-
__gdpScrollSpy?: EventListener;
|
|
132
|
-
__gdpSidebarTouchedAt?: number;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const Diff2HtmlUI: any;
|
|
136
|
-
}
|