rspress-plugin-api-extractor 0.1.1 → 0.2.0
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 +2 -2
- package/api-extracted-package.js +426 -0
- package/build-program.js +120 -0
- package/build-stages.js +664 -0
- package/category-resolver.js +50 -0
- package/code-post-processor.js +38 -0
- package/config-helpers.js +106 -0
- package/config-utils.js +258 -0
- package/content-hash.js +79 -0
- package/errors.js +29 -0
- package/formatter.js +69 -0
- package/hide-cut-transformer.js +96 -0
- package/index.d.ts +901 -831
- package/index.js +4 -6332
- package/layers/ConfigServiceLive.js +377 -0
- package/layers/ObservabilityLive.js +136 -0
- package/layers/PathDerivationServiceLive.js +16 -0
- package/layers/SnapshotServiceLive.js +94 -0
- package/layers/TypeRegistryServiceLive.js +46 -0
- package/llms-processing.js +270 -0
- package/llms-program.js +262 -0
- package/loader.js +186 -0
- package/markdown/cross-linker.js +156 -0
- package/markdown/helpers.js +364 -0
- package/markdown/index.js +11 -0
- package/markdown/page-generators/class-page.js +357 -0
- package/markdown/page-generators/enum-page.js +152 -0
- package/markdown/page-generators/function-page.js +127 -0
- package/markdown/page-generators/index-pages.js +27 -0
- package/markdown/page-generators/interface-page.js +307 -0
- package/markdown/page-generators/namespace-page.js +280 -0
- package/markdown/page-generators/type-alias-page.js +110 -0
- package/markdown/page-generators/variable-page.js +110 -0
- package/markdown/shiki-utils.js +48 -0
- package/migrations/001_create_snapshots.js +25 -0
- package/model-loader.js +95 -0
- package/multi-entry-resolver.js +70 -0
- package/og-resolver.js +271 -0
- package/package.json +63 -72
- package/path-derivation.js +48 -0
- package/plugin.js +218 -0
- package/prettier-formatter.js +73 -0
- package/public/tsconfig/rspress.json +44 -0
- package/remark-api-codeblocks.js +130 -0
- package/remark-with-api.js +172 -0
- package/route-collisions.js +52 -0
- package/runtime/components/ApiExample/index.js +33 -0
- package/runtime/components/ApiLlmsPackageActions/index.js +277 -0
- package/runtime/components/ApiLlmsViewOptions/index.js +294 -0
- package/runtime/components/ApiMember/index.js +53 -0
- package/runtime/components/ApiSignature/index.js +36 -0
- package/runtime/components/EnumMembersTable/index.css +99 -0
- package/runtime/components/EnumMembersTable/index.js +38 -0
- package/runtime/components/EnumMembersTable/index.module.js +10 -0
- package/runtime/components/ExampleBlock/index.css +11 -0
- package/runtime/components/ExampleBlock/index.js +31 -0
- package/runtime/components/ExampleBlock/index.module.js +9 -0
- package/runtime/components/MarkdownContent/index.js +31 -0
- package/runtime/components/MarkdownText/index.js +33 -0
- package/runtime/components/MemberSignature/index.css +26 -0
- package/runtime/components/MemberSignature/index.js +54 -0
- package/runtime/components/MemberSignature/index.module.js +10 -0
- package/runtime/components/ParametersTable/index.css +103 -0
- package/runtime/components/ParametersTable/index.js +38 -0
- package/runtime/components/ParametersTable/index.module.js +10 -0
- package/runtime/components/SignatureBlock/index.css +26 -0
- package/runtime/components/SignatureBlock/index.js +36 -0
- package/runtime/components/SignatureBlock/index.module.js +10 -0
- package/runtime/components/SignatureCode/index.css +52 -0
- package/runtime/components/SignatureCode/index.js +44 -0
- package/runtime/components/SignatureCode/index.module.js +10 -0
- package/runtime/components/SignatureToolbar/index.css +122 -0
- package/runtime/components/SignatureToolbar/index.js +52 -0
- package/runtime/components/SignatureToolbar/index.module.js +14 -0
- package/runtime/components/buttons/ButtonGroup.js +16 -0
- package/runtime/components/buttons/CopyCodeButton.js +44 -0
- package/runtime/components/buttons/WrapSignatureButton.js +24 -0
- package/runtime/components/buttons/index.css +36 -0
- package/runtime/components/buttons/index.module.js +9 -0
- package/runtime/components/icons/CheckIcon/index.js +23 -0
- package/runtime/components/icons/CopyIcon/index.js +23 -0
- package/runtime/components/icons/UnwrapIcon/index.js +25 -0
- package/runtime/components/icons/WrapIcon/index.js +23 -0
- package/runtime/components/shared/_twoslash.css +440 -0
- package/runtime/components/shared/types.js +0 -0
- package/runtime/components/shared/variables.css +82 -0
- package/runtime/hooks/useWrapToggle.js +35 -0
- package/runtime/index.d.ts +513 -173
- package/runtime/index.js +13 -664
- package/runtime/utils/decode-hast.js +33 -0
- package/runtime/utils/hast-renderer.js +24 -0
- package/schemas/config.js +199 -0
- package/schemas/index.js +5 -0
- package/schemas/opengraph.js +26 -0
- package/schemas/performance.js +19 -0
- package/serve.js +133 -0
- package/services/ConfigService.js +7 -0
- package/services/PathDerivationService.js +7 -0
- package/services/SnapshotService.js +7 -0
- package/services/TypeRegistryService.js +7 -0
- package/shiki-transformer.js +758 -0
- package/tsconfig-parser.js +127 -0
- package/tsdoc-metadata.json +11 -11
- package/twoslash-patterns.js +87 -0
- package/twoslash-transformer.js +316 -0
- package/type-reference-extractor.js +201 -0
- package/typescript-config.js +168 -0
- package/vfs-registry.js +121 -0
- package/0~llms-program.js +0 -344
- package/runtime/index.css +0 -1016
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { usePage, useSite } from "@rspress/core/runtime";
|
|
4
|
+
import { createPortal } from "react-dom";
|
|
5
|
+
|
|
6
|
+
//#region src/runtime/components/ApiLlmsPackageActions/index.tsx
|
|
7
|
+
function resolveUrl(urlPath) {
|
|
8
|
+
if (typeof window === "undefined") return urlPath;
|
|
9
|
+
if (urlPath.startsWith("http://") || urlPath.startsWith("https://")) return urlPath;
|
|
10
|
+
return `${window.location.origin}${urlPath}`;
|
|
11
|
+
}
|
|
12
|
+
function findMatchingScope(pathname, scopes) {
|
|
13
|
+
const sorted = [...scopes].sort((a, b) => b.packageRoute.length - a.packageRoute.length);
|
|
14
|
+
for (const scope of sorted) {
|
|
15
|
+
const base = scope.packageRoute.endsWith("/") ? scope.packageRoute : `${scope.packageRoute}/`;
|
|
16
|
+
if (pathname === scope.packageRoute || pathname.startsWith(base)) return scope;
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
async function copyToClipboard(text) {
|
|
21
|
+
await navigator.clipboard.writeText(text);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Package-scoped LLM actions injected via React portals into RSPress's
|
|
25
|
+
* existing LLMs UI containers. Adds package-level copy/open actions
|
|
26
|
+
* alongside the default page-level options.
|
|
27
|
+
*
|
|
28
|
+
* For outline mode: injects rows into .rp-outline__bottom
|
|
29
|
+
* For title mode: injects a dropdown into .rp-llms-container
|
|
30
|
+
*/
|
|
31
|
+
function ApiLlmsPackageActions() {
|
|
32
|
+
const { site } = useSite();
|
|
33
|
+
const { page } = usePage();
|
|
34
|
+
const [outlineTarget, setOutlineTarget] = useState(null);
|
|
35
|
+
const scopes = useMemo(() => {
|
|
36
|
+
if (import.meta.env.SSG_MD) return [];
|
|
37
|
+
return (site?.themeConfig)?.apiExtractorScopes ?? [];
|
|
38
|
+
}, [site]);
|
|
39
|
+
const activeScope = useMemo(() => findMatchingScope(page.routePath, scopes), [page.routePath, scopes]);
|
|
40
|
+
const placement = useMemo(() => {
|
|
41
|
+
const llmsUI = site?.themeConfig?.llmsUI;
|
|
42
|
+
return typeof llmsUI === "object" ? llmsUI?.placement ?? "title" : "title";
|
|
43
|
+
}, [site]);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (import.meta.env.SSG_MD || !activeScope) {
|
|
46
|
+
setOutlineTarget(null);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (placement !== "outline") return;
|
|
50
|
+
const timer = setTimeout(() => {
|
|
51
|
+
setOutlineTarget(document.querySelector(".rp-outline__bottom"));
|
|
52
|
+
}, 100);
|
|
53
|
+
return () => clearTimeout(timer);
|
|
54
|
+
}, [
|
|
55
|
+
activeScope,
|
|
56
|
+
placement,
|
|
57
|
+
page.routePath
|
|
58
|
+
]);
|
|
59
|
+
if (import.meta.env.SSG_MD || !activeScope) return null;
|
|
60
|
+
if (placement === "outline" && outlineTarget) return createPortal(/* @__PURE__ */ jsx(OutlinePackageActions, { scope: activeScope }), outlineTarget);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
function OutlinePackageActions({ scope }) {
|
|
64
|
+
const [copyFeedback, setCopyFeedback] = useState(null);
|
|
65
|
+
const [isOpenMenuOpen, setIsOpenMenuOpen] = useState(false);
|
|
66
|
+
const wrapperRef = useRef(null);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (!isOpenMenuOpen) return;
|
|
69
|
+
const handleClick = (e) => {
|
|
70
|
+
if (wrapperRef.current && !wrapperRef.current.contains(e.target)) setIsOpenMenuOpen(false);
|
|
71
|
+
};
|
|
72
|
+
document.addEventListener("mousedown", handleClick);
|
|
73
|
+
return () => document.removeEventListener("mousedown", handleClick);
|
|
74
|
+
}, [isOpenMenuOpen]);
|
|
75
|
+
const handleCopyDocs = useCallback(async () => {
|
|
76
|
+
try {
|
|
77
|
+
const url = resolveUrl(scope.llmsDocsTxt);
|
|
78
|
+
await copyToClipboard(await (await fetch(url)).text());
|
|
79
|
+
setCopyFeedback("Copied!");
|
|
80
|
+
setTimeout(() => setCopyFeedback(null), 1500);
|
|
81
|
+
} catch {
|
|
82
|
+
setCopyFeedback("Failed");
|
|
83
|
+
setTimeout(() => setCopyFeedback(null), 1500);
|
|
84
|
+
}
|
|
85
|
+
}, [scope]);
|
|
86
|
+
const handleCopyLink = useCallback(async (urlPath) => {
|
|
87
|
+
try {
|
|
88
|
+
await copyToClipboard(resolveUrl(urlPath));
|
|
89
|
+
setCopyFeedback("Copied!");
|
|
90
|
+
setTimeout(() => setCopyFeedback(null), 1500);
|
|
91
|
+
} catch {
|
|
92
|
+
setCopyFeedback("Failed");
|
|
93
|
+
setTimeout(() => setCopyFeedback(null), 1500);
|
|
94
|
+
}
|
|
95
|
+
}, []);
|
|
96
|
+
const q = `Read ${resolveUrl(scope.llmsTxt)}, I want to ask questions about the ${scope.name} package.`;
|
|
97
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
98
|
+
/* @__PURE__ */ jsxs("button", {
|
|
99
|
+
type: "button",
|
|
100
|
+
className: "rp-outline__action-row",
|
|
101
|
+
onClick: handleCopyDocs,
|
|
102
|
+
children: [/* @__PURE__ */ jsx(CopyIcon, {}), /* @__PURE__ */ jsx("span", { children: copyFeedback ?? `Copy ${scope.name} docs` })]
|
|
103
|
+
}),
|
|
104
|
+
/* @__PURE__ */ jsxs("button", {
|
|
105
|
+
type: "button",
|
|
106
|
+
className: "rp-outline__action-row",
|
|
107
|
+
onClick: () => handleCopyLink(scope.llmsTxt),
|
|
108
|
+
children: [/* @__PURE__ */ jsx(LinkIcon, {}), /* @__PURE__ */ jsx("span", { children: "Copy llms.txt link" })]
|
|
109
|
+
}),
|
|
110
|
+
/* @__PURE__ */ jsxs("div", {
|
|
111
|
+
ref: wrapperRef,
|
|
112
|
+
className: "rp-outline__open-in-wrapper",
|
|
113
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
114
|
+
type: "button",
|
|
115
|
+
className: "rp-outline__action-row",
|
|
116
|
+
onClick: () => setIsOpenMenuOpen(!isOpenMenuOpen),
|
|
117
|
+
children: [/* @__PURE__ */ jsx(ExternalLinkIcon, {}), /* @__PURE__ */ jsxs("span", { children: [
|
|
118
|
+
"Open ",
|
|
119
|
+
scope.name,
|
|
120
|
+
" in chat"
|
|
121
|
+
] })]
|
|
122
|
+
}), isOpenMenuOpen && /* @__PURE__ */ jsxs("div", {
|
|
123
|
+
className: "rp-llms-view-options__menu",
|
|
124
|
+
children: [/* @__PURE__ */ jsxs("a", {
|
|
125
|
+
className: "rp-llms-view-options__menu-item",
|
|
126
|
+
href: `https://chatgpt.com/?${new URLSearchParams({
|
|
127
|
+
hints: "search",
|
|
128
|
+
q
|
|
129
|
+
})}`,
|
|
130
|
+
target: "_blank",
|
|
131
|
+
rel: "noopener noreferrer",
|
|
132
|
+
onClick: () => setIsOpenMenuOpen(false),
|
|
133
|
+
children: [
|
|
134
|
+
/* @__PURE__ */ jsx("span", {
|
|
135
|
+
className: "rp-llms-view-options__item-icon",
|
|
136
|
+
children: /* @__PURE__ */ jsx(ChatGPTIcon, {})
|
|
137
|
+
}),
|
|
138
|
+
/* @__PURE__ */ jsx("span", { children: "Open in ChatGPT" }),
|
|
139
|
+
/* @__PURE__ */ jsx("span", {
|
|
140
|
+
className: "rp-llms-view-options__external-icon",
|
|
141
|
+
children: /* @__PURE__ */ jsx(ExternalLinkSmallIcon, {})
|
|
142
|
+
})
|
|
143
|
+
]
|
|
144
|
+
}), /* @__PURE__ */ jsxs("a", {
|
|
145
|
+
className: "rp-llms-view-options__menu-item",
|
|
146
|
+
href: `https://claude.ai/new?${new URLSearchParams({ q })}`,
|
|
147
|
+
target: "_blank",
|
|
148
|
+
rel: "noopener noreferrer",
|
|
149
|
+
onClick: () => setIsOpenMenuOpen(false),
|
|
150
|
+
children: [
|
|
151
|
+
/* @__PURE__ */ jsx("span", {
|
|
152
|
+
className: "rp-llms-view-options__item-icon",
|
|
153
|
+
children: /* @__PURE__ */ jsx(ClaudeIcon, {})
|
|
154
|
+
}),
|
|
155
|
+
/* @__PURE__ */ jsx("span", { children: "Open in Claude" }),
|
|
156
|
+
/* @__PURE__ */ jsx("span", {
|
|
157
|
+
className: "rp-llms-view-options__external-icon",
|
|
158
|
+
children: /* @__PURE__ */ jsx(ExternalLinkSmallIcon, {})
|
|
159
|
+
})
|
|
160
|
+
]
|
|
161
|
+
})]
|
|
162
|
+
})]
|
|
163
|
+
})
|
|
164
|
+
] });
|
|
165
|
+
}
|
|
166
|
+
function CopyIcon() {
|
|
167
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
168
|
+
width: 16,
|
|
169
|
+
height: 16,
|
|
170
|
+
viewBox: "0 0 24 24",
|
|
171
|
+
fill: "none",
|
|
172
|
+
stroke: "currentColor",
|
|
173
|
+
strokeWidth: 2,
|
|
174
|
+
strokeLinecap: "round",
|
|
175
|
+
strokeLinejoin: "round",
|
|
176
|
+
children: [
|
|
177
|
+
/* @__PURE__ */ jsx("title", { children: "Copy" }),
|
|
178
|
+
/* @__PURE__ */ jsx("rect", {
|
|
179
|
+
x: 9,
|
|
180
|
+
y: 9,
|
|
181
|
+
width: 13,
|
|
182
|
+
height: 13,
|
|
183
|
+
rx: 2,
|
|
184
|
+
ry: 2
|
|
185
|
+
}),
|
|
186
|
+
/* @__PURE__ */ jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
187
|
+
]
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function LinkIcon() {
|
|
191
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
192
|
+
width: 16,
|
|
193
|
+
height: 16,
|
|
194
|
+
viewBox: "0 0 24 24",
|
|
195
|
+
fill: "none",
|
|
196
|
+
stroke: "currentColor",
|
|
197
|
+
strokeWidth: 2,
|
|
198
|
+
strokeLinecap: "round",
|
|
199
|
+
strokeLinejoin: "round",
|
|
200
|
+
children: [
|
|
201
|
+
/* @__PURE__ */ jsx("title", { children: "Link" }),
|
|
202
|
+
/* @__PURE__ */ jsx("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
|
|
203
|
+
/* @__PURE__ */ jsx("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
|
|
204
|
+
]
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
function ExternalLinkIcon() {
|
|
208
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
209
|
+
width: 16,
|
|
210
|
+
height: 16,
|
|
211
|
+
viewBox: "0 0 24 24",
|
|
212
|
+
fill: "none",
|
|
213
|
+
stroke: "currentColor",
|
|
214
|
+
strokeWidth: 2,
|
|
215
|
+
strokeLinecap: "round",
|
|
216
|
+
strokeLinejoin: "round",
|
|
217
|
+
children: [
|
|
218
|
+
/* @__PURE__ */ jsx("title", { children: "External link" }),
|
|
219
|
+
/* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
220
|
+
/* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
221
|
+
/* @__PURE__ */ jsx("line", {
|
|
222
|
+
x1: 10,
|
|
223
|
+
y1: 14,
|
|
224
|
+
x2: 21,
|
|
225
|
+
y2: 3
|
|
226
|
+
})
|
|
227
|
+
]
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function ExternalLinkSmallIcon() {
|
|
231
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
232
|
+
width: 12,
|
|
233
|
+
height: 12,
|
|
234
|
+
viewBox: "0 0 24 24",
|
|
235
|
+
fill: "none",
|
|
236
|
+
stroke: "currentColor",
|
|
237
|
+
strokeWidth: 2,
|
|
238
|
+
strokeLinecap: "round",
|
|
239
|
+
strokeLinejoin: "round",
|
|
240
|
+
children: [
|
|
241
|
+
/* @__PURE__ */ jsx("title", { children: "External link" }),
|
|
242
|
+
/* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
243
|
+
/* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
244
|
+
/* @__PURE__ */ jsx("line", {
|
|
245
|
+
x1: 10,
|
|
246
|
+
y1: 14,
|
|
247
|
+
x2: 21,
|
|
248
|
+
y2: 3
|
|
249
|
+
})
|
|
250
|
+
]
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
function ChatGPTIcon() {
|
|
254
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
255
|
+
role: "img",
|
|
256
|
+
viewBox: "0 0 24 24",
|
|
257
|
+
fill: "currentColor",
|
|
258
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
259
|
+
width: 16,
|
|
260
|
+
height: 16,
|
|
261
|
+
children: [/* @__PURE__ */ jsx("title", { children: "ChatGPT" }), /* @__PURE__ */ jsx("path", { d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" })]
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
function ClaudeIcon() {
|
|
265
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
266
|
+
fill: "currentColor",
|
|
267
|
+
role: "img",
|
|
268
|
+
viewBox: "0 0 24 24",
|
|
269
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
270
|
+
width: 16,
|
|
271
|
+
height: 16,
|
|
272
|
+
children: [/* @__PURE__ */ jsx("title", { children: "Anthropic" }), /* @__PURE__ */ jsx("path", { d: "M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z" })]
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
//#endregion
|
|
277
|
+
export { ApiLlmsPackageActions, ApiLlmsPackageActions as default };
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useI18n, usePage, useSite } from "@rspress/core/runtime";
|
|
4
|
+
import { useMdUrl } from "@rspress/core/theme";
|
|
5
|
+
|
|
6
|
+
//#region src/runtime/components/ApiLlmsViewOptions/index.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Custom LlmsViewOptions that replaces RSPress's default via resolve.alias.
|
|
9
|
+
*
|
|
10
|
+
* - Outside package scope: reproduces the original RSPress dropdown behavior
|
|
11
|
+
* - Inside package scope: adds package-level copy/open actions to the dropdown
|
|
12
|
+
*
|
|
13
|
+
* Uses RSPress's own CSS classes (rp-llms-*) for visual consistency.
|
|
14
|
+
*/
|
|
15
|
+
function resolveUrl(urlPath) {
|
|
16
|
+
if (typeof window === "undefined") return urlPath;
|
|
17
|
+
return urlPath.startsWith("http") ? urlPath : `${window.location.origin}${urlPath}`;
|
|
18
|
+
}
|
|
19
|
+
function findScope(pathname, scopes) {
|
|
20
|
+
const sorted = [...scopes].sort((a, b) => b.packageRoute.length - a.packageRoute.length);
|
|
21
|
+
for (const s of sorted) {
|
|
22
|
+
const base = s.packageRoute.endsWith("/") ? s.packageRoute : `${s.packageRoute}/`;
|
|
23
|
+
if (pathname === s.packageRoute || pathname.startsWith(base)) return s;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
async function copyText(text) {
|
|
28
|
+
await navigator.clipboard.writeText(text);
|
|
29
|
+
}
|
|
30
|
+
function DownArrow({ className }) {
|
|
31
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
32
|
+
className,
|
|
33
|
+
width: 16,
|
|
34
|
+
height: 16,
|
|
35
|
+
viewBox: "0 0 24 24",
|
|
36
|
+
fill: "none",
|
|
37
|
+
stroke: "currentColor",
|
|
38
|
+
strokeWidth: 2,
|
|
39
|
+
strokeLinecap: "round",
|
|
40
|
+
strokeLinejoin: "round",
|
|
41
|
+
children: [/* @__PURE__ */ jsx("title", { children: "Toggle menu" }), /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })]
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function LinkIcon() {
|
|
45
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
46
|
+
width: 16,
|
|
47
|
+
height: 16,
|
|
48
|
+
viewBox: "0 0 24 24",
|
|
49
|
+
fill: "none",
|
|
50
|
+
stroke: "currentColor",
|
|
51
|
+
strokeWidth: 2,
|
|
52
|
+
strokeLinecap: "round",
|
|
53
|
+
strokeLinejoin: "round",
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ jsx("title", { children: "Link" }),
|
|
56
|
+
/* @__PURE__ */ jsx("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
|
|
57
|
+
/* @__PURE__ */ jsx("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
|
|
58
|
+
]
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function CopyIcon() {
|
|
62
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
63
|
+
width: 16,
|
|
64
|
+
height: 16,
|
|
65
|
+
viewBox: "0 0 24 24",
|
|
66
|
+
fill: "none",
|
|
67
|
+
stroke: "currentColor",
|
|
68
|
+
strokeWidth: 2,
|
|
69
|
+
strokeLinecap: "round",
|
|
70
|
+
strokeLinejoin: "round",
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ jsx("title", { children: "Copy" }),
|
|
73
|
+
/* @__PURE__ */ jsx("rect", {
|
|
74
|
+
x: 9,
|
|
75
|
+
y: 9,
|
|
76
|
+
width: 13,
|
|
77
|
+
height: 13,
|
|
78
|
+
rx: 2,
|
|
79
|
+
ry: 2
|
|
80
|
+
}),
|
|
81
|
+
/* @__PURE__ */ jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
82
|
+
]
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function ExternalLinkIcon() {
|
|
86
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
87
|
+
width: 12,
|
|
88
|
+
height: 12,
|
|
89
|
+
viewBox: "0 0 24 24",
|
|
90
|
+
fill: "none",
|
|
91
|
+
stroke: "currentColor",
|
|
92
|
+
strokeWidth: 2,
|
|
93
|
+
strokeLinecap: "round",
|
|
94
|
+
strokeLinejoin: "round",
|
|
95
|
+
children: [
|
|
96
|
+
/* @__PURE__ */ jsx("title", { children: "External link" }),
|
|
97
|
+
/* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
98
|
+
/* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
99
|
+
/* @__PURE__ */ jsx("line", {
|
|
100
|
+
x1: 10,
|
|
101
|
+
y1: 14,
|
|
102
|
+
x2: 21,
|
|
103
|
+
y2: 3
|
|
104
|
+
})
|
|
105
|
+
]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function ChatGPTIcon() {
|
|
109
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
110
|
+
role: "img",
|
|
111
|
+
viewBox: "0 0 24 24",
|
|
112
|
+
fill: "currentColor",
|
|
113
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
114
|
+
width: 16,
|
|
115
|
+
height: 16,
|
|
116
|
+
children: [/* @__PURE__ */ jsx("title", { children: "ChatGPT" }), /* @__PURE__ */ jsx("path", { d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" })]
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
function ClaudeIcon() {
|
|
120
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
121
|
+
fill: "currentColor",
|
|
122
|
+
role: "img",
|
|
123
|
+
viewBox: "0 0 24 24",
|
|
124
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
125
|
+
width: 16,
|
|
126
|
+
height: 16,
|
|
127
|
+
children: [/* @__PURE__ */ jsx("title", { children: "Anthropic" }), /* @__PURE__ */ jsx("path", { d: "M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z" })]
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function LlmsViewOptions(props) {
|
|
131
|
+
const { site } = useSite();
|
|
132
|
+
const { page } = usePage();
|
|
133
|
+
const { pathname } = useMdUrl();
|
|
134
|
+
const t = useI18n();
|
|
135
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
136
|
+
const [feedback, setFeedback] = useState(null);
|
|
137
|
+
const dropdownRef = useRef(null);
|
|
138
|
+
const llmsUI = site?.themeConfig?.llmsUI;
|
|
139
|
+
const configOptions = typeof llmsUI === "object" ? llmsUI?.viewOptions : void 0;
|
|
140
|
+
const options = props.options ?? configOptions ?? [
|
|
141
|
+
"markdownLink",
|
|
142
|
+
"chatgpt",
|
|
143
|
+
"claude"
|
|
144
|
+
];
|
|
145
|
+
const scopes = (site?.themeConfig)?.apiExtractorScopes ?? [];
|
|
146
|
+
const activeScope = useMemo(() => findScope(page.routePath, scopes), [page.routePath, scopes]);
|
|
147
|
+
useEffect(() => {
|
|
148
|
+
if (!isOpen) return;
|
|
149
|
+
const handler = (e) => {
|
|
150
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) setIsOpen(false);
|
|
151
|
+
};
|
|
152
|
+
document.addEventListener("mousedown", handler);
|
|
153
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
154
|
+
}, [isOpen]);
|
|
155
|
+
const fullMarkdownUrl = useMemo(() => typeof window !== "undefined" ? new URL(pathname, window.location.origin).toString() : "", [pathname]);
|
|
156
|
+
const pageQ = `Read ${fullMarkdownUrl}, I want to ask questions about it.`;
|
|
157
|
+
const pageItems = useMemo(() => {
|
|
158
|
+
const builtins = {
|
|
159
|
+
markdownLink: {
|
|
160
|
+
title: t("copyMarkdownLinkText"),
|
|
161
|
+
icon: /* @__PURE__ */ jsx(LinkIcon, {}),
|
|
162
|
+
onClick: () => copyText(fullMarkdownUrl)
|
|
163
|
+
},
|
|
164
|
+
chatgpt: {
|
|
165
|
+
title: t("openInText", { name: "ChatGPT" }),
|
|
166
|
+
href: `https://chatgpt.com/?${new URLSearchParams({
|
|
167
|
+
hints: "search",
|
|
168
|
+
q: pageQ
|
|
169
|
+
})}`,
|
|
170
|
+
icon: /* @__PURE__ */ jsx(ChatGPTIcon, {})
|
|
171
|
+
},
|
|
172
|
+
claude: {
|
|
173
|
+
title: t("openInText", { name: "Claude" }),
|
|
174
|
+
href: `https://claude.ai/new?${new URLSearchParams({ q: pageQ })}`,
|
|
175
|
+
icon: /* @__PURE__ */ jsx(ClaudeIcon, {})
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
return options.map((opt) => {
|
|
179
|
+
if (typeof opt === "string") return builtins[opt] ?? null;
|
|
180
|
+
return opt;
|
|
181
|
+
}).filter(Boolean);
|
|
182
|
+
}, [
|
|
183
|
+
options,
|
|
184
|
+
fullMarkdownUrl,
|
|
185
|
+
pageQ,
|
|
186
|
+
t
|
|
187
|
+
]);
|
|
188
|
+
const showFeedback = useCallback((msg) => {
|
|
189
|
+
setFeedback(msg);
|
|
190
|
+
setTimeout(() => setFeedback(null), 1500);
|
|
191
|
+
}, []);
|
|
192
|
+
const handleCopyDocs = useCallback(async () => {
|
|
193
|
+
if (!activeScope) return;
|
|
194
|
+
try {
|
|
195
|
+
await copyText(await (await fetch(resolveUrl(activeScope.llmsDocsTxt))).text());
|
|
196
|
+
showFeedback("Copied!");
|
|
197
|
+
} catch {
|
|
198
|
+
showFeedback("Failed");
|
|
199
|
+
}
|
|
200
|
+
}, [activeScope, showFeedback]);
|
|
201
|
+
const handleCopyLink = useCallback(async (urlPath) => {
|
|
202
|
+
try {
|
|
203
|
+
await copyText(resolveUrl(urlPath));
|
|
204
|
+
showFeedback("Copied!");
|
|
205
|
+
} catch {
|
|
206
|
+
showFeedback("Failed");
|
|
207
|
+
}
|
|
208
|
+
}, [showFeedback]);
|
|
209
|
+
if (!pathname) return null;
|
|
210
|
+
const packageItems = [];
|
|
211
|
+
if (activeScope) {
|
|
212
|
+
const pkgQ = `Read ${resolveUrl(activeScope.llmsTxt)}, I want to ask questions about the ${activeScope.name} package.`;
|
|
213
|
+
packageItems.push({
|
|
214
|
+
title: feedback ?? `Copy ${activeScope.name} docs`,
|
|
215
|
+
icon: /* @__PURE__ */ jsx(CopyIcon, {}),
|
|
216
|
+
onClick: handleCopyDocs
|
|
217
|
+
}, {
|
|
218
|
+
title: "Copy llms.txt link",
|
|
219
|
+
icon: /* @__PURE__ */ jsx(LinkIcon, {}),
|
|
220
|
+
onClick: () => handleCopyLink(activeScope.llmsTxt)
|
|
221
|
+
}, {
|
|
222
|
+
title: "Copy llms-full.txt link",
|
|
223
|
+
icon: /* @__PURE__ */ jsx(LinkIcon, {}),
|
|
224
|
+
onClick: () => handleCopyLink(activeScope.llmsFullTxt)
|
|
225
|
+
}, {
|
|
226
|
+
title: `Open ${activeScope.name} in ChatGPT`,
|
|
227
|
+
href: `https://chatgpt.com/?${new URLSearchParams({
|
|
228
|
+
hints: "search",
|
|
229
|
+
q: pkgQ
|
|
230
|
+
})}`,
|
|
231
|
+
icon: /* @__PURE__ */ jsx(ChatGPTIcon, {})
|
|
232
|
+
}, {
|
|
233
|
+
title: `Open ${activeScope.name} in Claude`,
|
|
234
|
+
href: `https://claude.ai/new?${new URLSearchParams({ q: pkgQ })}`,
|
|
235
|
+
icon: /* @__PURE__ */ jsx(ClaudeIcon, {})
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
239
|
+
ref: dropdownRef,
|
|
240
|
+
type: "button",
|
|
241
|
+
className: `rp-llms-button rp-llms-view-options__trigger ${isOpen ? "rp-llms-view-options__trigger--active" : ""}`,
|
|
242
|
+
onClick: () => setIsOpen(!isOpen),
|
|
243
|
+
children: [/* @__PURE__ */ jsx(DownArrow, { className: `rp-llms-view-options__arrow ${isOpen ? "rp-llms-view-options__arrow--rotated" : ""}` }), isOpen && /* @__PURE__ */ jsxs("div", {
|
|
244
|
+
className: "rp-llms-view-options__menu",
|
|
245
|
+
children: [pageItems.map((item) => /* @__PURE__ */ jsx(MenuItem, {
|
|
246
|
+
item,
|
|
247
|
+
onClose: () => setIsOpen(false)
|
|
248
|
+
}, item.title)), packageItems.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", { style: {
|
|
249
|
+
height: 1,
|
|
250
|
+
margin: "4px 0",
|
|
251
|
+
background: "var(--rp-c-divider)"
|
|
252
|
+
} }), packageItems.map((item) => /* @__PURE__ */ jsx(MenuItem, {
|
|
253
|
+
item,
|
|
254
|
+
onClose: () => setIsOpen(false)
|
|
255
|
+
}, item.title))] })]
|
|
256
|
+
})]
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
function MenuItem({ item, onClose }) {
|
|
260
|
+
if (item.href) return /* @__PURE__ */ jsxs("a", {
|
|
261
|
+
className: "rp-llms-view-options__menu-item",
|
|
262
|
+
href: item.href,
|
|
263
|
+
target: "_blank",
|
|
264
|
+
rel: "noopener noreferrer",
|
|
265
|
+
onClick: onClose,
|
|
266
|
+
children: [
|
|
267
|
+
/* @__PURE__ */ jsx("span", {
|
|
268
|
+
className: "rp-llms-view-options__item-icon",
|
|
269
|
+
children: item.icon
|
|
270
|
+
}),
|
|
271
|
+
/* @__PURE__ */ jsx("span", { children: item.title }),
|
|
272
|
+
/* @__PURE__ */ jsx("span", {
|
|
273
|
+
className: "rp-llms-view-options__external-icon",
|
|
274
|
+
children: /* @__PURE__ */ jsx(ExternalLinkIcon, {})
|
|
275
|
+
})
|
|
276
|
+
]
|
|
277
|
+
});
|
|
278
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
279
|
+
type: "button",
|
|
280
|
+
className: "rp-llms-view-options__menu-item",
|
|
281
|
+
onClick: (e) => {
|
|
282
|
+
e.stopPropagation();
|
|
283
|
+
item.onClick?.();
|
|
284
|
+
onClose();
|
|
285
|
+
},
|
|
286
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
287
|
+
className: "rp-llms-view-options__item-icon",
|
|
288
|
+
children: item.icon
|
|
289
|
+
}), /* @__PURE__ */ jsx("span", { children: item.title })]
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
//#endregion
|
|
294
|
+
export { LlmsViewOptions };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { decodeHast } from "../../utils/decode-hast.js";
|
|
2
|
+
import { MemberSignature } from "../MemberSignature/index.js";
|
|
3
|
+
import { createElement, useMemo } from "react";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/runtime/components/ApiMember/index.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Renders an individual class/interface member signature block.
|
|
9
|
+
*
|
|
10
|
+
* Replaces MemberSignatureWrapper with a simpler component that takes plain
|
|
11
|
+
* string props. The `code` prop contains only the member signature (not
|
|
12
|
+
* wrapped in a class skeleton), and `summary` is plain markdown-compatible
|
|
13
|
+
* text (not HTML with anchor tags, not base64-encoded).
|
|
14
|
+
*
|
|
15
|
+
* In SSG-MD mode, renders a heading with member name, summary text,
|
|
16
|
+
* and a plain code block with the member signature.
|
|
17
|
+
*/
|
|
18
|
+
function ApiMember({ code, memberName, summary, id, hast, hasParameters }) {
|
|
19
|
+
const parsedHast = useMemo(() => decodeHast(hast, "ApiMember"), [hast]);
|
|
20
|
+
const hasParamsBoolean = typeof hasParameters === "string" ? hasParameters === "true" : !!hasParameters;
|
|
21
|
+
if (import.meta.env.SSG_MD) return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22
|
+
`### ${memberName}\n\n`,
|
|
23
|
+
summary && `${summary}\n\n`,
|
|
24
|
+
`\`\`\`typescript
|
|
25
|
+
${code.trim()}
|
|
26
|
+
\`\`\`
|
|
27
|
+
`
|
|
28
|
+
] });
|
|
29
|
+
if (parsedHast) {
|
|
30
|
+
const memberProps = {
|
|
31
|
+
hast: parsedHast,
|
|
32
|
+
memberName,
|
|
33
|
+
hasParameters: hasParamsBoolean
|
|
34
|
+
};
|
|
35
|
+
if (summary != null) memberProps.summary = summary;
|
|
36
|
+
if (id != null) memberProps.id = id;
|
|
37
|
+
return createElement(MemberSignature, memberProps);
|
|
38
|
+
}
|
|
39
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
40
|
+
/* @__PURE__ */ jsx("h3", {
|
|
41
|
+
id,
|
|
42
|
+
children: memberName
|
|
43
|
+
}),
|
|
44
|
+
summary && /* @__PURE__ */ jsx("p", { children: summary }),
|
|
45
|
+
/* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", {
|
|
46
|
+
className: "language-typescript",
|
|
47
|
+
children: code.trim()
|
|
48
|
+
}) })
|
|
49
|
+
] });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
export { ApiMember, ApiMember as default };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { decodeHast } from "../../utils/decode-hast.js";
|
|
2
|
+
import { SignatureBlock } from "../SignatureBlock/index.js";
|
|
3
|
+
import { createElement, useMemo } from "react";
|
|
4
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/runtime/components/ApiSignature/index.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Renders a full API type signature block.
|
|
9
|
+
*
|
|
10
|
+
* Replaces SignatureBlockWrapper with a simpler component that takes plain
|
|
11
|
+
* string props (no base64 encoding for code). Produces clean semantic HTML
|
|
12
|
+
* that RSPress converts to LLM-readable markdown in SSG-MD mode, and renders
|
|
13
|
+
* interactive Shiki-highlighted code in browser mode.
|
|
14
|
+
*
|
|
15
|
+
* In SSG-MD mode, renders a "Signature" heading followed by a plain
|
|
16
|
+
* code block with the type signature.
|
|
17
|
+
*/
|
|
18
|
+
function ApiSignature({ code, heading: _heading = "Signature", id: _id = "signature", hast, hasParameters, hasMembers }) {
|
|
19
|
+
const parsedHast = useMemo(() => decodeHast(hast, "ApiSignature"), [hast]);
|
|
20
|
+
const hasTableBelow = (typeof hasParameters === "string" ? hasParameters === "true" : !!hasParameters) || (typeof hasMembers === "string" ? hasMembers === "true" : !!hasMembers);
|
|
21
|
+
if (import.meta.env.SSG_MD) return /* @__PURE__ */ jsx(Fragment, { children: `\`\`\`typescript
|
|
22
|
+
${code.trim()}
|
|
23
|
+
\`\`\`
|
|
24
|
+
` });
|
|
25
|
+
if (parsedHast) return createElement(SignatureBlock, {
|
|
26
|
+
hast: parsedHast,
|
|
27
|
+
hasParameters: hasTableBelow
|
|
28
|
+
});
|
|
29
|
+
return /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", {
|
|
30
|
+
className: "language-typescript",
|
|
31
|
+
children: code.trim()
|
|
32
|
+
}) });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { ApiSignature, ApiSignature as default };
|