repoview 0.5.1 → 0.6.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/CHANGELOG.md +87 -0
- package/CONTRIBUTING.md +4 -3
- package/DEVELOPMENT.md +84 -16
- package/README.md +71 -5
- package/dist/api.js +58 -0
- package/dist/api.js.map +1 -0
- package/dist/cli.js +454 -0
- package/dist/cli.js.map +1 -0
- package/dist/csv.js +64 -0
- package/dist/csv.js.map +1 -0
- package/dist/format.js +25 -0
- package/dist/format.js.map +1 -0
- package/dist/gist-router.js +153 -0
- package/dist/gist-router.js.map +1 -0
- package/dist/gists.js +130 -0
- package/dist/gists.js.map +1 -0
- package/dist/git.js +67 -0
- package/dist/git.js.map +1 -0
- package/dist/gitignore.js +34 -0
- package/dist/gitignore.js.map +1 -0
- package/dist/linkcheck.js +310 -0
- package/dist/linkcheck.js.map +1 -0
- package/dist/markdown.js +493 -0
- package/dist/markdown.js.map +1 -0
- package/dist/net.js +10 -0
- package/dist/net.js.map +1 -0
- package/dist/paths.js +59 -0
- package/dist/paths.js.map +1 -0
- package/dist/reload.js +55 -0
- package/dist/reload.js.map +1 -0
- package/dist/repo-context.js +80 -0
- package/dist/repo-context.js.map +1 -0
- package/dist/repo-router.js +810 -0
- package/dist/repo-router.js.map +1 -0
- package/dist/review-cli.js +228 -0
- package/dist/review-cli.js.map +1 -0
- package/dist/server.js +122 -0
- package/dist/server.js.map +1 -0
- package/dist/session.js +86 -0
- package/dist/session.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/views.js +780 -0
- package/dist/views.js.map +1 -0
- package/package.json +20 -9
- package/public/app.css +113 -0
- package/public/app.js +26 -3
- package/public/gist.js +60 -0
- package/public/review.js +9 -6
- package/public/session.js +61 -0
- package/src/cli.js +0 -91
- package/src/gitignore.js +0 -34
- package/src/linkcheck.js +0 -312
- package/src/markdown.js +0 -518
- package/src/review-cli.js +0 -245
- package/src/server.js +0 -1126
- package/src/views.js +0 -657
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import express from "express";
|
|
3
|
+
import { renderGistPage, renderGistEditPage, renderGistListPage, renderErrorPage, } from "./views.js";
|
|
4
|
+
const ID_RE = /^[A-Za-z0-9_-]+$/;
|
|
5
|
+
const MD_EXT = new Set([".md", ".markdown", ".mdown", ".mkd", ".mkdn"]);
|
|
6
|
+
/** Resolve the absolute base URL for returned gist links. */
|
|
7
|
+
function resolveBaseUrl(req, baseUrlEnv) {
|
|
8
|
+
if (baseUrlEnv)
|
|
9
|
+
return baseUrlEnv.replace(/\/+$/, "");
|
|
10
|
+
const host = req.get("host");
|
|
11
|
+
if (host)
|
|
12
|
+
return `${req.protocol}://${host}`;
|
|
13
|
+
return "";
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Routes for ephemeral gists: `POST /api/gists` (publish, open so remote agents
|
|
17
|
+
* can use it), `GET /gist/:id` (preview), `GET /gist/:id/raw`, and `GET /gists`
|
|
18
|
+
* (the list page).
|
|
19
|
+
*/
|
|
20
|
+
export function createGistRouter({ store, md, baseUrlEnv }) {
|
|
21
|
+
const router = express.Router();
|
|
22
|
+
router.post("/api/gists", express.json({ limit: "2mb" }), (req, res) => {
|
|
23
|
+
try {
|
|
24
|
+
const { content, filename, title, ttlSeconds } = req.body ?? {};
|
|
25
|
+
const ttlMs = typeof ttlSeconds === "number" && Number.isFinite(ttlSeconds) && ttlSeconds > 0
|
|
26
|
+
? ttlSeconds * 1000
|
|
27
|
+
: undefined;
|
|
28
|
+
const gist = store.create({ content, filename, title, ttlMs });
|
|
29
|
+
const base = resolveBaseUrl(req, baseUrlEnv);
|
|
30
|
+
res.status(201).json({
|
|
31
|
+
id: gist.id,
|
|
32
|
+
filename: gist.filename,
|
|
33
|
+
title: gist.title,
|
|
34
|
+
url: `${base}/gist/${gist.id}`,
|
|
35
|
+
rawUrl: `${base}/gist/${gist.id}/raw`,
|
|
36
|
+
createdAt: new Date(gist.createdAt).toISOString(),
|
|
37
|
+
expiresAt: new Date(gist.expiresAt).toISOString(),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
const err = e;
|
|
42
|
+
res.status(err.statusCode || 500).json({ error: err.message });
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
router.patch("/api/gists/:id", express.json({ limit: "2mb" }), (req, res) => {
|
|
46
|
+
if (!ID_RE.test(req.params.id)) {
|
|
47
|
+
return res.status(400).json({ error: "Invalid gist id" });
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const { content, filename, title, ttlSeconds } = req.body ?? {};
|
|
51
|
+
const ttlMs = typeof ttlSeconds === "number" && Number.isFinite(ttlSeconds) && ttlSeconds > 0
|
|
52
|
+
? ttlSeconds * 1000
|
|
53
|
+
: undefined;
|
|
54
|
+
const gist = store.update(req.params.id, { content, filename, title, ttlMs });
|
|
55
|
+
if (!gist)
|
|
56
|
+
return res.status(404).json({ error: "Gist not found or expired" });
|
|
57
|
+
const base = resolveBaseUrl(req, baseUrlEnv);
|
|
58
|
+
res.json({
|
|
59
|
+
id: gist.id,
|
|
60
|
+
filename: gist.filename,
|
|
61
|
+
title: gist.title,
|
|
62
|
+
url: `${base}/gist/${gist.id}`,
|
|
63
|
+
rawUrl: `${base}/gist/${gist.id}/raw`,
|
|
64
|
+
expiresAt: new Date(gist.expiresAt).toISOString(),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
const err = e;
|
|
69
|
+
res.status(err.statusCode || 500).json({ error: err.message });
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
router.get("/api/gists", (req, res) => {
|
|
73
|
+
const base = resolveBaseUrl(req, baseUrlEnv);
|
|
74
|
+
res.json({
|
|
75
|
+
gists: store.list().map((g) => ({
|
|
76
|
+
id: g.id,
|
|
77
|
+
filename: g.filename,
|
|
78
|
+
title: g.title,
|
|
79
|
+
url: `${base}/gist/${g.id}`,
|
|
80
|
+
rawUrl: `${base}/gist/${g.id}/raw`,
|
|
81
|
+
createdAt: new Date(g.createdAt).toISOString(),
|
|
82
|
+
expiresAt: new Date(g.expiresAt).toISOString(),
|
|
83
|
+
})),
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
router.delete("/api/gists/:id", (req, res) => {
|
|
87
|
+
if (!ID_RE.test(req.params.id)) {
|
|
88
|
+
return res.status(400).json({ error: "Invalid gist id" });
|
|
89
|
+
}
|
|
90
|
+
if (!store.delete(req.params.id)) {
|
|
91
|
+
return res.status(404).json({ error: "Gist not found" });
|
|
92
|
+
}
|
|
93
|
+
res.json({ ok: true, id: req.params.id });
|
|
94
|
+
});
|
|
95
|
+
router.get("/gists", (req, res) => {
|
|
96
|
+
res.send(renderGistListPage({ gists: store.list() }));
|
|
97
|
+
});
|
|
98
|
+
router.get("/gist/:id/edit", (req, res) => {
|
|
99
|
+
if (!ID_RE.test(req.params.id)) {
|
|
100
|
+
return res.status(400).send(renderErrorPage({
|
|
101
|
+
title: "Error",
|
|
102
|
+
message: "Invalid gist id",
|
|
103
|
+
repoBase: "",
|
|
104
|
+
repos: [],
|
|
105
|
+
currentRepoId: "",
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
const gist = store.get(req.params.id);
|
|
109
|
+
if (!gist) {
|
|
110
|
+
return res.status(404).send(renderGistListPage({
|
|
111
|
+
gists: store.list(),
|
|
112
|
+
notice: "That gist has expired or does not exist.",
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
res.send(renderGistEditPage({ gist }));
|
|
116
|
+
});
|
|
117
|
+
router.get("/gist/:id/raw", (req, res) => {
|
|
118
|
+
if (!ID_RE.test(req.params.id)) {
|
|
119
|
+
return res.status(400).type("text/plain").send("Invalid gist id");
|
|
120
|
+
}
|
|
121
|
+
const gist = store.get(req.params.id);
|
|
122
|
+
if (!gist) {
|
|
123
|
+
return res.status(404).type("text/plain").send("Gist not found or expired");
|
|
124
|
+
}
|
|
125
|
+
res.type("text/plain; charset=utf-8").send(gist.content);
|
|
126
|
+
});
|
|
127
|
+
router.get("/gist/:id", (req, res) => {
|
|
128
|
+
if (!ID_RE.test(req.params.id)) {
|
|
129
|
+
return res.status(400).send(renderErrorPage({
|
|
130
|
+
title: "Error",
|
|
131
|
+
message: "Invalid gist id",
|
|
132
|
+
repoBase: "",
|
|
133
|
+
repos: [],
|
|
134
|
+
currentRepoId: "",
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
const gist = store.get(req.params.id);
|
|
138
|
+
if (!gist) {
|
|
139
|
+
return res.status(404).send(renderGistListPage({
|
|
140
|
+
gists: store.list(),
|
|
141
|
+
notice: "That gist has expired or does not exist.",
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
144
|
+
const ext = path.posix.extname(gist.filename).toLowerCase();
|
|
145
|
+
const isMarkdown = MD_EXT.has(ext);
|
|
146
|
+
const html = isMarkdown
|
|
147
|
+
? md.render(gist.content, { baseDirPosix: "", repoBase: "" })
|
|
148
|
+
: md.renderCodeBlock(gist.content, { languageHint: ext ? ext.slice(1) : "" });
|
|
149
|
+
res.send(renderGistPage({ gist, html, isMarkdown }));
|
|
150
|
+
});
|
|
151
|
+
return router;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=gist-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gist-router.js","sourceRoot":"","sources":["../src/gist-router.ts"],"names":[],"mappings":"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"}
|
package/dist/gists.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const MINUTE = 60 * 1000;
|
|
4
|
+
const DAY = 24 * 60 * MINUTE;
|
|
5
|
+
function httpError(message, statusCode) {
|
|
6
|
+
const err = new Error(message);
|
|
7
|
+
err.statusCode = statusCode;
|
|
8
|
+
return err;
|
|
9
|
+
}
|
|
10
|
+
function sanitizeFilename(name) {
|
|
11
|
+
const base = path.posix.basename(String(name || "").trim());
|
|
12
|
+
const cleaned = base.replace(/[^A-Za-z0-9._-]+/g, "_").slice(0, 100);
|
|
13
|
+
return cleaned || "gist.md";
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* In-memory store of ephemeral published files ("gists"). Nothing is persisted —
|
|
17
|
+
* gists do not survive a restart — and each one expires after its TTL (default
|
|
18
|
+
* 24h). A background sweeper drops expired entries; access also expires lazily.
|
|
19
|
+
*/
|
|
20
|
+
export function createGistStore(opts = {}) {
|
|
21
|
+
const defaultTtlMs = opts.defaultTtlMs ?? DAY;
|
|
22
|
+
const maxTtlMs = opts.maxTtlMs ?? 7 * DAY;
|
|
23
|
+
const minTtlMs = opts.minTtlMs ?? MINUTE;
|
|
24
|
+
const maxContentBytes = opts.maxContentBytes ?? 1024 * 1024;
|
|
25
|
+
const maxGists = opts.maxGists ?? 500;
|
|
26
|
+
const sweepIntervalMs = opts.sweepIntervalMs ?? 5 * MINUTE;
|
|
27
|
+
const gists = new Map();
|
|
28
|
+
function genId() {
|
|
29
|
+
return crypto.randomBytes(9).toString("base64url"); // 12 url-safe chars
|
|
30
|
+
}
|
|
31
|
+
const timer = setInterval(() => {
|
|
32
|
+
const now = Date.now();
|
|
33
|
+
for (const [id, g] of gists)
|
|
34
|
+
if (g.expiresAt <= now)
|
|
35
|
+
gists.delete(id);
|
|
36
|
+
}, sweepIntervalMs);
|
|
37
|
+
timer.unref?.();
|
|
38
|
+
return {
|
|
39
|
+
create({ content, filename, title, ttlMs }) {
|
|
40
|
+
if (typeof content !== "string" || content.length === 0) {
|
|
41
|
+
throw httpError("content is required", 400);
|
|
42
|
+
}
|
|
43
|
+
if (Buffer.byteLength(content, "utf8") > maxContentBytes) {
|
|
44
|
+
throw httpError("content too large", 413);
|
|
45
|
+
}
|
|
46
|
+
const ttl = Math.min(maxTtlMs, Math.max(minTtlMs, ttlMs ?? defaultTtlMs));
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
// Cap memory use: evict the oldest gist when at capacity.
|
|
49
|
+
if (gists.size >= maxGists) {
|
|
50
|
+
let oldestId = null;
|
|
51
|
+
let oldest = Infinity;
|
|
52
|
+
for (const [id, g] of gists) {
|
|
53
|
+
if (g.createdAt < oldest) {
|
|
54
|
+
oldest = g.createdAt;
|
|
55
|
+
oldestId = id;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (oldestId)
|
|
59
|
+
gists.delete(oldestId);
|
|
60
|
+
}
|
|
61
|
+
let id = genId();
|
|
62
|
+
while (gists.has(id))
|
|
63
|
+
id = genId();
|
|
64
|
+
const gist = {
|
|
65
|
+
id,
|
|
66
|
+
title: title && title.trim() ? title.trim() : null,
|
|
67
|
+
filename: sanitizeFilename(filename),
|
|
68
|
+
content,
|
|
69
|
+
createdAt: now,
|
|
70
|
+
expiresAt: now + ttl,
|
|
71
|
+
};
|
|
72
|
+
gists.set(id, gist);
|
|
73
|
+
return gist;
|
|
74
|
+
},
|
|
75
|
+
get(id) {
|
|
76
|
+
const g = gists.get(id);
|
|
77
|
+
if (!g)
|
|
78
|
+
return undefined;
|
|
79
|
+
if (g.expiresAt <= Date.now()) {
|
|
80
|
+
gists.delete(id);
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
return g;
|
|
84
|
+
},
|
|
85
|
+
update(id, { content, filename, title, ttlMs }) {
|
|
86
|
+
const g = gists.get(id);
|
|
87
|
+
if (!g || g.expiresAt <= Date.now()) {
|
|
88
|
+
gists.delete(id);
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
if (content !== undefined) {
|
|
92
|
+
if (typeof content !== "string" || content.length === 0) {
|
|
93
|
+
throw httpError("content is required", 400);
|
|
94
|
+
}
|
|
95
|
+
if (Buffer.byteLength(content, "utf8") > maxContentBytes) {
|
|
96
|
+
throw httpError("content too large", 413);
|
|
97
|
+
}
|
|
98
|
+
g.content = content;
|
|
99
|
+
}
|
|
100
|
+
if (filename !== undefined)
|
|
101
|
+
g.filename = sanitizeFilename(filename);
|
|
102
|
+
if (title !== undefined)
|
|
103
|
+
g.title = title && title.trim() ? title.trim() : null;
|
|
104
|
+
if (ttlMs !== undefined) {
|
|
105
|
+
g.expiresAt = Date.now() + Math.min(maxTtlMs, Math.max(minTtlMs, ttlMs));
|
|
106
|
+
}
|
|
107
|
+
return g;
|
|
108
|
+
},
|
|
109
|
+
list() {
|
|
110
|
+
const now = Date.now();
|
|
111
|
+
const out = [];
|
|
112
|
+
for (const [id, g] of gists) {
|
|
113
|
+
if (g.expiresAt <= now) {
|
|
114
|
+
gists.delete(id);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
out.push(g);
|
|
118
|
+
}
|
|
119
|
+
return out.sort((a, b) => b.createdAt - a.createdAt);
|
|
120
|
+
},
|
|
121
|
+
delete(id) {
|
|
122
|
+
return gists.delete(id);
|
|
123
|
+
},
|
|
124
|
+
close() {
|
|
125
|
+
clearInterval(timer);
|
|
126
|
+
gists.clear();
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=gists.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gists.js","sourceRoot":"","sources":["../src/gists.ts"],"names":[],"mappings":"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"}
|
package/dist/git.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
export function execGit(repoRootReal, args, maxBytes = 1024 * 1024) {
|
|
5
|
+
return new Promise((resolve) => {
|
|
6
|
+
const child = spawn("git", args, { cwd: repoRootReal });
|
|
7
|
+
let out = "";
|
|
8
|
+
let size = 0;
|
|
9
|
+
let killed = false;
|
|
10
|
+
child.stdout.on("data", (chunk) => {
|
|
11
|
+
size += chunk.length;
|
|
12
|
+
if (size > maxBytes) {
|
|
13
|
+
if (!killed) {
|
|
14
|
+
killed = true;
|
|
15
|
+
child.kill();
|
|
16
|
+
}
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
out += String(chunk);
|
|
20
|
+
});
|
|
21
|
+
child.on("close", (code) => {
|
|
22
|
+
if (killed)
|
|
23
|
+
return resolve({ output: out, tooLarge: true, code });
|
|
24
|
+
resolve({ output: code === 0 ? out.trim() : null, tooLarge: false, code });
|
|
25
|
+
});
|
|
26
|
+
child.on("error", () => resolve({ output: null, tooLarge: false, code: -1 }));
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export function validateGitRef(ref) {
|
|
30
|
+
if (!ref || typeof ref !== "string")
|
|
31
|
+
return false;
|
|
32
|
+
return /^[a-zA-Z0-9_.\/\-~^]+$/.test(ref);
|
|
33
|
+
}
|
|
34
|
+
export async function getGitBranches(repoRootReal) {
|
|
35
|
+
const { output } = await execGit(repoRootReal, ["branch", "--format=%(refname:short)"]);
|
|
36
|
+
if (!output)
|
|
37
|
+
return [];
|
|
38
|
+
return output.split("\n").filter(Boolean);
|
|
39
|
+
}
|
|
40
|
+
export async function getGitTags(repoRootReal) {
|
|
41
|
+
const { output } = await execGit(repoRootReal, ["tag", "-l"]);
|
|
42
|
+
if (!output)
|
|
43
|
+
return [];
|
|
44
|
+
return output.split("\n").filter(Boolean);
|
|
45
|
+
}
|
|
46
|
+
export async function getGitDiffRaw(repoRootReal, base) {
|
|
47
|
+
const maxBytes = 512 * 1024;
|
|
48
|
+
const { output, tooLarge } = await execGit(repoRootReal, ["diff", base], maxBytes);
|
|
49
|
+
return { raw: output || "", tooLarge };
|
|
50
|
+
}
|
|
51
|
+
export async function getGitInfo(repoRootReal) {
|
|
52
|
+
const gitDir = path.join(repoRootReal, ".git");
|
|
53
|
+
try {
|
|
54
|
+
await fs.stat(gitDir);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return { branch: null, commit: null };
|
|
58
|
+
}
|
|
59
|
+
const [branchResult, commitResult] = await Promise.all([
|
|
60
|
+
execGit(repoRootReal, ["rev-parse", "--abbrev-ref", "HEAD"]),
|
|
61
|
+
execGit(repoRootReal, ["rev-parse", "HEAD"]),
|
|
62
|
+
]);
|
|
63
|
+
const branch = branchResult.output;
|
|
64
|
+
const commit = commitResult.output;
|
|
65
|
+
return { branch: branch && branch !== "HEAD" ? branch : branch, commit };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=git.js.map
|
package/dist/git.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import ignore from "ignore";
|
|
4
|
+
function toPosixPath(p) {
|
|
5
|
+
return p.split(path.sep).join("/");
|
|
6
|
+
}
|
|
7
|
+
export async function loadGitIgnoreMatcher(repoRootReal) {
|
|
8
|
+
const ig = ignore();
|
|
9
|
+
// Baseline ignores (never show these via toggle either).
|
|
10
|
+
ig.add([".git/"]);
|
|
11
|
+
try {
|
|
12
|
+
const content = await fs.readFile(path.join(repoRootReal, ".gitignore"), "utf8");
|
|
13
|
+
ig.add(content);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// No .gitignore or unreadable; ignore.
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
ignores(relPathPosix, { isDir = false } = {}) {
|
|
20
|
+
const p = toPosixPath(String(relPathPosix || "").replace(/^\/+/, ""));
|
|
21
|
+
if (!p)
|
|
22
|
+
return false;
|
|
23
|
+
if (ig.ignores(p))
|
|
24
|
+
return true;
|
|
25
|
+
if (isDir) {
|
|
26
|
+
const withSlash = p.endsWith("/") ? p : `${p}/`;
|
|
27
|
+
if (ig.ignores(withSlash))
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=gitignore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitignore.js","sourceRoot":"","sources":["../src/gitignore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,YAAoB;IAC7D,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAEpB,yDAAyD;IACzD,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAElB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC;QACjF,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,uCAAuC;IACzC,CAAC;IAED,OAAO;QACL,OAAO,CAAC,YAAoB,EAAE,EAAE,KAAK,GAAG,KAAK,KAA0B,EAAE;YACvE,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;YACtE,IAAI,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;YACrB,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC/B,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;gBAChD,IAAI,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC;oBAAE,OAAO,IAAI,CAAC;YACzC,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
|