shelving 1.227.0 → 1.229.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.
- package/extract/DirectoryExtractor.d.ts +8 -11
- package/extract/DirectoryExtractor.js +19 -67
- package/extract/Extractor.d.ts +6 -12
- package/extract/Extractor.js +2 -8
- package/extract/FileExtractor.d.ts +2 -1
- package/extract/FileExtractor.js +3 -3
- package/extract/IndexFileExtractor.d.ts +24 -0
- package/extract/IndexFileExtractor.js +48 -0
- package/extract/MarkupExtractor.d.ts +0 -2
- package/extract/MarkupExtractor.js +0 -2
- package/extract/MergingExtractor.d.ts +27 -0
- package/extract/MergingExtractor.js +65 -0
- package/extract/ModuleExtractor.d.ts +23 -0
- package/extract/ModuleExtractor.js +41 -0
- package/extract/PackageExtractor.d.ts +43 -0
- package/extract/PackageExtractor.js +132 -0
- package/extract/ThroughExtractor.d.ts +13 -0
- package/extract/ThroughExtractor.js +17 -0
- package/extract/index.d.ts +5 -0
- package/extract/index.js +5 -0
- package/firestore/server/FirestoreServerProvider.d.ts +1 -0
- package/package.json +4 -5
- package/ui/README.md +223 -0
- package/ui/app/App.d.ts +4 -4
- package/ui/app/App.js +4 -14
- package/ui/app/App.tsx +5 -14
- package/ui/block/Address.d.ts +6 -2
- package/ui/block/Address.js +7 -2
- package/ui/block/Address.module.css +23 -15
- package/ui/block/Address.tsx +20 -3
- package/ui/block/Block.d.ts +8 -9
- package/ui/block/Block.js +9 -4
- package/ui/block/Block.module.css +60 -76
- package/ui/block/Block.tsx +29 -12
- package/ui/block/Blockquote.d.ts +7 -2
- package/ui/block/Blockquote.js +8 -2
- package/ui/block/Blockquote.module.css +23 -16
- package/ui/block/Blockquote.tsx +28 -3
- package/ui/block/Card.d.ts +10 -9
- package/ui/block/Card.js +9 -6
- package/ui/block/Card.module.css +64 -69
- package/ui/block/Card.tsx +25 -14
- package/ui/block/Definitions.d.ts +7 -1
- package/ui/block/Definitions.js +8 -2
- package/ui/block/Definitions.module.css +50 -47
- package/ui/block/Definitions.tsx +30 -3
- package/ui/block/Divider.d.ts +4 -5
- package/ui/block/Divider.js +5 -2
- package/ui/block/Divider.module.css +20 -15
- package/ui/block/Divider.tsx +6 -7
- package/ui/block/Heading.d.ts +5 -1
- package/ui/block/Heading.js +6 -2
- package/ui/block/Heading.module.css +27 -19
- package/ui/block/Heading.tsx +19 -3
- package/ui/block/Image.d.ts +4 -2
- package/ui/block/Image.js +5 -2
- package/ui/block/Image.module.css +21 -15
- package/ui/block/Image.tsx +8 -3
- package/ui/block/List.d.ts +6 -2
- package/ui/block/List.js +8 -2
- package/ui/block/List.module.css +35 -22
- package/ui/block/List.tsx +15 -3
- package/ui/block/Panel.d.ts +26 -0
- package/ui/block/Panel.js +22 -0
- package/ui/block/Panel.module.css +32 -0
- package/ui/block/Panel.tsx +47 -0
- package/ui/block/Paragraph.d.ts +7 -11
- package/ui/block/Paragraph.js +8 -3
- package/ui/block/Paragraph.module.css +22 -30
- package/ui/block/Paragraph.tsx +22 -14
- package/ui/block/Preformatted.js +2 -2
- package/ui/block/Preformatted.module.css +44 -27
- package/ui/block/Preformatted.tsx +2 -2
- package/ui/block/Prose.module.css +17 -11
- package/ui/block/Subheading.js +6 -2
- package/ui/block/Subheading.module.css +25 -19
- package/ui/block/Subheading.tsx +18 -2
- package/ui/block/Table.d.ts +8 -2
- package/ui/block/Table.js +9 -2
- package/ui/block/Table.module.css +56 -53
- package/ui/block/Table.tsx +23 -3
- package/ui/block/Title.js +6 -2
- package/ui/block/Title.module.css +25 -19
- package/ui/block/Title.tsx +18 -2
- package/ui/block/Video.d.ts +3 -5
- package/ui/block/Video.js +4 -2
- package/ui/block/Video.module.css +86 -84
- package/ui/block/Video.tsx +5 -9
- package/ui/block/index.d.ts +1 -1
- package/ui/block/index.js +1 -1
- package/ui/block/index.ts +1 -1
- package/ui/dialog/Dialog.module.css +30 -23
- package/ui/dialog/Modal.module.css +14 -10
- package/ui/docs/DocumentationCard.js +1 -1
- package/ui/docs/DocumentationCard.tsx +1 -1
- package/ui/docs/DocumentationKind.js +2 -1
- package/ui/docs/DocumentationKind.tsx +3 -2
- package/ui/docs/DocumentationPage.js +1 -1
- package/ui/docs/DocumentationPage.tsx +1 -1
- package/ui/form/ArrayInput.js +1 -1
- package/ui/form/ArrayInput.tsx +1 -1
- package/ui/form/ArrayRadioInputs.js +1 -1
- package/ui/form/ArrayRadioInputs.tsx +1 -1
- package/ui/form/Button.d.ts +7 -5
- package/ui/form/Button.js +5 -6
- package/ui/form/Button.module.css +86 -71
- package/ui/form/Button.tsx +12 -10
- package/ui/form/ButtonInput.d.ts +2 -1
- package/ui/form/ButtonInput.js +4 -2
- package/ui/form/ButtonInput.tsx +5 -3
- package/ui/form/CheckboxInput.d.ts +3 -2
- package/ui/form/CheckboxInput.js +5 -3
- package/ui/form/CheckboxInput.tsx +6 -3
- package/ui/form/ChoiceRadioInputs.js +1 -1
- package/ui/form/ChoiceRadioInputs.tsx +1 -1
- package/ui/form/DataInput.js +1 -1
- package/ui/form/DataInput.tsx +1 -1
- package/ui/form/DictionaryInput.js +1 -1
- package/ui/form/DictionaryInput.tsx +1 -1
- package/ui/form/Field.module.css +44 -37
- package/ui/form/Form.module.css +27 -6
- package/ui/form/FormFooter.js +1 -1
- package/ui/form/FormFooter.tsx +1 -1
- package/ui/form/Input.d.ts +6 -9
- package/ui/form/Input.js +10 -12
- package/ui/form/Input.module.css +190 -170
- package/ui/form/Input.tsx +11 -12
- package/ui/form/OutputInput.d.ts +3 -2
- package/ui/form/OutputInput.js +4 -2
- package/ui/form/OutputInput.tsx +6 -4
- package/ui/form/Popover.module.css +28 -21
- package/ui/form/Progress.d.ts +9 -0
- package/ui/form/Progress.js +9 -1
- package/ui/form/Progress.module.css +49 -25
- package/ui/form/Progress.tsx +31 -2
- package/ui/form/RadioInput.d.ts +3 -2
- package/ui/form/RadioInput.js +5 -3
- package/ui/form/RadioInput.tsx +6 -3
- package/ui/form/SelectInput.js +2 -2
- package/ui/form/SelectInput.tsx +3 -3
- package/ui/form/index.d.ts +0 -1
- package/ui/form/index.js +0 -1
- package/ui/form/index.ts +0 -1
- package/ui/index.d.ts +1 -0
- package/ui/index.js +1 -0
- package/ui/index.ts +1 -0
- package/ui/inline/Code.js +6 -4
- package/ui/inline/Code.module.css +29 -14
- package/ui/inline/Code.tsx +7 -4
- package/ui/inline/Deleted.module.css +11 -7
- package/ui/inline/Emphasis.module.css +8 -4
- package/ui/inline/Inserted.module.css +11 -7
- package/ui/inline/Link.module.css +17 -13
- package/ui/inline/Mark.module.css +11 -14
- package/ui/inline/Small.module.css +7 -7
- package/ui/inline/Strong.module.css +8 -4
- package/ui/inline/Subscript.module.css +12 -8
- package/ui/inline/Superscript.module.css +12 -8
- package/ui/layout/CenteredLayout.js +2 -2
- package/ui/layout/CenteredLayout.module.css +15 -11
- package/ui/layout/CenteredLayout.tsx +2 -2
- package/ui/layout/Layout.d.ts +2 -2
- package/ui/layout/Layout.js +4 -2
- package/ui/layout/Layout.module.css +48 -46
- package/ui/layout/Layout.ts +4 -2
- package/ui/layout/README.md +1 -1
- package/ui/layout/SidebarLayout.d.ts +0 -2
- package/ui/layout/SidebarLayout.js +3 -4
- package/ui/layout/SidebarLayout.module.css +89 -79
- package/ui/layout/SidebarLayout.tsx +3 -5
- package/ui/menu/Menu.module.css +59 -55
- package/ui/misc/Catcher.js +1 -1
- package/ui/misc/Catcher.tsx +1 -1
- package/ui/misc/Loading.module.css +20 -16
- package/ui/misc/StatusIcon.d.ts +1 -1
- package/ui/misc/StatusIcon.js +1 -1
- package/ui/misc/StatusIcon.module.css +29 -25
- package/ui/misc/StatusIcon.tsx +2 -2
- package/ui/misc/Tag.d.ts +2 -2
- package/ui/misc/Tag.js +2 -2
- package/ui/misc/Tag.module.css +48 -31
- package/ui/misc/Tag.tsx +2 -2
- package/ui/misc/index.d.ts +0 -3
- package/ui/misc/index.js +0 -3
- package/ui/misc/index.tsx +0 -3
- package/ui/notice/Message.d.ts +3 -3
- package/ui/notice/Message.js +5 -5
- package/ui/notice/Message.module.css +10 -6
- package/ui/notice/Message.tsx +6 -6
- package/ui/notice/Notice.d.ts +4 -6
- package/ui/notice/Notice.js +4 -6
- package/ui/notice/Notice.module.css +39 -14
- package/ui/notice/Notice.tsx +6 -8
- package/ui/notice/Notices.d.ts +4 -1
- package/ui/notice/Notices.js +3 -3
- package/ui/notice/Notices.module.css +13 -9
- package/ui/notice/Notices.tsx +6 -4
- package/ui/notice/NoticesStore.d.ts +1 -1
- package/ui/notice/NoticesStore.ts +1 -1
- package/ui/style/Align.d.ts +13 -0
- package/ui/style/Align.js +6 -0
- package/ui/style/Align.module.css +17 -0
- package/ui/style/Align.tsx +20 -0
- package/ui/{misc → style}/Color.d.ts +4 -6
- package/ui/{misc → style}/Color.js +0 -1
- package/ui/style/Color.module.css +70 -0
- package/ui/{misc → style}/Color.tsx +4 -6
- package/ui/{block → style}/Flex.d.ts +10 -7
- package/ui/style/Flex.js +16 -0
- package/ui/style/Flex.module.css +76 -0
- package/ui/{block → style}/Flex.tsx +14 -18
- package/ui/style/Gap.d.ts +13 -0
- package/ui/style/Gap.js +5 -0
- package/ui/style/Gap.module.css +30 -0
- package/ui/style/Gap.tsx +20 -0
- package/ui/style/Padding.d.ts +17 -0
- package/ui/style/Padding.js +5 -0
- package/ui/style/Padding.module.css +31 -0
- package/ui/style/Padding.tsx +24 -0
- package/ui/style/Spacing.d.ts +15 -0
- package/ui/style/Spacing.js +6 -0
- package/ui/style/Spacing.module.css +29 -0
- package/ui/style/Spacing.tsx +22 -0
- package/ui/style/Status.module.css +36 -0
- package/ui/style/Thickness.d.ts +19 -0
- package/ui/style/Thickness.js +5 -0
- package/ui/style/Thickness.module.css +35 -0
- package/ui/style/Thickness.tsx +26 -0
- package/ui/style/Typography.d.ts +41 -0
- package/ui/style/Typography.module.css +70 -0
- package/ui/style/Typography.tsx +50 -0
- package/ui/style/Width.d.ts +11 -0
- package/ui/style/Width.js +5 -0
- package/ui/style/Width.module.css +19 -0
- package/ui/style/Width.tsx +18 -0
- package/ui/style/base.css +221 -0
- package/ui/style/index.d.ts +10 -0
- package/ui/style/index.js +10 -0
- package/ui/style/index.tsx +10 -0
- package/ui/tree/TreeMenu.d.ts +7 -6
- package/ui/tree/TreeMenu.js +17 -5
- package/ui/tree/TreeMenu.tsx +15 -6
- package/ui/tree/TreeSidebar.js +3 -3
- package/ui/tree/TreeSidebar.tsx +3 -3
- package/ui/util/notice.d.ts +1 -1
- package/ui/util/notice.ts +1 -1
- package/util/element.d.ts +3 -1
- package/util/element.js +20 -11
- package/ui/app/App.module.css +0 -147
- package/ui/block/Flex.js +0 -10
- package/ui/block/Flex.module.css +0 -71
- package/ui/form/SegmentedProgress.d.ts +0 -10
- package/ui/form/SegmentedProgress.js +0 -16
- package/ui/form/SegmentedProgress.module.css +0 -31
- package/ui/form/SegmentedProgress.tsx +0 -34
- package/ui/misc/Color.module.css +0 -199
- package/ui/misc/Status.module.css +0 -79
- package/ui/misc/Typography.d.ts +0 -33
- package/ui/misc/Typography.module.css +0 -54
- package/ui/misc/Typography.tsx +0 -41
- /package/ui/{misc → style}/Status.d.ts +0 -0
- /package/ui/{misc → style}/Status.js +0 -0
- /package/ui/{misc → style}/Status.tsx +0 -0
- /package/ui/{misc → style}/Typography.js +0 -0
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import type { ImmutableDictionary } from "../util/dictionary.js";
|
|
2
|
-
import {
|
|
2
|
+
import type { DirectoryElement } from "../util/element.js";
|
|
3
3
|
import { type AbsolutePath, type Matchables, type Path } from "../util/index.js";
|
|
4
4
|
import { Extractor } from "./Extractor.js";
|
|
5
5
|
import { FileExtractor } from "./FileExtractor.js";
|
|
6
6
|
/** Options for a directory extractor. */
|
|
7
7
|
export interface DirectoryExtractorOptions {
|
|
8
|
-
/** Filenames to treat as the directory's index file. Matched case-insensitively. */
|
|
9
|
-
readonly index?: Matchables;
|
|
10
8
|
/**
|
|
11
|
-
* Extractor dispatch table keyed by file extension (
|
|
9
|
+
* Extractor dispatch table keyed by file extension (without the leading dot, e.g. `"md"`).
|
|
12
10
|
* - Files with no matching extractor are silently skipped.
|
|
13
|
-
* - Defaults to `.md` (markdown), `.ts` (TypeScript), and `.txt` (plain text).
|
|
11
|
+
* - Defaults to `.md` (markdown), `.ts` / `.tsx` (TypeScript), and `.txt` (plain text).
|
|
14
12
|
*/
|
|
15
13
|
readonly extractors?: ImmutableDictionary<FileExtractor>;
|
|
16
14
|
/** Absolute base path used to resolve relative paths passed to `extract()`. */
|
|
@@ -25,17 +23,16 @@ export interface DirectoryExtractorOptions {
|
|
|
25
23
|
/**
|
|
26
24
|
* Extractor that walks a directory on disk and produces a `DirectoryElement` tree.
|
|
27
25
|
* - Recursively descends into subdirectories.
|
|
28
|
-
* -
|
|
29
|
-
* -
|
|
30
|
-
* -
|
|
31
|
-
*
|
|
26
|
+
* - Dispatches non-ignored files to a matching `FileExtractor` based on extension; files with no matching extractor are silently skipped.
|
|
27
|
+
* - Keys on the produced elements are the verbatim filenames (e.g. `"string.ts"`, `"README.md"`) and directory names (e.g. `"util"`).
|
|
28
|
+
* - This is a pure walker: same-key merging and README absorption are intentionally *not* applied here — wrap with `MergingExtractor`
|
|
29
|
+
* and/or `IndexFileExtractor` to opt in to those behaviours.
|
|
32
30
|
*/
|
|
33
31
|
export declare class DirectoryExtractor extends Extractor<Path, DirectoryElement> {
|
|
34
|
-
private readonly _indexes;
|
|
35
32
|
private readonly _extractors;
|
|
36
33
|
private readonly _base;
|
|
37
34
|
private readonly _ignore;
|
|
38
|
-
constructor({
|
|
35
|
+
constructor({ extractors, base, ignore }?: DirectoryExtractorOptions);
|
|
39
36
|
extract(source: Path): Promise<DirectoryElement>;
|
|
40
37
|
private _extractDirectory;
|
|
41
38
|
private _extractChild;
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import { readdir } from "node:fs/promises";
|
|
2
|
-
import { mergeElements } from "../util/element.js";
|
|
3
2
|
import { splitFileExtension } from "../util/file.js";
|
|
4
3
|
import { anyMatch, requirePath, splitPath } from "../util/index.js";
|
|
5
|
-
import {
|
|
6
|
-
import { Extractor, mergeTreeElements } from "./Extractor.js";
|
|
4
|
+
import { Extractor } from "./Extractor.js";
|
|
7
5
|
import { FileExtractor } from "./FileExtractor.js";
|
|
8
6
|
import { MarkupExtractor } from "./MarkupExtractor.js";
|
|
9
7
|
import { TypescriptExtractor } from "./TypescriptExtractor.js";
|
|
10
|
-
/**
|
|
11
|
-
* Default list of filenames patterns treated as the directory's index file.
|
|
12
|
-
* - Matched case-insensitively (all entries stored lowercase).
|
|
13
|
-
* - If matched but no extractor is registered for the file's extension, the index is silently skipped.
|
|
14
|
-
*/
|
|
15
|
-
const DEFAULT_INDEX = [/^readme\.txt$/i, /^readme\.md$/i, /^index\.md$/i, /^index\.ts$/i, /^index\.tsx$/i];
|
|
16
8
|
/** Default file extractor dispatch by extension. */
|
|
17
9
|
const DEFAULT_EXTRACTORS = {
|
|
18
10
|
md: new MarkupExtractor(),
|
|
@@ -27,35 +19,20 @@ const DEFAULT_EXTRACTORS = {
|
|
|
27
19
|
* - Skip hidden `.` prefixed and underscore-prefixed files and directories.
|
|
28
20
|
*/
|
|
29
21
|
const DEFAULT_IGNORE = [/\.test\.tsx?$/i, /\.spec\.tsx?$/i, /^node_modules$/i, /^[_.]/i];
|
|
30
|
-
/**
|
|
31
|
-
* Merge two tree elements, favouring the one with the highest priority.
|
|
32
|
-
* - We merge together elements with the same `key:` (e.g. `TEMPLATE.md` and `template.ts`).
|
|
33
|
-
* - `title` and `description` are taken from the higher-priority element.
|
|
34
|
-
* - `content` and `children` of both elements are merged (with the higher-priority element's content/children first).
|
|
35
|
-
*/
|
|
36
|
-
function _mergeChild(existing, next) {
|
|
37
|
-
if (!existing)
|
|
38
|
-
return next;
|
|
39
|
-
return next.priority > existing.priority
|
|
40
|
-
? { element: mergeTreeElements(next.element, existing.element), priority: next.priority }
|
|
41
|
-
: { element: mergeTreeElements(existing.element, next.element), priority: existing.priority };
|
|
42
|
-
}
|
|
43
22
|
/**
|
|
44
23
|
* Extractor that walks a directory on disk and produces a `DirectoryElement` tree.
|
|
45
24
|
* - Recursively descends into subdirectories.
|
|
46
|
-
* -
|
|
47
|
-
* -
|
|
48
|
-
* -
|
|
49
|
-
*
|
|
25
|
+
* - Dispatches non-ignored files to a matching `FileExtractor` based on extension; files with no matching extractor are silently skipped.
|
|
26
|
+
* - Keys on the produced elements are the verbatim filenames (e.g. `"string.ts"`, `"README.md"`) and directory names (e.g. `"util"`).
|
|
27
|
+
* - This is a pure walker: same-key merging and README absorption are intentionally *not* applied here — wrap with `MergingExtractor`
|
|
28
|
+
* and/or `IndexFileExtractor` to opt in to those behaviours.
|
|
50
29
|
*/
|
|
51
30
|
export class DirectoryExtractor extends Extractor {
|
|
52
|
-
_indexes;
|
|
53
31
|
_extractors;
|
|
54
32
|
_base;
|
|
55
33
|
_ignore;
|
|
56
|
-
constructor({
|
|
34
|
+
constructor({ extractors = DEFAULT_EXTRACTORS, base, ignore = DEFAULT_IGNORE } = {}) {
|
|
57
35
|
super();
|
|
58
|
-
this._indexes = index;
|
|
59
36
|
this._extractors = extractors;
|
|
60
37
|
this._base = base;
|
|
61
38
|
this._ignore = ignore;
|
|
@@ -66,62 +43,37 @@ export class DirectoryExtractor extends Extractor {
|
|
|
66
43
|
async _extractDirectory(source) {
|
|
67
44
|
const name = splitPath(source).at(-1) ?? "";
|
|
68
45
|
const entries = await readdir(source, { withFileTypes: true });
|
|
69
|
-
|
|
70
|
-
let index;
|
|
71
|
-
const items = {};
|
|
46
|
+
const children = [];
|
|
72
47
|
for (const entry of entries) {
|
|
73
|
-
// Should we ignore this entry?
|
|
74
48
|
if (anyMatch(entry.name, ...this._ignore))
|
|
75
49
|
continue;
|
|
76
|
-
// Extract the child element and possibly merge it.
|
|
77
50
|
const child = await this._extractChild(source, entry);
|
|
78
|
-
if (child)
|
|
79
|
-
|
|
80
|
-
if (anyMatch(entry.name, ...this._indexes)) {
|
|
81
|
-
index = _mergeChild(index, child);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
const key = child.element.key;
|
|
85
|
-
items[key] = _mergeChild(items[key], child);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
51
|
+
if (child)
|
|
52
|
+
children.push(child);
|
|
88
53
|
}
|
|
89
|
-
const children = Object.values(items).map(({ element }) => element);
|
|
90
54
|
return {
|
|
91
55
|
type: "tree-directory",
|
|
92
|
-
key:
|
|
56
|
+
key: name,
|
|
93
57
|
props: {
|
|
94
58
|
source,
|
|
95
59
|
name,
|
|
96
|
-
|
|
97
|
-
// Renderers fall back to `name` otherwise.
|
|
98
|
-
title: index?.element.props.title,
|
|
99
|
-
description: index?.element.props.description,
|
|
100
|
-
content: index?.element.props.content,
|
|
101
|
-
children: mergeElements(index?.element.props.children, children),
|
|
60
|
+
children,
|
|
102
61
|
},
|
|
103
62
|
};
|
|
104
63
|
}
|
|
105
64
|
async _extractChild(base, entry) {
|
|
106
65
|
const name = entry.name;
|
|
107
66
|
const path = requirePath(name, base);
|
|
108
|
-
if (entry.isDirectory())
|
|
109
|
-
return
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
else if (entry.isFile()) {
|
|
115
|
-
const [base, extension] = splitFileExtension(name);
|
|
116
|
-
if (!base || !extension)
|
|
117
|
-
return; // Skip files with no base name or extension.
|
|
67
|
+
if (entry.isDirectory())
|
|
68
|
+
return this._extractDirectory(path);
|
|
69
|
+
if (entry.isFile()) {
|
|
70
|
+
const [stem, extension] = splitFileExtension(name);
|
|
71
|
+
if (!stem || !extension)
|
|
72
|
+
return;
|
|
118
73
|
const extractor = this._extractors[extension];
|
|
119
74
|
if (!extractor)
|
|
120
|
-
return;
|
|
121
|
-
return
|
|
122
|
-
element: await extractor.extract(Bun.file(path)),
|
|
123
|
-
priority: extractor.priority,
|
|
124
|
-
};
|
|
75
|
+
return;
|
|
76
|
+
return extractor.extract(Bun.file(path));
|
|
125
77
|
}
|
|
126
78
|
}
|
|
127
79
|
}
|
package/extract/Extractor.d.ts
CHANGED
|
@@ -2,23 +2,17 @@ import { type TreeElement } from "../util/element.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Base class for an extractor that converts input into a tree element.
|
|
4
4
|
* - Extractors are composable: outer extractors delegate to inner extractors.
|
|
5
|
-
* - The output type is always a `TreeElement` (or a more specific subtype
|
|
5
|
+
* - The output type is always a `TreeElement` (or a more specific subtype).
|
|
6
6
|
*/
|
|
7
7
|
export declare abstract class Extractor<I, O extends TreeElement = TreeElement> {
|
|
8
8
|
/** Extract a tree element from the given input. */
|
|
9
|
-
abstract extract(input: I):
|
|
10
|
-
/**
|
|
11
|
-
* Priority used to resolve same-key collisions when merging elements.
|
|
12
|
-
* - Higher-priority elements contribute their `title`, `description`, `path` to the merged result.
|
|
13
|
-
* - Higher-priority elements a prefixed (rather than suffixed) in `children` and `content` when merged.
|
|
14
|
-
* - Defaults to `0`; subclasses override (e.g. `MarkupExtractor` is `10`).
|
|
15
|
-
*/
|
|
16
|
-
readonly priority: number;
|
|
9
|
+
abstract extract(input: I): O | Promise<O>;
|
|
17
10
|
}
|
|
18
11
|
/**
|
|
19
|
-
* Merge two
|
|
20
|
-
*
|
|
21
|
-
* - `description`
|
|
12
|
+
* Merge two tree elements — `primary` keeps its identity (`type`, `key`, `source`); `secondary` contributes any
|
|
13
|
+
* metadata `primary` does not already have.
|
|
14
|
+
* - `title` and `description` are taken from `primary` when set, otherwise from `secondary` — primary stays canonical
|
|
15
|
+
* but a missing field falls back rather than disappearing.
|
|
22
16
|
* - `content` and `children` from both are concatenated (primary first).
|
|
23
17
|
*/
|
|
24
18
|
export declare function mergeTreeElements<T extends TreeElement>(primary: T, secondary: TreeElement): T;
|
package/extract/Extractor.js
CHANGED
|
@@ -2,16 +2,9 @@ import { mergeElements } from "../util/element.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Base class for an extractor that converts input into a tree element.
|
|
4
4
|
* - Extractors are composable: outer extractors delegate to inner extractors.
|
|
5
|
-
* - The output type is always a `TreeElement` (or a more specific subtype
|
|
5
|
+
* - The output type is always a `TreeElement` (or a more specific subtype).
|
|
6
6
|
*/
|
|
7
7
|
export class Extractor {
|
|
8
|
-
/**
|
|
9
|
-
* Priority used to resolve same-key collisions when merging elements.
|
|
10
|
-
* - Higher-priority elements contribute their `title`, `description`, `path` to the merged result.
|
|
11
|
-
* - Higher-priority elements a prefixed (rather than suffixed) in `children` and `content` when merged.
|
|
12
|
-
* - Defaults to `0`; subclasses override (e.g. `MarkupExtractor` is `10`).
|
|
13
|
-
*/
|
|
14
|
-
priority = 0;
|
|
15
8
|
}
|
|
16
9
|
export function mergeTreeElements(primary, secondary) {
|
|
17
10
|
return {
|
|
@@ -20,6 +13,7 @@ export function mergeTreeElements(primary, secondary) {
|
|
|
20
13
|
key: primary.key,
|
|
21
14
|
props: {
|
|
22
15
|
...primary.props,
|
|
16
|
+
title: primary.props.title ?? secondary.props.title,
|
|
23
17
|
description: primary.props.description ?? secondary.props.description,
|
|
24
18
|
content: _mergeContent(primary.props.content, secondary.props.content),
|
|
25
19
|
children: mergeElements(primary.props.children, secondary.props.children),
|
|
@@ -6,7 +6,8 @@ import { Extractor } from "./Extractor.js";
|
|
|
6
6
|
* - Reads the file's content as text and stores it in `content`.
|
|
7
7
|
* - Sets `source` to the file's absolute path (`BunFile.name`); throws `RequiredError` if missing or non-absolute.
|
|
8
8
|
* - Sets `name` to the basename without extension, preserving case (e.g. `"OptionalSchema"` from `"OptionalSchema.ts"`); URL paths use `name`.
|
|
9
|
-
* - Sets `key` to the
|
|
9
|
+
* - Sets `key` to the verbatim filename including extension (e.g. `"OptionalSchema.ts"`). Keys are unique within a directory
|
|
10
|
+
* and used by `MergingExtractor` to pair siblings (`{base}.md` + `{base}.ts`) and by `PackageExtractor` to look up sources.
|
|
10
11
|
* - 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.
|
|
11
12
|
* - Subclasses (e.g. `MarkupExtractor`, `TypescriptExtractor`) override `extractProps()` to parse the content into richer elements.
|
|
12
13
|
*/
|
package/extract/FileExtractor.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { RequiredError } from "../error/RequiredError.js";
|
|
2
2
|
import { splitFileExtension } from "../util/file.js";
|
|
3
3
|
import { isAbsolutePath, splitPath } from "../util/index.js";
|
|
4
|
-
import { requireSlug } from "../util/string.js";
|
|
5
4
|
import { Extractor } from "./Extractor.js";
|
|
6
5
|
/**
|
|
7
6
|
* Base extractor for a file in a tree.
|
|
8
7
|
* - Reads the file's content as text and stores it in `content`.
|
|
9
8
|
* - Sets `source` to the file's absolute path (`BunFile.name`); throws `RequiredError` if missing or non-absolute.
|
|
10
9
|
* - Sets `name` to the basename without extension, preserving case (e.g. `"OptionalSchema"` from `"OptionalSchema.ts"`); URL paths use `name`.
|
|
11
|
-
* - Sets `key` to the
|
|
10
|
+
* - Sets `key` to the verbatim filename including extension (e.g. `"OptionalSchema.ts"`). Keys are unique within a directory
|
|
11
|
+
* and used by `MergingExtractor` to pair siblings (`{base}.md` + `{base}.ts`) and by `PackageExtractor` to look up sources.
|
|
12
12
|
* - 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.
|
|
13
13
|
* - Subclasses (e.g. `MarkupExtractor`, `TypescriptExtractor`) override `extractProps()` to parse the content into richer elements.
|
|
14
14
|
*/
|
|
@@ -23,7 +23,7 @@ export class FileExtractor extends Extractor {
|
|
|
23
23
|
const props = { ...this.extractProps(base, text), source };
|
|
24
24
|
return {
|
|
25
25
|
type: "tree-file",
|
|
26
|
-
key:
|
|
26
|
+
key: filename,
|
|
27
27
|
props,
|
|
28
28
|
};
|
|
29
29
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type DirectoryElement } from "../util/element.js";
|
|
2
|
+
import { type Matchables } from "../util/regexp.js";
|
|
3
|
+
import type { Extractor } from "./Extractor.js";
|
|
4
|
+
import { ThroughExtractor } from "./ThroughExtractor.js";
|
|
5
|
+
/** Options for an `IndexFileExtractor`. */
|
|
6
|
+
export interface IndexFileExtractorOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Filename patterns treated as the directory's index file. Matched case-insensitively against each child element's `key`.
|
|
9
|
+
* - Defaults to README and index files: `["readme.txt", "readme.md", "index.md", "index.ts", "index.tsx"]`.
|
|
10
|
+
*/
|
|
11
|
+
readonly index?: Matchables;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Through extractor that walks a `DirectoryElement` tree and absorbs each directory's index file into the directory itself.
|
|
15
|
+
* - For each directory: finds the first child whose `key` matches any `index` pattern.
|
|
16
|
+
* - The matched child's `title`, `description`, `content`, and `children` are folded into the parent directory.
|
|
17
|
+
* - The matched child is removed from the parent's children list.
|
|
18
|
+
* - Recurses into subdirectories before absorbing — the deepest level happens first.
|
|
19
|
+
*/
|
|
20
|
+
export declare class IndexFileExtractor<I> extends ThroughExtractor<I, DirectoryElement> {
|
|
21
|
+
private readonly _index;
|
|
22
|
+
constructor(source: Extractor<I, DirectoryElement>, { index }?: IndexFileExtractorOptions);
|
|
23
|
+
extract(input: I): Promise<DirectoryElement>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { mergeElements, walkElements } from "../util/element.js";
|
|
2
|
+
import { anyMatch } from "../util/regexp.js";
|
|
3
|
+
import { ThroughExtractor } from "./ThroughExtractor.js";
|
|
4
|
+
/**
|
|
5
|
+
* Default index file patterns.
|
|
6
|
+
* - Matched case-insensitively (all entries stored lowercase).
|
|
7
|
+
* - The first child of a directory that matches any pattern is absorbed.
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_INDEX = [/^readme\.txt$/i, /^readme\.md$/i, /^index\.md$/i, /^index\.ts$/i, /^index\.tsx$/i];
|
|
10
|
+
/**
|
|
11
|
+
* Through extractor that walks a `DirectoryElement` tree and absorbs each directory's index file into the directory itself.
|
|
12
|
+
* - For each directory: finds the first child whose `key` matches any `index` pattern.
|
|
13
|
+
* - The matched child's `title`, `description`, `content`, and `children` are folded into the parent directory.
|
|
14
|
+
* - The matched child is removed from the parent's children list.
|
|
15
|
+
* - Recurses into subdirectories before absorbing — the deepest level happens first.
|
|
16
|
+
*/
|
|
17
|
+
export class IndexFileExtractor extends ThroughExtractor {
|
|
18
|
+
_index;
|
|
19
|
+
constructor(source, { index = DEFAULT_INDEX } = {}) {
|
|
20
|
+
super(source);
|
|
21
|
+
this._index = index;
|
|
22
|
+
}
|
|
23
|
+
async extract(input) {
|
|
24
|
+
const root = await this.source.extract(input);
|
|
25
|
+
return _absorbIndex(root, this._index);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Recursively absorb the index file in `dir` and all nested directories. */
|
|
29
|
+
function _absorbIndex(dir, index) {
|
|
30
|
+
// Recurse first so nested directories absorb their own indexes before we look at this level.
|
|
31
|
+
const recursed = Array.from(walkElements(dir.props.children)).map(child => child.type === "tree-directory" ? _absorbIndex(child, index) : child);
|
|
32
|
+
// Find the index child by key.
|
|
33
|
+
const indexChild = recursed.find(child => anyMatch(child.key, ...index));
|
|
34
|
+
if (!indexChild)
|
|
35
|
+
return { ...dir, props: { ...dir.props, children: recursed } };
|
|
36
|
+
// Fold the index child into the directory, and drop it from children.
|
|
37
|
+
const remaining = recursed.filter(child => child !== indexChild);
|
|
38
|
+
return {
|
|
39
|
+
...dir,
|
|
40
|
+
props: {
|
|
41
|
+
...dir.props,
|
|
42
|
+
title: dir.props.title ?? indexChild.props.title,
|
|
43
|
+
description: dir.props.description ?? indexChild.props.description,
|
|
44
|
+
content: dir.props.content ?? indexChild.props.content,
|
|
45
|
+
children: mergeElements(indexChild.props.children, remaining),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -10,8 +10,6 @@ import { FileExtractor } from "./FileExtractor.js";
|
|
|
10
10
|
* - Sets `description` to the first prose paragraph as a plain-text summary (used for card listings and `<meta>`).
|
|
11
11
|
*/
|
|
12
12
|
export declare class MarkupExtractor extends FileExtractor {
|
|
13
|
-
/** Markdown contributes the canonical title/path when merging same-key elements. */
|
|
14
|
-
readonly priority = 10;
|
|
15
13
|
extractProps(name: string, text: string): Partial<FileElementProps> & {
|
|
16
14
|
name: string;
|
|
17
15
|
};
|
|
@@ -11,8 +11,6 @@ import { FileExtractor } from "./FileExtractor.js";
|
|
|
11
11
|
* - Sets `description` to the first prose paragraph as a plain-text summary (used for card listings and `<meta>`).
|
|
12
12
|
*/
|
|
13
13
|
export class MarkupExtractor extends FileExtractor {
|
|
14
|
-
/** Markdown contributes the canonical title/path when merging same-key elements. */
|
|
15
|
-
priority = 10;
|
|
16
14
|
extractProps(name, text) {
|
|
17
15
|
const { title, description } = extractMarkdownProps(text);
|
|
18
16
|
// The title `# h1` is surfaced separately as `title`, so strip it from the body to avoid rendering it twice.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ImmutableDictionary } from "../util/dictionary.js";
|
|
2
|
+
import { type DirectoryElement } from "../util/element.js";
|
|
3
|
+
import type { Extractor } from "./Extractor.js";
|
|
4
|
+
import { ThroughExtractor } from "./ThroughExtractor.js";
|
|
5
|
+
/** Options for a `MergingExtractor`. */
|
|
6
|
+
export interface MergingExtractorOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Templated key pairs that should merge. Each key is a `{base}` template matched against the secondary element's key;
|
|
9
|
+
* each value is an ordered list of `{base}` templates for the primary candidates to merge into.
|
|
10
|
+
* - The first primary candidate that exists in the same directory wins; remaining candidates are ignored.
|
|
11
|
+
* - If no candidate exists the secondary is left in place as its own tree-file element.
|
|
12
|
+
* - Defaults to `{ "{base}.md": ["{base}.ts", "{base}.tsx", "{base}.js", "{base}.jsx"] }`.
|
|
13
|
+
*/
|
|
14
|
+
readonly merges?: ImmutableDictionary<readonly string[]>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Through extractor that walks a `DirectoryElement` tree and merges sibling tree elements whose keys match a `merges` template pair.
|
|
18
|
+
* - Walks every directory recursively, applying the merge at each level.
|
|
19
|
+
* - The primary (winning) element keeps its `key`, `source`, and `type`; the secondary's `title`, `description`,
|
|
20
|
+
* `content`, and `children` are folded in via `mergeTreeElements()`.
|
|
21
|
+
* - A secondary with no matching primary is left in place — pure prose files (e.g. `concepts.md` with no `concepts.ts`) stand alone.
|
|
22
|
+
*/
|
|
23
|
+
export declare class MergingExtractor<I> extends ThroughExtractor<I, DirectoryElement> {
|
|
24
|
+
private readonly _merges;
|
|
25
|
+
constructor(source: Extractor<I, DirectoryElement>, { merges }?: MergingExtractorOptions);
|
|
26
|
+
extract(input: I): Promise<DirectoryElement>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { walkElements } from "../util/element.js";
|
|
2
|
+
import { matchTemplate, renderTemplate } from "../util/template.js";
|
|
3
|
+
import { mergeTreeElements } from "./Extractor.js";
|
|
4
|
+
import { ThroughExtractor } from "./ThroughExtractor.js";
|
|
5
|
+
/**
|
|
6
|
+
* Default merges map: a markdown file is absorbed into its same-base TypeScript counterpart.
|
|
7
|
+
* - Key (secondary) and values (primary candidates) are `{base}`-templated key strings.
|
|
8
|
+
* - Candidates are checked in order — the first one that exists in the tree wins.
|
|
9
|
+
* - A secondary with no matching primary is left in place as its own element.
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_MERGES = {
|
|
12
|
+
"{base}.md": ["{base}.ts", "{base}.tsx", "{base}.js", "{base}.jsx"],
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Through extractor that walks a `DirectoryElement` tree and merges sibling tree elements whose keys match a `merges` template pair.
|
|
16
|
+
* - Walks every directory recursively, applying the merge at each level.
|
|
17
|
+
* - The primary (winning) element keeps its `key`, `source`, and `type`; the secondary's `title`, `description`,
|
|
18
|
+
* `content`, and `children` are folded in via `mergeTreeElements()`.
|
|
19
|
+
* - A secondary with no matching primary is left in place — pure prose files (e.g. `concepts.md` with no `concepts.ts`) stand alone.
|
|
20
|
+
*/
|
|
21
|
+
export class MergingExtractor extends ThroughExtractor {
|
|
22
|
+
_merges;
|
|
23
|
+
constructor(source, { merges = DEFAULT_MERGES } = {}) {
|
|
24
|
+
super(source);
|
|
25
|
+
this._merges = merges;
|
|
26
|
+
}
|
|
27
|
+
async extract(input) {
|
|
28
|
+
const root = await this.source.extract(input);
|
|
29
|
+
return _mergeDirectory(root, this._merges);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Recursively merge same-template siblings inside `dir` and all nested directories. */
|
|
33
|
+
function _mergeDirectory(dir, merges) {
|
|
34
|
+
const children = Array.from(walkElements(dir.props.children));
|
|
35
|
+
const merged = _mergeChildren(children, merges).map(child => child.type === "tree-directory" ? _mergeDirectory(child, merges) : child);
|
|
36
|
+
return { ...dir, props: { ...dir.props, children: merged } };
|
|
37
|
+
}
|
|
38
|
+
/** Merge same-template siblings at one directory level. */
|
|
39
|
+
function _mergeChildren(children, merges) {
|
|
40
|
+
// Index children by key so we can look up primary candidates quickly.
|
|
41
|
+
const byKey = new Map();
|
|
42
|
+
for (const child of children)
|
|
43
|
+
byKey.set(child.key, child);
|
|
44
|
+
// Walk in original order, deciding for each whether it's a secondary that should fold into a primary.
|
|
45
|
+
const skip = new Set();
|
|
46
|
+
for (const secondary of children) {
|
|
47
|
+
for (const [lhs, candidates] of Object.entries(merges)) {
|
|
48
|
+
const matches = matchTemplate(lhs, secondary.key);
|
|
49
|
+
if (!matches)
|
|
50
|
+
continue;
|
|
51
|
+
for (const rhs of candidates) {
|
|
52
|
+
const primaryKey = renderTemplate(rhs, matches);
|
|
53
|
+
const primary = byKey.get(primaryKey);
|
|
54
|
+
if (!primary || primary === secondary)
|
|
55
|
+
continue;
|
|
56
|
+
byKey.set(primaryKey, mergeTreeElements(primary, secondary));
|
|
57
|
+
skip.add(secondary);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
if (skip.has(secondary))
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return children.filter(c => !skip.has(c)).map(c => byKey.get(c.key) ?? c);
|
|
65
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type DirectoryElement, type DocumentationElement, type FileElement } from "../util/element.js";
|
|
2
|
+
import { Extractor } from "./Extractor.js";
|
|
3
|
+
/** Input for a `ModuleExtractor`. */
|
|
4
|
+
export interface ModuleExtractorInput {
|
|
5
|
+
/** Display name for the module, derived from the package.json export key (e.g. `"util/string"`, `"firestore/client"`). */
|
|
6
|
+
readonly name: string;
|
|
7
|
+
/**
|
|
8
|
+
* The source element this module is built from.
|
|
9
|
+
* - `FileElement` — the module is backed by a single source file (with its `.md` sibling already merged in by `MergingExtractor`).
|
|
10
|
+
* - `DirectoryElement` — the module is backed by a directory; its absorbed index file provides the content.
|
|
11
|
+
*/
|
|
12
|
+
readonly source: FileElement | DirectoryElement;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Extractor that builds a `kind: "module"` `DocumentationElement` from a source file or directory.
|
|
16
|
+
* - The module's `content`, `description`, and `title` are taken from the source element (`MergingExtractor` and
|
|
17
|
+
* `IndexFileExtractor` are expected to have run upstream so `.md` siblings and `README.md` are already folded in).
|
|
18
|
+
* - The module's `children` are every `tree-documentation` element found by deep-walking the source — flattened across
|
|
19
|
+
* files and subdirectories, but never descending into a `tree-documentation`'s own members.
|
|
20
|
+
*/
|
|
21
|
+
export declare class ModuleExtractor extends Extractor<ModuleExtractorInput, DocumentationElement> {
|
|
22
|
+
extract({ name, source }: ModuleExtractorInput): DocumentationElement;
|
|
23
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { walkElements } from "../util/element.js";
|
|
2
|
+
import { requireSlug } from "../util/string.js";
|
|
3
|
+
import { Extractor } from "./Extractor.js";
|
|
4
|
+
/**
|
|
5
|
+
* Extractor that builds a `kind: "module"` `DocumentationElement` from a source file or directory.
|
|
6
|
+
* - The module's `content`, `description`, and `title` are taken from the source element (`MergingExtractor` and
|
|
7
|
+
* `IndexFileExtractor` are expected to have run upstream so `.md` siblings and `README.md` are already folded in).
|
|
8
|
+
* - The module's `children` are every `tree-documentation` element found by deep-walking the source — flattened across
|
|
9
|
+
* files and subdirectories, but never descending into a `tree-documentation`'s own members.
|
|
10
|
+
*/
|
|
11
|
+
export class ModuleExtractor extends Extractor {
|
|
12
|
+
extract({ name, source }) {
|
|
13
|
+
const children = _collectChildren(source);
|
|
14
|
+
return {
|
|
15
|
+
type: "tree-documentation",
|
|
16
|
+
key: requireSlug(name),
|
|
17
|
+
props: {
|
|
18
|
+
name,
|
|
19
|
+
title: name,
|
|
20
|
+
kind: "module",
|
|
21
|
+
description: source.props.description,
|
|
22
|
+
content: source.props.content,
|
|
23
|
+
children: children.length ? children : undefined,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Collect every `tree-documentation` element reachable inside `element`, descending through directories and files but not through documented symbols. */
|
|
29
|
+
function _collectChildren(element) {
|
|
30
|
+
const result = [];
|
|
31
|
+
for (const child of walkElements(element.props.children)) {
|
|
32
|
+
const treeChild = child;
|
|
33
|
+
if (treeChild.type === "tree-documentation") {
|
|
34
|
+
result.push(treeChild);
|
|
35
|
+
}
|
|
36
|
+
else if (treeChild.type === "tree-directory" || treeChild.type === "tree-file") {
|
|
37
|
+
result.push(..._collectChildren(treeChild));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type DirectoryElement } from "../util/element.js";
|
|
2
|
+
import { type AbsolutePath, type Path } from "../util/path.js";
|
|
3
|
+
import { Extractor } from "./Extractor.js";
|
|
4
|
+
import { ModuleExtractor } from "./ModuleExtractor.js";
|
|
5
|
+
/** Options for a `PackageExtractor`. */
|
|
6
|
+
export interface PackageExtractorOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Pre-extracted source tree the `package.json` exports resolve against — typically the result of
|
|
9
|
+
* `IndexFileExtractor(MergingExtractor(DirectoryExtractor()))` over the source root.
|
|
10
|
+
*/
|
|
11
|
+
readonly tree: DirectoryElement;
|
|
12
|
+
/**
|
|
13
|
+
* Source-file extensions tried when resolving an export's last segment to a source file (e.g. `./util/string` → `string.ts`, `string.tsx`, …).
|
|
14
|
+
* - Checked in declaration order; first match wins.
|
|
15
|
+
* - Defaults to `["ts", "tsx", "js", "jsx"]`.
|
|
16
|
+
*/
|
|
17
|
+
readonly extensions?: readonly string[];
|
|
18
|
+
/** `ModuleExtractor` used to build each module element. Defaults to a fresh `new ModuleExtractor()`. */
|
|
19
|
+
readonly module?: ModuleExtractor;
|
|
20
|
+
/** Absolute base path used to resolve a relative `package.json` path passed to `extract()`. */
|
|
21
|
+
readonly base?: AbsolutePath;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Extractor that reads a `package.json` and produces a flat tree of modules — one `kind: "module"`
|
|
25
|
+
* `DocumentationElement` per export entry, in declaration order.
|
|
26
|
+
* - Static export keys (e.g. `"./api"`, `"./firestore/client"`) become one module each.
|
|
27
|
+
* - Wildcard export keys (e.g. `"./util/*"`) expand against the source tree — one module per matching child file (with
|
|
28
|
+
* an extension in `extensions`) or subdirectory.
|
|
29
|
+
* - The `"."` root export is skipped — its content is the root tree element itself.
|
|
30
|
+
* - Throws if a static export key has no matching source element in the tree.
|
|
31
|
+
*/
|
|
32
|
+
export declare class PackageExtractor extends Extractor<Path, DirectoryElement> {
|
|
33
|
+
private readonly _tree;
|
|
34
|
+
private readonly _extensions;
|
|
35
|
+
private readonly _module;
|
|
36
|
+
private readonly _base;
|
|
37
|
+
constructor({ tree, extensions, module, base }: PackageExtractorOptions);
|
|
38
|
+
extract(packageJson: Path): Promise<DirectoryElement>;
|
|
39
|
+
/** Resolve a static export subpath (e.g. `"firestore/client"`) to a file or directory element in the tree. */
|
|
40
|
+
private _resolve;
|
|
41
|
+
/** Expand a wildcard export subpath (e.g. `"util/*"`) into one module per matching child. */
|
|
42
|
+
private _expandWildcard;
|
|
43
|
+
}
|