shelving
Version:
Toolkit for using data in JavaScript.
40 lines (39 loc) • 2.21 kB
JavaScript
import { RequiredError } from "../error/RequiredError.js";
import { splitFileExtension } from "../util/file.js";
import { isAbsolutePath, splitPath } from "../util/index.js";
import { Extractor } from "./Extractor.js";
/**
* Base extractor for a file in a tree.
* - Reads the file's content as text and stores it in `content`.
* - Sets `source` to the file's absolute path (`BunFile.name`); throws `RequiredError` if missing or non-absolute.
* - Sets `name` to the basename without extension, preserving case (e.g. `"OptionalSchema"` from `"OptionalSchema.ts"`); URL paths use `name`.
* - Sets `key` to the verbatim filename including extension (e.g. `"OptionalSchema.ts"`). Keys are unique within a directory
* and used by `MergingExtractor` to pair siblings (`{base}.md` + `{base}.ts`) and by `PackageExtractor` to look up sources.
* - Does NOT set `title` — `title` is only set by subclasses that have a confident source for one (e.g. `MarkupExtractor` uses the first `<h1>`). Renderers fall back to `name` when missing.
* - Subclasses (e.g. `MarkupExtractor`, `TypescriptExtractor`) override `extractProps()` to parse the content into richer elements.
*/
export class FileExtractor extends Extractor {
async extract(file) {
const source = file.name;
if (!source || !isAbsolutePath(source))
throw new RequiredError("FileExtractor requires an absolute file path", { received: source });
const filename = splitPath(source).at(-1) ?? "unnamed";
const [base = filename] = splitFileExtension(filename);
const text = await file.text();
const props = { ...this.extractProps(base, text), source };
return {
type: "tree-file",
key: filename,
props,
};
}
/**
* Build the file element props from the extracted content.
* - `name` is the basename without extension (e.g. `"array"`) — display-ready, used by menus, cards, and URL paths.
* - Override to parse `text` into richer elements (content/children/description) and to set
* `title` if a confident title is available.
*/
extractProps(name, content) {
return { name, content };
}
}