@dynamik-dev/refdocs 0.5.1 → 0.6.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.
Files changed (41) hide show
  1. package/README.md +33 -7
  2. package/dist/src/add.d.ts +0 -9
  3. package/dist/src/add.d.ts.map +1 -1
  4. package/dist/src/add.js +9 -55
  5. package/dist/src/add.js.map +1 -1
  6. package/dist/src/chunker.d.ts.map +1 -1
  7. package/dist/src/chunker.js +23 -3
  8. package/dist/src/chunker.js.map +1 -1
  9. package/dist/src/config.d.ts +3 -4
  10. package/dist/src/config.d.ts.map +1 -1
  11. package/dist/src/config.js +19 -16
  12. package/dist/src/config.js.map +1 -1
  13. package/dist/src/index.js +65 -85
  14. package/dist/src/index.js.map +1 -1
  15. package/dist/src/indexer.d.ts +11 -1
  16. package/dist/src/indexer.d.ts.map +1 -1
  17. package/dist/src/indexer.js +129 -7
  18. package/dist/src/indexer.js.map +1 -1
  19. package/dist/src/search.d.ts +15 -2
  20. package/dist/src/search.d.ts.map +1 -1
  21. package/dist/src/search.js +59 -20
  22. package/dist/src/search.js.map +1 -1
  23. package/dist/src/types.d.ts +5 -9
  24. package/dist/src/types.d.ts.map +1 -1
  25. package/dist/tests/chunker.test.js +33 -12
  26. package/dist/tests/chunker.test.js.map +1 -1
  27. package/dist/tests/global.test.js +16 -26
  28. package/dist/tests/global.test.js.map +1 -1
  29. package/dist/tests/indexer.test.js +162 -12
  30. package/dist/tests/indexer.test.js.map +1 -1
  31. package/dist/tests/search.test.js +103 -12
  32. package/dist/tests/search.test.js.map +1 -1
  33. package/package.json +2 -8
  34. package/dist/src/crawl.d.ts +0 -25
  35. package/dist/src/crawl.d.ts.map +0 -1
  36. package/dist/src/crawl.js +0 -226
  37. package/dist/src/crawl.js.map +0 -1
  38. package/dist/tests/crawl.test.d.ts +0 -2
  39. package/dist/tests/crawl.test.d.ts.map +0 -1
  40. package/dist/tests/crawl.test.js +0 -343
  41. package/dist/tests/crawl.test.js.map +0 -1
