fumadocs-core 8.0.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/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/breadcrumb.d.ts +11 -0
- package/dist/breadcrumb.js +47 -0
- package/dist/chunk-2ZGUSAWB.js +12 -0
- package/dist/chunk-AFKH746E.js +40 -0
- package/dist/chunk-GT3Y35O6.js +46 -0
- package/dist/chunk-WEAGW6MQ.js +63 -0
- package/dist/dynamic-link.d.ts +14 -0
- package/dist/dynamic-link.js +33 -0
- package/dist/get-toc-YF_TdazL.d.ts +14 -0
- package/dist/link.d.ts +24 -0
- package/dist/link.js +7 -0
- package/dist/mdx-plugins/index.d.ts +89 -0
- package/dist/mdx-plugins/index.js +353 -0
- package/dist/middleware.d.ts +10 -0
- package/dist/middleware.js +43 -0
- package/dist/page-tree-izSPERQk.d.ts +37 -0
- package/dist/remark-structure-RwYPDA6M.d.ts +34 -0
- package/dist/search/client.d.ts +13 -0
- package/dist/search/client.js +52 -0
- package/dist/search/server.d.ts +51 -0
- package/dist/search/server.js +209 -0
- package/dist/search/shared.d.ts +8 -0
- package/dist/search/shared.js +0 -0
- package/dist/search-algolia/client.d.ts +28 -0
- package/dist/search-algolia/client.js +68 -0
- package/dist/search-algolia/server.d.ts +45 -0
- package/dist/search-algolia/server.js +68 -0
- package/dist/server/index.d.ts +57 -0
- package/dist/server/index.js +148 -0
- package/dist/sidebar.d.ts +19 -0
- package/dist/sidebar.js +88 -0
- package/dist/source/index.d.ts +171 -0
- package/dist/source/index.js +389 -0
- package/dist/toc.d.ts +20 -0
- package/dist/toc.js +113 -0
- package/package.json +158 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import {
|
|
2
|
+
flattenNode,
|
|
3
|
+
remarkHeading,
|
|
4
|
+
visit
|
|
5
|
+
} from "../chunk-GT3Y35O6.js";
|
|
6
|
+
import {
|
|
7
|
+
slash
|
|
8
|
+
} from "../chunk-2ZGUSAWB.js";
|
|
9
|
+
import {
|
|
10
|
+
__async,
|
|
11
|
+
__spreadValues
|
|
12
|
+
} from "../chunk-WEAGW6MQ.js";
|
|
13
|
+
|
|
14
|
+
// src/mdx-plugins/index.ts
|
|
15
|
+
import {
|
|
16
|
+
default as default2
|
|
17
|
+
} from "remark-gfm";
|
|
18
|
+
|
|
19
|
+
// src/mdx-plugins/rehype-code.ts
|
|
20
|
+
import rehypeShikiji from "rehype-shikiji";
|
|
21
|
+
import {
|
|
22
|
+
transformerNotationHighlight,
|
|
23
|
+
transformerNotationWordHighlight
|
|
24
|
+
} from "shikiji-transformers";
|
|
25
|
+
|
|
26
|
+
// src/mdx-plugins/hast-utils.ts
|
|
27
|
+
function visit2(node, tagNames, handler) {
|
|
28
|
+
if (node.type === "element") {
|
|
29
|
+
if (tagNames.includes(node.tagName)) {
|
|
30
|
+
handler(node);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if ("children" in node)
|
|
35
|
+
node.children.forEach((n) => {
|
|
36
|
+
visit2(n, tagNames, handler);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/mdx-plugins/rehype-code.ts
|
|
41
|
+
var metaValues = [
|
|
42
|
+
{
|
|
43
|
+
name: "title",
|
|
44
|
+
regex: new RegExp('title="(?<value>[^"]*)"')
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "custom",
|
|
48
|
+
regex: new RegExp('custom="(?<value>[^"]+)"')
|
|
49
|
+
}
|
|
50
|
+
];
|
|
51
|
+
var rehypeCodeDefaultOptions = {
|
|
52
|
+
themes: {
|
|
53
|
+
light: "github-light",
|
|
54
|
+
dark: "github-dark"
|
|
55
|
+
},
|
|
56
|
+
defaultLang: "plaintext",
|
|
57
|
+
defaultColor: false,
|
|
58
|
+
transformers: [
|
|
59
|
+
transformerNotationHighlight(),
|
|
60
|
+
transformerNotationWordHighlight()
|
|
61
|
+
],
|
|
62
|
+
parseMetaString(meta) {
|
|
63
|
+
const map = {};
|
|
64
|
+
for (const value of metaValues) {
|
|
65
|
+
const result = value.regex.exec(meta);
|
|
66
|
+
if (result == null ? void 0 : result.groups) {
|
|
67
|
+
map[value.name] = result.groups.value;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return map;
|
|
71
|
+
},
|
|
72
|
+
filterMetaString(meta) {
|
|
73
|
+
let replaced = meta;
|
|
74
|
+
for (const value of metaValues) {
|
|
75
|
+
replaced = replaced.replace(value.regex, "");
|
|
76
|
+
}
|
|
77
|
+
return replaced;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
function rehypeCode(options = {}) {
|
|
81
|
+
const codeOptions = __spreadValues(__spreadValues({}, rehypeCodeDefaultOptions), options);
|
|
82
|
+
codeOptions.transformers || (codeOptions.transformers = []);
|
|
83
|
+
codeOptions.transformers = [
|
|
84
|
+
{
|
|
85
|
+
name: "rehype-code:filter-meta",
|
|
86
|
+
preprocess(code, { meta }) {
|
|
87
|
+
var _a;
|
|
88
|
+
if (meta && codeOptions.filterMetaString) {
|
|
89
|
+
meta.__raw = codeOptions.filterMetaString((_a = meta.__raw) != null ? _a : "");
|
|
90
|
+
}
|
|
91
|
+
return code.replace(/\n$/, "");
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
...codeOptions.transformers
|
|
95
|
+
];
|
|
96
|
+
const prefix = "language-";
|
|
97
|
+
const transformer = rehypeShikiji.call(this, codeOptions);
|
|
98
|
+
return (root, vfile) => __async(this, null, function* () {
|
|
99
|
+
visit2(root, ["pre"], (element) => {
|
|
100
|
+
var _a;
|
|
101
|
+
const head = element.children[0];
|
|
102
|
+
if (element.children.length === 0 || head.type !== "element" || head.tagName !== "code")
|
|
103
|
+
return;
|
|
104
|
+
(_a = head.properties).className || (_a.className = []);
|
|
105
|
+
const classes = head.properties.className;
|
|
106
|
+
if (!Array.isArray(classes))
|
|
107
|
+
return;
|
|
108
|
+
const hasLanguage = classes.some(
|
|
109
|
+
(d) => typeof d === "string" && d.startsWith(prefix)
|
|
110
|
+
);
|
|
111
|
+
if (!hasLanguage && codeOptions.defaultLang)
|
|
112
|
+
classes.push(`${prefix}${codeOptions.defaultLang}`);
|
|
113
|
+
});
|
|
114
|
+
if (transformer)
|
|
115
|
+
yield transformer.call(this, root, vfile, () => {
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/mdx-plugins/remark-image.ts
|
|
121
|
+
import { existsSync } from "fs";
|
|
122
|
+
import path from "path";
|
|
123
|
+
var VALID_BLUR_EXT = [".jpeg", ".png", ".webp", ".avif", ".jpg"];
|
|
124
|
+
var EXTERNAL_URL_REGEX = /^https?:\/\//;
|
|
125
|
+
var PUBLIC_DIR = path.join(process.cwd(), "public");
|
|
126
|
+
function remarkImage({
|
|
127
|
+
placeholder = "blur"
|
|
128
|
+
} = {}) {
|
|
129
|
+
return (tree, _file, done) => {
|
|
130
|
+
const importsToInject = [];
|
|
131
|
+
visit(tree, ["image"], (node) => {
|
|
132
|
+
var _a;
|
|
133
|
+
let url = decodeURI(node.url);
|
|
134
|
+
if (!url || EXTERNAL_URL_REGEX.test(url)) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (url.startsWith("/")) {
|
|
138
|
+
const urlPath = path.join(PUBLIC_DIR, url);
|
|
139
|
+
if (!existsSync(urlPath)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
url = slash(urlPath);
|
|
143
|
+
}
|
|
144
|
+
const variableName = `__img${importsToInject.length}`;
|
|
145
|
+
const hasBlur = placeholder === "blur" && VALID_BLUR_EXT.some((ext) => url.endsWith(ext));
|
|
146
|
+
importsToInject.push({ variableName, importPath: url });
|
|
147
|
+
Object.assign(node, {
|
|
148
|
+
type: "mdxJsxFlowElement",
|
|
149
|
+
name: "img",
|
|
150
|
+
attributes: [
|
|
151
|
+
{
|
|
152
|
+
type: "mdxJsxAttribute",
|
|
153
|
+
name: "alt",
|
|
154
|
+
value: (_a = node.alt) != null ? _a : "image"
|
|
155
|
+
},
|
|
156
|
+
hasBlur && {
|
|
157
|
+
type: "mdxJsxAttribute",
|
|
158
|
+
name: "placeholder",
|
|
159
|
+
value: "blur"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
type: "mdxJsxAttribute",
|
|
163
|
+
name: "src",
|
|
164
|
+
value: {
|
|
165
|
+
type: "mdxJsxAttributeValueExpression",
|
|
166
|
+
value: variableName,
|
|
167
|
+
data: {
|
|
168
|
+
estree: {
|
|
169
|
+
body: [
|
|
170
|
+
{
|
|
171
|
+
type: "ExpressionStatement",
|
|
172
|
+
expression: { type: "Identifier", name: variableName }
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
].filter(Boolean)
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
if (importsToInject.length) {
|
|
183
|
+
const imports = importsToInject.map(
|
|
184
|
+
({ variableName, importPath }) => ({
|
|
185
|
+
type: "mdxjsEsm",
|
|
186
|
+
data: {
|
|
187
|
+
estree: {
|
|
188
|
+
body: [
|
|
189
|
+
{
|
|
190
|
+
type: "ImportDeclaration",
|
|
191
|
+
source: { type: "Literal", value: importPath },
|
|
192
|
+
specifiers: [
|
|
193
|
+
{
|
|
194
|
+
type: "ImportDefaultSpecifier",
|
|
195
|
+
local: { type: "Identifier", name: variableName }
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
);
|
|
204
|
+
tree.children.unshift(...imports);
|
|
205
|
+
}
|
|
206
|
+
done();
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/mdx-plugins/remark-dynamic-content.ts
|
|
211
|
+
import fs from "fs";
|
|
212
|
+
import path2 from "path";
|
|
213
|
+
var regex = new RegExp("^\\|reference:(?<path>.+)\\|");
|
|
214
|
+
function remarkDynamicContent(options = {}) {
|
|
215
|
+
const {
|
|
216
|
+
cwd = process.cwd(),
|
|
217
|
+
trim = true,
|
|
218
|
+
visit: filter = ["text", "code"]
|
|
219
|
+
} = options;
|
|
220
|
+
return (tree) => {
|
|
221
|
+
visit(tree, filter, (node) => {
|
|
222
|
+
var _a;
|
|
223
|
+
if (!("value" in node) || typeof node.value !== "string")
|
|
224
|
+
return;
|
|
225
|
+
const result = regex.exec(node.value);
|
|
226
|
+
if ((_a = result == null ? void 0 : result.groups) == null ? void 0 : _a.path) {
|
|
227
|
+
const dest = path2.resolve(cwd, result[1]);
|
|
228
|
+
let value = fs.readFileSync(dest).toString();
|
|
229
|
+
if (trim)
|
|
230
|
+
value = value.trim();
|
|
231
|
+
node.value = value;
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/mdx-plugins/remark-structure.ts
|
|
238
|
+
import Slugger from "github-slugger";
|
|
239
|
+
import { remark } from "remark";
|
|
240
|
+
import remarkGfm from "remark-gfm";
|
|
241
|
+
import remarkMdx from "remark-mdx";
|
|
242
|
+
var slugger = new Slugger();
|
|
243
|
+
function remarkStructure({
|
|
244
|
+
types = ["paragraph", "blockquote", "heading"]
|
|
245
|
+
} = {}) {
|
|
246
|
+
return (node, file) => {
|
|
247
|
+
slugger.reset();
|
|
248
|
+
const data = { contents: [], headings: [] };
|
|
249
|
+
let lastHeading = "";
|
|
250
|
+
visit(node, types, (element) => {
|
|
251
|
+
var _a, _b;
|
|
252
|
+
const content = flattenNode(element).trim();
|
|
253
|
+
if (element.type === "heading") {
|
|
254
|
+
element.data || (element.data = {});
|
|
255
|
+
(_a = element.data).hProperties || (_a.hProperties = {});
|
|
256
|
+
const properties = element.data.hProperties;
|
|
257
|
+
const id = (_b = properties.id) != null ? _b : slugger.slug(content);
|
|
258
|
+
data.headings.push({
|
|
259
|
+
id,
|
|
260
|
+
content
|
|
261
|
+
});
|
|
262
|
+
lastHeading = id;
|
|
263
|
+
return "skip";
|
|
264
|
+
}
|
|
265
|
+
if (content.length > 0) {
|
|
266
|
+
data.contents.push({
|
|
267
|
+
heading: lastHeading,
|
|
268
|
+
content
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
return "skip";
|
|
272
|
+
});
|
|
273
|
+
file.data.structuredData = data;
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
function structure(content, remarkPlugins = [], options = {}) {
|
|
277
|
+
const result = remark().use(remarkGfm).use(remarkMdx).use(remarkPlugins).use(remarkStructure, options).processSync(content);
|
|
278
|
+
return result.data.structuredData;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// src/mdx-plugins/remark-install.ts
|
|
282
|
+
function remarkInstall({
|
|
283
|
+
Tab = "Tab",
|
|
284
|
+
Tabs = "Tabs",
|
|
285
|
+
packageManagers = [
|
|
286
|
+
(name) => ({ command: `npm install ${name}`, packageManager: "npm" }),
|
|
287
|
+
(name) => ({ command: `pnpm add ${name}`, packageManager: "pnpm" }),
|
|
288
|
+
(name) => ({ command: `yarn add ${name}`, packageManager: "yarn" })
|
|
289
|
+
]
|
|
290
|
+
} = {}) {
|
|
291
|
+
return (tree) => {
|
|
292
|
+
visit(tree, ["code"], (node) => {
|
|
293
|
+
if (node.lang !== "package-install")
|
|
294
|
+
return "skip";
|
|
295
|
+
const managers = packageManagers.map((manager) => manager(node.value));
|
|
296
|
+
const insert = {
|
|
297
|
+
type: "mdxJsxFlowElement",
|
|
298
|
+
name: Tabs,
|
|
299
|
+
attributes: [
|
|
300
|
+
{
|
|
301
|
+
type: "mdxJsxAttribute",
|
|
302
|
+
name: "items",
|
|
303
|
+
value: {
|
|
304
|
+
type: "mdxJsxAttributeValueExpression",
|
|
305
|
+
data: {
|
|
306
|
+
estree: {
|
|
307
|
+
body: [
|
|
308
|
+
{
|
|
309
|
+
type: "ExpressionStatement",
|
|
310
|
+
expression: {
|
|
311
|
+
type: "ArrayExpression",
|
|
312
|
+
elements: managers.map(({ packageManager }) => ({
|
|
313
|
+
type: "Literal",
|
|
314
|
+
value: packageManager
|
|
315
|
+
}))
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
],
|
|
324
|
+
children: managers.map(({ command, packageManager }) => ({
|
|
325
|
+
type: "mdxJsxFlowElement",
|
|
326
|
+
name: Tab,
|
|
327
|
+
attributes: [
|
|
328
|
+
{ type: "mdxJsxAttribute", name: "value", value: packageManager }
|
|
329
|
+
],
|
|
330
|
+
children: [
|
|
331
|
+
{
|
|
332
|
+
type: "code",
|
|
333
|
+
lang: "bash",
|
|
334
|
+
value: command
|
|
335
|
+
}
|
|
336
|
+
]
|
|
337
|
+
}))
|
|
338
|
+
};
|
|
339
|
+
Object.assign(node, insert);
|
|
340
|
+
});
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
export {
|
|
344
|
+
rehypeCode,
|
|
345
|
+
rehypeCodeDefaultOptions,
|
|
346
|
+
remarkDynamicContent,
|
|
347
|
+
default2 as remarkGfm,
|
|
348
|
+
remarkHeading,
|
|
349
|
+
remarkImage,
|
|
350
|
+
remarkInstall,
|
|
351
|
+
remarkStructure,
|
|
352
|
+
structure
|
|
353
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NextMiddleware } from 'next/dist/server/web/types';
|
|
2
|
+
|
|
3
|
+
interface MiddlewareOptions {
|
|
4
|
+
languages: string[];
|
|
5
|
+
defaultLanguage: string;
|
|
6
|
+
format?: (locale: string, path: string) => string;
|
|
7
|
+
}
|
|
8
|
+
declare function createI18nMiddleware({ languages, defaultLanguage, format, }: MiddlewareOptions): NextMiddleware;
|
|
9
|
+
|
|
10
|
+
export { createI18nMiddleware };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import "./chunk-WEAGW6MQ.js";
|
|
2
|
+
|
|
3
|
+
// src/middleware.ts
|
|
4
|
+
import { match as matchLocale } from "@formatjs/intl-localematcher";
|
|
5
|
+
import Negotiator from "negotiator";
|
|
6
|
+
import nextLib from "next/server";
|
|
7
|
+
function getLocale(request, locales, defaultLanguage) {
|
|
8
|
+
const negotiatorHeaders = {};
|
|
9
|
+
request.headers.forEach((value, key) => negotiatorHeaders[key] = value);
|
|
10
|
+
const languages = new Negotiator({ headers: negotiatorHeaders }).languages(
|
|
11
|
+
locales
|
|
12
|
+
);
|
|
13
|
+
return matchLocale(languages, locales, defaultLanguage);
|
|
14
|
+
}
|
|
15
|
+
var defaultFormat = (locale, path) => {
|
|
16
|
+
return `/${locale}/${path}`;
|
|
17
|
+
};
|
|
18
|
+
function createI18nMiddleware({
|
|
19
|
+
languages,
|
|
20
|
+
defaultLanguage,
|
|
21
|
+
format = defaultFormat
|
|
22
|
+
}) {
|
|
23
|
+
return (request) => {
|
|
24
|
+
const { pathname } = request.nextUrl;
|
|
25
|
+
const pathnameIsMissingLocale = languages.every(
|
|
26
|
+
(locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
|
|
27
|
+
);
|
|
28
|
+
if (pathnameIsMissingLocale) {
|
|
29
|
+
const locale = getLocale(request, languages, defaultLanguage);
|
|
30
|
+
let path = pathname;
|
|
31
|
+
while (path.startsWith("/")) {
|
|
32
|
+
path = path.slice(1);
|
|
33
|
+
}
|
|
34
|
+
return nextLib.NextResponse.redirect(
|
|
35
|
+
new URL(format(locale, path), request.url)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
return nextLib.NextResponse.next();
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
createI18nMiddleware
|
|
43
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
|
|
3
|
+
interface Root {
|
|
4
|
+
name: string;
|
|
5
|
+
children: Node[];
|
|
6
|
+
}
|
|
7
|
+
type Node = Item | Separator | Folder;
|
|
8
|
+
interface Item {
|
|
9
|
+
type: 'page';
|
|
10
|
+
name: string;
|
|
11
|
+
url: string;
|
|
12
|
+
external?: boolean;
|
|
13
|
+
icon?: ReactElement;
|
|
14
|
+
}
|
|
15
|
+
interface Separator {
|
|
16
|
+
type: 'separator';
|
|
17
|
+
name: string;
|
|
18
|
+
}
|
|
19
|
+
interface Folder {
|
|
20
|
+
type: 'folder';
|
|
21
|
+
name: string;
|
|
22
|
+
root?: boolean;
|
|
23
|
+
index?: Item;
|
|
24
|
+
icon?: ReactElement;
|
|
25
|
+
children: Node[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type pageTree_Folder = Folder;
|
|
29
|
+
type pageTree_Item = Item;
|
|
30
|
+
type pageTree_Node = Node;
|
|
31
|
+
type pageTree_Root = Root;
|
|
32
|
+
type pageTree_Separator = Separator;
|
|
33
|
+
declare namespace pageTree {
|
|
34
|
+
export type { pageTree_Folder as Folder, pageTree_Item as Item, pageTree_Node as Node, pageTree_Root as Root, pageTree_Separator as Separator };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { type Item as I, type Node as N, type Root as R, pageTree as p };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Root } from 'mdast';
|
|
2
|
+
import { Transformer, PluggableList } from 'unified';
|
|
3
|
+
|
|
4
|
+
interface Heading {
|
|
5
|
+
id: string;
|
|
6
|
+
content: string;
|
|
7
|
+
}
|
|
8
|
+
interface Content {
|
|
9
|
+
heading: string | undefined;
|
|
10
|
+
content: string;
|
|
11
|
+
}
|
|
12
|
+
interface StructuredData {
|
|
13
|
+
headings: Heading[];
|
|
14
|
+
/**
|
|
15
|
+
* Refer to paragraphs, a heading may contains multiple contents as well
|
|
16
|
+
*/
|
|
17
|
+
contents: Content[];
|
|
18
|
+
}
|
|
19
|
+
interface Options {
|
|
20
|
+
/**
|
|
21
|
+
* Types to be scanned, default: `["heading", "blockquote", "paragraph"]`
|
|
22
|
+
*/
|
|
23
|
+
types?: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Attach structured data to VFile, you can access via `vfile.data.structuredData`.
|
|
27
|
+
*/
|
|
28
|
+
declare function remarkStructure({ types, }?: Options): Transformer<Root, Root>;
|
|
29
|
+
/**
|
|
30
|
+
* Extract data from markdown/mdx content
|
|
31
|
+
*/
|
|
32
|
+
declare function structure(content: string, remarkPlugins?: PluggableList, options?: Options): StructuredData;
|
|
33
|
+
|
|
34
|
+
export { type StructuredData as S, remarkStructure as r, structure as s };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SWRResponse } from 'swr';
|
|
2
|
+
import { SortedResult } from './shared.js';
|
|
3
|
+
|
|
4
|
+
interface UseDocsSearch {
|
|
5
|
+
search: string;
|
|
6
|
+
setSearch: (v: string) => void;
|
|
7
|
+
query: SWRResponse<SortedResult[] | 'empty', Error, {
|
|
8
|
+
keepPreviousData: true;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
declare function useDocsSearch(locale?: string, tag?: string): UseDocsSearch;
|
|
12
|
+
|
|
13
|
+
export { useDocsSearch };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__async
|
|
3
|
+
} from "../chunk-WEAGW6MQ.js";
|
|
4
|
+
|
|
5
|
+
// src/search/client.ts
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
|
+
import useSWR from "swr";
|
|
8
|
+
function fetchDocs(api, query, locale, tag) {
|
|
9
|
+
return __async(this, null, function* () {
|
|
10
|
+
if (query.length === 0)
|
|
11
|
+
return "empty";
|
|
12
|
+
const params = new URLSearchParams();
|
|
13
|
+
params.set("query", query);
|
|
14
|
+
if (locale)
|
|
15
|
+
params.set("locale", locale);
|
|
16
|
+
if (tag)
|
|
17
|
+
params.set("tag", tag);
|
|
18
|
+
const res = yield fetch(`${api}?${params.toString()}`);
|
|
19
|
+
if (!res.ok)
|
|
20
|
+
throw new Error(yield res.text());
|
|
21
|
+
return yield res.json();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function useDocsSearch(locale, tag) {
|
|
25
|
+
const [search, setSearch] = useState("");
|
|
26
|
+
const debouncedValue = useDebounce(search, 100);
|
|
27
|
+
const query = useSWR(
|
|
28
|
+
["/api/search", debouncedValue, locale, tag],
|
|
29
|
+
(_0) => __async(this, [_0], function* ([api, value]) {
|
|
30
|
+
return fetchDocs(api, value, locale, tag);
|
|
31
|
+
}),
|
|
32
|
+
{
|
|
33
|
+
keepPreviousData: true
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
return { search, setSearch, query };
|
|
37
|
+
}
|
|
38
|
+
function useDebounce(value, delayMs = 1e3) {
|
|
39
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
const handler = setTimeout(() => {
|
|
42
|
+
setDebouncedValue(value);
|
|
43
|
+
}, delayMs);
|
|
44
|
+
return () => {
|
|
45
|
+
clearTimeout(handler);
|
|
46
|
+
};
|
|
47
|
+
}, [value, delayMs]);
|
|
48
|
+
return debouncedValue;
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
useDocsSearch
|
|
52
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
import { S as StructuredData } from '../remark-structure-RwYPDA6M.js';
|
|
3
|
+
import { SortedResult } from './shared.js';
|
|
4
|
+
import 'mdast';
|
|
5
|
+
import 'unified';
|
|
6
|
+
|
|
7
|
+
interface SearchAPI {
|
|
8
|
+
GET: (request: NextRequest) => NextResponse<SortedResult[]> | Promise<NextResponse<SortedResult[]>>;
|
|
9
|
+
}
|
|
10
|
+
interface SimpleOptions {
|
|
11
|
+
indexes: Index[];
|
|
12
|
+
language?: string;
|
|
13
|
+
}
|
|
14
|
+
interface AdvancedOptions {
|
|
15
|
+
indexes: AdvancedIndex[];
|
|
16
|
+
/**
|
|
17
|
+
* Enabled custom tags
|
|
18
|
+
*/
|
|
19
|
+
tag?: boolean;
|
|
20
|
+
language?: string;
|
|
21
|
+
}
|
|
22
|
+
type ToI18n<T extends {
|
|
23
|
+
indexes: unknown;
|
|
24
|
+
}> = Omit<T, 'indexes' | 'language'> & {
|
|
25
|
+
indexes: [language: string, indexes: T['indexes']][];
|
|
26
|
+
};
|
|
27
|
+
declare function createSearchAPI<T extends 'simple' | 'advanced'>(type: T, options: T extends 'simple' ? SimpleOptions : AdvancedOptions): SearchAPI;
|
|
28
|
+
declare function createI18nSearchAPI<T extends 'simple' | 'advanced'>(type: T, options: ToI18n<T extends 'simple' ? SimpleOptions : AdvancedOptions>): SearchAPI;
|
|
29
|
+
interface Index {
|
|
30
|
+
title: string;
|
|
31
|
+
content: string;
|
|
32
|
+
url: string;
|
|
33
|
+
keywords?: string;
|
|
34
|
+
}
|
|
35
|
+
declare function initSearchAPI({ indexes, language }: SimpleOptions): SearchAPI;
|
|
36
|
+
interface AdvancedIndex {
|
|
37
|
+
id: string;
|
|
38
|
+
title: string;
|
|
39
|
+
/**
|
|
40
|
+
* Required if `tag` is enabled
|
|
41
|
+
*/
|
|
42
|
+
tag?: string;
|
|
43
|
+
/**
|
|
44
|
+
* preprocess mdx content with `structure`
|
|
45
|
+
*/
|
|
46
|
+
structuredData: StructuredData;
|
|
47
|
+
url: string;
|
|
48
|
+
}
|
|
49
|
+
declare function initSearchAPIAdvanced({ indexes, language, tag, }: AdvancedOptions): SearchAPI;
|
|
50
|
+
|
|
51
|
+
export { createI18nSearchAPI, createSearchAPI, initSearchAPI, initSearchAPIAdvanced };
|