starlight-dot-md 0.1.2 → 0.2.1

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/README.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # starlight-dot-md
2
2
 
3
- A Starlight plugin that exposes raw markdown files at `.md` URLs.
3
+ A Starlight plugin that serves your docs (.md, .mdx, .mdoc) as raw markdown for AI agents.
4
4
 
5
- For installation, usage, and configuration options, see the [documentation](https://starlight-dot-md.shf0811.workers.dev/).
5
+ ## Usage
6
+
7
+ Install the package:
8
+
9
+ ```bash
10
+ npm install starlight-dot-md@latest
11
+ ```
12
+
13
+ Add the plugin to your Astro config:
14
+
15
+ ```js
16
+ import starlight from "@astrojs/starlight";
17
+ import { defineConfig } from "astro/config";
18
+ import starlightDotMd from "starlight-dot-md";
19
+
20
+ export default defineConfig({
21
+ integrations: [
22
+ starlight({
23
+ // ...
24
+ plugins: [starlightDotMd()],
25
+ }),
26
+ ],
27
+ });
28
+ ```
29
+
30
+ That's it! You can now access any page's source by appending `.md` to its URL (e.g., for a page at `/guides/example`, access `/guides/example.md`).
31
+
32
+ For more details, see the [documentation](https://starlight-dot-md.shf0811.workers.dev/).
package/dist/index.d.mts CHANGED
@@ -3,6 +3,7 @@ import { StarlightPlugin } from "@astrojs/starlight/types";
3
3
  //#region src/types.d.ts
4
4
  type StarlightDotMdOptions = {
5
5
  excludePatterns?: string[];
6
+ includeFrontmatter?: boolean;
6
7
  includePatterns?: string[];
7
8
  preserveExtension?: boolean;
8
9
  };
package/dist/index.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  import { readdirSync, statSync } from "node:fs";
2
2
  import { join, relative } from "node:path";
3
-
4
3
  //#region src/index.ts
5
4
  function findFilesByExtension(dir, baseDir, extension) {
6
5
  const results = [];
@@ -50,7 +49,7 @@ function starlightDotMd(options = {}) {
50
49
  hooks: { setup({ addIntegration }) {
51
50
  addIntegration({
52
51
  name: "starlight-dot-md",
53
- hooks: { "astro:config:setup": ({ injectRoute, updateConfig }) => {
52
+ hooks: { "astro:config:setup": ({ injectRoute, updateConfig, config }) => {
54
53
  injectRoute({
55
54
  pattern: "/[...slug].md",
56
55
  entrypoint: "starlight-dot-md/slug.md",
@@ -69,15 +68,16 @@ function starlightDotMd(options = {}) {
69
68
  });
70
69
  }
71
70
  updateConfig({ vite: { plugins: [vitePluginStarlightDotMdContext({
71
+ includeFrontmatter: options.includeFrontmatter ?? true,
72
72
  excludePatterns: options.excludePatterns ?? [],
73
73
  includePatterns: options.includePatterns ?? [],
74
- preserveExtension: options.preserveExtension ?? false
74
+ preserveExtension: options.preserveExtension ?? false,
75
+ trailingSlash: config.trailingSlash ?? "ignore"
75
76
  }, options.preserveExtension ?? false)] } });
76
77
  } }
77
78
  });
78
79
  } }
79
80
  };
80
81
  }
81
-
82
82
  //#endregion
83
- export { starlightDotMd as default };
83
+ export { starlightDotMd as default };
package/dist/slug.md.mjs CHANGED
@@ -1,7 +1,6 @@
1
- import { i as isMdx, n as isIncluded, r as isMdoc, t as isExcluded } from "./utils-BJKtrfbz.mjs";
1
+ import { a as isMdx, i as isMdoc, n as isExcluded, o as originalSlugFromOutput, r as isIncluded, s as transformSlugForOutput, t as generateMarkdownContent } from "./utils-K4BnESpG.mjs";
2
2
  import { getCollection, getEntry } from "astro:content";
3
3
  import { context } from "virtual:starlight-dot-md/context";
4
-
5
4
  //#region src/slug.md.ts
6
5
  function shouldServe(slug) {
7
6
  if (!isIncluded(slug) || isExcluded(slug)) return false;
@@ -9,18 +8,19 @@ function shouldServe(slug) {
9
8
  return true;
10
9
  }
11
10
  const getStaticPaths = async () => {
12
- return (await getCollection("docs")).filter((entry) => shouldServe(entry.id)).map((entry) => ({ params: { slug: entry.id } }));
11
+ return (await getCollection("docs")).filter((entry) => shouldServe(entry.id)).map((entry) => ({ params: { slug: transformSlugForOutput(entry.id) } }));
13
12
  };
14
13
  const GET = async ({ params }) => {
15
- const slug = params.slug;
16
- if (!slug || !shouldServe(slug)) return new Response("Not found", { status: 404 });
14
+ const outputSlug = params.slug;
15
+ if (!outputSlug) return new Response("Not found", { status: 404 });
16
+ const slug = originalSlugFromOutput(outputSlug);
17
+ if (!shouldServe(slug)) return new Response("Not found", { status: 404 });
17
18
  const entry = await getEntry("docs", slug);
18
19
  if (!entry) return new Response("Not found", { status: 404 });
19
- return new Response(entry.body, {
20
+ return new Response(generateMarkdownContent(entry), {
20
21
  status: 200,
21
22
  headers: { "Content-Type": "text/markdown; charset=utf-8" }
22
23
  });
23
24
  };
24
-
25
25
  //#endregion
26
- export { GET, getStaticPaths };
26
+ export { GET, getStaticPaths };
@@ -1,23 +1,23 @@
1
- import { n as isIncluded, r as isMdoc, t as isExcluded } from "./utils-BJKtrfbz.mjs";
1
+ import { i as isMdoc, n as isExcluded, o as originalSlugFromOutput, r as isIncluded, s as transformSlugForOutput, t as generateMarkdownContent } from "./utils-K4BnESpG.mjs";
2
2
  import { getCollection, getEntry } from "astro:content";
3
-
4
3
  //#region src/slug.mdoc.ts
5
4
  function shouldServe(slug) {
6
5
  return isMdoc(slug) && isIncluded(slug) && !isExcluded(slug);
7
6
  }
8
7
  const getStaticPaths = async () => {
9
- return (await getCollection("docs")).filter((entry) => shouldServe(entry.id)).map((entry) => ({ params: { slug: entry.id } }));
8
+ return (await getCollection("docs")).filter((entry) => shouldServe(entry.id)).map((entry) => ({ params: { slug: transformSlugForOutput(entry.id) } }));
10
9
  };
11
10
  const GET = async ({ params }) => {
12
- const slug = params.slug;
13
- if (!slug || !shouldServe(slug)) return new Response("Not found", { status: 404 });
11
+ const outputSlug = params.slug;
12
+ if (!outputSlug) return new Response("Not found", { status: 404 });
13
+ const slug = originalSlugFromOutput(outputSlug);
14
+ if (!shouldServe(slug)) return new Response("Not found", { status: 404 });
14
15
  const entry = await getEntry("docs", slug);
15
16
  if (!entry) return new Response("Not found", { status: 404 });
16
- return new Response(entry.body, {
17
+ return new Response(generateMarkdownContent(entry), {
17
18
  status: 200,
18
19
  headers: { "Content-Type": "text/markdown; charset=utf-8" }
19
20
  });
20
21
  };
21
-
22
22
  //#endregion
23
- export { GET, getStaticPaths };
23
+ export { GET, getStaticPaths };
package/dist/slug.mdx.mjs CHANGED
@@ -1,23 +1,23 @@
1
- import { i as isMdx, n as isIncluded, t as isExcluded } from "./utils-BJKtrfbz.mjs";
1
+ import { a as isMdx, n as isExcluded, o as originalSlugFromOutput, r as isIncluded, s as transformSlugForOutput, t as generateMarkdownContent } from "./utils-K4BnESpG.mjs";
2
2
  import { getCollection, getEntry } from "astro:content";
3
-
4
3
  //#region src/slug.mdx.ts
5
4
  function shouldServe(slug) {
6
5
  return isMdx(slug) && isIncluded(slug) && !isExcluded(slug);
7
6
  }
8
7
  const getStaticPaths = async () => {
9
- return (await getCollection("docs")).filter((entry) => shouldServe(entry.id)).map((entry) => ({ params: { slug: entry.id } }));
8
+ return (await getCollection("docs")).filter((entry) => shouldServe(entry.id)).map((entry) => ({ params: { slug: transformSlugForOutput(entry.id) } }));
10
9
  };
11
10
  const GET = async ({ params }) => {
12
- const slug = params.slug;
13
- if (!slug || !shouldServe(slug)) return new Response("Not found", { status: 404 });
11
+ const outputSlug = params.slug;
12
+ if (!outputSlug) return new Response("Not found", { status: 404 });
13
+ const slug = originalSlugFromOutput(outputSlug);
14
+ if (!shouldServe(slug)) return new Response("Not found", { status: 404 });
14
15
  const entry = await getEntry("docs", slug);
15
16
  if (!entry) return new Response("Not found", { status: 404 });
16
- return new Response(entry.body, {
17
+ return new Response(generateMarkdownContent(entry), {
17
18
  status: 200,
18
19
  headers: { "Content-Type": "text/markdown; charset=utf-8" }
19
20
  });
20
21
  };
21
-
22
22
  //#endregion
23
- export { GET, getStaticPaths };
23
+ export { GET, getStaticPaths };
@@ -0,0 +1,33 @@
1
+ import { context } from "virtual:starlight-dot-md/context";
2
+ import { mdocSlugs, mdxSlugs } from "virtual:starlight-dot-md/files";
3
+ import picomatch from "picomatch";
4
+ import yaml from "yaml";
5
+ //#region src/utils.ts
6
+ function isMdx(slug) {
7
+ return mdxSlugs.has(slug);
8
+ }
9
+ function isMdoc(slug) {
10
+ return mdocSlugs.has(slug);
11
+ }
12
+ function isExcluded(slug) {
13
+ if (!context.excludePatterns || context.excludePatterns.length === 0) return false;
14
+ return picomatch.isMatch(slug, context.excludePatterns);
15
+ }
16
+ function isIncluded(slug) {
17
+ if (!context.includePatterns || context.includePatterns.length === 0) return true;
18
+ return picomatch.isMatch(slug, context.includePatterns);
19
+ }
20
+ function transformSlugForOutput(slug) {
21
+ if (context.trailingSlash === "always" && slug !== "index") return `${slug}/index`;
22
+ return slug;
23
+ }
24
+ function originalSlugFromOutput(outputSlug) {
25
+ if (context.trailingSlash === "always" && outputSlug !== "index" && outputSlug.endsWith("/index")) return outputSlug.slice(0, -6);
26
+ return outputSlug;
27
+ }
28
+ function generateMarkdownContent(entry) {
29
+ if (!context.includeFrontmatter) return entry.body ?? "";
30
+ return `---\n${yaml.stringify(entry.data)}---\n\n${entry.body ?? ""}`;
31
+ }
32
+ //#endregion
33
+ export { isMdx as a, isMdoc as i, isExcluded as n, originalSlugFromOutput as o, isIncluded as r, transformSlugForOutput as s, generateMarkdownContent as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-dot-md",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "description": "A Starlight plugin that exposes raw markdown files at `.md` URLs.",
5
5
  "keywords": [
6
6
  "astro",
@@ -15,7 +15,7 @@
15
15
  "type": "module",
16
16
  "repository": {
17
17
  "type": "git",
18
- "url": "https://github.com/morinokami/starlight-dot-md.git",
18
+ "url": "git+https://github.com/morinokami/starlight-dot-md.git",
19
19
  "directory": "packages/starlight-dot-md"
20
20
  },
21
21
  "bugs": {
@@ -34,20 +34,24 @@
34
34
  "dist"
35
35
  ],
36
36
  "dependencies": {
37
- "picomatch": "4.0.3"
37
+ "picomatch": "4.0.4",
38
+ "yaml": "2.8.3"
38
39
  },
39
40
  "devDependencies": {
40
- "@astrojs/starlight": "0.37.3",
41
- "@types/node": "25.0.9",
42
- "@types/picomatch": "4.0.2",
43
- "astro": "5.16.11",
44
- "tsdown": "0.18.3",
45
- "typescript": "5.9.3"
41
+ "@astrojs/starlight": "0.38.3",
42
+ "@types/node": "25.6.0",
43
+ "@types/picomatch": "4.0.3",
44
+ "astro": "6.1.7",
45
+ "publint": "0.3.18",
46
+ "tsdown": "0.21.9",
47
+ "typescript": "6.0.3"
46
48
  },
47
49
  "peerDependencies": {
48
50
  "astro": ">=5.0.0"
49
51
  },
50
52
  "scripts": {
51
- "build": "tsdown"
53
+ "build": "tsdown",
54
+ "lint": "biome ci",
55
+ "publint": "publint"
52
56
  }
53
57
  }
@@ -1,22 +0,0 @@
1
- import { context } from "virtual:starlight-dot-md/context";
2
- import { mdocSlugs, mdxSlugs } from "virtual:starlight-dot-md/files";
3
- import picomatch from "picomatch";
4
-
5
- //#region src/utils.ts
6
- function isMdx(slug) {
7
- return mdxSlugs.has(slug);
8
- }
9
- function isMdoc(slug) {
10
- return mdocSlugs.has(slug);
11
- }
12
- function isExcluded(slug) {
13
- if (!context.excludePatterns || context.excludePatterns.length === 0) return false;
14
- return picomatch.isMatch(slug, context.excludePatterns);
15
- }
16
- function isIncluded(slug) {
17
- if (!context.includePatterns || context.includePatterns.length === 0) return true;
18
- return picomatch.isMatch(slug, context.includePatterns);
19
- }
20
-
21
- //#endregion
22
- export { isMdx as i, isIncluded as n, isMdoc as r, isExcluded as t };