package/dist/src/crawl.js DELETED
@@ -1,226 +0,0 @@
1
- import { mkdirSync, writeFileSync } from "node:fs";
2
- import { join, dirname, extname } from "node:path";
3
- import * as cheerio from "cheerio";
4
- import { Readability } from "@mozilla/readability";
5
- import TurndownService from "turndown";
6
- import { JSDOM } from "jsdom";
7
- const DEFAULT_CRAWL_OPTIONS = {
8
- maxPages: 200,
9
- depth: 3,
10
- delayMs: 150,
11
- };
12
- const USER_AGENT = "refdocs-cli/0.4.0";
13
- function sleep(ms) {
14
- return new Promise((resolve) => setTimeout(resolve, ms));
15
- }
16
- export function normalizeUrl(raw) {
17
- try {
18
- const u = new URL(raw);
19
- u.hash = "";
20
- // Strip trailing slash unless it's the root
21
- if (u.pathname.length > 1 && u.pathname.endsWith("/")) {
22
- u.pathname = u.pathname.slice(0, -1);
23
- }
24
- return u.toString();
25
- }
26
- catch {
27
- return raw;
28
- }
29
- }
30
- export function isSubPath(candidate, scope) {
31
- const candidateUrl = new URL(candidate);
32
- const scopeUrl = new URL(scope);
33
- if (candidateUrl.origin !== scopeUrl.origin)
34
- return false;
35
- const scopePath = scopeUrl.pathname.endsWith("/")
36
- ? scopeUrl.pathname
37
- : scopeUrl.pathname + "/";
38
- return (candidateUrl.pathname === scopeUrl.pathname ||
39
- candidateUrl.pathname.startsWith(scopePath));
40
- }
41
- export function urlToFilePath(pageUrl) {
42
- const u = new URL(pageUrl);
43
- let path = u.pathname;
44
- if (path.endsWith("/"))
45
- path = path + "index";
46
- if (path === "")
47
- path = "/index";
48
- // Strip leading slash
49
- path = path.replace(/^\//, "");
50
- // If it already has an extension, keep it but ensure .md for HTML pages
51
- const ext = extname(path);
52
- if (!ext || ext === ".html" || ext === ".htm") {
53
- path = path.replace(/\.(html|htm)$/, "") + ".md";
54
- }
55
- // Ensure .md extension for extensionless paths
56
- if (!extname(path)) {
57
- path = path + ".md";
58
- }
59
- return path;
60
- }
61
- export function htmlToMarkdown(html, url) {
62
- const dom = new JSDOM(html, { url });
63
- const reader = new Readability(dom.window.document);
64
- const article = reader.parse();
65
- const turndown = new TurndownService({
66
- headingStyle: "atx",
67
- codeBlockStyle: "fenced",
68
- bulletListMarker: "-",
69
- });
70
- if (article?.content) {
71
- let md = turndown.turndown(article.content);
72
- // Prepend the title as an h1 if readability extracted one
73
- if (article.title) {
74
- md = `# ${article.title}\n\n${md}`;
75
- }
76
- return md;
77
- }
78
- // Fallback: convert the whole body
79
- return turndown.turndown(html);
80
- }
81
- export function discoverLinks(html, pageUrl, scope) {
82
- const $ = cheerio.load(html);
83
- const links = [];
84
- const base = new URL(pageUrl);
85
- $("a[href]").each((_, el) => {
86
- const href = $(el).attr("href");
87
- if (!href)
88
- return;
89
- // Skip anchors, javascript:, mailto:, etc.
90
- if (href.startsWith("#") || href.startsWith("javascript:") || href.startsWith("mailto:")) {
91
- return;
92
- }
93
- try {
94
- const resolved = new URL(href, base).toString();
95
- const normalized = normalizeUrl(resolved);
96
- // Only follow links within scope and same origin
97
- if (isSubPath(normalized, scope)) {
98
- // Skip common non-page extensions
99
- const ext = extname(new URL(normalized).pathname).toLowerCase();
100
- if (ext && ![".html", ".htm", ""].includes(ext))
101
- return;
102
- links.push(normalized);
103
- }
104
- }
105
- catch {
106
- // Invalid URL, skip
107
- }
108
- });
109
- return [...new Set(links)];
110
- }
111
- async function fetchPage(url) {
112
- const response = await fetch(url, {
113
- headers: {
114
- "User-Agent": USER_AGENT,
115
- Accept: "text/html,text/plain,text/markdown,*/*",
116
- },
117
- redirect: "follow",
118
- });
119
- if (!response.ok) {
120
- throw new Error(`HTTP ${response.status} fetching ${url}`);
121
- }
122
- const contentType = response.headers.get("content-type") ?? "";
123
- const html = await response.text();
124
- return { html, contentType };
125
- }
126
- export function isTextFileUrl(url) {
127
- try {
128
- const pathname = new URL(url).pathname.toLowerCase();
129
- return pathname.endsWith(".txt") || pathname.endsWith(".md");
130
- }
131
- catch {
132
- return false;
133
- }
134
- }
135
- export function isGitHubUrl(url) {
136
- try {
137
- return new URL(url).hostname === "github.com";
138
- }
139
- catch {
140
- return false;
141
- }
142
- }
143
- export function deriveLocalPath(url) {
144
- const u = new URL(url);
145
- const hostname = u.hostname;
146
- let path = u.pathname.replace(/^\//, "");
147
- if (!path)
148
- path = "index";
149
- return `ref-docs/${hostname}/${path}`;
150
- }
151
- export function deriveCrawlDir(url) {
152
- const u = new URL(url);
153
- const hostname = u.hostname;
154
- let path = u.pathname.replace(/^\//, "").replace(/\/+$/, "");
155
- if (!path)
156
- path = "root";
157
- return `ref-docs/${hostname}/${path}`;
158
- }
159
- export async function fetchSingleFile(url) {
160
- const response = await fetch(url, {
161
- headers: { "User-Agent": USER_AGENT },
162
- redirect: "follow",
163
- });
164
- if (!response.ok) {
165
- throw new Error(`HTTP ${response.status} fetching ${url}`);
166
- }
167
- const contentType = response.headers.get("content-type") ?? "";
168
- const content = await response.text();
169
- return { content, contentType };
170
- }
171
- export async function crawlSite(startUrl, outputDir, options) {
172
- const opts = {
173
- maxPages: options?.maxPages ?? DEFAULT_CRAWL_OPTIONS.maxPages,
174
- depth: options?.depth ?? DEFAULT_CRAWL_OPTIONS.depth,
175
- delayMs: options?.delayMs ?? DEFAULT_CRAWL_OPTIONS.delayMs,
176
- };
177
- const scope = normalizeUrl(startUrl);
178
- const visited = new Set();
179
- const queue = [{ url: scope, depth: 0 }];
180
- const pages = [];
181
- let filesWritten = 0;
182
- while (queue.length > 0 && filesWritten < opts.maxPages) {
183
- const item = queue.shift();
184
- const normalized = normalizeUrl(item.url);
185
- if (visited.has(normalized))
186
- continue;
187
- visited.add(normalized);
188
- try {
189
- const { html, contentType } = await fetchPage(normalized);
190
- // Only process HTML pages
191
- if (!contentType.includes("text/html"))
192
- continue;
193
- const markdown = htmlToMarkdown(html, normalized);
194
- const filePath = urlToFilePath(normalized);
195
- const fullPath = join(outputDir, filePath);
196
- mkdirSync(dirname(fullPath), { recursive: true });
197
- writeFileSync(fullPath, markdown, "utf-8");
198
- filesWritten++;
199
- pages.push(normalized);
200
- // Discover links if we haven't hit max depth
201
- if (item.depth < opts.depth) {
202
- const links = discoverLinks(html, normalized, scope);
203
- for (const link of links) {
204
- if (!visited.has(normalizeUrl(link))) {
205
- queue.push({ url: link, depth: item.depth + 1 });
206
- }
207
- }
208
- }
209
- // Throttle between requests
210
- if (queue.length > 0) {
211
- await sleep(opts.delayMs);
212
- }
213
- }
214
- catch (err) {
215
- // Log but don't fail the whole crawl for one bad page
216
- const msg = err instanceof Error ? err.message : String(err);
217
- process.stderr.write(`Warning: skipping ${normalized} (${msg})\n`);
218
- }
219
- }
220
- const hitLimit = filesWritten >= opts.maxPages && queue.length > 0;
221
- if (hitLimit) {
222
- process.stderr.write(`Reached ${opts.maxPages} page limit. Use --max-pages to increase.\n`);
223
- }
224
- return { filesWritten, pages };
225
- }
226
- //# sourceMappingURL=crawl.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crawl.js","sourceRoot":"","sources":["../../src/crawl.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=crawl.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crawl.test.d.ts","sourceRoot":"","sources":["../../tests/crawl.test.ts"],"names":[],"mappings":""}
@@ -1,343 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
2
- import { readFileSync, mkdtempSync, rmSync, existsSync } from "node:fs";
3
- import { join } from "node:path";
4
- import { tmpdir } from "node:os";
5
- import { isTextFileUrl, isGitHubUrl, deriveLocalPath, deriveCrawlDir, normalizeUrl, isSubPath, urlToFilePath, htmlToMarkdown, discoverLinks, crawlSite, } from "../src/crawl.js";
6
- const FIXTURES_DIR = join(import.meta.dirname, "fixtures", "crawl-site");
7
- function loadFixture(name) {
8
- return readFileSync(join(FIXTURES_DIR, name), "utf-8");
9
- }
10
- // --- Pure function unit tests ---
11
- describe("isTextFileUrl", () => {
12
- it("returns true for .txt URLs", () => {
13
- expect(isTextFileUrl("https://hono.dev/llms.txt")).toBe(true);
14
- expect(isTextFileUrl("https://example.com/docs/llms-full.txt")).toBe(true);
15
- });
16
- it("returns true for .md URLs", () => {
17
- expect(isTextFileUrl("https://example.com/README.md")).toBe(true);
18
- });
19
- it("returns false for HTML pages", () => {
20
- expect(isTextFileUrl("https://hono.dev/docs")).toBe(false);
21
- expect(isTextFileUrl("https://hono.dev/docs/getting-started")).toBe(false);
22
- });
23
- it("returns false for .html URLs", () => {
24
- expect(isTextFileUrl("https://example.com/page.html")).toBe(false);
25
- });
26
- it("returns false for invalid URLs", () => {
27
- expect(isTextFileUrl("not-a-url")).toBe(false);
28
- });
29
- });
30
- describe("isGitHubUrl", () => {
31
- it("returns true for github.com URLs", () => {
32
- expect(isGitHubUrl("https://github.com/honojs/hono")).toBe(true);
33
- expect(isGitHubUrl("https://github.com/honojs/hono/tree/main/docs")).toBe(true);
34
- });
35
- it("returns false for other URLs", () => {
36
- expect(isGitHubUrl("https://hono.dev/docs")).toBe(false);
37
- expect(isGitHubUrl("https://gitlab.com/foo/bar")).toBe(false);
38
- });
39
- it("returns false for invalid URLs", () => {
40
- expect(isGitHubUrl("not-a-url")).toBe(false);
41
- });
42
- });
43
- describe("deriveLocalPath", () => {
44
- it("derives path from URL with file", () => {
45
- expect(deriveLocalPath("https://hono.dev/llms-full.txt")).toBe("ref-docs/hono.dev/llms-full.txt");
46
- });
47
- it("derives path from URL with deep path", () => {
48
- expect(deriveLocalPath("https://example.com/docs/api/reference.md")).toBe("ref-docs/example.com/docs/api/reference.md");
49
- });
50
- it("handles root path", () => {
51
- expect(deriveLocalPath("https://example.com/")).toBe("ref-docs/example.com/index");
52
- expect(deriveLocalPath("https://example.com")).toBe("ref-docs/example.com/index");
53
- });
54
- });
55
- describe("deriveCrawlDir", () => {
56
- it("derives directory from URL path", () => {
57
- expect(deriveCrawlDir("https://hono.dev/docs")).toBe("ref-docs/hono.dev/docs");
58
- });
59
- it("strips trailing slashes", () => {
60
- expect(deriveCrawlDir("https://hono.dev/docs/")).toBe("ref-docs/hono.dev/docs");
61
- });
62
- it("handles deep paths", () => {
63
- expect(deriveCrawlDir("https://example.com/api/v2/docs")).toBe("ref-docs/example.com/api/v2/docs");
64
- });
65
- it("handles root URL", () => {
66
- expect(deriveCrawlDir("https://example.com")).toBe("ref-docs/example.com/root");
67
- expect(deriveCrawlDir("https://example.com/")).toBe("ref-docs/example.com/root");
68
- });
69
- });
70
- describe("normalizeUrl", () => {
71
- it("strips fragment", () => {
72
- expect(normalizeUrl("https://example.com/docs#section")).toBe("https://example.com/docs");
73
- });
74
- it("strips trailing slash from non-root path", () => {
75
- expect(normalizeUrl("https://example.com/docs/")).toBe("https://example.com/docs");
76
- });
77
- it("preserves trailing slash on root", () => {
78
- expect(normalizeUrl("https://example.com/")).toBe("https://example.com/");
79
- });
80
- it("returns input for invalid URLs", () => {
81
- expect(normalizeUrl("not-a-url")).toBe("not-a-url");
82
- });
83
- });
84
- describe("isSubPath", () => {
85
- it("returns true for exact match", () => {
86
- expect(isSubPath("https://example.com/docs", "https://example.com/docs")).toBe(true);
87
- });
88
- it("returns true for child path", () => {
89
- expect(isSubPath("https://example.com/docs/api", "https://example.com/docs")).toBe(true);
90
- });
91
- it("returns true for deeply nested child", () => {
92
- expect(isSubPath("https://example.com/docs/api/auth/jwt", "https://example.com/docs")).toBe(true);
93
- });
94
- it("returns false for sibling path", () => {
95
- expect(isSubPath("https://example.com/blog", "https://example.com/docs")).toBe(false);
96
- });
97
- it("returns false for partial prefix match", () => {
98
- expect(isSubPath("https://example.com/docs-v2", "https://example.com/docs")).toBe(false);
99
- });
100
- it("returns false for different origin", () => {
101
- expect(isSubPath("https://other.com/docs/api", "https://example.com/docs")).toBe(false);
102
- });
103
- it("handles root scope", () => {
104
- expect(isSubPath("https://example.com/anything", "https://example.com/")).toBe(true);
105
- expect(isSubPath("https://example.com/deep/nested/path", "https://example.com/")).toBe(true);
106
- });
107
- });
108
- describe("urlToFilePath", () => {
109
- it("converts extensionless path to .md", () => {
110
- expect(urlToFilePath("https://example.com/docs/api")).toBe("docs/api.md");
111
- });
112
- it("converts .html to .md", () => {
113
- expect(urlToFilePath("https://example.com/docs/api.html")).toBe("docs/api.md");
114
- });
115
- it("converts .htm to .md", () => {
116
- expect(urlToFilePath("https://example.com/page.htm")).toBe("page.md");
117
- });
118
- it("handles trailing slash with index", () => {
119
- expect(urlToFilePath("https://example.com/docs/")).toBe("docs/index.md");
120
- });
121
- it("handles root path", () => {
122
- expect(urlToFilePath("https://example.com/")).toBe("index.md");
123
- });
124
- it("preserves non-html extensions", () => {
125
- expect(urlToFilePath("https://example.com/data.json")).toBe("data.json");
126
- });
127
- });
128
- // --- HTML-to-markdown conversion tests ---
129
- describe("htmlToMarkdown", () => {
130
- it("extracts article content and prepends title", () => {
131
- const html = loadFixture("getting-started.html");
132
- const md = htmlToMarkdown(html, "https://example.com/docs/getting-started");
133
- expect(md).toContain("# Getting Started");
134
- expect(md).toContain("Install Acme via npm");
135
- expect(md).toContain("npm install acme");
136
- });
137
- it("strips navigation chrome", () => {
138
- const html = loadFixture("index.html");
139
- const md = htmlToMarkdown(html, "https://example.com/docs");
140
- // Readability should strip the nav links
141
- expect(md).not.toContain("<nav>");
142
- // But article content should be present
143
- expect(md).toContain("Acme");
144
- });
145
- it("preserves code blocks", () => {
146
- const html = loadFixture("api-auth.html");
147
- const md = htmlToMarkdown(html, "https://example.com/docs/api/auth");
148
- expect(md).toContain("secret");
149
- expect(md).toContain("authenticate");
150
- });
151
- });
152
- // --- Link discovery tests ---
153
- describe("discoverLinks", () => {
154
- it("finds same-origin links within scope", () => {
155
- const html = loadFixture("index.html");
156
- const links = discoverLinks(html, "https://example.com/docs", "https://example.com/docs");
157
- expect(links).toContain("https://example.com/docs/getting-started");
158
- expect(links).toContain("https://example.com/docs/api");
159
- expect(links).toContain("https://example.com/docs/api/auth");
160
- });
161
- it("excludes external links", () => {
162
- const html = loadFixture("index.html");
163
- const links = discoverLinks(html, "https://example.com/docs", "https://example.com/docs");
164
- const external = links.filter((l) => !l.startsWith("https://example.com"));
165
- expect(external).toEqual([]);
166
- });
167
- it("excludes links outside scope", () => {
168
- const html = loadFixture("index.html");
169
- const links = discoverLinks(html, "https://example.com/docs", "https://example.com/docs");
170
- // /blog is outside /docs scope
171
- expect(links).not.toContain("https://example.com/blog");
172
- });
173
- it("deduplicates links", () => {
174
- const html = loadFixture("index.html");
175
- const links = discoverLinks(html, "https://example.com/docs", "https://example.com/docs");
176
- const unique = new Set(links);
177
- expect(links.length).toBe(unique.size);
178
- });
179
- it("resolves relative links against page URL", () => {
180
- // The fixture uses absolute paths like /docs/api, which resolve against the origin
181
- const html = loadFixture("api.html");
182
- const links = discoverLinks(html, "https://example.com/docs/api", "https://example.com/docs");
183
- expect(links).toContain("https://example.com/docs/api/auth");
184
- expect(links).toContain("https://example.com/docs/api/middleware");
185
- });
186
- });
187
- // --- crawlSite integration tests (mocked fetch) ---
188
- describe("crawlSite", () => {
189
- let tmpDir;
190
- const SITE_MAP = {
191
- "https://example.com/docs": { file: "index.html", contentType: "text/html; charset=utf-8" },
192
- "https://example.com/docs/getting-started": { file: "getting-started.html", contentType: "text/html" },
193
- "https://example.com/docs/api": { file: "api.html", contentType: "text/html" },
194
- "https://example.com/docs/api/auth": { file: "api-auth.html", contentType: "text/html" },
195
- "https://example.com/docs/api/middleware": { file: "api-middleware.html", contentType: "text/html" },
196
- };
197
- beforeEach(() => {
198
- tmpDir = mkdtempSync(join(tmpdir(), "refdocs-crawl-"));
199
- vi.stubGlobal("fetch", vi.fn(async (url) => {
200
- const normalized = url.replace(/\/$/, "");
201
- const entry = SITE_MAP[normalized] ?? SITE_MAP[url];
202
- if (!entry) {
203
- return { ok: false, status: 404, headers: new Headers() };
204
- }
205
- const body = loadFixture(entry.file);
206
- return {
207
- ok: true,
208
- status: 200,
209
- headers: new Headers({ "content-type": entry.contentType }),
210
- text: async () => body,
211
- };
212
- }));
213
- });
214
- afterEach(() => {
215
- rmSync(tmpDir, { recursive: true, force: true });
216
- vi.restoreAllMocks();
217
- });
218
- it("crawls all pages within scope", async () => {
219
- const result = await crawlSite("https://example.com/docs", tmpDir, { delayMs: 0 });
220
- expect(result.filesWritten).toBe(5);
221
- expect(result.pages).toContain("https://example.com/docs");
222
- expect(result.pages).toContain("https://example.com/docs/getting-started");
223
- expect(result.pages).toContain("https://example.com/docs/api");
224
- expect(result.pages).toContain("https://example.com/docs/api/auth");
225
- expect(result.pages).toContain("https://example.com/docs/api/middleware");
226
- });
227
- it("writes .md files to correct paths", async () => {
228
- await crawlSite("https://example.com/docs", tmpDir, { delayMs: 0 });
229
- expect(existsSync(join(tmpDir, "docs.md"))).toBe(true);
230
- expect(existsSync(join(tmpDir, "docs", "getting-started.md"))).toBe(true);
231
- expect(existsSync(join(tmpDir, "docs", "api.md"))).toBe(true);
232
- expect(existsSync(join(tmpDir, "docs", "api", "auth.md"))).toBe(true);
233
- expect(existsSync(join(tmpDir, "docs", "api", "middleware.md"))).toBe(true);
234
- });
235
- it("produces valid markdown content", async () => {
236
- await crawlSite("https://example.com/docs", tmpDir, { delayMs: 0 });
237
- const content = readFileSync(join(tmpDir, "docs", "getting-started.md"), "utf-8");
238
- expect(content).toContain("# Getting Started");
239
- expect(content).toContain("npm install acme");
240
- });
241
- it("respects maxPages limit", async () => {
242
- const result = await crawlSite("https://example.com/docs", tmpDir, {
243
- maxPages: 2,
244
- delayMs: 0,
245
- });
246
- expect(result.filesWritten).toBe(2);
247
- });
248
- it("respects depth limit", async () => {
249
- const result = await crawlSite("https://example.com/docs", tmpDir, {
250
- depth: 1,
251
- delayMs: 0,
252
- });
253
- // depth 0 = the seed page, depth 1 = direct children
254
- // Seed (depth 0): /docs → discovers /docs/getting-started, /docs/api, /docs/api/auth
255
- // Depth 1: /docs/getting-started, /docs/api, /docs/api/auth
256
- // These pages discover /docs/api/middleware at depth 2, which should NOT be fetched
257
- expect(result.pages).toContain("https://example.com/docs");
258
- expect(result.pages).toContain("https://example.com/docs/getting-started");
259
- expect(result.pages).toContain("https://example.com/docs/api");
260
- expect(result.pages).not.toContain("https://example.com/docs/api/middleware");
261
- });
262
- it("does not visit the same URL twice", async () => {
263
- await crawlSite("https://example.com/docs", tmpDir, { delayMs: 0 });
264
- const fetchMock = vi.mocked(fetch);
265
- const urls = fetchMock.mock.calls.map((call) => call[0]);
266
- const unique = new Set(urls);
267
- expect(urls.length).toBe(unique.size);
268
- });
269
- it("skips 404 pages without failing", async () => {
270
- // Override to make one page 404
271
- vi.mocked(fetch).mockImplementation(async (input) => {
272
- const url = typeof input === "string" ? input : input.toString();
273
- const normalized = url.replace(/\/$/, "");
274
- if (normalized === "https://example.com/docs/api") {
275
- return { ok: false, status: 404, headers: new Headers() };
276
- }
277
- const entry = SITE_MAP[normalized] ?? SITE_MAP[url];
278
- if (!entry) {
279
- return { ok: false, status: 404, headers: new Headers() };
280
- }
281
- const body = loadFixture(entry.file);
282
- return {
283
- ok: true,
284
- status: 200,
285
- headers: new Headers({ "content-type": entry.contentType }),
286
- text: async () => body,
287
- };
288
- });
289
- const result = await crawlSite("https://example.com/docs", tmpDir, { delayMs: 0 });
290
- // Should still crawl successfully, just minus the 404 page
291
- expect(result.filesWritten).toBeGreaterThan(0);
292
- expect(result.pages).not.toContain("https://example.com/docs/api");
293
- });
294
- it("skips non-HTML responses", async () => {
295
- vi.mocked(fetch).mockImplementation(async (input) => {
296
- const url = typeof input === "string" ? input : input.toString();
297
- const normalized = url.replace(/\/$/, "");
298
- if (normalized === "https://example.com/docs/getting-started") {
299
- return {
300
- ok: true,
301
- status: 200,
302
- headers: new Headers({ "content-type": "application/json" }),
303
- text: async () => "{}",
304
- };
305
- }
306
- const entry = SITE_MAP[normalized] ?? SITE_MAP[url];
307
- if (!entry) {
308
- return { ok: false, status: 404, headers: new Headers() };
309
- }
310
- const body = loadFixture(entry.file);
311
- return {
312
- ok: true,
313
- status: 200,
314
- headers: new Headers({ "content-type": entry.contentType }),
315
- text: async () => body,
316
- };
317
- });
318
- const result = await crawlSite("https://example.com/docs", tmpDir, { delayMs: 0 });
319
- expect(result.pages).not.toContain("https://example.com/docs/getting-started");
320
- expect(existsSync(join(tmpDir, "docs", "getting-started.md"))).toBe(false);
321
- });
322
- it("applies throttle delay between requests", async () => {
323
- const start = Date.now();
324
- await crawlSite("https://example.com/docs", tmpDir, {
325
- maxPages: 3,
326
- delayMs: 50,
327
- });
328
- const elapsed = Date.now() - start;
329
- // 3 pages, 2 delays of 50ms each = ~100ms minimum
330
- expect(elapsed).toBeGreaterThanOrEqual(80);
331
- });
332
- it("defaults work when options are omitted", async () => {
333
- // This tests the fix for undefined overriding defaults
334
- const result = await crawlSite("https://example.com/docs", tmpDir, {
335
- maxPages: undefined,
336
- depth: undefined,
337
- delayMs: 0,
338
- });
339
- // Should use default maxPages (200) and depth (3), not crash
340
- expect(result.filesWritten).toBe(5);
341
- });
342
- });
343
- //# sourceMappingURL=crawl.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crawl.test.js","sourceRoot":"","sources":["../../tests/crawl.test.ts"],"names":[],"mappings":"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"}