@dogsbay/format-astro 0.2.0-beta.10 → 0.2.0-beta.100

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.
Files changed (50) hide show
  1. package/dist/base-path.d.ts +93 -7
  2. package/dist/base-path.d.ts.map +1 -1
  3. package/dist/base-path.js +122 -8
  4. package/dist/base-path.js.map +1 -1
  5. package/dist/blog.d.ts +134 -0
  6. package/dist/blog.d.ts.map +1 -0
  7. package/dist/blog.js +319 -0
  8. package/dist/blog.js.map +1 -0
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +1 -0
  11. package/dist/cli.js.map +1 -1
  12. package/dist/diff-decoration.d.ts +79 -0
  13. package/dist/diff-decoration.d.ts.map +1 -0
  14. package/dist/diff-decoration.js +541 -0
  15. package/dist/diff-decoration.js.map +1 -0
  16. package/dist/granularity.d.ts +83 -0
  17. package/dist/granularity.d.ts.map +1 -0
  18. package/dist/granularity.js +247 -0
  19. package/dist/granularity.js.map +1 -0
  20. package/dist/index.d.ts +22 -4
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +26 -3
  23. package/dist/index.js.map +1 -1
  24. package/dist/lead.d.ts +19 -0
  25. package/dist/lead.d.ts.map +1 -1
  26. package/dist/lead.js +101 -6
  27. package/dist/lead.js.map +1 -1
  28. package/dist/llms-txt.d.ts +48 -2
  29. package/dist/llms-txt.d.ts.map +1 -1
  30. package/dist/llms-txt.js +131 -14
  31. package/dist/llms-txt.js.map +1 -1
  32. package/dist/plugins.js +1 -1
  33. package/dist/plugins.js.map +1 -1
  34. package/dist/project.d.ts +310 -13
  35. package/dist/project.d.ts.map +1 -1
  36. package/dist/project.js +2227 -207
  37. package/dist/project.js.map +1 -1
  38. package/dist/serialize.d.ts +23 -0
  39. package/dist/serialize.d.ts.map +1 -1
  40. package/dist/serialize.js +442 -136
  41. package/dist/serialize.js.map +1 -1
  42. package/dist/sitemap.d.ts +81 -0
  43. package/dist/sitemap.d.ts.map +1 -0
  44. package/dist/sitemap.js +200 -0
  45. package/dist/sitemap.js.map +1 -0
  46. package/dist/taxonomy.d.ts +48 -1
  47. package/dist/taxonomy.d.ts.map +1 -1
  48. package/dist/taxonomy.js +61 -23
  49. package/dist/taxonomy.js.map +1 -1
  50. package/package.json +8 -7
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * Single source of truth for the `basePath` URL prefix.
3
3
  *
4
- * `basePath` is the path-under-host where docs are served. By default
5
- * it's `/docs` (every existing dogsbay site uses this); set
6
- * `site.basePath: ""` in `dogsbay.config.yml` to serve at the host
7
- * root, or `"/handbook"` (etc.) for any other prefix.
4
+ * `basePath` is the path-under-host where docs are served. The default
5
+ * is `""` (host root, matching every other SSG); set
6
+ * `site.basePath: "/docs"` in `dogsbay.config.yml` for the legacy
7
+ * "docs nested under marketing site" shape, or `"/handbook"` (etc.)
8
+ * for any other prefix. See plans/default-basepath-root.md for the
9
+ * rationale behind the default flip in v0.3.
8
10
  *
9
11
  * Every emitter that builds URLs, file paths, or rewrites links
10
12
  * reads from `AstroProjectOptions.basePath` and runs it through
@@ -22,8 +24,18 @@
22
24
  *
23
25
  * See plans/configurable-base-path.md.
24
26
  */
