boltdocs 1.3.1 → 1.3.3

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 (33) hide show
  1. package/dist/CodeBlock-QYIKJMEB.mjs +7 -0
  2. package/dist/PackageManagerTabs-XW3AVXVX.mjs +99 -0
  3. package/dist/{SearchDialog-5EDRACEG.mjs → SearchDialog-FBNGKRPK.mjs} +2 -1
  4. package/dist/{SearchDialog-X57WPTNN.css → SearchDialog-O3V36MXA.css} +32 -27
  5. package/dist/{cache-EHR7SXRU.mjs → cache-GQHF6BXI.mjs} +1 -1
  6. package/dist/{chunk-GSYECEZY.mjs → chunk-CYBWLFOG.mjs} +5 -1
  7. package/dist/{chunk-NS7WHDYA.mjs → chunk-D7YBQG6H.mjs} +7 -20
  8. package/dist/chunk-FMTOYQLO.mjs +37 -0
  9. package/dist/chunk-KS5B3O6W.mjs +43 -0
  10. package/dist/{PackageManagerTabs-XEKI3L7P.mjs → chunk-S5G55FBI.mjs} +4 -105
  11. package/dist/client/index.css +32 -27
  12. package/dist/client/index.js +113 -88
  13. package/dist/client/index.mjs +73 -31
  14. package/dist/client/ssr.css +32 -27
  15. package/dist/client/ssr.js +44 -59
  16. package/dist/client/ssr.mjs +2 -1
  17. package/dist/node/index.js +15 -14
  18. package/dist/node/index.mjs +13 -16
  19. package/package.json +1 -1
  20. package/src/client/index.ts +1 -0
  21. package/src/client/theme/components/CodeBlock/CodeBlock.tsx +11 -36
  22. package/src/client/theme/components/PackageManagerTabs/PackageManagerTabs.tsx +12 -35
  23. package/src/client/theme/components/mdx/Tabs.tsx +36 -4
  24. package/src/client/theme/components/mdx/mdx-components.css +8 -0
  25. package/src/client/theme/icons/yarn.tsx +16 -0
  26. package/src/client/theme/styles/markdown.css +26 -29
  27. package/src/client/utils.ts +23 -0
  28. package/src/node/ssg/meta.ts +11 -12
  29. package/src/node/ssg/sitemap.ts +2 -1
  30. package/src/node/utils.ts +11 -0
  31. package/tsconfig.json +1 -1
  32. package/dist/CodeBlock-V3Z5EKGR.mjs +0 -6
  33. package/dist/chunk-2YRDWM6O.mjs +0 -56
