@knitli/astro-docs-template 0.4.3 → 0.4.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knitli/astro-docs-template",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Opinionated Astro + Starlight docs site template with Knitli branding",
5
5
  "keywords": [
6
6
  "knitli",
@@ -45,25 +45,26 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@astrojs/check": "^0.9.6",
48
- "@astrojs/cloudflare": "^13.1.7",
48
+ "@astrojs/cloudflare": "^13.1.8",
49
49
  "@astrojs/compiler-rs": "^0.1.6",
50
50
  "@astrojs/markdoc": "^1.0.0",
51
51
  "@astrojs/mdx": "^5.0.3",
52
52
  "@astrojs/sitemap": "^3.7.2",
53
- "@astrojs/starlight": "^0.38.2",
53
+ "@astrojs/starlight": "^0.38.3",
54
54
  "@biomejs/biome": "^2.4.2",
55
55
  "@knitli/docs-components": "*",
56
56
  "@knitli/tsconfig": "*",
57
- "@nuasite/llm-enhancements": "^0.19.1",
57
+ "@nuasite/llm-enhancements": "^0.23.0",
58
58
  "@types/bun": "^1.3.4",
59
- "@types/node": "^24.0.2",
60
- "astro": "^6.1.4",
59
+ "@types/mdast": "^4.0.4",
60
+ "@types/node": "^24.12.2",
61
+ "astro": "^6.1.5",
61
62
  "astro-cloudflare-pages-headers": "^1.7.7",
62
63
  "astro-d2": "^0.10.0",
63
64
  "astro-favicons": "3.1.6",
64
- "bun": "^1.3.9",
65
+ "bun": "^1.3.11",
65
66
  "lightningcss": "^1.30.2",
66
- "postcss": "^8.5.9",
67
+ "postcss": "8.5.6",
67
68
  "postcss-nesting": "^14.0.0",
68
69
  "rehype-external-links": "^3.0.0",
69
70
  "sharp": "^0.34.5",
@@ -78,7 +79,8 @@
78
79
  "starlight-sidebar-topics": ">=0.7.1",
79
80
  "starlight-tags": ">=0.4.0",
80
81
  "svgo": "^4.0.0",
81
- "vite": "^7.3.1",
82
+ "unist-util-visit": "^5.1.0",
83
+ "vite": "^7.3.2",
82
84
  "vite-tsconfig-paths": "6.1.1"
83
85
  },