25
- /** Default `basePath` when no override is supplied. */
26
- export declare const DEFAULT_BASE_PATH = "/docs";
27
+ /**
28
+ * Default `basePath` when no override is supplied.
29
+ *
30
+ * Changed in v0.3 from `"/docs"` to `""` (host root) so the default
31
+ * matches the plurality of doc-site deployments (GH Pages project
32
+ * sites, `docs.acme.com` subdomains, standalone wikis) and aligns
33
+ * with peer SSGs (Astro, Next, MkDocs, Docusaurus). The `cli`'s
34
+ * `site build` emits a one-shot migration warning when this default
35
+ * is hit so users from the `/docs` era can opt in to either value
36
+ * explicitly. See plans/default-basepath-root.md.
37
+ */
38
+ export declare const DEFAULT_BASE_PATH = "";
27
39
  /**
28
40
  * Normalize a user-supplied `basePath` to canonical form.
29
41
  *
@@ -33,7 +45,7 @@ export declare const DEFAULT_BASE_PATH = "/docs";
33
45
  * non-empty prefix.
34
46
  *
35
47
  * Examples:
36
- * - `undefined` → `"/docs"` (default)
48
+ * - `undefined` → `""` (default in v0.3+; was `"/docs"` previously)
37
49
  * - `""` → `""`
38
50
  * - `"/"` → `""`
39
51
  * - `"docs"` → `"/docs"`
@@ -90,6 +102,70 @@ export declare function joinBaseUrl(basePath: string, section: string | undefine
90
102
  * site with `site.basePath` set.
91
103
  */
92
104
  export declare function withBasePath(basePath: string, indexPath: string): string;
105
+ /**
106
+ * Parse `site.url` into its origin and path-component parts. The
107
+ * path component (if any) becomes the **urlBase** — the prefix the
108
+ * host serves dist/ at, distinct from `basePath` (which is the
109
+ * filesystem position of content within that served space).
110
+ *
111
+ * Used by emitters that need to (a) emit Astro's `base` config
112
+ * (= urlBase), (b) produce absolute URLs in sitemap / canonical /
113
+ * llms.txt (= origin + combined prefix + slug), or (c) build the
114
+ * combined prefix that internal hrefs need (`combinePrefix` below).
115
+ *
116
+ * Returns `origin` undefined when `siteUrl` is missing or unparseable
117
+ * — the caller then degrades to relative URLs (existing behavior).
118
+ *
119
+ * - `undefined` → `{ origin: undefined, urlBase: "" }`
120
+ * - `"https://example.com"` → `{ origin: "https://example.com", urlBase: "" }`
121
+ * - `"https://example.com/"` → `{ origin: "https://example.com", urlBase: "" }`
122
+ * - `"https://example.com/docs"` → `{ origin: "https://example.com", urlBase: "/docs" }`
123
+ * - `"https://example.com/docs/"` → `{ origin: "https://example.com", urlBase: "/docs" }`
124
+ * - `"https://user.github.io/dogsbay-docs"` → `{ origin: "https://user.github.io", urlBase: "/dogsbay-docs" }`
125
+ * - `"/relative-path"` → `{ origin: undefined, urlBase: "" }` (not a full URL)
126
+ *
127
+ * See plans/astro-base-from-site-url.md.
128
+ */
129
+ export declare function parseSiteUrl(siteUrl: string | undefined): {
130
+ origin: string | undefined;
131
+ urlBase: string;
132
+ };
133
+ /**
134
+ * Combine a urlBase (host subpath, from `site.url`) with a
135
+ * basePath (filesystem layout prefix, from `site.basePath`) into the
136
+ * single prefix that nav hrefs, sitemap URLs, llms.txt, and the
137
+ * link rewriter all need.
138
+ *
139
+ * Both inputs MUST already be normalized (output of `normalizeBasePath`
140
+ * or `parseSiteUrl`): empty string OR a single leading slash with no
141
+ * trailing slash. The output respects the same shape.
142
+ *
143
+ * - `combinePrefix("", "")` → `""`
144
+ * - `combinePrefix("", "/docs")` → `"/docs"`
145
+ * - `combinePrefix("/repo", "")` → `"/repo"`
146
+ * - `combinePrefix("/repo", "/docs")` → `"/repo/docs"`
147
+ * - `combinePrefix("/handbook", "/team-docs")` → `"/handbook/team-docs"`
148
+ *
149
+ * See plans/astro-base-from-site-url.md.
150
+ */
151
+ export declare function combinePrefix(urlBase: string, basePath: string): string;
152
+ /**
153
+ * One-shot resolver: given the user's `site.url` + `site.basePath`,
154
+ * return everything emitters need. Convenience wrapper around
155
+ * `parseSiteUrl` + `normalizeBasePath` + `combinePrefix` so callers
156
+ * only do the math once.
157
+ *
158
+ * Used at the boundary in cli/site-build and cli/site-init to compute
159
+ * the effective prefixes before threading them into the emit tier.
160
+ *
161
+ * See plans/astro-base-from-site-url.md.
162
+ */
163
+ export declare function resolvePrefixes(siteUrl: string | undefined, basePath: string | undefined): {
164
+ origin: string | undefined;
165
+ urlBase: string;
166
+ basePath: string;
167
+ combined: string;
168
+ };
93
169
  /**
94
170
  * Build the `currentPath` value embedded in generated `.astro` pages
95
171
  * for `getPagination` lookups. No trailing slash so it matches the
@@ -100,6 +176,16 @@ export declare function withBasePath(basePath: string, indexPath: string): strin
100
176
  * - default basePath, empty slug → `"/docs"`
101
177
  * - empty basePath, slug "auth" → `"/auth"`
102
178
  * - empty basePath, empty slug → `"/"`
179
+ * - empty basePath, slug "index" → `"/"` (root home)
180
+ *
181
+ * A bare `index` slug means the directory root: `content/index.md` is
182
+ * deliberately loaded with slug `"index"` (so the root-home and `.md`-mirror
183
+ * special cases fire — see plans/dir-index-slug-nav-drop.md), but the page is
184
+ * served at the directory URL and its nav href drops `index` (via
185
+ * `fileToHref`'s `/index` strip). `currentPath` must match that nav href for
186
+ * `getPagination` to find the home page, so we drop a whole-slug `index` here
187
+ * too. Without this the home page's `currentPath` (`/base/index`) never matches
188
+ * its nav entry (`/base`), so prev/next silently falls back to the first item.
103
189
  */
