refactor(cli): Share the content-index walk
Extract readContentIndex from buildRegistry so the validator can read raw files while the server keeps the scanned registry, both from one walk.
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
|||||||
deriveCompletions,
|
deriveCompletions,
|
||||||
type ContentRegistry,
|
type ContentRegistry,
|
||||||
} from "../content-registry.js";
|
} from "../content-registry.js";
|
||||||
|
import { readContentIndex } from "../content-index.js";
|
||||||
import type { CompletionsPayload } from "../completions/types.js";
|
import type { CompletionsPayload } from "../completions/types.js";
|
||||||
|
|
||||||
interface ContentIndex {
|
interface ContentIndex {
|
||||||
@@ -86,39 +87,7 @@ function getBestIP(): string {
|
|||||||
* 扫描目录内的 .md 等文件,构建内容注册表(路径索引 + 每文档内联内容)
|
* 扫描目录内的 .md 等文件,构建内容注册表(路径索引 + 每文档内联内容)
|
||||||
*/
|
*/
|
||||||
export function buildRegistry(dir: string): ContentRegistry {
|
export function buildRegistry(dir: string): ContentRegistry {
|
||||||
const index: Record<string, string> = {};
|
return buildRegistryFromIndex(readContentIndex(dir));
|
||||||
|
|
||||||
function scan(currentPath: string, relativePath: string) {
|
|
||||||
const entries = readdirSync(currentPath);
|
|
||||||
|
|
||||||
for (const entry of entries) {
|
|
||||||
if (entry.startsWith(".") || entry === "node_modules") continue;
|
|
||||||
|
|
||||||
const fullPath = join(currentPath, entry);
|
|
||||||
const relPath = relativePath ? join(relativePath, entry) : entry;
|
|
||||||
const normalizedRelPath = normalizePathKey(relPath);
|
|
||||||
|
|
||||||
const stats = statSync(fullPath);
|
|
||||||
if (stats.isDirectory()) {
|
|
||||||
scan(fullPath, relPath);
|
|
||||||
} else if (
|
|
||||||
entry.endsWith(".md") ||
|
|
||||||
entry.endsWith(".csv") ||
|
|
||||||
entry.endsWith(".yarn") ||
|
|
||||||
entry.endsWith(".svg")
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
index[normalizedRelPath] = readFileSync(fullPath, "utf-8");
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`读取文件失败:${fullPath}`, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scan(dir, "");
|
|
||||||
|
|
||||||
return buildRegistryFromIndex(index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* Filesystem walk that builds a raw `{ path: content }` index.
|
||||||
|
*
|
||||||
|
* Extracted from `buildRegistry` in `commands/serve.ts` so the validator can
|
||||||
|
* obtain the *raw* file contents (needed for accurate line numbers) while the
|
||||||
|
* server gets the scanned registry — both from the same walk.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { readdirSync, statSync, readFileSync } from "fs";
|
||||||
|
import { join } from "path";
|
||||||
|
import { normalizePathKey } from "./content-registry.js";
|
||||||
|
|
||||||
|
export interface ContentIndex {
|
||||||
|
[path: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Recursively read indexable files (`.md`, `.csv`, `.yarn`, `.svg`). */
|
||||||
|
export function readContentIndex(dir: string): ContentIndex {
|
||||||
|
const index: ContentIndex = {};
|
||||||
|
|
||||||
|
function scan(currentPath: string, relativePath: string) {
|
||||||
|
const entries = readdirSync(currentPath);
|
||||||
|
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry.startsWith(".") || entry === "node_modules") continue;
|
||||||
|
|
||||||
|
const fullPath = join(currentPath, entry);
|
||||||
|
const relPath = relativePath ? join(relativePath, entry) : entry;
|
||||||
|
const normalizedRelPath = normalizePathKey(relPath);
|
||||||
|
|
||||||
|
const stats = statSync(fullPath);
|
||||||
|
if (stats.isDirectory()) {
|
||||||
|
scan(fullPath, relPath);
|
||||||
|
} else if (
|
||||||
|
entry.endsWith(".md") ||
|
||||||
|
entry.endsWith(".csv") ||
|
||||||
|
entry.endsWith(".yarn") ||
|
||||||
|
entry.endsWith(".svg")
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
index[normalizedRelPath] = readFileSync(fullPath, "utf-8");
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`读取文件失败:${fullPath}`, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scan(dir, "");
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user