@@ -1,3 +1,5 @@
1
+ import { escapeHtml } from "../utils";
2
+
1
3
  /**
2
4
  * Replaces placeholder or default meta tags in the HTML template with page-specific values.
3
5
  *
@@ -9,26 +11,23 @@ export function replaceMetaTags(
9
11
  html: string,
10
12
  meta: { title: string; description: string },
11
13
  ): string {
14
+ const title = escapeHtml(meta.title);
15
+ const description = escapeHtml(meta.description);
16
+
12
17
  return html
13
- .replace(/<title>.*?<\/title>/, `<title>${meta.title}</title>`)
18
+ .replace(/<title>.*?<\/title>/, `<title>${title}</title>`)
14
19
  .replace(
15
20
  /(<meta name="description" content=")[^"]*(")/,
16
- `$1${meta.description}$2`,
17
- )
18
- .replace(
19
- /(<meta property="og:title" content=")[^"]*(")/,
20
- `$1${meta.title}$2`,
21
+ `$1${description}$2`,
21
22
  )
23
+ .replace(/(<meta property="og:title" content=")[^"]*(")/, `$1${title}$2`)
22
24
  .replace(
23
25
  /(<meta property="og:description" content=")[^"]*(")/,
24
- `$1${meta.description}$2`,
25
- )
26
- .replace(
27
- /(<meta name="twitter:title" content=")[^"]*(")/,
28
- `$1${meta.title}$2`,
26
+ `$1${description}$2`,
29
27
  )
28
+ .replace(/(<meta name="twitter:title" content=")[^"]*(")/, `$1${title}$2`)
30
29
  .replace(
31
30
  /(<meta name="twitter:description" content=")[^"]*(")/,
32
- `$1${meta.description}$2`,
31
+ `$1${description}$2`,
33
32
  );
34
33
  }
@@ -1,4 +1,5 @@
1
1
  import { BoltdocsConfig } from "../config";
2
+ import { escapeXml } from "../utils";
2
3
 
3
4
  /**
4
5
  * Generates a standard XML sitemap for search engine crawlers.
@@ -43,7 +44,7 @@ export function generateSitemap(
43
44
  ${entries
44
45
  .map(
45
46
  (e) => ` <url>
46
- <loc>${baseUrl}${e.url}</loc>
47
+ <loc>${escapeXml(baseUrl)}${escapeXml(e.url)}</loc>
47
48
  <lastmod>${today}</lastmod>
48
49
  <changefreq>${e.changefreq}</changefreq>
49
50
  <priority>${e.priority}</priority>
package/src/node/utils.ts CHANGED
@@ -86,10 +86,21 @@ export function escapeHtml(str: string): string {
86
86
  return str
87
87
  .replace(/&/g, "&amp;")
88
88
  .replace(/"/g, "&quot;")
89
+ .replace(/'/g, "&apos;")
89
90
  .replace(/</g, "&lt;")
90
91
  .replace(/>/g, "&gt;");
91
92
  }
92
93
 
94
+ /**
95
+ * Alias for escapeHtml to be used in XML contexts (like sitemaps).
96
+ *
97
+ * @param str - The raw string to escape
98
+ * @returns The escaped string
99
+ */
100
+ export function escapeXml(str: string): string {
101
+ return escapeHtml(str);
102
+ }
103
+
93
104
  /**
94
105
  * Converts a file path relative to the `docsDir` into a URL route path.
95
106
  * Handles removing extensions, converting `index` files to directory roots,
package/tsconfig.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "compilerOptions": {
3
3
  "target": "ES2022",
4
4
  "module": "ESNext",
5
- "moduleResolution": "Node",
5
+ "moduleResolution": "Bundler",
6
6
  "esModuleInterop": true,
7
7
  "strict": true,
8
8
  "skipLibCheck": true,
@@ -1,6 +0,0 @@
1
- import {
2
- CodeBlock
3
- } from "./chunk-2YRDWM6O.mjs";
4
- export {
5
- CodeBlock
6
- };
@@ -1,56 +0,0 @@
1
- // src/client/theme/components/CodeBlock/CodeBlock.tsx
2
- import React, { useState, useRef, useCallback } from "react";
3
- import { Copy, Check } from "lucide-react";
4
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
- function CodeBlock({ children, ...props }) {
6
- const [copied, setCopied] = useState(false);
7
- const preRef = useRef(null);
8
- let language = "";
9
- if (React.isValidElement(children)) {
10
- const childProps = children.props;
11
- language = childProps?.["data-language"] || "";
12
- if (!language && childProps?.className) {
13
- const match = childProps.className.match(/language-(\w+)/);
14
- if (match) language = match[1];
15
- }
16
- }
17
- const handleCopy = useCallback(async () => {
18
- const code = preRef.current?.textContent || "";
19
- try {
20
- await navigator.clipboard.writeText(code);
21
- setCopied(true);
22
- setTimeout(() => setCopied(false), 2e3);
23
- } catch {
24
- const textarea = document.createElement("textarea");
25
- textarea.value = code;
26
- textarea.style.position = "fixed";
27
- textarea.style.opacity = "0";
28
- document.body.appendChild(textarea);
29
- textarea.select();
30
- document.execCommand("copy");
31
- document.body.removeChild(textarea);
32
- setCopied(true);
33
- setTimeout(() => setCopied(false), 2e3);
34
- }
35
- }, []);
36
- return /* @__PURE__ */ jsxs("div", { className: "code-block-wrapper", children: [
37
- /* @__PURE__ */ jsxs("div", { className: "code-block-header", children: [
38
- /* @__PURE__ */ jsx("span", { className: "code-block-lang", children: language || "code" }),
39
- /* @__PURE__ */ jsx(
40
- "button",
41
- {
42
- className: `code-block-copy ${copied ? "copied" : ""}`,
43
- onClick: handleCopy,
44
- type: "button",
45
- "aria-label": "Copy code",
46
- children: copied ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Check, { size: 20 }) }) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Copy, { size: 20 }) })
47
- }
48
- )
49
- ] }),
50
- /* @__PURE__ */ jsx("pre", { ref: preRef, ...props, children })
51
- ] });
52
- }
53
-
54
- export {
55
- CodeBlock
56
- };