104
190
  export declare function buildCurrentPath(basePath: string, section: string | undefined, slug: string): string;
105
191
  //# sourceMappingURL=base-path.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-path.d.ts","sourceRoot":"","sources":["../src/base-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKnE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAE3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,EAAE,MAAM,GACX,MAAM,CAMR;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGxE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,EAAE,MAAM,GACX,MAAM,CAMR"}
1
+ {"version":3,"file":"base-path.d.ts","sourceRoot":"","sources":["../src/base-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKnE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAE3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,EAAE,MAAM,GACX,MAAM,CAMR;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGxE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG;IACzD,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,CAiBA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMvE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B;IACD,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CASA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,EAAE,MAAM,GACX,MAAM,CAMR"}
package/dist/base-path.js CHANGED
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * Single source of truth for the `basePath` URL prefix.
3
3
  *
4
- * `basePath` is the path-under-host where docs are served. By default
5
- * it's `/docs` (every existing dogsbay site uses this); set
6
- * `site.basePath: ""` in `dogsbay.config.yml` to serve at the host
7
- * root, or `"/handbook"` (etc.) for any other prefix.
4
+ * `basePath` is the path-under-host where docs are served. The default
5
+ * is `""` (host root, matching every other SSG); set
6
+ * `site.basePath: "/docs"` in `dogsbay.config.yml` for the legacy
7
+ * "docs nested under marketing site" shape, or `"/handbook"` (etc.)
8
+ * for any other prefix. See plans/default-basepath-root.md for the
9
+ * rationale behind the default flip in v0.3.
8
10
  *
9
11
  * Every emitter that builds URLs, file paths, or rewrites links
10
12
  * reads from `AstroProjectOptions.basePath` and runs it through
@@ -22,8 +24,18 @@
22
24
  *
23
25
  * See plans/configurable-base-path.md.
24
26
  */
25
- /** Default `basePath` when no override is supplied. */
26
- export const DEFAULT_BASE_PATH = "/docs";
27
+ /**
28
+ * Default `basePath` when no override is supplied.
29
+ *
30
+ * Changed in v0.3 from `"/docs"` to `""` (host root) so the default
31
+ * matches the plurality of doc-site deployments (GH Pages project
32
+ * sites, `docs.acme.com` subdomains, standalone wikis) and aligns
33
+ * with peer SSGs (Astro, Next, MkDocs, Docusaurus). The `cli`'s
34
+ * `site build` emits a one-shot migration warning when this default
35
+ * is hit so users from the `/docs` era can opt in to either value
36
+ * explicitly. See plans/default-basepath-root.md.
37
+ */
38
+ export const DEFAULT_BASE_PATH = "";
27
39
  /**
28
40
  * Normalize a user-supplied `basePath` to canonical form.
29
41
  *
@@ -33,7 +45,7 @@ export const DEFAULT_BASE_PATH = "/docs";
33
45
  * non-empty prefix.
34
46
  *
35
47
  * Examples:
36
- * - `undefined` → `"/docs"` (default)
48
+ * - `undefined` → `""` (default in v0.3+; was `"/docs"` previously)
37
49
  * - `""` → `""`
38
50
  * - `"/"` → `""`
39
51
  * - `"docs"` → `"/docs"`
@@ -111,6 +123,98 @@ export function withBasePath(basePath, indexPath) {
111
123
  const cleanIndex = indexPath.startsWith("/") ? indexPath : `/${indexPath}`;
112
124
  return basePath ? `${basePath}${cleanIndex}` : cleanIndex;
113
125
  }
126
+ /**
127
+ * Parse `site.url` into its origin and path-component parts. The
128
+ * path component (if any) becomes the **urlBase** — the prefix the
129
+ * host serves dist/ at, distinct from `basePath` (which is the
130
+ * filesystem position of content within that served space).
131
+ *
132
+ * Used by emitters that need to (a) emit Astro's `base` config
133
+ * (= urlBase), (b) produce absolute URLs in sitemap / canonical /
134
+ * llms.txt (= origin + combined prefix + slug), or (c) build the
135
+ * combined prefix that internal hrefs need (`combinePrefix` below).
136
+ *
137
+ * Returns `origin` undefined when `siteUrl` is missing or unparseable
138
+ * — the caller then degrades to relative URLs (existing behavior).
139
+ *
140
+ * - `undefined` → `{ origin: undefined, urlBase: "" }`
141
+ * - `"https://example.com"` → `{ origin: "https://example.com", urlBase: "" }`
142
+ * - `"https://example.com/"` → `{ origin: "https://example.com", urlBase: "" }`
143
+ * - `"https://example.com/docs"` → `{ origin: "https://example.com", urlBase: "/docs" }`
144
+ * - `"https://example.com/docs/"` → `{ origin: "https://example.com", urlBase: "/docs" }`
145
+ * - `"https://user.github.io/dogsbay-docs"` → `{ origin: "https://user.github.io", urlBase: "/dogsbay-docs" }`
146
+ * - `"/relative-path"` → `{ origin: undefined, urlBase: "" }` (not a full URL)
147
+ *
148
+ * See plans/astro-base-from-site-url.md.
149
+ */
150
+ export function parseSiteUrl(siteUrl) {
151
+ if (!siteUrl)
152
+ return { origin: undefined, urlBase: "" };
153
+ // Only accept absolute http(s) URLs as full site URLs. Anything else
154
+ // (relative paths, mailto:, tel:, …) yields no origin — emitters
155
+ // fall back to whatever they do today when site.url is missing.
156
+ if (!/^https?:\/\//i.test(siteUrl)) {
157
+ return { origin: undefined, urlBase: "" };
158
+ }
159
+ let parsed;
160
+ try {
161
+ parsed = new URL(siteUrl);
162
+ }
163
+ catch {
164
+ return { origin: undefined, urlBase: "" };
165
+ }
166
+ const origin = `${parsed.protocol}//${parsed.host}`;
167
+ const urlBase = normalizeBasePath(parsed.pathname);
168
+ return { origin, urlBase };
169
+ }
170
+ /**
171
+ * Combine a urlBase (host subpath, from `site.url`) with a
172
+ * basePath (filesystem layout prefix, from `site.basePath`) into the
173
+ * single prefix that nav hrefs, sitemap URLs, llms.txt, and the
174
+ * link rewriter all need.
175
+ *
176
+ * Both inputs MUST already be normalized (output of `normalizeBasePath`
177
+ * or `parseSiteUrl`): empty string OR a single leading slash with no
178
+ * trailing slash. The output respects the same shape.
179
+ *
180
+ * - `combinePrefix("", "")` → `""`
181
+ * - `combinePrefix("", "/docs")` → `"/docs"`
182
+ * - `combinePrefix("/repo", "")` → `"/repo"`
183
+ * - `combinePrefix("/repo", "/docs")` → `"/repo/docs"`
184
+ * - `combinePrefix("/handbook", "/team-docs")` → `"/handbook/team-docs"`
185
+ *
186
+ * See plans/astro-base-from-site-url.md.
187
+ */
188
+ export function combinePrefix(urlBase, basePath) {
189
+ // Both already normalized — concatenation is safe; no double slashes
190
+ // appear because each is empty OR starts with `/` and has no trailing.
191
+ if (!urlBase)
192
+ return basePath;
193
+ if (!basePath)
194
+ return urlBase;
195
+ return `${urlBase}${basePath}`;
196
+ }
197
+ /**
198
+ * One-shot resolver: given the user's `site.url` + `site.basePath`,
199
+ * return everything emitters need. Convenience wrapper around
200
+ * `parseSiteUrl` + `normalizeBasePath` + `combinePrefix` so callers
201
+ * only do the math once.
202
+ *
203
+ * Used at the boundary in cli/site-build and cli/site-init to compute
204
+ * the effective prefixes before threading them into the emit tier.
205
+ *
206
+ * See plans/astro-base-from-site-url.md.
207
+ */
208
+ export function resolvePrefixes(siteUrl, basePath) {
209
+ const { origin, urlBase } = parseSiteUrl(siteUrl);
210
+ const normalizedBasePath = normalizeBasePath(basePath);
211
+ return {
212
+ origin,
213
+ urlBase,
214
+ basePath: normalizedBasePath,
215
+ combined: combinePrefix(urlBase, normalizedBasePath),
216
+ };
217
+ }
114
218
  /**
115
219
  * Build the `currentPath` value embedded in generated `.astro` pages
116
220
  * for `getPagination` lookups. No trailing slash so it matches the
@@ -121,6 +225,16 @@ export function withBasePath(basePath, indexPath) {
121
225
  * - default basePath, empty slug → `"/docs"`
122
226
  * - empty basePath, slug "auth" → `"/auth"`
123
227
  * - empty basePath, empty slug → `"/"`
228
+ * - empty basePath, slug "index" → `"/"` (root home)
229
+ *
230
+ * A bare `index` slug means the directory root: `content/index.md` is
231
+ * deliberately loaded with slug `"index"` (so the root-home and `.md`-mirror
232
+ * special cases fire — see plans/dir-index-slug-nav-drop.md), but the page is
233
+ * served at the directory URL and its nav href drops `index` (via
234
+ * `fileToHref`'s `/index` strip). `currentPath` must match that nav href for
235
+ * `getPagination` to find the home page, so we drop a whole-slug `index` here
236
+ * too. Without this the home page's `currentPath` (`/base/index`) never matches
237
+ * its nav entry (`/base`), so prev/next silently falls back to the first item.
124
238
  */
125
239
  export function buildCurrentPath(basePath, section, slug) {
126
240
  const parts = [];
@@ -128,7 +242,7 @@ export function buildCurrentPath(basePath, section, slug) {
128
242
  parts.push(seg);
129
243
  if (section)
130
244
  parts.push(section);
131
- if (slug)
245
+ if (slug && slug !== "index")
132
246
  parts.push(slug);
133
247
  return parts.length === 0 ? "/" : `/${parts.join("/")}`;
134
248
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base-path.js","sourceRoot":"","sources":["../src/base-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,uDAAuD;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IACzD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,iBAAiB,CAAC;IAClD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,OAAO,IAAI,OAAO,EAAE,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CACzB,QAAgB,EAChB,OAA2B,EAC3B,IAAY;IAEZ,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,gBAAgB,CAAC,QAAQ,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9D,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,IAAI,IAAI,IAAI,KAAK,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,SAAiB;IAC9D,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC;IAC3E,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,OAA2B,EAC3B,IAAY;IAEZ,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,gBAAgB,CAAC,QAAQ,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9D,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"base-path.js","sourceRoot":"","sources":["../src/base-path.ts"],"names":[],"mappings":"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"}
package/dist/blog.d.ts ADDED
@@ -0,0 +1,134 @@
1
+ import type { ExportPage } from "@dogsbay/types";
2
+ /** Resolved `blog:` config (defaults filled). */
3
+ export interface BlogEmitConfig {
4
+ /**
5
+ * Where the reverse-chronological index lives, relative to the site.
6
+ * `"/"` (the default) means the site root IS the blog index — the
7
+ * shape a blog-only site wants.
8
+ */
9
+ indexPath: string;
10
+ /** Posts per index page. */
11
+ postsPerPage: number;
12
+ /** Emit an RSS feed route. Phase 4; accepted and ignored for now. */
13
+ rss: boolean;
14
+ /** Which `PageMeta` date orders the list. */
15
+ dateField: "created" | "updated";
16
+ }
17
+ /** Defaults for a `blog:` block that omits fields. */
18
+ export declare const BLOG_DEFAULTS: BlogEmitConfig;
19
+ /** One post in the emitted data file. */
20
+ export interface BlogPostRef {
21
+ slug: string;
22
+ title: string;
23
+ url: string;
24
+ description?: string;
25
+ /** ISO date from `meta[dateField]`. Absent when the post carries none. */
26
+ date?: string;
27
+ /** Only when it differs from `date` — the layout shows it as "updated". */
28
+ updated?: string;
29
+ author?: string[];
30
+ tags?: string[];
31
+ heroImage?: string;
32
+ /** Whole minutes, minimum 1. */
33
+ readingMinutes: number;
34
+ }
35
+ /** `src/data/blog.json`. */
36
+ export interface BlogData {
37
+ /** URL-form index path, prefixed with the COMBINED serving prefix. */
38
+ indexPath: string;
39
+ /**
40
+ * Filesystem-layout prefix (`site.basePath`), used to place route
41
+ * files under `src/pages/`. Deliberately NOT the same field as the URL
42
+ * prefix: Astro's `base` adds `urlBase` at request time, so baking it
43
+ * into file paths too would double it. Same split `taxonomy.ts` takes
44
+ * as `basePath` + `urlPrefix`.
45
+ */
46
+ basePath: string;
47
+ /**
48
+ * The COMBINED serving prefix (urlBase + basePath). What DocsLayout's
49
+ * `basePath` prop wants — it composes the llms.txt link, switcher
50
+ * hrefs and the alternate link from it, all of which are URLs. Kept
51
+ * separate from `basePath` above, which is a filesystem path.
52
+ */
53
+ urlPrefix: string;
54
+ /** `content.section`, when the build has one. Part of route placement. */
55
+ section?: string;
56
+ postsPerPage: number;
57
+ /** Newest first. */
58
+ posts: BlogPostRef[];
59
+ postCount: number;
60
+ }
61
+ /** Prev/next for one post, in date order. */
62
+ export interface BlogAdjacency {
63
+ /** The OLDER neighbour — back along the timeline, rendered on the left. */
64
+ prev?: {
65
+ title: string;
66
+ href: string;
67
+ };
68
+ /** The NEWER neighbour — forward, rendered on the right. */
69
+ next?: {
70
+ title: string;
71
+ href: string;
72
+ };
73
+ }
74
+ /**
75
+ * Count words in a page's body.
76
+ *
77
+ * Deliberately crude: whitespace-split on the extracted plain text.
78
+ * Reading time is a reading CUE, not a measurement, and a more precise
79
+ * count would not change the rendered minutes.
80
+ */
81
+ export declare function countWords(page: ExportPage): number;
82
+ /** Whole minutes at {@link WORDS_PER_MINUTE}, never less than 1. */
83
+ export declare function readingMinutes(page: ExportPage): number;
84
+ /**
85
+ * Build the post list from the page set.
86
+ *
87
+ * EVERY page is a post except the one that would occupy the index
88
+ * route itself. A site that declares `blog:` IS a blog; there is no
89
+ * second "is this a post?" axis to configure, and inventing one would
90
+ * mean a post silently vanishing because a field was missing.
91
+ *
92
+ * Undated posts sort last, in title order, rather than being dropped —
93
+ * a post with no date is an authoring mistake worth SEEING, not
94
+ * hiding.
95
+ */
96
+ export declare function buildBlogData(pages: ExportPage[], opts: {
97
+ basePath: string;
98
+ urlPrefix?: string;
99
+ /** `content.section`, threaded exactly as taxonomy.ts threads it. */
100
+ section?: string;
101
+ /** `excludeFromRoutes` predicate — see makeSlugExcluder. */
102
+ excludeSlug?: (slug: string) => boolean;
103
+ config: BlogEmitConfig;
104
+ }): BlogData;
105
+ /**
106
+ * Prev/next per post slug, in TIME order — `prev` older, `next` newer.
107
+ *
108
+ * The footer renders prev on the left and next on the right, so this is
109
+ * the direction a timeline runs: older behind you, newer ahead. It also
110
+ * matches how a series is read. `data.posts` is newest-first for the
111
+ * index listing, so the neighbours are deliberately taken the other way
112
+ * round from the array order.
113
+ *
114
+ * The first version had `prev` as the NEWER neighbour, reasoning that a
115
+ * blog archive is browsed backwards. That made the right-hand link walk
116
+ * a reader BACKWARDS through a series — part 1's "next" was nothing, and
117
+ * its left-hand link was part 2.
118
+ */
119
+ export declare function blogAdjacency(data: BlogData): Map<string, BlogAdjacency>;
120
+ /** Number of index pages at the configured page size. */
121
+ export declare function indexPageCount(data: BlogData): number;
122
+ /**
123
+ * Emit `src/data/blog.json` plus the index route(s).
124
+ *
125
+ * Page 1 lives at the index path; subsequent pages at
126
+ * `<indexPath>/page/<n>`. Data JSON is overwritten unconditionally —
127
+ * it is pure derived data — while route files respect the marker.
128
+ */
129
+ export declare function emitBlogFiles(outputDir: string, data: BlogData, config: BlogEmitConfig): {
130
+ routes: string[];
131
+ skipped: string[];
132
+ pruned: string[];
133
+ };
134
+ //# sourceMappingURL=blog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog.d.ts","sourceRoot":"","sources":["../src/blog.ts"],"names":[],"mappings":"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"}