starlight-theme-celestia 0.3.0 → 0.3.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "starlight-theme-celestia",
3
3
  "type": "module",
4
- "version": "0.3.0",
4
+ "version": "0.3.2",
5
5
  "description": "A clean, modern theme for Astro Starlight",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -28,6 +28,7 @@
28
28
  "dependencies": {
29
29
  "@aria-ui/core": "^0.2.0",
30
30
  "@aria-ui/utils": "^0.1.5",
31
+ "@astrojs/markdown-remark": "^7.3.0",
31
32
  "@fontsource/inter": "^5.0.0",
32
33
  "@pagefind/default-ui": "^1.5.2",
33
34
  "@shikijs/transformers": "^4.0.2",
@@ -38,7 +39,7 @@
38
39
  "rehype": "^13.0.2",
39
40
  "remark-custom-header-id": "^1.0.0",
40
41
  "shiki-twoslash-renderer": "^0.3.3",
41
- "starlight-versions": "^0.9.0"
42
+ "starlight-versions": "^0.10.0"
42
43
  },
43
44
  "peerDependencies": {
44
45
  "@astrojs/starlight": "*",
@@ -53,7 +54,7 @@
53
54
  }
54
55
  },
55
56
  "devDependencies": {
56
- "@astrojs/starlight": "^0.41.0",
57
+ "@astrojs/starlight": "^0.42.0",
57
58
  "@tailwindcss/cli": "^4.2.2",
58
59
  "@tailwindcss/vite": "^4.2.2",
59
60
  "@types/node": "^26.0.0",
package/src/index.test.ts CHANGED
@@ -1,4 +1,7 @@
1
+ import { unified } from "@astrojs/markdown-remark";
1
2
  import type { StarlightPlugin, StarlightUserConfig } from "@astrojs/starlight/types";
3
+ import type { AstroConfig, AstroIntegration, AstroUserConfig } from "astro";
4
+ import { mergeConfig } from "astro/config";
2
5
  import { expect, test } from "bun:test";
3
6
 
4
7
  import starlightCelestiaTheme from "./index";
@@ -57,3 +60,67 @@ test("a user override of the sidebar wins over the multi-sidebar one", async ()
57
60
 
58
61
  expect(config.components?.Sidebar).toBe("./src/components/Sidebar.astro");
59
62
  });
63
+
64
+ async function setupMarkdown(markdown: AstroUserConfig["markdown"] = {}) {
65
+ let integration: AstroIntegration | undefined;
66
+ await starlightCelestiaTheme().hooks["config:setup"]!({
67
+ config: {},
68
+ updateConfig: () => {},
69
+ addIntegration: (value: AstroIntegration) => {
70
+ integration = value;
71
+ },
72
+ astroConfig: { root: new URL("file:///project/"), vite: {} },
73
+ } as unknown as ConfigSetupOptions);
74
+
75
+ const hook = integration!.hooks["astro:config:setup"]!;
76
+ let result: AstroUserConfig = { markdown };
77
+ await hook({
78
+ config: { markdown } as AstroConfig,
79
+ updateConfig: (value: AstroUserConfig) => {
80
+ result = mergeConfig(result, value);
81
+ return result;
82
+ },
83
+ } as unknown as Parameters<typeof hook>[0]);
84
+ return result.markdown!;
85
+ }
86
+
87
+ test("the theme uses unified to render custom heading IDs with a non-unified processor configured", async () => {
88
+ const markdown = await setupMarkdown({
89
+ processor: {
90
+ name: "satteri",
91
+ options: {},
92
+ createRenderer: async () => {
93
+ throw new Error("the incompatible processor must not render theme Markdown");
94
+ },
95
+ },
96
+ });
97
+ expect(markdown.processor!.name).toBe("unified");
98
+ expect(markdown.remarkPlugins).toBeUndefined();
99
+ const renderer = await markdown.processor!.createRenderer({});
100
+ const result = await renderer.render("## A heading {#custom-id}");
101
+ expect(result.code).toContain('id="custom-id"');
102
+ expect(result.code).not.toContain("{#custom-id}");
103
+ });
104
+
105
+ test("the theme preserves an existing unified processor and shared Markdown settings", async () => {
106
+ const remarkPlugin = () => () => {};
107
+ const rehypePlugin = () => () => {};
108
+ const recmaPlugin = () => () => {};
109
+ const processor = unified({
110
+ remarkPlugins: [remarkPlugin],
111
+ rehypePlugins: [rehypePlugin],
112
+ recmaPlugins: [recmaPlugin],
113
+ remarkRehype: { clobberPrefix: "user-" },
114
+ gfm: false,
115
+ smartypants: false,
116
+ });
117
+ const markdown = await setupMarkdown({ processor, syntaxHighlight: false });
118
+ expect(markdown.processor).toBe(processor);
119
+ expect(processor.options.remarkPlugins[0]).toBe(remarkPlugin);
120
+ expect(processor.options.rehypePlugins).toEqual([rehypePlugin]);
121
+ expect(processor.options.recmaPlugins).toEqual([recmaPlugin]);
122
+ expect(processor.options.remarkRehype).toEqual({ clobberPrefix: "user-" });
123
+ expect(processor.options.gfm).toBe(false);
124
+ expect(processor.options.smartypants).toBe(false);
125
+ expect(markdown.syntaxHighlight).toBe(false);
126
+ });
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { isUnifiedProcessor, unified } from "@astrojs/markdown-remark";
1
2
  import type { StarlightConfig, StarlightPlugin, StarlightUserConfig } from "@astrojs/starlight/types";
2
3
  import type { AstroConfig } from "astro";
3
4
  import remarkCustomHeaderId from "remark-custom-header-id";
@@ -72,11 +73,17 @@ export default function starlightCelestiaTheme(options: ThemeCelestiaOptions = {
72
73
  addIntegration({
73
74
  name: "starlight-theme-celestia-integration",
74
75
  hooks: {
75
- "astro:config:setup": ({ updateConfig }) => {
76
+ "astro:config:setup": ({ config, updateConfig }) => {
77
+ // Reuse unified so user options and Astro's legacy-plugin migration tracking survive.
78
+ // Astro migrates any top-level remark/rehype settings when updateConfig validates this processor.
79
+ const currentProcessor = config.markdown.processor;
80
+ const processor = currentProcessor && isUnifiedProcessor(currentProcessor) ? currentProcessor : unified();
81
+ processor.options.remarkPlugins.push(remarkCustomHeaderId);
82
+
76
83
  updateConfig({
77
84
  markdown: {
78
85
  shikiConfig: createShikiConfig({ twoslash: true }),
79
- remarkPlugins: [remarkCustomHeaderId],
86
+ processor,
80
87
  },
81
88
  vite: {
82
89
  plugins: [
@@ -104,7 +104,7 @@ export function transformerContainer(): ShikiTransformer {
104
104
  };
105
105
  }
106
106
 
107
- // A simple function to make typescript happy
107
+ // Root-only nodes, including MDX module declarations, cannot be nested inside an element.
108
108
  function normalizeContent(children: RootContent[]): ElementContent[] {
109
- return children.filter((child) => child.type !== "doctype");
109
+ return children.filter((child): child is ElementContent => !["doctype", "mdxjsEsm"].includes(child.type));
110
110
  }
@@ -0,0 +1,4 @@
1
+ declare module "virtual:starlight/user-config" {
2
+ const config: import("@astrojs/starlight/types").StarlightConfig;
3
+ export default config;
4
+ }