@dogsbay/types 0.1.2
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/dist/format.d.ts +350 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +2 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/json.d.ts +26 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/json.js +88 -0
- package/dist/json.js.map +1 -0
- package/dist/meta.d.ts +100 -0
- package/dist/meta.d.ts.map +1 -0
- package/dist/meta.js +130 -0
- package/dist/meta.js.map +1 -0
- package/dist/plugin.d.ts +269 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +16 -0
- package/dist/plugin.js.map +1 -0
- package/dist/tree.d.ts +115 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/tree.js +2 -0
- package/dist/tree.js.map +1 -0
- package/package.json +43 -0
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import type { TreeNode } from "./tree.js";
|
|
2
|
+
import type { PageMeta } from "./meta.js";
|
|
3
|
+
/**
|
|
4
|
+
* A page for format conversion: slug → tree.
|
|
5
|
+
*
|
|
6
|
+
* This is the universal contract between importers and exporters.
|
|
7
|
+
* Importers produce ExportPage[], exporters consume them.
|
|
8
|
+
*/
|
|
9
|
+
export interface Heading {
|
|
10
|
+
depth: number;
|
|
11
|
+
slug: string;
|
|
12
|
+
text: string;
|
|
13
|
+
/** Symbol kind for API reference TOC entries (class, meth, attr, func, module) */
|
|
14
|
+
kind?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ExportPage {
|
|
17
|
+
/** File path relative to docs root, e.g. "getting-started" or "guides/install" */
|
|
18
|
+
slug: string;
|
|
19
|
+
/** Page title */
|
|
20
|
+
title: string;
|
|
21
|
+
/** Page content as TreeNode[] */
|
|
22
|
+
tree: TreeNode[];
|
|
23
|
+
/** Headings extracted during parsing (for TOC generation) */
|
|
24
|
+
headings: Heading[];
|
|
25
|
+
/** Target URL for redirect/navigation pages (no body content, just a link) */
|
|
26
|
+
redirect?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Raw frontmatter data from the source page. Includes all YAML fields that
|
|
29
|
+
* were present in the original source (title, description, tags, custom
|
|
30
|
+
* fields like pcx_content_type, sidebar.*, etc.).
|
|
31
|
+
*
|
|
32
|
+
* Importers populate this with all frontmatter values; exporters can use
|
|
33
|
+
* specific keys or emit the whole object as frontmatter on output.
|
|
34
|
+
* Specific fields (title, redirect) are also lifted to named ExportPage
|
|
35
|
+
* fields for convenient access.
|
|
36
|
+
*/
|
|
37
|
+
frontmatter?: Record<string, unknown>;
|
|
38
|
+
/**
|
|
39
|
+
* Parsed, validated, normalized metadata. Populated by importers
|
|
40
|
+
* via `parseMeta(frontmatter, options)`. Drives taxonomy emission,
|
|
41
|
+
* status badges, search facets, and Diátaxis-aware layouts.
|
|
42
|
+
*
|
|
43
|
+
* `frontmatter` stays opaque (preserves unknown keys for round-
|
|
44
|
+
* trip); `meta` is the typed slice the renderer consumes.
|
|
45
|
+
*/
|
|
46
|
+
meta?: PageMeta;
|
|
47
|
+
/**
|
|
48
|
+
* Axis metadata for multi-source aggregation. Populated by the
|
|
49
|
+
* loader when ≥1 axis is active so downstream emitters (the
|
|
50
|
+
* version switcher data file, the per-page frontmatter that
|
|
51
|
+
* lets a page identify itself in the switcher) can reconstruct
|
|
52
|
+
* cross-axis equivalents.
|
|
53
|
+
*
|
|
54
|
+
* Undefined when no axis is active (single-source / single-
|
|
55
|
+
* version / single-namespace site). When set, `originalSlug`
|
|
56
|
+
* is always present (the slug as the importer produced it,
|
|
57
|
+
* before any axis prefixing); `namespace` / `version` /
|
|
58
|
+
* `locale` are present only when their axis is active.
|
|
59
|
+
*
|
|
60
|
+
* See plans/multi-source-content.md.
|
|
61
|
+
*/
|
|
62
|
+
multiSource?: MultiSourceMeta;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Per-page axis metadata. Set by the loader's aggregator when
|
|
66
|
+
* multi-source axes are active; consumed by emitters that need
|
|
67
|
+
* to reconstruct cross-version / cross-locale / cross-namespace
|
|
68
|
+
* equivalents (switcherMap.json, hreflang tags, etc.).
|
|
69
|
+
*/
|
|
70
|
+
export interface MultiSourceMeta {
|
|
71
|
+
/** Namespace key (when namespace axis active). */
|
|
72
|
+
namespace?: string;
|
|
73
|
+
/** Version id (when version axis active). */
|
|
74
|
+
version?: string;
|
|
75
|
+
/** Locale code (when locale axis active; reserved for PR 5). */
|
|
76
|
+
locale?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Slug as the importer produced it, BEFORE the loader applied
|
|
79
|
+
* any axis prefix. Lets emitters compute the logical key
|
|
80
|
+
* (`<namespace>/<originalSlug>`) that identifies "this same
|
|
81
|
+
* page across versions / locales".
|
|
82
|
+
*/
|
|
83
|
+
originalSlug: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Navigation item for sidebar/TOC structures.
|
|
87
|
+
*
|
|
88
|
+
* Universal across formats — importers extract nav from source config
|
|
89
|
+
* (mkdocs.yml, sidebars.js, folder structure), exporters write it to
|
|
90
|
+
* the target format's nav mechanism.
|
|
91
|
+
*/
|
|
92
|
+
export interface NavItem {
|
|
93
|
+
label: string;
|
|
94
|
+
href?: string;
|
|
95
|
+
children?: NavItem[];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Standard interface for format plugins.
|
|
99
|
+
*
|
|
100
|
+
* Each format package (e.g. @dogsbay/format-mkdocs) exports a plugin
|
|
101
|
+
* conforming to this interface. The CLI discovers and composes them.
|
|
102
|
+
*/
|
|
103
|
+
export interface FormatPlugin {
|
|
104
|
+
/** Format identifier, e.g. "mkdocs", "obsidian", "astro" */
|
|
105
|
+
name: string;
|
|
106
|
+
/** Whether this format supports importing (source → tree) */
|
|
107
|
+
canImport: boolean;
|
|
108
|
+
/** Whether this format supports exporting (tree → target) */
|
|
109
|
+
canExport: boolean;
|
|
110
|
+
/** Auto-detect whether a path is this format */
|
|
111
|
+
detectSource: (path: string) => boolean;
|
|
112
|
+
/** Format-specific CLI options for import */
|
|
113
|
+
importOptions?: FormatOption[];
|
|
114
|
+
/** Format-specific CLI options for export */
|
|
115
|
+
exportOptions?: FormatOption[];
|
|
116
|
+
/** Import: read source format, produce pages + nav */
|
|
117
|
+
import?(source: string, opts: Record<string, unknown>): Promise<{
|
|
118
|
+
pages: ExportPage[];
|
|
119
|
+
nav: NavItem[];
|
|
120
|
+
}>;
|
|
121
|
+
/** Export: write pages + nav to target format */
|
|
122
|
+
export?(pages: ExportPage[], nav: NavItem[], output: string, opts: Record<string, unknown>): Promise<void>;
|
|
123
|
+
}
|
|
124
|
+
export interface FormatOption {
|
|
125
|
+
flags: string;
|
|
126
|
+
description: string;
|
|
127
|
+
default?: string;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Plausible analytics configuration.
|
|
131
|
+
*
|
|
132
|
+
* When present in `SiteConfig`, the docs layout emits a `<script>` tag
|
|
133
|
+
* loading Plausible's tracker. Cookie-less by default, no consent banner
|
|
134
|
+
* needed for EU.
|
|
135
|
+
*/
|
|
136
|
+
export interface PlausibleConfig {
|
|
137
|
+
/**
|
|
138
|
+
* Tracking domain — the value used as `data-domain` on the script tag.
|
|
139
|
+
* Typically matches the site's hostname, e.g. "docs.example.com".
|
|
140
|
+
*/
|
|
141
|
+
domain: string;
|
|
142
|
+
/**
|
|
143
|
+
* Optional override for the Plausible script URL. Use this when
|
|
144
|
+
* self-hosting Plausible or proxying through your own subdomain.
|
|
145
|
+
* Default: "https://plausible.io/js/script.js".
|
|
146
|
+
*/
|
|
147
|
+
scriptUrl?: string;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Runtime site configuration consumed by docs-layout and other runtime
|
|
151
|
+
* components. Written to `src/data/site.json` by `exportAstroProject`.
|
|
152
|
+
*
|
|
153
|
+
* Every field is optional except `siteName`, which has a sensible
|
|
154
|
+
* default ("Documentation") emitted by the project generator. Fields
|
|
155
|
+
* left undefined are omitted from the emitted JSON to keep output clean.
|
|
156
|
+
*/
|
|
157
|
+
export interface SiteConfig {
|
|
158
|
+
/** Site name shown in header, page title suffixes, copyright notices. */
|
|
159
|
+
siteName: string;
|
|
160
|
+
/**
|
|
161
|
+
* Canonical site URL. Required for `<link rel="canonical">`,
|
|
162
|
+
* sitemap.xml entries, and absolute OG meta tags. Without it, those
|
|
163
|
+
* features degrade to relative URLs.
|
|
164
|
+
*/
|
|
165
|
+
siteUrl?: string;
|
|
166
|
+
/**
|
|
167
|
+
* Site-wide description used as the default `<meta name="description">`
|
|
168
|
+
* and fallback `og:description` when a page doesn't supply one.
|
|
169
|
+
*/
|
|
170
|
+
description?: string;
|
|
171
|
+
/**
|
|
172
|
+
* Default OG image URL — used as `og:image` and `twitter:image`
|
|
173
|
+
* fallback when a page doesn't set `ogImage` in its frontmatter.
|
|
174
|
+
* Should be ~1200x630 PNG/JPG.
|
|
175
|
+
*/
|
|
176
|
+
ogImage?: string;
|
|
177
|
+
/**
|
|
178
|
+
* Twitter / X handle including the leading "@". Emits as
|
|
179
|
+
* `<meta name="twitter:site">`.
|
|
180
|
+
*/
|
|
181
|
+
twitterHandle?: string;
|
|
182
|
+
/**
|
|
183
|
+
* Theme color hint for browsers / iOS Safari status bar. Hex string
|
|
184
|
+
* e.g. "#0a0a0a".
|
|
185
|
+
*/
|
|
186
|
+
themeColor?: string;
|
|
187
|
+
/**
|
|
188
|
+
* Source repo URL (for edit-on-GitHub links and similar). Combined
|
|
189
|
+
* with `editUri` to produce per-page edit URLs.
|
|
190
|
+
*/
|
|
191
|
+
repoUrl?: string;
|
|
192
|
+
/**
|
|
193
|
+
* Path prefix appended to `repoUrl` for edit URLs, e.g.
|
|
194
|
+
* "blob/main/docs/". Resulting per-page link is
|
|
195
|
+
* `{repoUrl}/{editUri}/{slug}.md`.
|
|
196
|
+
*/
|
|
197
|
+
editUri?: string;
|
|
198
|
+
/** Footer copyright text. */
|
|
199
|
+
copyright?: string;
|
|
200
|
+
/**
|
|
201
|
+
* Brand keywords for the site, used by the
|
|
202
|
+
* `seo/h1-brand-keyword` audit rule to verify that landing
|
|
203
|
+
* pages (home + `meta.type: landing` pages) include at least
|
|
204
|
+
* one of these strings in their H1 heading.
|
|
205
|
+
*
|
|
206
|
+
* Match is case-insensitive substring; ordering doesn't
|
|
207
|
+
* matter. Most sites set 1-3 entries (full name, short name,
|
|
208
|
+
* tagline). Sites that omit this config get no
|
|
209
|
+
* brand-keyword findings.
|
|
210
|
+
*/
|
|
211
|
+
brandKeywords?: string[];
|
|
212
|
+
/**
|
|
213
|
+
* Plausible analytics configuration. When set, docs-layout emits the
|
|
214
|
+
* tracker script. When undefined, no analytics script is injected.
|
|
215
|
+
*/
|
|
216
|
+
plausible?: PlausibleConfig;
|
|
217
|
+
/**
|
|
218
|
+
* Display config for hierarchical tag chips, sourced from
|
|
219
|
+
* `taxonomies.tags.prefixes` in `dogsbay.config.yml`. Keyed by
|
|
220
|
+
* the top-level prefix (`concept`, `difficulty`, etc.) — each
|
|
221
|
+
* entry supplies an optional human label and one of the closed
|
|
222
|
+
* palette colors. Consumed by `<TagList>` to render two-part
|
|
223
|
+
* chips with prefix-keyed colors. See plans/tag-display-config.md.
|
|
224
|
+
*/
|
|
225
|
+
tagPrefixes?: Record<string, TagPrefixDisplay>;
|
|
226
|
+
/**
|
|
227
|
+
* Per-tag leaf-label overrides (slug → display string). URLs and
|
|
228
|
+
* taxonomy term-page paths still use the slug; only chip text
|
|
229
|
+
* changes. Sourced from `taxonomies.tags.labels`.
|
|
230
|
+
*/
|
|
231
|
+
tagLabels?: Record<string, string>;
|
|
232
|
+
/**
|
|
233
|
+
* Map of taxonomy name → index path, sourced from declared
|
|
234
|
+
* `taxonomies` entries in `dogsbay.config.yml`. Lets renderer
|
|
235
|
+
* components (`TypeBadge`, `StatusBadge`, etc.) discover whether
|
|
236
|
+
* a built-in field has a browse destination AND what its path is.
|
|
237
|
+
*
|
|
238
|
+
* Example: `{ tags: "/tags", type: "/types", status: "/by-status" }`.
|
|
239
|
+
* A field absent from this map has no destination — the badge
|
|
240
|
+
* renders as a plain span; a field present in the map renders as
|
|
241
|
+
* a link to `<indexPath>/<value>/`.
|
|
242
|
+
*
|
|
243
|
+
* See plans/tag-display-config.md.
|
|
244
|
+
*/
|
|
245
|
+
taxonomyIndexPaths?: Record<string, string>;
|
|
246
|
+
/**
|
|
247
|
+
* Per-taxonomy display config (prefixes + labels), keyed by
|
|
248
|
+
* taxonomy name. Powers the search-facet UI (`<SearchFacets>`)
|
|
249
|
+
* — facet checkboxes show "Concept: Accessibility" instead of
|
|
250
|
+
* `concept/a11y`, "How-to" instead of `how-to`, etc., reusing
|
|
251
|
+
* the same prefix/label mapping that drives `<TagList>` and
|
|
252
|
+
* the taxonomy term pages.
|
|
253
|
+
*
|
|
254
|
+
* `tagPrefixes` / `tagLabels` mirror `taxonomyDisplay.tags`
|
|
255
|
+
* for back-compat with the chip-rendering path. `<TagList>`
|
|
256
|
+
* still consumes those.
|
|
257
|
+
*
|
|
258
|
+
* See plans/search-facets.md.
|
|
259
|
+
*/
|
|
260
|
+
taxonomyDisplay?: Record<string, TaxonomyDisplay>;
|
|
261
|
+
/**
|
|
262
|
+
* Per-page LLM action UI configuration ("Copy as markdown",
|
|
263
|
+
* "Open in Claude/ChatGPT/…"). When omitted, the action cluster
|
|
264
|
+
* is not rendered. See plans/llm-page-actions.md.
|
|
265
|
+
*
|
|
266
|
+
* The agent-readiness data layer (.md endpoints, llms.txt,
|
|
267
|
+
* Accept negotiation) is independent of this config — it always
|
|
268
|
+
* ships as long as `mdMirror` / `llmsTxt` are enabled in
|
|
269
|
+
* AstroProjectOptions. This config only controls the
|
|
270
|
+
* human-facing UI cluster.
|
|
271
|
+
*/
|
|
272
|
+
llmActions?: LlmActionsConfig;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Closed list of LLM provider deep-link targets. Each one is a
|
|
276
|
+
* web app accepting `?q=` query strings to seed a new chat with
|
|
277
|
+
* the provided prompt text. Order in this union determines render
|
|
278
|
+
* order when no explicit list is configured.
|
|
279
|
+
*/
|
|
280
|
+
export type LlmProviderName = "claude" | "chatgpt" | "perplexity" | "gemini";
|
|
281
|
+
/**
|
|
282
|
+
* Where the per-page LLM action cluster appears.
|
|
283
|
+
* - `header` — top-right of the page header (sticky, always visible)
|
|
284
|
+
* - `inline` — directly below the breadcrumb, above the H1
|
|
285
|
+
* - `both` — both placements; useful for sites that want the
|
|
286
|
+
* cluster visible during long scrolls AND in line
|
|
287
|
+
* with the content for first-glance discovery
|
|
288
|
+
*/
|
|
289
|
+
export type LlmActionsPlacement = "header" | "inline" | "both";
|
|
290
|
+
/**
|
|
291
|
+
* Per-page LLM action UI configuration.
|
|
292
|
+
*
|
|
293
|
+
* Default behavior when this object is enabled but partial:
|
|
294
|
+
* - `providers` → all four providers, in this order:
|
|
295
|
+
* claude, chatgpt, perplexity, gemini.
|
|
296
|
+
* - `placement` → "header"
|
|
297
|
+
* - `copyButton` → true
|
|
298
|
+
* - `promptTemplate` → "Read this docs page: {url}"
|
|
299
|
+
* - `footerLink` → true (footer link to /llms.txt)
|
|
300
|
+
*
|
|
301
|
+
* Per-page opt-out is via frontmatter `llmActions: false` — see
|
|
302
|
+
* format-astro/src/project.ts.
|
|
303
|
+
*/
|
|
304
|
+
export interface LlmActionsConfig {
|
|
305
|
+
/**
|
|
306
|
+
* Master toggle. When `false`, no PageActions UI is rendered
|
|
307
|
+
* regardless of other fields. Default `true` when the parent
|
|
308
|
+
* `llmActions` object is present.
|
|
309
|
+
*/
|
|
310
|
+
enabled?: boolean;
|
|
311
|
+
/** Provider list, in render order. */
|
|
312
|
+
providers?: LlmProviderName[];
|
|
313
|
+
/** Where to render the action cluster. */
|
|
314
|
+
placement?: LlmActionsPlacement;
|
|
315
|
+
/** Show the standalone "Copy markdown" button next to the dropdown. */
|
|
316
|
+
copyButton?: boolean;
|
|
317
|
+
/**
|
|
318
|
+
* Prompt template for "Open in {provider}" deep links. The
|
|
319
|
+
* placeholder `{url}` is replaced by the absolute `.md` URL of
|
|
320
|
+
* the current page; the result is URL-encoded into `?q=`.
|
|
321
|
+
*/
|
|
322
|
+
promptTemplate?: string;
|
|
323
|
+
/** Add a footer link to `/llms.txt`. */
|
|
324
|
+
footerLink?: boolean;
|
|
325
|
+
}
|
|
326
|
+
/** Per-taxonomy display config — display labels for chip / facet UI. */
|
|
327
|
+
export interface TaxonomyDisplay {
|
|
328
|
+
/** Per-prefix display config keyed by top-level segment. */
|
|
329
|
+
prefixes?: Record<string, TagPrefixDisplay>;
|
|
330
|
+
/** Per-slug label overrides; key = full slug, value = display string. */
|
|
331
|
+
labels?: Record<string, string>;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Display config for one taxonomy prefix. Color is one of the
|
|
335
|
+
* fixed palette names emitted into the runtime by `<TagList>`.
|
|
336
|
+
* Both fields are optional: with only `label`, the chip renders
|
|
337
|
+
* two-part text in the default palette slot; with only `color`,
|
|
338
|
+
* the slug stays as the chip label.
|
|
339
|
+
*/
|
|
340
|
+
export interface TagPrefixDisplay {
|
|
341
|
+
label?: string;
|
|
342
|
+
color?: TagPaletteName;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Closed palette of color names for tag chip backgrounds. Mirrored
|
|
346
|
+
* from `@dogsbay/cli`'s `PaletteName` so runtime consumers can
|
|
347
|
+
* type-narrow without importing CLI internals.
|
|
348
|
+
*/
|
|
349
|
+
export type TagPaletteName = "blue" | "amber" | "emerald" | "violet" | "rose" | "slate";
|
|
350
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/format.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { TreeNode, InlineNode, InlineText, InlineLink, InlineImage, InlineCode, InlineFootnoteRef, InlineKbd, InlineIcon, InlineMath, InlineHtml, InlineBreak } from "./tree.js";
|
|
2
|
+
export { treeToJson, chunkByHeadings, extractText } from "./json.js";
|
|
3
|
+
export type { RagChunk } from "./json.js";
|
|
4
|
+
export type { ExportPage, Heading, NavItem, FormatPlugin, FormatOption, SiteConfig, PlausibleConfig, TagPrefixDisplay, TagPaletteName, TaxonomyDisplay, LlmActionsConfig, LlmActionsPlacement, LlmProviderName } from "./format.js";
|
|
5
|
+
export type { PageMeta, PageStatus, ParseMetaOptions } from "./meta.js";
|
|
6
|
+
export { parseMeta } from "./meta.js";
|
|
7
|
+
export type { DogsbayPlugin, DogsbayPluginContext, DogsbayPluginFactory, PluginVisibleConfig, PluginLogger, PluginRule, PluginIssue, PluginConfigEntry, EmitFilesHelpers, AstroIntegrationRef, } from "./plugin.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACtL,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrE,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACpO,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAIrE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/json.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { TreeNode } from "./tree.js";
|
|
2
|
+
/**
|
|
3
|
+
* A chunk of content suitable for RAG retrieval.
|
|
4
|
+
* Each chunk corresponds to a heading section in the document.
|
|
5
|
+
*/
|
|
6
|
+
export interface RagChunk {
|
|
7
|
+
heading: string | null;
|
|
8
|
+
headingLevel: number;
|
|
9
|
+
path: string[];
|
|
10
|
+
content: string;
|
|
11
|
+
metadata: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Convert a TreeNode[] to structured JSON for LLM consumption.
|
|
15
|
+
*/
|
|
16
|
+
export declare function treeToJson(nodes: TreeNode[]): unknown;
|
|
17
|
+
/**
|
|
18
|
+
* Split a TreeNode[] into chunks at heading boundaries.
|
|
19
|
+
* Each chunk contains the text content under a heading section.
|
|
20
|
+
*/
|
|
21
|
+
export declare function chunkByHeadings(nodes: TreeNode[], maxLevel?: number): RagChunk[];
|
|
22
|
+
/**
|
|
23
|
+
* Extract plain text from a TreeNode, stripping any markup.
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractText(node: TreeNode): string;
|
|
26
|
+
//# sourceMappingURL=json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAErD;AAkBD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,EAAE,EACjB,QAAQ,GAAE,MAAU,GACnB,QAAQ,EAAE,CAoDZ;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAiBlD"}
|
package/dist/json.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a TreeNode[] to structured JSON for LLM consumption.
|
|
3
|
+
*/
|
|
4
|
+
export function treeToJson(nodes) {
|
|
5
|
+
return nodes.map(nodeToJson);
|
|
6
|
+
}
|
|
7
|
+
function nodeToJson(node) {
|
|
8
|
+
const result = { type: node.type };
|
|
9
|
+
if (node.props && Object.keys(node.props).length > 0) {
|
|
10
|
+
result.props = node.props;
|
|
11
|
+
}
|
|
12
|
+
if (node.html) {
|
|
13
|
+
result.text = node.html;
|
|
14
|
+
}
|
|
15
|
+
if (node.children && node.children.length > 0) {
|
|
16
|
+
result.children = node.children.map(nodeToJson);
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Split a TreeNode[] into chunks at heading boundaries.
|
|
22
|
+
* Each chunk contains the text content under a heading section.
|
|
23
|
+
*/
|
|
24
|
+
export function chunkByHeadings(nodes, maxLevel = 3) {
|
|
25
|
+
const chunks = [];
|
|
26
|
+
const headingStack = [];
|
|
27
|
+
let currentContent = [];
|
|
28
|
+
let currentHeading = null;
|
|
29
|
+
let currentLevel = 0;
|
|
30
|
+
function flush() {
|
|
31
|
+
const content = currentContent.join("\n").trim();
|
|
32
|
+
if (content || currentHeading) {
|
|
33
|
+
chunks.push({
|
|
34
|
+
heading: currentHeading,
|
|
35
|
+
headingLevel: currentLevel,
|
|
36
|
+
path: headingStack.map((h) => h.title),
|
|
37
|
+
content,
|
|
38
|
+
metadata: {},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
currentContent = [];
|
|
42
|
+
}
|
|
43
|
+
function walkNodes(nodes) {
|
|
44
|
+
for (const node of nodes) {
|
|
45
|
+
if (node.type === "heading") {
|
|
46
|
+
const level = node.props?.level ?? 1;
|
|
47
|
+
if (level <= maxLevel) {
|
|
48
|
+
flush();
|
|
49
|
+
while (headingStack.length > 0 &&
|
|
50
|
+
headingStack[headingStack.length - 1].level >= level) {
|
|
51
|
+
headingStack.pop();
|
|
52
|
+
}
|
|
53
|
+
const title = extractText(node);
|
|
54
|
+
headingStack.push({ title, level });
|
|
55
|
+
currentHeading = title;
|
|
56
|
+
currentLevel = level;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
currentContent.push(extractText(node));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
walkNodes(nodes);
|
|
64
|
+
flush();
|
|
65
|
+
return chunks;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Extract plain text from a TreeNode, stripping any markup.
|
|
69
|
+
*/
|
|
70
|
+
export function extractText(node) {
|
|
71
|
+
const parts = [];
|
|
72
|
+
if (node.html) {
|
|
73
|
+
parts.push(stripHtml(node.html));
|
|
74
|
+
}
|
|
75
|
+
if (node.type === "code" && node.props?.code) {
|
|
76
|
+
parts.push(String(node.props.code).trim());
|
|
77
|
+
}
|
|
78
|
+
if (node.children) {
|
|
79
|
+
for (const child of node.children) {
|
|
80
|
+
parts.push(extractText(child));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return parts.filter(Boolean).join(" ").trim();
|
|
84
|
+
}
|
|
85
|
+
function stripHtml(html) {
|
|
86
|
+
return html.replace(/<[^>]+>/g, "").trim();
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=json.js.map
|
package/dist/json.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"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"}
|
package/dist/meta.d.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed page metadata — the parsed, validated, normalized slice of
|
|
3
|
+
* frontmatter the renderer cares about.
|
|
4
|
+
*
|
|
5
|
+
* Importers populate `ExportPage.meta` by calling `parseMeta` on the
|
|
6
|
+
* source frontmatter. Free-form / format-specific keys stay in
|
|
7
|
+
* `ExportPage.frontmatter` (opaque, preserved for round-trip).
|
|
8
|
+
*
|
|
9
|
+
* See plans/metadata-and-taxonomies.md for the design rationale.
|
|
10
|
+
*/
|
|
11
|
+
/** Lifecycle states. Closed enum — fixed set with defined render semantics. */
|
|
12
|
+
export type PageStatus = "draft" | "preview" | "stable" | "deprecated";
|
|
13
|
+
export interface PageMeta {
|
|
14
|
+
/**
|
|
15
|
+
* Flat or slash-nested string tags. `tags: ["api/rest"]` means the
|
|
16
|
+
* page lives under `/tags/api/` AND `/tags/api/rest/` at emit
|
|
17
|
+
* time. Slash is the only nesting separator.
|
|
18
|
+
*/
|
|
19
|
+
tags?: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Broader grouping. Auto-derived from path when frontmatter
|
|
22
|
+
* doesn't supply a valid value (`content/guides/auth.md` →
|
|
23
|
+
* `["guides"]`). Override with `category: foo` or
|
|
24
|
+
* `category: [foo, bar]`.
|
|
25
|
+
*
|
|
26
|
+
* No first-class "belongs nowhere" sentinel in v1: `category: []`
|
|
27
|
+
* falls through to slug-derived default. See
|
|
28
|
+
* plans/metadata-and-taxonomies.md.
|
|
29
|
+
*/
|
|
30
|
+
category?: string[];
|
|
31
|
+
/**
|
|
32
|
+
* Page type. Open string. Diátaxis values (`tutorial`, `how-to`,
|
|
33
|
+
* `reference`, `explanation`) are conventional; users can add
|
|
34
|
+
* `api-endpoint`, `release-notes`, etc.
|
|
35
|
+
*/
|
|
36
|
+
type?: string;
|
|
37
|
+
/** Lifecycle. Drafts excluded from prod builds; deprecated gets a banner. */
|
|
38
|
+
status?: PageStatus;
|
|
39
|
+
/** Audience facets — `["developer"]`, `["admin", "end-user"]`, etc. */
|
|
40
|
+
audience?: string[];
|
|
41
|
+
/** ISO date strings. Consumers parse to Date when needed. */
|
|
42
|
+
updated?: string;
|
|
43
|
+
created?: string;
|
|
44
|
+
/** Sort hint for navigation/list pages. Lower weight first. */
|
|
45
|
+
weight?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Free-form properties beyond well-known fields. Queryable from
|
|
48
|
+
* templates; doesn't get auto-generated index pages. Validate via
|
|
49
|
+
* `propSchema` in `dogsbay.config.yml`.
|
|
50
|
+
*/
|
|
51
|
+
props?: Record<string, unknown>;
|
|
52
|
+
/**
|
|
53
|
+
* Custom taxonomies declared in config. Key is the taxonomy name
|
|
54
|
+
* (e.g. `audience`, `product`); value is the term list. Term
|
|
55
|
+
* strings may be slash-nested when the taxonomy is hierarchical.
|
|
56
|
+
*/
|
|
57
|
+
taxonomies?: Record<string, string[]>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Options for `parseMeta`. The slug enables path-based `category`
|
|
61
|
+
* auto-derivation; the `taxonomyNames` set tells the parser which
|
|
62
|
+
* frontmatter keys to lift into `meta.taxonomies`.
|
|
63
|
+
*/
|
|
64
|
+
export interface ParseMetaOptions {
|
|
65
|
+
/**
|
|
66
|
+
* Slug of the page being parsed (e.g. `"guides/auth"`). Used to
|
|
67
|
+
* auto-derive `category` when frontmatter doesn't set it. Pass
|
|
68
|
+
* `undefined` to skip path-based derivation.
|
|
69
|
+
*/
|
|
70
|
+
slug?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Names of user-declared taxonomies (from `dogsbay.config.yml`'s
|
|
73
|
+
* `taxonomies:` block). Frontmatter values for these keys are
|
|
74
|
+
* lifted into `meta.taxonomies[name]`. Without this, the parser
|
|
75
|
+
* doesn't know which extra keys to treat as taxonomies vs
|
|
76
|
+
* arbitrary frontmatter.
|
|
77
|
+
*/
|
|
78
|
+
taxonomyNames?: readonly string[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse and normalize frontmatter into `PageMeta`. Pure function;
|
|
82
|
+
* no I/O. Unknown frontmatter keys are not lifted — they stay in
|
|
83
|
+
* the caller's opaque frontmatter copy.
|
|
84
|
+
*
|
|
85
|
+
* Behavior:
|
|
86
|
+
* - `tags`, `audience` accept string[] or single string (coerced).
|
|
87
|
+
* - `category` accepts string[] or single string. When absent and
|
|
88
|
+
* `slug` is provided, auto-derives from path segments (excluding
|
|
89
|
+
* the leaf filename).
|
|
90
|
+
* - `type` accepts any string.
|
|
91
|
+
* - `status` accepts only the four enum values; others are dropped.
|
|
92
|
+
* - `weight` accepts numbers; non-numeric is dropped.
|
|
93
|
+
* - `updated` / `created` are stored as ISO strings; Date objects
|
|
94
|
+
* are converted via `.toISOString()`.
|
|
95
|
+
* - `props` accepts an object; non-objects dropped.
|
|
96
|
+
* - Keys named in `options.taxonomyNames` are lifted into
|
|
97
|
+
* `meta.taxonomies` as string arrays.
|
|
98
|
+
*/
|
|
99
|
+
export declare function parseMeta(frontmatter: Record<string, unknown> | undefined, options?: ParseMetaOptions): PageMeta;
|
|
100
|
+
//# sourceMappingURL=meta.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../src/meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEvE,MAAM,WAAW,QAAQ;IACvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,6EAA6E;IAC7E,MAAM,CAAC,EAAE,UAAU,CAAC;IAEpB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEhC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACvC;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAUD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAChD,OAAO,GAAE,gBAAqB,GAC7B,QAAQ,CAwCV"}
|
package/dist/meta.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed page metadata — the parsed, validated, normalized slice of
|
|
3
|
+
* frontmatter the renderer cares about.
|
|
4
|
+
*
|
|
5
|
+
* Importers populate `ExportPage.meta` by calling `parseMeta` on the
|
|
6
|
+
* source frontmatter. Free-form / format-specific keys stay in
|
|
7
|
+
* `ExportPage.frontmatter` (opaque, preserved for round-trip).
|
|
8
|
+
*
|
|
9
|
+
* See plans/metadata-and-taxonomies.md for the design rationale.
|
|
10
|
+
*/
|
|
11
|
+
/** Closed enum for status validation. */
|
|
12
|
+
const STATUS_VALUES = [
|
|
13
|
+
"draft",
|
|
14
|
+
"preview",
|
|
15
|
+
"stable",
|
|
16
|
+
"deprecated",
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Parse and normalize frontmatter into `PageMeta`. Pure function;
|
|
20
|
+
* no I/O. Unknown frontmatter keys are not lifted — they stay in
|
|
21
|
+
* the caller's opaque frontmatter copy.
|
|
22
|
+
*
|
|
23
|
+
* Behavior:
|
|
24
|
+
* - `tags`, `audience` accept string[] or single string (coerced).
|
|
25
|
+
* - `category` accepts string[] or single string. When absent and
|
|
26
|
+
* `slug` is provided, auto-derives from path segments (excluding
|
|
27
|
+
* the leaf filename).
|
|
28
|
+
* - `type` accepts any string.
|
|
29
|
+
* - `status` accepts only the four enum values; others are dropped.
|
|
30
|
+
* - `weight` accepts numbers; non-numeric is dropped.
|
|
31
|
+
* - `updated` / `created` are stored as ISO strings; Date objects
|
|
32
|
+
* are converted via `.toISOString()`.
|
|
33
|
+
* - `props` accepts an object; non-objects dropped.
|
|
34
|
+
* - Keys named in `options.taxonomyNames` are lifted into
|
|
35
|
+
* `meta.taxonomies` as string arrays.
|
|
36
|
+
*/
|
|
37
|
+
export function parseMeta(frontmatter, options = {}) {
|
|
38
|
+
const fm = frontmatter ?? {};
|
|
39
|
+
const meta = {};
|
|
40
|
+
const tags = coerceStringArray(fm.tags);
|
|
41
|
+
if (tags)
|
|
42
|
+
meta.tags = tags;
|
|
43
|
+
const category = coerceStringArray(fm.category) ?? deriveCategoryFromSlug(options.slug);
|
|
44
|
+
if (category)
|
|
45
|
+
meta.category = category;
|
|
46
|
+
if (typeof fm.type === "string" && fm.type.length > 0) {
|
|
47
|
+
meta.type = fm.type;
|
|
48
|
+
}
|
|
49
|
+
if (typeof fm.status === "string" && STATUS_VALUES.includes(fm.status)) {
|
|
50
|
+
meta.status = fm.status;
|
|
51
|
+
}
|
|
52
|
+
const audience = coerceStringArray(fm.audience);
|
|
53
|
+
if (audience)
|
|
54
|
+
meta.audience = audience;
|
|
55
|
+
const updated = coerceIsoDate(fm.updated);
|
|
56
|
+
if (updated)
|
|
57
|
+
meta.updated = updated;
|
|
58
|
+
const created = coerceIsoDate(fm.created);
|
|
59
|
+
if (created)
|
|
60
|
+
meta.created = created;
|
|
61
|
+
if (typeof fm.weight === "number" && Number.isFinite(fm.weight)) {
|
|
62
|
+
meta.weight = fm.weight;
|
|
63
|
+
}
|
|
64
|
+
if (isPlainObject(fm.props)) {
|
|
65
|
+
meta.props = { ...fm.props };
|
|
66
|
+
}
|
|
67
|
+
const taxonomies = collectTaxonomies(fm, options.taxonomyNames);
|
|
68
|
+
if (taxonomies)
|
|
69
|
+
meta.taxonomies = taxonomies;
|
|
70
|
+
return meta;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Auto-derive `category` from a slug. The leaf segment is treated
|
|
74
|
+
* as the page filename and dropped; remaining segments become the
|
|
75
|
+
* category path.
|
|
76
|
+
*
|
|
77
|
+
* - `"guides/auth"` → `["guides"]`
|
|
78
|
+
* - `"guides/oauth/setup"` → `["guides", "oauth"]`
|
|
79
|
+
* - `"intro"` → undefined (no parent path)
|
|
80
|
+
* - `""` / undefined → undefined
|
|
81
|
+
*/
|
|
82
|
+
function deriveCategoryFromSlug(slug) {
|
|
83
|
+
if (!slug)
|
|
84
|
+
return undefined;
|
|
85
|
+
const parts = slug.split("/").filter((p) => p.length > 0);
|
|
86
|
+
if (parts.length < 2)
|
|
87
|
+
return undefined;
|
|
88
|
+
return parts.slice(0, -1);
|
|
89
|
+
}
|
|
90
|
+
function coerceStringArray(value) {
|
|
91
|
+
if (typeof value === "string") {
|
|
92
|
+
return value.length > 0 ? [value] : undefined;
|
|
93
|
+
}
|
|
94
|
+
if (Array.isArray(value)) {
|
|
95
|
+
const out = value.filter((v) => typeof v === "string" && v.length > 0);
|
|
96
|
+
return out.length > 0 ? out : undefined;
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
function coerceIsoDate(value) {
|
|
101
|
+
if (value instanceof Date && !Number.isNaN(value.getTime())) {
|
|
102
|
+
return value.toISOString();
|
|
103
|
+
}
|
|
104
|
+
if (typeof value === "string" && value.length > 0) {
|
|
105
|
+
const parsed = new Date(value);
|
|
106
|
+
return Number.isNaN(parsed.getTime()) ? undefined : parsed.toISOString();
|
|
107
|
+
}
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
function isPlainObject(value) {
|
|
111
|
+
return (typeof value === "object" &&
|
|
112
|
+
value !== null &&
|
|
113
|
+
!Array.isArray(value) &&
|
|
114
|
+
!(value instanceof Date));
|
|
115
|
+
}
|
|
116
|
+
function collectTaxonomies(fm, taxonomyNames) {
|
|
117
|
+
if (!taxonomyNames || taxonomyNames.length === 0)
|
|
118
|
+
return undefined;
|
|
119
|
+
const out = {};
|
|
120
|
+
for (const name of taxonomyNames) {
|
|
121
|
+
// Skip well-known names that have their own typed slot.
|
|
122
|
+
if (name === "tags" || name === "category" || name === "audience")
|
|
123
|
+
continue;
|
|
124
|
+
const value = coerceStringArray(fm[name]);
|
|
125
|
+
if (value)
|
|
126
|
+
out[name] = value;
|
|
127
|
+
}
|
|
128
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=meta.js.map
|
package/dist/meta.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../src/meta.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin types — the surface third-party plugins target.
|
|
3
|
+
*
|
|
4
|
+
* Design and rationale: plans/plugin-api.md.
|
|
5
|
+
*
|
|
6
|
+
* The interface is deliberately framework-agnostic. Plugins do NOT
|
|
7
|
+
* see the inner workings of the Astro build; they receive parsed
|
|
8
|
+
* pages as TreeNode-bearing `ExportPage[]` and contribute generated
|
|
9
|
+
* outputs (transformed pages, audit rules, client modules, styles,
|
|
10
|
+
* astro integrations) through named hooks.
|
|
11
|
+
*
|
|
12
|
+
* The runtime side (loader, codegen) lives in `packages/cli`. This
|
|
13
|
+
* file owns only the shapes — keeping `@dogsbay/types` light.
|
|
14
|
+
*/
|
|
15
|
+
import type { ExportPage, NavItem, SiteConfig } from "./format.js";
|
|
16
|
+
/**
|
|
17
|
+
* Logger handed to plugin hooks. Output is automatically prefixed
|
|
18
|
+
* with the plugin's id so users can attribute messages.
|
|
19
|
+
*/
|
|
20
|
+
export interface PluginLogger {
|
|
21
|
+
info(msg: string): void;
|
|
22
|
+
warn(msg: string): void;
|
|
23
|
+
error(msg: string): void;
|
|
24
|
+
debug(msg: string): void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Read-only context passed to every plugin hook.
|
|
28
|
+
*
|
|
29
|
+
* Plugins MUST NOT mutate `config` directly — return a new config
|
|
30
|
+
* from `extendConfig` to change resolved configuration. The other
|
|
31
|
+
* fields are stable across the build.
|
|
32
|
+
*/
|
|
33
|
+
export interface DogsbayPluginContext {
|
|
34
|
+
/**
|
|
35
|
+
* Resolved site configuration — the same shape `dogsbay site
|
|
36
|
+
* build` works against, with defaults applied.
|
|
37
|
+
*
|
|
38
|
+
* Plugins receive this as a snapshot. To modify config, return
|
|
39
|
+
* a new value from `extendConfig`. Hooks fired AFTER
|
|
40
|
+
* `extendConfig` see the modified config.
|
|
41
|
+
*/
|
|
42
|
+
readonly config: PluginVisibleConfig;
|
|
43
|
+
/** Absolute path of the directory containing `dogsbay.config.yml`. */
|
|
44
|
+
readonly siteRoot: string;
|
|
45
|
+
/**
|
|
46
|
+
* Absolute path of the generated Astro project. Usually
|
|
47
|
+
* `<siteRoot>/astro`; sometimes `<siteRoot>` when `output: "."`
|
|
48
|
+
* is configured.
|
|
49
|
+
*/
|
|
50
|
+
readonly outputDir: string;
|
|
51
|
+
/** Logger prefixed with the plugin's id. */
|
|
52
|
+
readonly logger: PluginLogger;
|
|
53
|
+
/**
|
|
54
|
+
* Build command currently running. Lets plugins skip work that
|
|
55
|
+
* only matters in production builds, or run dev-only diagnostics.
|
|
56
|
+
*/
|
|
57
|
+
readonly command: "build" | "dev" | "check";
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Subset of the resolved config that plugins are allowed to read.
|
|
61
|
+
*
|
|
62
|
+
* The full `DogsbayConfig` lives in `@dogsbay/cli`; re-exposing it
|
|
63
|
+
* here would cause a circular dep. Plugins typically only need
|
|
64
|
+
* `site` (for name, basePath, etc.) plus the option pieces they
|
|
65
|
+
* declared themselves. Cast through `unknown` if you genuinely need
|
|
66
|
+
* deeper access — that's a deliberate friction point because the
|
|
67
|
+
* shape can change between minor versions.
|
|
68
|
+
*/
|
|
69
|
+
export interface PluginVisibleConfig {
|
|
70
|
+
site: SiteConfig;
|
|
71
|
+
/** Free-form access for everything the typed surface omits. */
|
|
72
|
+
[key: string]: unknown;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Audit rule contract — re-stated here to avoid a circular dep
|
|
76
|
+
* between `@dogsbay/types` and `@dogsbay/cli` (where the canonical
|
|
77
|
+
* audit module lives). The shape MUST stay in sync with
|
|
78
|
+
* `packages/cli/src/audit/types.ts` — adapted via a runtime
|
|
79
|
+
* pass-through in the loader.
|
|
80
|
+
*/
|
|
81
|
+
export interface PluginRule {
|
|
82
|
+
id: string;
|
|
83
|
+
category: string;
|
|
84
|
+
stage: "source" | "source-corpus" | "dist";
|
|
85
|
+
severity: "error" | "warning";
|
|
86
|
+
description: string;
|
|
87
|
+
/**
|
|
88
|
+
* The audit runner narrows this on the rule's declared `stage`.
|
|
89
|
+
* Plugins import the concrete context types from
|
|
90
|
+
* `@dogsbay/cli/audit` if they need typed access.
|
|
91
|
+
*/
|
|
92
|
+
run(ctx: unknown): PluginIssue[];
|
|
93
|
+
}
|
|
94
|
+
export interface PluginIssue {
|
|
95
|
+
ruleId: string;
|
|
96
|
+
severity: "error" | "warning" | "info";
|
|
97
|
+
file: string;
|
|
98
|
+
line?: number;
|
|
99
|
+
message: string;
|
|
100
|
+
context?: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Helpers passed to `emitFiles` so plugins don't need to import
|
|
104
|
+
* `node:fs` directly. The runtime resolves all paths relative to
|
|
105
|
+
* `outputDir`.
|
|
106
|
+
*/
|
|
107
|
+
export interface EmitFilesHelpers {
|
|
108
|
+
/** Write a UTF-8 / Uint8Array file to `<outputDir>/<relPath>`. */
|
|
109
|
+
writeFile(relPath: string, contents: string | Uint8Array): void;
|
|
110
|
+
/** Recursively copy `srcAbs` (absolute) to `<outputDir>/<destRel>`. */
|
|
111
|
+
copyDir(srcAbs: string, destRel: string): void;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The plugin shape. All fields except `name` are optional; plugins
|
|
115
|
+
* implement only the hooks they need.
|
|
116
|
+
*
|
|
117
|
+
* Lifecycle order during `dogsbay site build`:
|
|
118
|
+
*
|
|
119
|
+
* 1. `extendConfig` — modify resolved config
|
|
120
|
+
* 2. (content import runs)
|
|
121
|
+
* 3. `onContentImported` — mutate pages + nav
|
|
122
|
+
* 4. `transformNav` — sugar for nav-only patches
|
|
123
|
+
* 5. (format-astro emitters run)
|
|
124
|
+
* 6. `emitFiles` — write extra files
|
|
125
|
+
* 7. (client-module / config / style codegen runs)
|
|
126
|
+
* 8. `auditRules` — registered for `site check`
|
|
127
|
+
* 9. (astro.config.mjs codegen)
|
|
128
|
+
*
|
|
129
|
+
* `clientModules`, `styles`, `defineClientConfig`, `componentWrappers`,
|
|
130
|
+
* and `addAstroIntegrations` are queried before the corresponding
|
|
131
|
+
* codegen step; their return value is treated as data, not as a
|
|
132
|
+
* lifecycle hook with side-effect ordering.
|
|
133
|
+
*/
|
|
134
|
+
export interface DogsbayPlugin {
|
|
135
|
+
/**
|
|
136
|
+
* npm package name (or local synthetic name). Used in diagnostics
|
|
137
|
+
* and as the default `id` if `id` isn't set.
|
|
138
|
+
*/
|
|
139
|
+
name: string;
|
|
140
|
+
/**
|
|
141
|
+
* Plugin instance id. Defaults to `name`. Provide explicitly when
|
|
142
|
+
* the same plugin is loaded twice (e.g. one OpenAPI instance per
|
|
143
|
+
* schema). The loader auto-suffixes (`#1`, `#2`) duplicates if
|
|
144
|
+
* no explicit id is supplied — that's a fallback, not a
|
|
145
|
+
* recommendation.
|
|
146
|
+
*/
|
|
147
|
+
id?: string;
|
|
148
|
+
/** Plugin ids that MUST run after this one. */
|
|
149
|
+
before?: string[];
|
|
150
|
+
/** Plugin ids that MUST run before this one. */
|
|
151
|
+
after?: string[];
|
|
152
|
+
extendConfig?(ctx: DogsbayPluginContext): PluginVisibleConfig | Promise<PluginVisibleConfig>;
|
|
153
|
+
onContentImported?(pages: ExportPage[], nav: NavItem[], ctx: DogsbayPluginContext): {
|
|
154
|
+
pages: ExportPage[];
|
|
155
|
+
nav: NavItem[];
|
|
156
|
+
} | Promise<{
|
|
157
|
+
pages: ExportPage[];
|
|
158
|
+
nav: NavItem[];
|
|
159
|
+
}>;
|
|
160
|
+
transformNav?(nav: NavItem[], ctx: DogsbayPluginContext): NavItem[] | Promise<NavItem[]> | undefined;
|
|
161
|
+
emitFiles?(ctx: DogsbayPluginContext & {
|
|
162
|
+
pages: ExportPage[];
|
|
163
|
+
nav: NavItem[];
|
|
164
|
+
} & EmitFilesHelpers): void | Promise<void>;
|
|
165
|
+
/**
|
|
166
|
+
* Absolute paths of `.js` / `.ts` modules to import in the docs
|
|
167
|
+
* layout. Each module is loaded for its side effects and SHOULD
|
|
168
|
+
* listen for `astro:page-load` to handle view transitions.
|
|
169
|
+
*/
|
|
170
|
+
clientModules?(ctx: DogsbayPluginContext): string[];
|
|
171
|
+
/**
|
|
172
|
+
* Absolute paths of `.css` files to inject into the layout. Each
|
|
173
|
+
* file is copied into `<outputDir>/src/styles/plugins/` and
|
|
174
|
+
* imported from the global stylesheet.
|
|
175
|
+
*/
|
|
176
|
+
styles?(ctx: DogsbayPluginContext): string[];
|
|
177
|
+
/**
|
|
178
|
+
* Build-time → client-time config bridge. The returned value is
|
|
179
|
+
* exposed at `virtual:dogsbay-plugin-config/<plugin-id>` so the
|
|
180
|
+
* client modules can `import config from ".../<plugin-id>"`.
|
|
181
|
+
*
|
|
182
|
+
* The value is JSON-serialized into a TypeScript file at codegen
|
|
183
|
+
* time, so it must be JSON-safe (no functions, classes, or
|
|
184
|
+
* circular refs). Strings, numbers, booleans, arrays, and plain
|
|
185
|
+
* objects are fine.
|
|
186
|
+
*/
|
|
187
|
+
defineClientConfig?(ctx: DogsbayPluginContext): unknown;
|
|
188
|
+
/**
|
|
189
|
+
* Wrap a built-in slot. Unlike Starlight (single-string-replaces-
|
|
190
|
+
* everything), wrappers compose: each plugin's wrapper sees the
|
|
191
|
+
* previous wrapper's output via `<slot />`. Order matches plugin
|
|
192
|
+
* declaration order — earlier-declared wrappers are outermost,
|
|
193
|
+
* later-declared wrappers are innermost.
|
|
194
|
+
*
|
|
195
|
+
* Each plugin's wrapper component MUST render a `<slot />` —
|
|
196
|
+
* that's where the inner content lands. The runtime emits a
|
|
197
|
+
* `<Slot>Stack.astro` codegen file that imports each wrapper and
|
|
198
|
+
* recursively nests them; per-page emission uses the stack
|
|
199
|
+
* around the article body.
|
|
200
|
+
*
|
|
201
|
+
* Available slots in v1:
|
|
202
|
+
* - "MarkdownContent" — wraps the page article body
|
|
203
|
+
*
|
|
204
|
+
* Future slots (DocsHeader, Sidebar, TOC, Footer, Pagination)
|
|
205
|
+
* land as plugin demand surfaces.
|
|
206
|
+
*
|
|
207
|
+
* @returns map of slot name → absolute path to the wrapper
|
|
208
|
+
* `.astro` component shipped with the plugin
|
|
209
|
+
*/
|
|
210
|
+
componentWrappers?(ctx: DogsbayPluginContext): Record<string, string>;
|
|
211
|
+
auditRules?(ctx: DogsbayPluginContext): PluginRule[];
|
|
212
|
+
/**
|
|
213
|
+
* Astro integrations to register on the generated project. Use
|
|
214
|
+
* for things no Dogsbay hook covers (sitemap, OG image generation,
|
|
215
|
+
* custom Vite plugins). The integrations are appended to the
|
|
216
|
+
* `integrations:` array in `astro.config.mjs` via codegen, so they
|
|
217
|
+
* must be importable from npm package paths — local-file
|
|
218
|
+
* integrations need the plugin to ship them as part of its package.
|
|
219
|
+
*/
|
|
220
|
+
addAstroIntegrations?(ctx: DogsbayPluginContext): AstroIntegrationRef[];
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Reference to an Astro integration as it should appear in the
|
|
224
|
+
* generated `astro.config.mjs`. Avoids a `@types/astro` dep here.
|
|
225
|
+
*
|
|
226
|
+
* Example:
|
|
227
|
+
* { import: "@astrojs/sitemap", options: { customPages: [] } }
|
|
228
|
+
* → import sitemap from "@astrojs/sitemap";
|
|
229
|
+
* // ...
|
|
230
|
+
* integrations: [..., sitemap({ customPages: [] })]
|
|
231
|
+
*/
|
|
232
|
+
export interface AstroIntegrationRef {
|
|
233
|
+
/** Module specifier for the integration's default export. */
|
|
234
|
+
import: string;
|
|
235
|
+
/**
|
|
236
|
+
* Options to pass to the integration factory. Must be JSON-safe;
|
|
237
|
+
* the codegen serializes via `JSON.stringify`. For options that
|
|
238
|
+
* can't be JSON-serialized (functions, etc.), use a thin wrapper
|
|
239
|
+
* package and pass options through `extendConfig` instead.
|
|
240
|
+
*/
|
|
241
|
+
options?: unknown;
|
|
242
|
+
/**
|
|
243
|
+
* Optional factory call name. Defaults to the integration's
|
|
244
|
+
* default export. Use when the package's default export is the
|
|
245
|
+
* integration object itself rather than a factory.
|
|
246
|
+
*/
|
|
247
|
+
callable?: boolean;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Plugin factory — the default export plugin authors ship.
|
|
251
|
+
*
|
|
252
|
+
* The factory pattern (rather than a plain object) gives plugin
|
|
253
|
+
* authors a place to validate options and stash per-instance state
|
|
254
|
+
* before returning the hook bag.
|
|
255
|
+
*/
|
|
256
|
+
export type DogsbayPluginFactory<O = unknown> = (options?: O) => DogsbayPlugin;
|
|
257
|
+
/**
|
|
258
|
+
* Plugin entry as it appears in `dogsbay.config.yml`. Either a bare
|
|
259
|
+
* package name (no options) or a `{ name, id?, options? }` object.
|
|
260
|
+
*/
|
|
261
|
+
export type PluginConfigEntry = string | {
|
|
262
|
+
/** npm package name or local path. */
|
|
263
|
+
name: string;
|
|
264
|
+
/** Optional instance id; required when the same plugin appears more than once. */
|
|
265
|
+
id?: string;
|
|
266
|
+
/** Options forwarded to the plugin's factory. */
|
|
267
|
+
options?: unknown;
|
|
268
|
+
};
|
|
269
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin types — the surface third-party plugins target.
|
|
3
|
+
*
|
|
4
|
+
* Design and rationale: plans/plugin-api.md.
|
|
5
|
+
*
|
|
6
|
+
* The interface is deliberately framework-agnostic. Plugins do NOT
|
|
7
|
+
* see the inner workings of the Astro build; they receive parsed
|
|
8
|
+
* pages as TreeNode-bearing `ExportPage[]` and contribute generated
|
|
9
|
+
* outputs (transformed pages, audit rules, client modules, styles,
|
|
10
|
+
* astro integrations) through named hooks.
|
|
11
|
+
*
|
|
12
|
+
* The runtime side (loader, codegen) lives in `packages/cli`. This
|
|
13
|
+
* file owns only the shapes — keeping `@dogsbay/types` light.
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
package/dist/tree.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal document tree node.
|
|
3
|
+
*
|
|
4
|
+
* All format loaders (MkDocs, AsciiDoc, DITA, Dogsbay MD) produce TreeNode[].
|
|
5
|
+
* All renderers (ContentRenderer.astro) and exporters consume TreeNode[].
|
|
6
|
+
*
|
|
7
|
+
* This is a semantic model — it captures what content means, not how it was
|
|
8
|
+
* originally written. Format-specific syntax details do not belong here.
|
|
9
|
+
*/
|
|
10
|
+
export interface TreeNode {
|
|
11
|
+
/** Semantic node type: "callout", "tabs", "code", "heading", "paragraph", etc. */
|
|
12
|
+
type: string;
|
|
13
|
+
/** Semantic properties. Shape depends on type. */
|
|
14
|
+
props?: Record<string, unknown>;
|
|
15
|
+
/** Pre-rendered HTML content (for inline/prose nodes). */
|
|
16
|
+
html?: string;
|
|
17
|
+
/** Child nodes for container types. */
|
|
18
|
+
children?: TreeNode[];
|
|
19
|
+
/** Structured inline children (replaces html for portable rendering). */
|
|
20
|
+
inline?: InlineNode[];
|
|
21
|
+
/**
|
|
22
|
+
* Arbitrary metadata that travels with the node but does not affect
|
|
23
|
+
* rendering. Loaders can attach source-format hints, provenance info,
|
|
24
|
+
* or processing flags here. Renderers and exporters should ignore
|
|
25
|
+
* keys they do not recognise.
|
|
26
|
+
*/
|
|
27
|
+
meta?: Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Inline node — structured representation of inline/rich text content.
|
|
31
|
+
*
|
|
32
|
+
* Inspired by Notion's rich text model: formatting is flat annotations
|
|
33
|
+
* on spans, not nested elements. `{ bold: true, italic: true }` rather
|
|
34
|
+
* than `<strong><em>text</em></strong>`.
|
|
35
|
+
*
|
|
36
|
+
* Links use `children` because link text can contain formatted spans.
|
|
37
|
+
*/
|
|
38
|
+
export type InlineNode = InlineText | InlineLink | InlineImage | InlineCode | InlineHighlight | InlineFootnoteRef | InlineKbd | InlineIcon | InlineMath | InlineHtml | InlineBreak;
|
|
39
|
+
/** Text span with flat formatting annotations. */
|
|
40
|
+
export interface InlineText {
|
|
41
|
+
type: "text";
|
|
42
|
+
text: string;
|
|
43
|
+
bold?: boolean;
|
|
44
|
+
italic?: boolean;
|
|
45
|
+
strikethrough?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/** Link wrapping inline children (link text can contain formatting). */
|
|
48
|
+
export interface InlineLink {
|
|
49
|
+
type: "link";
|
|
50
|
+
href: string;
|
|
51
|
+
title?: string;
|
|
52
|
+
children: InlineNode[];
|
|
53
|
+
}
|
|
54
|
+
/** Image (block or inline depending on context). */
|
|
55
|
+
export interface InlineImage {
|
|
56
|
+
type: "image";
|
|
57
|
+
src: string;
|
|
58
|
+
alt?: string;
|
|
59
|
+
title?: string;
|
|
60
|
+
width?: number;
|
|
61
|
+
height?: number;
|
|
62
|
+
}
|
|
63
|
+
/** Inline code span. */
|
|
64
|
+
export interface InlineCode {
|
|
65
|
+
type: "code";
|
|
66
|
+
text: string;
|
|
67
|
+
}
|
|
68
|
+
/** Highlighted/marked text (==text== in Obsidian/pymdownx.mark). */
|
|
69
|
+
export interface InlineHighlight {
|
|
70
|
+
type: "highlight";
|
|
71
|
+
children: InlineNode[];
|
|
72
|
+
}
|
|
73
|
+
/** Footnote reference. */
|
|
74
|
+
export interface InlineFootnoteRef {
|
|
75
|
+
type: "footnote-ref";
|
|
76
|
+
label: string;
|
|
77
|
+
content?: string;
|
|
78
|
+
}
|
|
79
|
+
/** Keyboard shortcut keys. */
|
|
80
|
+
export interface InlineKbd {
|
|
81
|
+
type: "kbd";
|
|
82
|
+
keys: string[];
|
|
83
|
+
}
|
|
84
|
+
/** Inline math: $E=mc^2$ — rendered by app-level math component. */
|
|
85
|
+
export interface InlineMath {
|
|
86
|
+
type: "math";
|
|
87
|
+
latex: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Icon or emoji shortcode (e.g. :material-check:, :smile:).
|
|
91
|
+
* Resolved at render time by an IconRegistry.
|
|
92
|
+
*/
|
|
93
|
+
export interface InlineIcon {
|
|
94
|
+
type: "icon";
|
|
95
|
+
/** Full shortcode name as written (e.g. "material-check", "smile") */
|
|
96
|
+
name: string;
|
|
97
|
+
/** Icon library: "material" | "fontawesome" | "octicons" | "simple" | "emoji" | "custom" */
|
|
98
|
+
library?: string;
|
|
99
|
+
/** Sub-variant (e.g. "brands", "solid", "regular" for FontAwesome) */
|
|
100
|
+
variant?: string;
|
|
101
|
+
/** Size hint from shortcode (e.g. "16", "24" for Octicons) */
|
|
102
|
+
size?: string;
|
|
103
|
+
/** Attributes from attr_list syntax { .class style="..." } */
|
|
104
|
+
attrs?: Record<string, string>;
|
|
105
|
+
}
|
|
106
|
+
/** Raw HTML escape hatch for unsupported inline types. */
|
|
107
|
+
export interface InlineHtml {
|
|
108
|
+
type: "html-inline";
|
|
109
|
+
html: string;
|
|
110
|
+
}
|
|
111
|
+
/** Line break. */
|
|
112
|
+
export interface InlineBreak {
|
|
113
|
+
type: "break";
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../src/tree.ts"],"names":[],"mappings":"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"}
|
package/dist/tree.js
ADDED
package/dist/tree.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree.js","sourceRoot":"","sources":["../src/tree.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dogsbay/types",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Universal document tree model for Dogsbay format loaders and renderers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"test": "vitest run",
|
|
17
|
+
"test:watch": "vitest"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"dogsbay",
|
|
25
|
+
"documentation",
|
|
26
|
+
"treenode",
|
|
27
|
+
"types"
|
|
28
|
+
],
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"typescript": "^5.7.0",
|
|
31
|
+
"vitest": "^3.0.0"
|
|
32
|
+
},
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/dogsbay/dogsbay.git",
|
|
37
|
+
"directory": "packages/types"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/dogsbay/dogsbay/tree/main/packages/types",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/dogsbay/dogsbay/issues"
|
|
42
|
+
}
|
|
43
|
+
}
|