84
86
  "devDependencies": {
package/src/config.ts CHANGED
@@ -18,6 +18,8 @@ import { defineConfig, fontProviders } from "astro/config";
18
18
  import cloudflarePagesHeaders from "astro-cloudflare-pages-headers";
19
19
  import astroD2 from "astro-d2";
20
20
  import favicons from "astro-favicons";
21
+ import type { PluginCreator } from "postcss";
22
+ import type { pluginOptions } from "postcss-nesting";
21
23
  import rehypeExternalLinks from "rehype-external-links";
22
24
  import starlightAnnouncement from "starlight-announcement";
23
25
  import starlightChangelogs from "starlight-changelogs";
@@ -34,6 +36,7 @@ import starlightSidebarTopics from "starlight-sidebar-topics";
34
36
  import starlightTags from "starlight-tags";
35
37
  import { searchForWorkspaceRoot } from "vite";
36
38
  import viteTsconfigPaths from "vite-tsconfig-paths";
39
+ import { remarkVersion } from "./remarkPlugin.js";
37
40
 
38
41
  type defaultIntegration =
39
42
  | "sitemap"
@@ -48,6 +51,12 @@ function nonNullable<T>(value: T): value is NonNullable<T> {
48
51
  return value != null;
49
52
  }
50
53
 
54
+ const postcssNesting = async (options?: { edition: "2021" | "2024-02" }) => {
55
+ // Dynamically import postcss-nesting to avoid bundling it in the template's node_modules
56
+ const { default: createPlugin } = await import("postcss-nesting");
57
+ return createPlugin(options) as unknown as PluginCreator<pluginOptions>;
58
+ };
59
+
51
60
  // ── Defaults (defined before interface so `typeof` references work) ──
52
61
 
53
62
  export const {
@@ -396,7 +405,7 @@ const defaultHeadersConfig: OutgoingHttpHeaders = {
396
405
  "default-src 'self'; script-src 'self' 'unsafe-inline' static.cloudflareinsights.com zaraz.cloudflare.com; connect-src 'self' cloudflareinsights.com *.cloudflareinsights.com; img-src 'self' media.knitli.com data: avatars.githubusercontent.com ui-avatars.com media.knitli.com knitli.com; style-src 'self' 'unsafe-inline' fonts.googleapis.com; font-src 'self' fonts.gstatic.com; frame-ancestors 'none'",
397
406
  };
398
407
 
399
- export default function createConfig(options: DocsTemplateOptions) {
408
+ export default async function createConfig(options: DocsTemplateOptions) {
400
409
  const {
401
410
  appName,
402
411
  description,
@@ -452,6 +461,7 @@ export default function createConfig(options: DocsTemplateOptions) {
452
461
  { content: { type: "text", value: " ↗" }, rel: ["nofollow"] },
453
462
  ],
454
463
  ],
464
+ remarkPlugins: [remarkVersion],
455
465
  },
456
466
  server: {
457
467
  headers: { ...defaultHeadersConfig, ...headersConfig },
@@ -464,6 +474,9 @@ export default function createConfig(options: DocsTemplateOptions) {
464
474
  allow: [searchForWorkspaceRoot(rootDir)],
465
475
  },
466
476
  },
477
+ optimizeDeps: {
478
+ exclude: [""],
479
+ },
467
480
  assetsInclude: [
468
481
  "src/*.webp",
469
482
  "src/*.png",
@@ -511,7 +524,11 @@ export default function createConfig(options: DocsTemplateOptions) {
511
524
  },
512
525
  css: {
513
526
  postcss: {
514
- plugins: [require("postcss-nesting")()],
527
+ plugins: [
528
+ await postcssNesting({
529
+ edition: "2024-02",
530
+ }),
531
+ ],
515
532
  },
516
533
  },
517
534
  },
@@ -0,0 +1,59 @@
1
+ // SPDX-FileCopyrightText: 2026 Knitli Inc.
2
+ //
3
+ // SPDX-License-Identifier: MIT OR Apache-2.0
4
+
5
+ /**
6
+ * Remark plugin that replaces {{VERSION}} tokens in markdown content
7
+ * with the current version derived from `git describe`.
8
+ *
9
+ * Runs at build time — no runtime cost.
10
+ */
11
+
12
+ import { execFileSync } from "node:child_process";
13
+ import type { Root, Text } from "mdast";
14
+ import { visit } from "unist-util-visit";
15
+
16
+ let cachedVersion: string | undefined;
17
+
18
+ function getVersion(): string {
19
+ if (cachedVersion !== undefined) return cachedVersion;
20
+
21
+ try {
22
+ const raw = execFileSync("git", ["describe", "--tags", "--always"], {
23
+ encoding: "utf-8",
24
+ timeout: 5000,
25
+ }).trim();
26
+
27
+ // Convert git describe output to clean version:
28
+ // v0.2.0 -> 0.2.0
29
+ // v0.2.0-3-gabcdef -> 0.2.0-dev
30
+ // v0.1.0-alpha.5-103-gabcdef -> 0.1.0-dev
31
+ // v0.2.0-beta.1 -> 0.2.0-beta.1
32
+ const match = raw.match(
33
+ /^v?(\d+\.\d+\.\d+)(?:-[a-z]+\.\d+)?(?:-(\d+)-g[a-f0-9]+)?$/,
34
+ );
35
+ if (match) {
36
+ const baseVersion = match[1];
37
+ const commitDistance = match[2];
38
+ cachedVersion = commitDistance ? `${baseVersion}-dev` : baseVersion;
39
+ } else {
40
+ cachedVersion = raw.replace(/^v/, "");
41
+ }
42
+ } catch {
43
+ cachedVersion = "0.0.0-unknown";
44
+ }
45
+
46
+ return cachedVersion || "0.0.0-unknown";
47
+ }
48
+
49
+ export function remarkVersion(): (tree: Root) => void {
50
+ return (tree: Root) => {
51
+ const version = getVersion();
52
+
53
+ visit(tree, "text", (node: Text) => {
54
+ if (node.value.includes("{{VERSION}}")) {
55
+ node.value = node.value.replaceAll("{{VERSION}}", version);
56
+ }
57
+ });
58
+ };
59
+ }