dogsbay 0.2.0-beta.112 → 0.2.0-beta.113

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.
@@ -514,6 +514,8 @@ export async function siteBuild(cwd, options) {
514
514
  out: t.out,
515
515
  siteName: config.site.name,
516
516
  siteUrl: config.site.url,
517
+ copyright: config.site.copyright,
518
+ poweredBy: config.poweredBy,
517
519
  stripPrefix: combinedPrefix,
518
520
  sourceDir: resolvedSources[0],
519
521
  assetMounts: importResult.assetMounts,
@@ -575,7 +577,9 @@ export async function siteBuild(cwd, options) {
575
577
  const { copied } = emitPassthroughAstroPages(passthroughCopies, outputDir, generatedPaths);
576
578
  console.log(` Copied ${copied} passthrough .astro page${copied === 1 ? "" : "s"}`);
577
579
  }
578
- emitConfigDerivedFiles(outputDir, astroOpts);
580
+ // Pages are needed for the redirect rules: the dangling-target and
581
+ // live-page-at-the-source checks are only possible against the emitted set.
582
+ emitConfigDerivedFiles(outputDir, astroOpts, pages);
579
583
  // Deploy artifacts — write-if-missing so adding `deploy: github-pages`
580
584
  // to dogsbay.config.yml on an existing site materializes the workflow
581
585
  // on the next build. Author edits survive (only fired when the file
@@ -1096,6 +1100,8 @@ async function runSecondaryExport(pages, nav, opts) {
1096
1100
  await exporter.export(pages, exportNav, out, {
1097
1101
  siteName: opts.siteName,
1098
1102
  siteUrl: opts.siteUrl,
1103
+ copyright: opts.copyright,
1104
+ poweredBy: opts.poweredBy,
1099
1105
  sourceDir: opts.sourceDir,
1100
1106
  assetMounts: opts.assetMounts,
1101
1107
  plugin: opts.plugin,
@@ -168,6 +168,8 @@ function validate(parsed, sourcePath) {
168
168
  content,
169
169
  output: obj.output,
170
170
  outputs: parseOutputs(obj.outputs, sourcePath),
171
+ redirects: parseRedirects(obj.redirects, sourcePath),
172
+ poweredBy: obj.poweredBy,
171
173
  deploy: obj.deploy,
172
174
  analytics: obj.analytics,
173
175
  agent,
@@ -1116,3 +1118,35 @@ function parseOutputs(raw, sourcePath) {
1116
1118
  return { format: e.format, path: e.path };
1117
1119
  });
1118
1120
  }
1121
+ /**
1122
+ * `redirects:` — a map of source path → target. Shape only; the rules
1123
+ * themselves (loops, chains, dangling targets, platform limits) are validated
1124
+ * by `format-astro` at emit time, where the page set is known.
1125
+ */
1126
+ function parseRedirects(raw, sourcePath) {
1127
+ if (raw === undefined)
1128
+ return undefined;
1129
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
1130
+ throw new Error(`redirects must be a map of "/from/": "/to/" in ${sourcePath}`);
1131
+ }
1132
+ const out = {};
1133
+ for (const [from, value] of Object.entries(raw)) {
1134
+ if (typeof value === "string") {
1135
+ out[from] = value;
1136
+ continue;
1137
+ }
1138
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
1139
+ const v = value;
1140
+ if (typeof v.to !== "string") {
1141
+ throw new Error(`redirects["${from}"] needs a string \`to\` in ${sourcePath}`);
1142
+ }
1143
+ if (v.status !== undefined && typeof v.status !== "number") {
1144
+ throw new Error(`redirects["${from}"].status must be a number in ${sourcePath}`);
1145
+ }
1146
+ out[from] = { to: v.to, ...(v.status !== undefined ? { status: v.status } : {}) };
1147
+ continue;
1148
+ }
1149
+ throw new Error(`redirects["${from}"] must be a path string or { to, status } in ${sourcePath}`);
1150
+ }
1151
+ return out;
1152
+ }
@@ -124,6 +124,22 @@ export interface DogsbayConfig {
124
124
  * See plans/cli-grammar.md.
125
125
  */
126
126
  outputs?: OutputTarget[];
127
+ /**
128
+ * Redirects for paths with no surviving page — bulk moves, retired
129
+ * sections, external targets. `"/old/": "/new/"` is shorthand for a 301.
130
+ * A page that still exists should declare `aliases:` in its own
131
+ * frontmatter instead, so the knowledge is deleted with the page.
132
+ * See plans/redirects-and-aliases.md.
133
+ */
134
+ redirects?: Record<string, string | {
135
+ to: string;
136
+ status?: number;
137
+ }>;
138
+ /**
139
+ * "Powered by DogsBay" footer attribution on generated sites. Default true.
140
+ * Set `poweredBy: false` to remove it. See docs/powered-by.md.
141
+ */
142
+ poweredBy?: boolean;
127
143
  deploy?: DeployConfig;
128
144
  /**
129
145
  * Build / asset behaviour. Knobs that affect how the site
@@ -27,6 +27,8 @@ export function configToAstroOptions(config) {
27
27
  plausibleDomain: config.analytics?.plausible?.domain,
28
28
  plausibleScriptUrl: config.analytics?.plausible?.scriptUrl,
29
29
  deploy: config.deploy?.target,
30
+ redirects: config.redirects,
31
+ poweredBy: config.poweredBy,
30
32
  inlineStylesheets: config.build?.inlineStylesheets,
31
33
  navMode: config.build?.navMode,
32
34
  llmsTxt: config.agent?.llmsTxt,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dogsbay",
3
- "version": "0.2.0-beta.112",
3
+ "version": "0.2.0-beta.113",
4
4
  "description": "CLI for Dogsbay — scaffold, build, and serve documentation sites with markdown / MkDocs / Obsidian / OpenAPI sources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,32 +42,32 @@
42
42
  "typescript": "^5.9.3",
43
43
  "valibot": "1.1.0",
44
44
  "yaml": "^2.9.0",
45
- "@dogsbay/adoc2md-modular": "0.2.0-beta.112",
46
- "@dogsbay/autodoc-python": "0.2.0-beta.112",
47
- "@dogsbay/format-asciidoc": "0.2.0-beta.112",
48
- "@dogsbay/format-astro": "0.2.0-beta.112",
49
- "@dogsbay/format-dita": "0.2.0-beta.112",
50
- "@dogsbay/commands": "0.2.0-beta.112",
51
- "@dogsbay/format-docusaurus": "0.2.0-beta.112",
52
- "@dogsbay/format-dogsbay-md": "0.2.0-beta.112",
53
- "@dogsbay/format-fluidtopics-markdown": "0.2.0-beta.112",
54
- "@dogsbay/format-gatsby": "0.2.0-beta.112",
55
- "@dogsbay/format-gitbook": "0.2.0-beta.112",
56
- "@dogsbay/format-hugo": "0.2.0-beta.112",
57
- "@dogsbay/format-fluidtopics-rest": "0.2.0-beta.112",
58
- "@dogsbay/format-mdx": "0.2.0-beta.112",
59
- "@dogsbay/format-mkdocs": "0.2.0-beta.112",
60
- "@dogsbay/format-myst": "0.2.0-beta.112",
61
- "@dogsbay/format-obsidian": "0.2.0-beta.112",
62
- "@dogsbay/format-openapi": "0.2.0-beta.112",
63
- "@dogsbay/format-rst": "0.2.0-beta.112",
64
- "@dogsbay/format-starlight": "0.2.0-beta.112",
65
- "@dogsbay/format-openknowledge": "0.2.0-beta.112",
66
- "@dogsbay/format-topicmap": "0.2.0-beta.112",
67
- "@dogsbay/minja": "0.2.0-beta.112",
68
- "@dogsbay/format-vitepress": "0.2.0-beta.112",
69
- "@dogsbay/serialize-core": "0.2.0-beta.112",
70
- "@dogsbay/types": "0.2.0-beta.112"
45
+ "@dogsbay/adoc2md-modular": "0.2.0-beta.113",
46
+ "@dogsbay/autodoc-python": "0.2.0-beta.113",
47
+ "@dogsbay/commands": "0.2.0-beta.113",
48
+ "@dogsbay/format-asciidoc": "0.2.0-beta.113",
49
+ "@dogsbay/format-astro": "0.2.0-beta.113",
50
+ "@dogsbay/format-dita": "0.2.0-beta.113",
51
+ "@dogsbay/format-docusaurus": "0.2.0-beta.113",
52
+ "@dogsbay/format-dogsbay-md": "0.2.0-beta.113",
53
+ "@dogsbay/format-fluidtopics-markdown": "0.2.0-beta.113",
54
+ "@dogsbay/format-fluidtopics-rest": "0.2.0-beta.113",
55
+ "@dogsbay/format-gatsby": "0.2.0-beta.113",
56
+ "@dogsbay/format-gitbook": "0.2.0-beta.113",
57
+ "@dogsbay/format-hugo": "0.2.0-beta.113",
58
+ "@dogsbay/format-mdx": "0.2.0-beta.113",
59
+ "@dogsbay/format-mkdocs": "0.2.0-beta.113",
60
+ "@dogsbay/format-myst": "0.2.0-beta.113",
61
+ "@dogsbay/format-obsidian": "0.2.0-beta.113",
62
+ "@dogsbay/format-openapi": "0.2.0-beta.113",
63
+ "@dogsbay/format-openknowledge": "0.2.0-beta.113",
64
+ "@dogsbay/format-rst": "0.2.0-beta.113",
65
+ "@dogsbay/format-starlight": "0.2.0-beta.113",
66
+ "@dogsbay/format-topicmap": "0.2.0-beta.113",
67
+ "@dogsbay/format-vitepress": "0.2.0-beta.113",
68
+ "@dogsbay/minja": "0.2.0-beta.113",
69
+ "@dogsbay/serialize-core": "0.2.0-beta.113",
70
+ "@dogsbay/types": "0.2.0-beta.113"
71
71
  },
72
72
  "devDependencies": {
73
73
  "@types/markdown-it": "^14.1.2",