@dogsbay/format-astro 0.2.0-beta.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/dist/base-path.d.ts +83 -0
- package/dist/base-path.d.ts.map +1 -0
- package/dist/base-path.js +110 -0
- package/dist/base-path.js.map +1 -0
- package/dist/cli.d.ts +22 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +53 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/lead.d.ts +39 -0
- package/dist/lead.d.ts.map +1 -0
- package/dist/lead.js +38 -0
- package/dist/lead.js.map +1 -0
- package/dist/llms-txt.d.ts +81 -0
- package/dist/llms-txt.d.ts.map +1 -0
- package/dist/llms-txt.js +288 -0
- package/dist/llms-txt.js.map +1 -0
- package/dist/plugins.d.ts +40 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +339 -0
- package/dist/plugins.js.map +1 -0
- package/dist/project.d.ts +320 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +1858 -0
- package/dist/project.js.map +1 -0
- package/dist/serialize.d.ts +30 -0
- package/dist/serialize.d.ts.map +1 -0
- package/dist/serialize.js +1197 -0
- package/dist/serialize.js.map +1 -0
- package/dist/taxonomy.d.ts +87 -0
- package/dist/taxonomy.d.ts.map +1 -0
- package/dist/taxonomy.js +467 -0
- package/dist/taxonomy.js.map +1 -0
- package/package.json +47 -0
package/dist/plugins.js
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin-runtime codegen — the format-astro side of the plugin API.
|
|
3
|
+
*
|
|
4
|
+
* Each Dogsbay site build emits a fresh set of plugin-runtime
|
|
5
|
+
* source files in the generated Astro project so plugins'
|
|
6
|
+
* client-side code, virtual config modules, and stylesheets
|
|
7
|
+
* participate in the user's Astro / Vite / Tailwind build.
|
|
8
|
+
*
|
|
9
|
+
* The emitters are intentionally idempotent: running a build twice
|
|
10
|
+
* with the same plugin set produces the same output. When a plugin
|
|
11
|
+
* is removed from config, the next build leaves orphan files
|
|
12
|
+
* untouched (cheap; format-astro never deletes user-modifiable
|
|
13
|
+
* files); the orphans are inert because no `import` references
|
|
14
|
+
* them. A `pnpm clean` clears them.
|
|
15
|
+
*
|
|
16
|
+
* Files written:
|
|
17
|
+
*
|
|
18
|
+
* src/lib/plugin-runtime.ts
|
|
19
|
+
* The single entry point DocsLayout's <script> imports. Each
|
|
20
|
+
* plugin's clientModules paths get an `import "..."` line in
|
|
21
|
+
* declaration order.
|
|
22
|
+
*
|
|
23
|
+
* src/lib/plugin-config/<id>.ts
|
|
24
|
+
* One per plugin that called `defineClientConfig`. Exports the
|
|
25
|
+
* value as `default` so client modules can do
|
|
26
|
+
* `import config from "virtual:dogsbay-plugin-config/<id>"`.
|
|
27
|
+
*
|
|
28
|
+
* src/styles/plugins/<id>.css
|
|
29
|
+
* Copy of each plugin's `styles()` files. Imported into
|
|
30
|
+
* `src/styles/global.css` via an injected block delimited by
|
|
31
|
+
* marker comments — re-runs replace just that block.
|
|
32
|
+
*
|
|
33
|
+
* astro.config.plugins.mjs
|
|
34
|
+
* Module that exports a Vite alias map keyed by virtual config
|
|
35
|
+
* name. astro.config.mjs imports + spreads it; the alias map
|
|
36
|
+
* is tiny (one entry per plugin with defineClientConfig).
|
|
37
|
+
*
|
|
38
|
+
* See plans/plugin-api.md.
|
|
39
|
+
*/
|
|
40
|
+
import { writeFileSync, readFileSync, existsSync, mkdirSync, copyFileSync, rmSync } from "node:fs";
|
|
41
|
+
import { dirname, join, basename, extname } from "node:path";
|
|
42
|
+
/**
|
|
43
|
+
* Slots the runtime emits stack files for. Each entry is always
|
|
44
|
+
* emitted (even when no plugin contributes) so per-page emission
|
|
45
|
+
* can unconditionally import + use the stack. Adding a new slot
|
|
46
|
+
* requires both an entry here and a usage site in format-astro's
|
|
47
|
+
* page emitter.
|
|
48
|
+
*/
|
|
49
|
+
const KNOWN_SLOTS = ["MarkdownContent"];
|
|
50
|
+
const PLUGIN_RUNTIME_REL = "src/lib/plugin-runtime.ts";
|
|
51
|
+
const PLUGIN_CONFIG_DIR_REL = "src/lib/plugin-config";
|
|
52
|
+
const PLUGIN_STYLES_DIR_REL = "src/styles/plugins";
|
|
53
|
+
const PLUGIN_WRAPPERS_DIR_REL = "src/components/wrappers";
|
|
54
|
+
const PLUGIN_VITE_REL = "astro.config.plugins.mjs";
|
|
55
|
+
const GLOBAL_CSS_REL = "src/styles/global.css";
|
|
56
|
+
const GLOBAL_CSS_BEGIN = "/* dogsbay:plugins:begin */";
|
|
57
|
+
const GLOBAL_CSS_END = "/* dogsbay:plugins:end */";
|
|
58
|
+
/**
|
|
59
|
+
* Emit the plugin-runtime artefacts. Safe to call when there are
|
|
60
|
+
* no plugins — every emitted file is shaped to compile and behave
|
|
61
|
+
* as a no-op when no plugin contributes that surface.
|
|
62
|
+
*/
|
|
63
|
+
export function emitPluginRuntime(options) {
|
|
64
|
+
emitClientModulesEntry(options);
|
|
65
|
+
emitClientConfigModules(options);
|
|
66
|
+
emitPluginStyles(options);
|
|
67
|
+
emitPluginViteAliases(options);
|
|
68
|
+
emitWrapperStacks(options);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Write `src/lib/plugin-runtime.ts` — the single entry point
|
|
72
|
+
* DocsLayout pulls in. One import per client-module path, in
|
|
73
|
+
* plugin declaration order.
|
|
74
|
+
*/
|
|
75
|
+
function emitClientModulesEntry(options) {
|
|
76
|
+
const lines = [
|
|
77
|
+
"// Auto-generated by dogsbay site build. Do not edit by hand.",
|
|
78
|
+
"// One import per plugin client module, in declaration order.",
|
|
79
|
+
"// See plans/plugin-api.md → \"Build pipeline integration\".",
|
|
80
|
+
"",
|
|
81
|
+
];
|
|
82
|
+
for (const { pluginId, paths } of options.clientModules) {
|
|
83
|
+
lines.push(`// ${pluginId}`);
|
|
84
|
+
for (const p of paths) {
|
|
85
|
+
// Convert absolute paths to a Vite-friendly URL form. Astro
|
|
86
|
+
// can resolve absolute fs paths via Vite's `/@fs/` prefix in
|
|
87
|
+
// dev, and at build time Vite/rollup follow them directly.
|
|
88
|
+
lines.push(`import ${JSON.stringify(p)};`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (options.clientModules.length === 0) {
|
|
92
|
+
lines.push("// No plugin client modules registered.");
|
|
93
|
+
}
|
|
94
|
+
lines.push("");
|
|
95
|
+
writeFile(join(options.outputDir, PLUGIN_RUNTIME_REL), lines.join("\n"));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Write one TypeScript file per plugin that called
|
|
99
|
+
* `defineClientConfig`. Each file `export default` the JSON-
|
|
100
|
+
* serialized value so client modules import a typed default.
|
|
101
|
+
*/
|
|
102
|
+
function emitClientConfigModules(options) {
|
|
103
|
+
const dir = join(options.outputDir, PLUGIN_CONFIG_DIR_REL);
|
|
104
|
+
if (options.clientConfigs.length === 0) {
|
|
105
|
+
// Nothing to emit; leave the dir alone if it exists from prior
|
|
106
|
+
// builds (idempotency rule above).
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
mkdirSync(dir, { recursive: true });
|
|
110
|
+
for (const { pluginId, value } of options.clientConfigs) {
|
|
111
|
+
const fileName = `${slugifyPluginId(pluginId)}.ts`;
|
|
112
|
+
const safeJson = JSON.stringify(value, null, 2);
|
|
113
|
+
const contents = [
|
|
114
|
+
`// Auto-generated config for plugin "${pluginId}".`,
|
|
115
|
+
`// Imported by client modules via`,
|
|
116
|
+
`// virtual:dogsbay-plugin-config/${pluginId}`,
|
|
117
|
+
"",
|
|
118
|
+
`export default ${safeJson};`,
|
|
119
|
+
"",
|
|
120
|
+
].join("\n");
|
|
121
|
+
writeFile(join(dir, fileName), contents);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Copy plugin styles into `src/styles/plugins/<plugin-id>__<file>.css`
|
|
126
|
+
* and inject `@import` lines into `src/styles/global.css` between
|
|
127
|
+
* the marker comments. The marker block is replaced (not appended)
|
|
128
|
+
* so re-runs are idempotent.
|
|
129
|
+
*/
|
|
130
|
+
function emitPluginStyles(options) {
|
|
131
|
+
const stylesDir = join(options.outputDir, PLUGIN_STYLES_DIR_REL);
|
|
132
|
+
const imports = [];
|
|
133
|
+
if (options.styles.length > 0) {
|
|
134
|
+
mkdirSync(stylesDir, { recursive: true });
|
|
135
|
+
for (const { pluginId, paths } of options.styles) {
|
|
136
|
+
for (const p of paths) {
|
|
137
|
+
const ext = extname(p) || ".css";
|
|
138
|
+
const baseName = basename(p, ext);
|
|
139
|
+
const dest = `${slugifyPluginId(pluginId)}__${baseName}${ext}`;
|
|
140
|
+
copyFileSync(p, join(stylesDir, dest));
|
|
141
|
+
imports.push(`@import "./plugins/${dest}";`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Patch global.css. If the file doesn't exist (e.g. a partial
|
|
146
|
+
// scaffold), leave it alone — the scaffold emitter owns global.css.
|
|
147
|
+
const cssPath = join(options.outputDir, GLOBAL_CSS_REL);
|
|
148
|
+
if (!existsSync(cssPath))
|
|
149
|
+
return;
|
|
150
|
+
const current = readFileSync(cssPath, "utf-8");
|
|
151
|
+
const block = imports.length > 0
|
|
152
|
+
? `${GLOBAL_CSS_BEGIN}\n${imports.join("\n")}\n${GLOBAL_CSS_END}`
|
|
153
|
+
: `${GLOBAL_CSS_BEGIN}\n${GLOBAL_CSS_END}`;
|
|
154
|
+
let next;
|
|
155
|
+
const beginIdx = current.indexOf(GLOBAL_CSS_BEGIN);
|
|
156
|
+
const endIdx = current.indexOf(GLOBAL_CSS_END);
|
|
157
|
+
if (beginIdx >= 0 && endIdx > beginIdx) {
|
|
158
|
+
next =
|
|
159
|
+
current.slice(0, beginIdx) +
|
|
160
|
+
block +
|
|
161
|
+
current.slice(endIdx + GLOBAL_CSS_END.length);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
// Append at end; ensure trailing newline.
|
|
165
|
+
const trimmed = current.endsWith("\n") ? current : `${current}\n`;
|
|
166
|
+
next = `${trimmed}${block}\n`;
|
|
167
|
+
}
|
|
168
|
+
writeFileSync(cssPath, next);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Write `astro.config.plugins.mjs` — a tiny module exporting:
|
|
172
|
+
* - `pluginAliases`: Vite alias map for `virtual:dogsbay-plugin-config/<id>`
|
|
173
|
+
* - `pluginFsAllow`: array of directory paths to add to
|
|
174
|
+
* `vite.server.fs.allow`, so plugins shipped from absolute
|
|
175
|
+
* paths outside the project root (workspace deps, monorepo
|
|
176
|
+
* layouts) can be served by the Vite dev server.
|
|
177
|
+
*
|
|
178
|
+
* The user's `astro.config.mjs` imports both and spreads them
|
|
179
|
+
* into the appropriate Vite config slots.
|
|
180
|
+
*/
|
|
181
|
+
function emitPluginViteAliases(options) {
|
|
182
|
+
const aliasEntries = [];
|
|
183
|
+
for (const { pluginId } of options.clientConfigs) {
|
|
184
|
+
const target = `./${PLUGIN_CONFIG_DIR_REL}/${slugifyPluginId(pluginId)}.ts`;
|
|
185
|
+
aliasEntries.push(` ${JSON.stringify(`virtual:dogsbay-plugin-config/${pluginId}`)}: new URL(${JSON.stringify(target)}, import.meta.url).pathname,`);
|
|
186
|
+
}
|
|
187
|
+
// Collect parent dirs of every clientModule + style file. Vite
|
|
188
|
+
// refuses to serve files outside the project root unless the
|
|
189
|
+
// path is on `server.fs.allow`. We add the immediate parent;
|
|
190
|
+
// Vite's allow check is recursive.
|
|
191
|
+
const fsAllowSet = new Set();
|
|
192
|
+
for (const { paths } of options.clientModules) {
|
|
193
|
+
for (const p of paths)
|
|
194
|
+
fsAllowSet.add(dirname(p));
|
|
195
|
+
}
|
|
196
|
+
for (const { paths } of options.styles) {
|
|
197
|
+
for (const p of paths)
|
|
198
|
+
fsAllowSet.add(dirname(p));
|
|
199
|
+
}
|
|
200
|
+
const contents = [
|
|
201
|
+
"// Auto-generated by dogsbay site build. Do not edit by hand.",
|
|
202
|
+
"// astro.config.mjs imports + spreads pluginAliases into",
|
|
203
|
+
"// vite.resolve.alias and pluginFsAllow into vite.server.fs.allow.",
|
|
204
|
+
"",
|
|
205
|
+
"export const pluginAliases = {",
|
|
206
|
+
...aliasEntries,
|
|
207
|
+
"};",
|
|
208
|
+
"",
|
|
209
|
+
"export const pluginFsAllow = [",
|
|
210
|
+
...Array.from(fsAllowSet).map((p) => ` ${JSON.stringify(p)},`),
|
|
211
|
+
"];",
|
|
212
|
+
"",
|
|
213
|
+
].join("\n");
|
|
214
|
+
writeFile(join(options.outputDir, PLUGIN_VITE_REL), contents);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* For each known slot, emit a `<Slot>Stack.astro` component that
|
|
218
|
+
* imports every contributing plugin's wrapper and recursively
|
|
219
|
+
* nests them. Plugin order maps to outer→inner — the first
|
|
220
|
+
* plugin's wrapper is the outermost.
|
|
221
|
+
*
|
|
222
|
+
* When no plugin contributes to a slot, the stack file is a
|
|
223
|
+
* passthrough (`<slot />`). Always emitting the file means
|
|
224
|
+
* per-page emission can unconditionally import and use the stack
|
|
225
|
+
* regardless of which plugins are loaded.
|
|
226
|
+
*/
|
|
227
|
+
function emitWrapperStacks(options) {
|
|
228
|
+
const wrappersDir = join(options.outputDir, PLUGIN_WRAPPERS_DIR_REL);
|
|
229
|
+
mkdirSync(wrappersDir, { recursive: true });
|
|
230
|
+
const groups = groupWrappersBySlot(options.componentWrappers ?? []);
|
|
231
|
+
for (const slot of KNOWN_SLOTS) {
|
|
232
|
+
const entries = groups.get(slot) ?? [];
|
|
233
|
+
const stackPath = join(wrappersDir, `${slot}Stack.astro`);
|
|
234
|
+
writeFile(stackPath, renderStack(slot, entries));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function groupWrappersBySlot(wrappers) {
|
|
238
|
+
const out = new Map();
|
|
239
|
+
for (const w of wrappers) {
|
|
240
|
+
const list = out.get(w.slot) ?? [];
|
|
241
|
+
list.push(w);
|
|
242
|
+
out.set(w.slot, list);
|
|
243
|
+
}
|
|
244
|
+
return out;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Render the source of `<Slot>Stack.astro`. Recursive nesting:
|
|
248
|
+
* first plugin → outermost,
|
|
249
|
+
* last plugin → innermost,
|
|
250
|
+
* final inner content → `<slot />`.
|
|
251
|
+
*/
|
|
252
|
+
function renderStack(slotName, entries) {
|
|
253
|
+
if (entries.length === 0) {
|
|
254
|
+
return [
|
|
255
|
+
`---`,
|
|
256
|
+
`// Auto-generated by dogsbay site build. No plugin contributed`,
|
|
257
|
+
`// a wrapper for the "${slotName}" slot — passthrough.`,
|
|
258
|
+
`---`,
|
|
259
|
+
``,
|
|
260
|
+
`<slot />`,
|
|
261
|
+
``,
|
|
262
|
+
].join("\n");
|
|
263
|
+
}
|
|
264
|
+
// Build import statements, one per entry. Identifiers must be
|
|
265
|
+
// unique across the file — qualify with plugin id + index.
|
|
266
|
+
const importLines = [];
|
|
267
|
+
const componentNames = [];
|
|
268
|
+
entries.forEach((entry, idx) => {
|
|
269
|
+
const ident = `Wrap_${idx}_${slugifyIdent(entry.pluginId)}`;
|
|
270
|
+
importLines.push(`import ${ident} from ${JSON.stringify(entry.path)};`);
|
|
271
|
+
componentNames.push(ident);
|
|
272
|
+
});
|
|
273
|
+
// Pretty-print the nested body for readability — one tag per
|
|
274
|
+
// line with two-space indent per level.
|
|
275
|
+
const formatted = formatNested(componentNames);
|
|
276
|
+
return [
|
|
277
|
+
`---`,
|
|
278
|
+
`// Auto-generated by dogsbay site build. Wrappers contributed by:`,
|
|
279
|
+
...entries.map((e, i) => `// ${i + 1}. ${e.pluginId} → ${e.path}`),
|
|
280
|
+
`// Order: outer → inner = first → last plugin.`,
|
|
281
|
+
importLines.join("\n"),
|
|
282
|
+
`---`,
|
|
283
|
+
``,
|
|
284
|
+
formatted,
|
|
285
|
+
``,
|
|
286
|
+
].join("\n");
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Render an indented tree of nested wrapper components for
|
|
290
|
+
* readability. Output:
|
|
291
|
+
* <A>
|
|
292
|
+
* <B>
|
|
293
|
+
* <slot />
|
|
294
|
+
* </B>
|
|
295
|
+
* </A>
|
|
296
|
+
*/
|
|
297
|
+
function formatNested(names) {
|
|
298
|
+
const lines = [];
|
|
299
|
+
names.forEach((name, idx) => {
|
|
300
|
+
const indent = " ".repeat(idx);
|
|
301
|
+
lines.push(`${indent}<${name}>`);
|
|
302
|
+
});
|
|
303
|
+
lines.push(`${" ".repeat(names.length)}<slot />`);
|
|
304
|
+
for (let i = names.length - 1; i >= 0; i--) {
|
|
305
|
+
const indent = " ".repeat(i);
|
|
306
|
+
lines.push(`${indent}</${names[i]}>`);
|
|
307
|
+
}
|
|
308
|
+
return lines.join("\n");
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Convert a plugin id into a JavaScript-safe identifier suffix.
|
|
312
|
+
* Used as a uniqueness qualifier on the imported component name.
|
|
313
|
+
*/
|
|
314
|
+
function slugifyIdent(id) {
|
|
315
|
+
return id.replace(/[^A-Za-z0-9_]/g, "_");
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Replace anything that's not safe in a filename / npm-package-
|
|
319
|
+
* subpath segment. Plugin ids look like `@dogsbay/plugin-image-zoom`
|
|
320
|
+
* or `@dogsbay/plugin-image-zoom#1`; slashes and `@` and `#` are
|
|
321
|
+
* the parts we need to flatten. The result is reversible enough
|
|
322
|
+
* for the user to figure out which file maps to which plugin.
|
|
323
|
+
*/
|
|
324
|
+
function slugifyPluginId(id) {
|
|
325
|
+
return id.replace(/^@/, "").replace(/\//g, "__").replace(/#/g, "_at_");
|
|
326
|
+
}
|
|
327
|
+
function writeFile(absPath, contents) {
|
|
328
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
329
|
+
writeFileSync(absPath, contents);
|
|
330
|
+
}
|
|
331
|
+
/** Test-only: clear emitted plugin runtime files. */
|
|
332
|
+
export function _clearPluginRuntime(outputDir) {
|
|
333
|
+
for (const rel of [PLUGIN_RUNTIME_REL, PLUGIN_VITE_REL]) {
|
|
334
|
+
rmSync(join(outputDir, rel), { force: true });
|
|
335
|
+
}
|
|
336
|
+
rmSync(join(outputDir, PLUGIN_CONFIG_DIR_REL), { recursive: true, force: true });
|
|
337
|
+
rmSync(join(outputDir, PLUGIN_STYLES_DIR_REL), { recursive: true, force: true });
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=plugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import type { ExportPage, NavItem } from "@dogsbay/types";
|
|
2
|
+
export interface AstroProjectOptions {
|
|
3
|
+
siteName?: string;
|
|
4
|
+
theme?: string;
|
|
5
|
+
local?: boolean;
|
|
6
|
+
repoUrl?: string;
|
|
7
|
+
editUri?: string;
|
|
8
|
+
copyright?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Brand keywords for the site. Emitted into `src/data/site.json`
|
|
11
|
+
* so the `seo/h1-brand-keyword` audit rule can read them.
|
|
12
|
+
*/
|
|
13
|
+
brandKeywords?: string[];
|
|
14
|
+
/** Source project directory (for copying extra_css, assets, etc.) */
|
|
15
|
+
sourceDir?: string;
|
|
16
|
+
/** Custom CSS files from mkdocs.yml extra_css */
|
|
17
|
+
extraCss?: string[];
|
|
18
|
+
/** Enable Astro image optimization (copies to src/assets/ instead of public/) */
|
|
19
|
+
imageOptimization?: boolean;
|
|
20
|
+
/** Controls CodeBlock title bar: true = always (default), "auto" = only with explicit title, false = never */
|
|
21
|
+
codeBlockTitle?: boolean | "auto";
|
|
22
|
+
/** Section name — pages go under docs/{section}/, nav gets a top-level entry */
|
|
23
|
+
section?: string;
|
|
24
|
+
/**
|
|
25
|
+
* URL path prefix where pages are served. Default `"/docs"`. Set to
|
|
26
|
+
* `""` to serve at the host root, `"/handbook"` (etc.) for any
|
|
27
|
+
* other prefix. Threaded through every emitter that builds URLs,
|
|
28
|
+
* file output paths, or rewrites links — so changing this lifts
|
|
29
|
+
* the entire site to the new prefix in one shot. See
|
|
30
|
+
* `normalizeBasePath` and plans/configurable-base-path.md.
|
|
31
|
+
*/
|
|
32
|
+
basePath?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Path prefix for tag term pages, used when emitting the page-level
|
|
35
|
+
* `<TagList>` chip strip. Default `/tags` — match the indexPath
|
|
36
|
+
* declared in `dogsbay.config.yml`'s `taxonomies.tags` block.
|
|
37
|
+
*/
|
|
38
|
+
tagsIndexPath?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Per-prefix display config for tag chips (label + palette color).
|
|
41
|
+
* Sourced from `taxonomies.tags.prefixes`. Emitted into
|
|
42
|
+
* `site.json` and forwarded to `<TagList>` so chips render with
|
|
43
|
+
* prefix-keyed colors and two-part labels. Absent → flat chips.
|
|
44
|
+
* See plans/tag-display-config.md.
|
|
45
|
+
*/
|
|
46
|
+
tagPrefixes?: import("@dogsbay/types").SiteConfig["tagPrefixes"];
|
|
47
|
+
/**
|
|
48
|
+
* Per-tag leaf-label overrides. Sourced from
|
|
49
|
+
* `taxonomies.tags.labels`. URLs continue to use slugs.
|
|
50
|
+
*/
|
|
51
|
+
tagLabels?: import("@dogsbay/types").SiteConfig["tagLabels"];
|
|
52
|
+
/**
|
|
53
|
+
* Map of taxonomy name → index path, sourced from declared
|
|
54
|
+
* `taxonomies` entries. Lets renderer components surface a link
|
|
55
|
+
* from built-in field badges (`TypeBadge`, `StatusBadge`) when
|
|
56
|
+
* the user has opted in to a browse destination.
|
|
57
|
+
*/
|
|
58
|
+
taxonomyIndexPaths?: import("@dogsbay/types").SiteConfig["taxonomyIndexPaths"];
|
|
59
|
+
/**
|
|
60
|
+
* Per-taxonomy display config (`prefixes` + `labels`), keyed by
|
|
61
|
+
* taxonomy name. Powers the search-facet UI; mirrors the same
|
|
62
|
+
* data the chip components consume but in a per-taxonomy shape.
|
|
63
|
+
* See plans/search-facets.md.
|
|
64
|
+
*/
|
|
65
|
+
taxonomyDisplay?: import("@dogsbay/types").SiteConfig["taxonomyDisplay"];
|
|
66
|
+
/** Canonical site URL — required for sitemap.xml + canonical tags */
|
|
67
|
+
siteUrl?: string;
|
|
68
|
+
/** Site-wide description used as default <meta name="description"> */
|
|
69
|
+
description?: string;
|
|
70
|
+
/** Default OG image URL (1200×630 PNG/JPG) */
|
|
71
|
+
ogImage?: string;
|
|
72
|
+
/** Twitter / X handle including "@" */
|
|
73
|
+
twitterHandle?: string;
|
|
74
|
+
/** Theme color hint for browsers (hex) */
|
|
75
|
+
themeColor?: string;
|
|
76
|
+
/** Plausible domain — when set, docs-layout emits the tracker script */
|
|
77
|
+
plausibleDomain?: string;
|
|
78
|
+
/** Optional Plausible script URL override (for self-hosted) */
|
|
79
|
+
plausibleScriptUrl?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Declared versions for the version axis. When present and ≥2,
|
|
82
|
+
* `emitSwitcherMap` emits `src/data/switcherMap.json` with per-
|
|
83
|
+
* page version equivalents and a header with this list (so the
|
|
84
|
+
* VersionSwitcher component can render labels + EOL marks even
|
|
85
|
+
* when a page is missing an equivalent in some version).
|
|
86
|
+
*
|
|
87
|
+
* See plans/multi-source-content.md and
|
|
88
|
+
* docs-dev/multi-source-architecture.md.
|
|
89
|
+
*/
|
|
90
|
+
versions?: Array<{
|
|
91
|
+
id: string;
|
|
92
|
+
label?: string;
|
|
93
|
+
eol?: boolean;
|
|
94
|
+
}>;
|
|
95
|
+
/**
|
|
96
|
+
* Which version is the default. Marked in switcherMap.json so
|
|
97
|
+
* the switcher can highlight it; PR 4c wires the default-
|
|
98
|
+
* version redirect that uses this same field.
|
|
99
|
+
*/
|
|
100
|
+
defaultVersion?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Declared locales for the i18n axis. Same role as
|
|
103
|
+
* `versions` for the locale axis.
|
|
104
|
+
*/
|
|
105
|
+
locales?: Array<{
|
|
106
|
+
id: string;
|
|
107
|
+
label?: string;
|
|
108
|
+
}>;
|
|
109
|
+
/**
|
|
110
|
+
* Which locale is the default. Used for the default-locale
|
|
111
|
+
* redirect AND the missing-translation fallback.
|
|
112
|
+
*/
|
|
113
|
+
defaultLocale?: string;
|
|
114
|
+
/**
|
|
115
|
+
* When set, emit a deploy config file + dev dep + script for the
|
|
116
|
+
* named platform. Only "cloudflare-workers" supported today.
|
|
117
|
+
* Other adapters (netlify, vercel, gh-pages) follow the same shape;
|
|
118
|
+
* left unimplemented per Phase 1 scope.
|
|
119
|
+
*/
|
|
120
|
+
deploy?: "cloudflare-workers";
|
|
121
|
+
/**
|
|
122
|
+
* Overwrite all files including maintainer-customizable scaffold
|
|
123
|
+
* files (theme.css, astro.config.mjs, package.json, site.json,
|
|
124
|
+
* tsconfig.json, wrangler.jsonc, ui component copies). Default
|
|
125
|
+
* behaviour: scaffold those files only on first run; on subsequent
|
|
126
|
+
* runs leave them alone and regenerate ONLY the auto-managed files
|
|
127
|
+
* (`src/pages/docs/**`, `src/data/nav.json`, `public/robots.txt`).
|
|
128
|
+
*
|
|
129
|
+
* Use this when intentionally re-scaffolding (theme upgrade, deploy
|
|
130
|
+
* target switch, etc.) and you've reviewed the diff.
|
|
131
|
+
*/
|
|
132
|
+
force?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Emit `public/llms.txt`, `public/llms-full.txt`, and per-section
|
|
135
|
+
* `public/<dir>/llms.txt` files for LLM discovery. Default `true`.
|
|
136
|
+
* Disable when the host enforces a different content policy or when
|
|
137
|
+
* the site is private / not for agent consumption.
|
|
138
|
+
*/
|
|
139
|
+
llmsTxt?: boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Emit a companion `<page>.md.ts` Astro endpoint for every generated
|
|
142
|
+
* page so agents can fetch raw Dogsbay-MD at `<page>.md`. Prerendered
|
|
143
|
+
* to static `.md` files in `dist/`. Default `true`.
|
|
144
|
+
*/
|
|
145
|
+
mdMirror?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* `Content-Signal` directive for the AI training corpus permission
|
|
148
|
+
* emitted in robots.txt. Default `"no"` — opt out of training by
|
|
149
|
+
* default; writers explicitly opt in by passing `"yes"`.
|
|
150
|
+
*/
|
|
151
|
+
aiTrain?: "yes" | "no";
|
|
152
|
+
/**
|
|
153
|
+
* `Content-Signal` directive for AI inference / agent read-time
|
|
154
|
+
* access emitted in robots.txt. Default `"yes"` — agents reading
|
|
155
|
+
* docs at user-request time is the whole point of agent-readiness.
|
|
156
|
+
*/
|
|
157
|
+
aiInput?: "yes" | "no";
|
|
158
|
+
/**
|
|
159
|
+
* `Content-Signal` directive for inclusion in agent and human
|
|
160
|
+
* search results emitted in robots.txt. Default `"yes"`.
|
|
161
|
+
*/
|
|
162
|
+
aiSearch?: "yes" | "no";
|
|
163
|
+
/**
|
|
164
|
+
* Per-page LLM action UI ("Copy as markdown", "Open in Claude/
|
|
165
|
+
* ChatGPT/Perplexity/Gemini"). When omitted, the cluster is not
|
|
166
|
+
* rendered. Independent of `mdMirror` / `llmsTxt` — those drive
|
|
167
|
+
* the data layer, this drives the human UI on top.
|
|
168
|
+
* See plans/llm-page-actions.md.
|
|
169
|
+
*/
|
|
170
|
+
llmActions?: import("@dogsbay/types").SiteConfig["llmActions"];
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Export pages + nav to a complete Astro project directory.
|
|
174
|
+
*
|
|
175
|
+
* Thin orchestrator. The heavy lifting lives in four focused emitters
|
|
176
|
+
* (one per emission tier) that this function calls in sequence:
|
|
177
|
+
*
|
|
178
|
+
* 1. emitSiteScaffold — Tier 2 (scaffold-once): package.json,
|
|
179
|
+
* theme, astro.config.mjs, components, etc.
|
|
180
|
+
* 2. emitAstroPages — Tier 1 (content): nav.json, .astro pages,
|
|
181
|
+
* .md mirror endpoints (when enabled)
|
|
182
|
+
* 3. emitConfigDerivedFiles — Tier 1 (config-derived): robots.txt
|
|
183
|
+
* 4. emitAgentReadinessFiles — Tier 1 (agent-tier): llms.txt, _headers,
|
|
184
|
+
* middleware.ts (when enabled)
|
|
185
|
+
*
|
|
186
|
+
* Each emitter is also callable directly — site init / site build (in
|
|
187
|
+
* progress) call only the subset they need.
|
|
188
|
+
*/
|
|
189
|
+
export declare function exportAstroProject(pages: ExportPage[], nav: NavItem[], outputDir: string, options?: AstroProjectOptions): Promise<void>;
|
|
190
|
+
/**
|
|
191
|
+
* Emit the project scaffold: package.json, astro.config.mjs, tsconfig,
|
|
192
|
+
* theme/global CSS, site.json, copied UI components, deploy config.
|
|
193
|
+
*
|
|
194
|
+
* @returns the count of files skipped because the project is already
|
|
195
|
+
* scaffolded (used by the orchestrator's "preserved N files" log).
|
|
196
|
+
*/
|
|
197
|
+
/**
|
|
198
|
+
* Emit `src/data/site.json` from the resolved options. Pure
|
|
199
|
+
* config-derived (Tier 1) — overwrites unconditionally so config
|
|
200
|
+
* edits in `dogsbay.config.yml` propagate to the rendered site on
|
|
201
|
+
* every `dogsbay site build` without needing `--force`.
|
|
202
|
+
*
|
|
203
|
+
* Standalone helper so `site build` can refresh it without going
|
|
204
|
+
* through the full scaffold path. `emitSiteScaffold` also calls it.
|
|
205
|
+
*/
|
|
206
|
+
export declare function emitSiteConfig(outputDir: string, siteName: string, options: AstroProjectOptions): void;
|
|
207
|
+
export declare function emitSiteScaffold(outputDir: string, siteName: string, options: AstroProjectOptions, writeScaffold: boolean): number;
|
|
208
|
+
/**
|
|
209
|
+
* Emit content-tier files: nav.json, every page's .astro, the per-page
|
|
210
|
+
* .md mirror endpoint (when `mdMirror` is enabled), and the index
|
|
211
|
+
* redirect. Returns the count of pages emitted and the merged nav for
|
|
212
|
+
* downstream consumers (llms.txt builder).
|
|
213
|
+
*/
|
|
214
|
+
export declare function emitAstroPages(pages: ExportPage[], nav: NavItem[], outputDir: string, options: AstroProjectOptions): Promise<{
|
|
215
|
+
generated: number;
|
|
216
|
+
outputNav: NavItem[];
|
|
217
|
+
}>;
|
|
218
|
+
/**
|
|
219
|
+
* Emit `public/robots.txt` with `Content-Signal` directives + sitemap
|
|
220
|
+
* link. Always overwrites — the file's contents are pure derivation
|
|
221
|
+
* from `options`. Maintainers wanting custom Disallow rules layer
|
|
222
|
+
* them at the CDN level.
|
|
223
|
+
*/
|
|
224
|
+
export declare function emitConfigDerivedFiles(outputDir: string, options: AstroProjectOptions): void;
|
|
225
|
+
/**
|
|
226
|
+
* Shape of the emitted `src/data/switcherMap.json` file.
|
|
227
|
+
* Switcher components import this JSON directly, so the shape
|
|
228
|
+
* is also the runtime contract.
|
|
229
|
+
*
|
|
230
|
+
* Each `byLogicalKey` value is a FLAT LIST of variants — every
|
|
231
|
+
* (locale, version) combo where this logical page exists, with
|
|
232
|
+
* its full URL. Switcher components filter the list to find
|
|
233
|
+
* relevant alternates:
|
|
234
|
+
*
|
|
235
|
+
* - VersionSwitcher filters where `locale === currentLocale`
|
|
236
|
+
* (so the dropdown only crosses the version axis).
|
|
237
|
+
* - LocaleSwitcher filters where `version === currentVersion`.
|
|
238
|
+
*
|
|
239
|
+
* For axes that aren't active site-wide, the field is undefined
|
|
240
|
+
* on every variant; switchers for that axis simply render
|
|
241
|
+
* nothing.
|
|
242
|
+
*/
|
|
243
|
+
export interface SwitcherMap {
|
|
244
|
+
/**
|
|
245
|
+
* Declared versions in declaration order. The component uses
|
|
246
|
+
* this to render the dropdown in canonical order even when
|
|
247
|
+
* some entries are missing from a given page's variants list
|
|
248
|
+
* (those entries render as greyed-out / "no equivalent").
|
|
249
|
+
*/
|
|
250
|
+
versions: Array<{
|
|
251
|
+
id: string;
|
|
252
|
+
label?: string;
|
|
253
|
+
eol?: boolean;
|
|
254
|
+
default?: boolean;
|
|
255
|
+
}>;
|
|
256
|
+
/**
|
|
257
|
+
* Declared locales in declaration order. Same role as
|
|
258
|
+
* `versions` but for the i18n axis.
|
|
259
|
+
*/
|
|
260
|
+
locales: Array<{
|
|
261
|
+
id: string;
|
|
262
|
+
label?: string;
|
|
263
|
+
default?: boolean;
|
|
264
|
+
}>;
|
|
265
|
+
/**
|
|
266
|
+
* Per-logical-key list of variants. Logical key is
|
|
267
|
+
* `<namespace>/<originalSlug>` (namespace defaults to "docs"
|
|
268
|
+
* when the namespace axis is inactive). Each variant carries
|
|
269
|
+
* the full URL plus the (locale, version) combo it represents.
|
|
270
|
+
*/
|
|
271
|
+
byLogicalKey: Record<string, SwitcherVariant[]>;
|
|
272
|
+
}
|
|
273
|
+
export interface SwitcherVariant {
|
|
274
|
+
/** Present when the locale axis is active for this site. */
|
|
275
|
+
locale?: string;
|
|
276
|
+
/** Present when the version axis is active for this site. */
|
|
277
|
+
version?: string;
|
|
278
|
+
/** Full URL (with basePath) for this variant. */
|
|
279
|
+
url: string;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Emit `src/data/switcherMap.json` describing per-page
|
|
283
|
+
* version + locale equivalents. Always writes the file —
|
|
284
|
+
* even when no axis is active — with empty `versions: []`,
|
|
285
|
+
* `locales: []`, `byLogicalKey: {}`. Keeps the per-page
|
|
286
|
+
* static import working in every site, with switchers
|
|
287
|
+
* rendering nothing when their axis has < 2 declared entries.
|
|
288
|
+
*
|
|
289
|
+
* Pages without `multiSource` metadata are skipped — they
|
|
290
|
+
* aren't part of any axis, so they don't appear in any
|
|
291
|
+
* switcher. Pages with multiSource (any axis active) DO
|
|
292
|
+
* appear, even when this particular page sits in the
|
|
293
|
+
* default-bucket of the relevant axis (e.g. an unversioned
|
|
294
|
+
* baseline page in a multi-version site).
|
|
295
|
+
*/
|
|
296
|
+
export declare function emitSwitcherMap(pages: ExportPage[], outputDir: string, options: AstroProjectOptions): void;
|
|
297
|
+
/**
|
|
298
|
+
* Emit redirect stub pages for missing translations. For each
|
|
299
|
+
* page that exists in the default locale, ensure there's a
|
|
300
|
+
* corresponding URL for every other declared locale: if no
|
|
301
|
+
* page already exists at that URL, write a stub Astro page
|
|
302
|
+
* that 302-redirects to the default-locale equivalent.
|
|
303
|
+
*
|
|
304
|
+
* Stubs aren't emitted FROM other-locale TO default-locale —
|
|
305
|
+
* only the other way. The default locale is the canonical
|
|
306
|
+
* baseline; if a writer authored content only in (say) `fr`,
|
|
307
|
+
* we don't manufacture an `en` URL with a fake redirect.
|
|
308
|
+
*/
|
|
309
|
+
export declare function emitMissingTranslationStubs(pages: ExportPage[], outputDir: string, options: AstroProjectOptions): void;
|
|
310
|
+
/**
|
|
311
|
+
* Emit agent-readiness files: `public/llms.txt` + `llms-full.txt` +
|
|
312
|
+
* per-section indexes when `llmsTxt` is enabled; `public/_headers`
|
|
313
|
+
* (Cloudflare Link header) alongside; and `src/middleware.ts` when
|
|
314
|
+
* `mdMirror` is enabled.
|
|
315
|
+
*
|
|
316
|
+
* `.md` mirror endpoints themselves are emitted per-page inside
|
|
317
|
+
* `emitAstroPages` (they share the page-loop's serialization step).
|
|
318
|
+
*/
|
|
319
|
+
export declare function emitAgentReadinessFiles(pages: ExportPage[], outputNav: NavItem[], outputDir: string, siteName: string, options: AstroProjectOptions): void;
|
|
320
|
+
//# sourceMappingURL=project.d.ts.map
|