fumadocs-core 13.2.0 → 13.2.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.
|
@@ -20,6 +20,12 @@ function remarkHeading({
|
|
|
20
20
|
return (root, file) => {
|
|
21
21
|
const toc = [];
|
|
22
22
|
slugger.reset();
|
|
23
|
+
if (file.data.frontmatter) {
|
|
24
|
+
const frontmatter = file.data.frontmatter;
|
|
25
|
+
if (frontmatter._openapi?.toc) {
|
|
26
|
+
toc.push(...frontmatter._openapi.toc);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
23
29
|
visit(root, "heading", (heading) => {
|
|
24
30
|
heading.data ||= {};
|
|
25
31
|
heading.data.hProperties ||= {};
|
|
@@ -43,17 +43,41 @@ type RehypeCodeOptions = RehypeShikiOptions & {
|
|
|
43
43
|
declare function rehypeCode(this: Processor, options?: Partial<RehypeCodeOptions>): Transformer<Root, Root>;
|
|
44
44
|
|
|
45
45
|
interface RemarkImageOptions {
|
|
46
|
+
/**
|
|
47
|
+
* Directory to resolve absolute image paths
|
|
48
|
+
*/
|
|
49
|
+
publicDir?: string;
|
|
46
50
|
/**
|
|
47
51
|
* Preferred placeholder type
|
|
48
52
|
*
|
|
49
53
|
* @defaultValue 'blur'
|
|
50
54
|
*/
|
|
51
55
|
placeholder?: 'blur' | 'none';
|
|
56
|
+
/**
|
|
57
|
+
* Import images in the file, and let bundlers handle it.
|
|
58
|
+
*
|
|
59
|
+
* ```tsx
|
|
60
|
+
* import MyImage from "./public/img.png";
|
|
61
|
+
*
|
|
62
|
+
* <img src={MyImage} />
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* When disabled, `placeholder` will be ignored.
|
|
66
|
+
*
|
|
67
|
+
* @defaultValue true
|
|
68
|
+
*/
|
|
69
|
+
useImport?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Fetch image size of external URLs
|
|
72
|
+
*
|
|
73
|
+
* @defaultValue true
|
|
74
|
+
*/
|
|
75
|
+
external?: boolean;
|
|
52
76
|
}
|
|
53
77
|
/**
|
|
54
|
-
* Turn images into
|
|
78
|
+
* Turn images into Next.js Image compatible usage.
|
|
55
79
|
*/
|
|
56
|
-
declare function remarkImage({ placeholder, }?: RemarkImageOptions): Transformer<Root$1, Root$1>;
|
|
80
|
+
declare function remarkImage({ placeholder, external, useImport, publicDir, }?: RemarkImageOptions): Transformer<Root$1, Root$1>;
|
|
57
81
|
|
|
58
82
|
declare module 'mdast' {
|
|
59
83
|
interface HeadingData extends Data {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
flattenNode,
|
|
3
3
|
remarkHeading
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-UQV4A7HQ.js";
|
|
5
5
|
import {
|
|
6
6
|
slash
|
|
7
7
|
} from "../chunk-UWEEHUJV.js";
|
|
@@ -270,68 +270,104 @@ function transformerTab() {
|
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
// src/mdx-plugins/remark-image.ts
|
|
273
|
-
import { existsSync } from "fs";
|
|
274
273
|
import path from "path";
|
|
275
274
|
import { visit } from "unist-util-visit";
|
|
275
|
+
import sizeOf from "image-size";
|
|
276
276
|
var VALID_BLUR_EXT = [".jpeg", ".png", ".webp", ".avif", ".jpg"];
|
|
277
277
|
var EXTERNAL_URL_REGEX = /^https?:\/\//;
|
|
278
|
-
var PUBLIC_DIR = path.join(process.cwd(), "public");
|
|
279
278
|
function remarkImage({
|
|
280
|
-
placeholder = "blur"
|
|
279
|
+
placeholder = "blur",
|
|
280
|
+
external = true,
|
|
281
|
+
useImport = true,
|
|
282
|
+
publicDir = path.join(process.cwd(), "public")
|
|
281
283
|
} = {}) {
|
|
282
|
-
return (tree
|
|
284
|
+
return async (tree) => {
|
|
283
285
|
const importsToInject = [];
|
|
286
|
+
const promises = [];
|
|
284
287
|
visit(tree, "image", (node) => {
|
|
285
|
-
|
|
286
|
-
if (!
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
288
|
+
const src = decodeURI(node.url);
|
|
289
|
+
if (!src) return;
|
|
290
|
+
const isExternal = EXTERNAL_URL_REGEX.test(src);
|
|
291
|
+
if (isExternal && external || !useImport) {
|
|
292
|
+
promises.push(
|
|
293
|
+
getImageSize(src, publicDir).then((size) => {
|
|
294
|
+
if (!size.width || !size.height) return;
|
|
295
|
+
Object.assign(node, {
|
|
296
|
+
type: "mdxJsxFlowElement",
|
|
297
|
+
name: "img",
|
|
298
|
+
attributes: [
|
|
299
|
+
{
|
|
300
|
+
type: "mdxJsxAttribute",
|
|
301
|
+
name: "alt",
|
|
302
|
+
value: node.alt ?? "image"
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
type: "mdxJsxAttribute",
|
|
306
|
+
name: "src",
|
|
307
|
+
value: src
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
type: "mdxJsxAttribute",
|
|
311
|
+
name: "width",
|
|
312
|
+
value: size.width.toString()
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
type: "mdxJsxAttribute",
|
|
316
|
+
name: "height",
|
|
317
|
+
value: size.height.toString()
|
|
318
|
+
}
|
|
319
|
+
]
|
|
320
|
+
});
|
|
321
|
+
})
|
|
322
|
+
);
|
|
323
|
+
} else if (!isExternal) {
|
|
324
|
+
const variableName = `__img${importsToInject.length.toString()}`;
|
|
325
|
+
const hasBlur = placeholder === "blur" && VALID_BLUR_EXT.some((ext) => src.endsWith(ext));
|
|
326
|
+
importsToInject.push({
|
|
327
|
+
variableName,
|
|
328
|
+
importPath: slash(
|
|
329
|
+
// with imports, relative paths don't have to be absolute
|
|
330
|
+
src.startsWith("/") ? path.join(publicDir, src) : src
|
|
331
|
+
)
|
|
332
|
+
});
|
|
333
|
+
Object.assign(node, {
|
|
334
|
+
type: "mdxJsxFlowElement",
|
|
335
|
+
name: "img",
|
|
336
|
+
attributes: [
|
|
337
|
+
{
|
|
338
|
+
type: "mdxJsxAttribute",
|
|
339
|
+
name: "alt",
|
|
340
|
+
value: node.alt ?? "image"
|
|
341
|
+
},
|
|
342
|
+
hasBlur && {
|
|
343
|
+
type: "mdxJsxAttribute",
|
|
344
|
+
name: "placeholder",
|
|
345
|
+
value: "blur"
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
type: "mdxJsxAttribute",
|
|
349
|
+
name: "src",
|
|
350
|
+
value: {
|
|
351
|
+
type: "mdxJsxAttributeValueExpression",
|
|
352
|
+
value: variableName,
|
|
353
|
+
data: {
|
|
354
|
+
estree: {
|
|
355
|
+
body: [
|
|
356
|
+
{
|
|
357
|
+
type: "ExpressionStatement",
|
|
358
|
+
expression: { type: "Identifier", name: variableName }
|
|
359
|
+
}
|
|
360
|
+
]
|
|
361
|
+
}
|
|
327
362
|
}
|
|
328
363
|
}
|
|
329
364
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
}
|
|
365
|
+
].filter(Boolean)
|
|
366
|
+
});
|
|
367
|
+
}
|
|
333
368
|
});
|
|
334
|
-
|
|
369
|
+
await Promise.all(promises);
|
|
370
|
+
if (importsToInject.length > 0) {
|
|
335
371
|
const imports = importsToInject.map(
|
|
336
372
|
({ variableName, importPath }) => ({
|
|
337
373
|
type: "mdxjsEsm",
|
|
@@ -355,9 +391,20 @@ function remarkImage({
|
|
|
355
391
|
);
|
|
356
392
|
tree.children.unshift(...imports);
|
|
357
393
|
}
|
|
358
|
-
done();
|
|
359
394
|
};
|
|
360
395
|
}
|
|
396
|
+
function resolveSrc(src, dir) {
|
|
397
|
+
return src.startsWith("/") || !path.isAbsolute(src) ? path.join(dir, src) : src;
|
|
398
|
+
}
|
|
399
|
+
async function getImageSize(src, dir) {
|
|
400
|
+
if (EXTERNAL_URL_REGEX.test(src)) {
|
|
401
|
+
const res = await fetch(src);
|
|
402
|
+
return sizeOf(
|
|
403
|
+
await res.arrayBuffer().then((buffer) => new Uint8Array(buffer))
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
return sizeOf(resolveSrc(src, dir));
|
|
407
|
+
}
|
|
361
408
|
|
|
362
409
|
// src/mdx-plugins/remark-structure.ts
|
|
363
410
|
import Slugger from "github-slugger";
|
|
@@ -373,6 +420,13 @@ function remarkStructure({
|
|
|
373
420
|
slugger.reset();
|
|
374
421
|
const data = { contents: [], headings: [] };
|
|
375
422
|
let lastHeading = "";
|
|
423
|
+
if (file.data.frontmatter) {
|
|
424
|
+
const frontmatter = file.data.frontmatter;
|
|
425
|
+
if (frontmatter._openapi?.structuredData) {
|
|
426
|
+
data.headings.push(...frontmatter._openapi.structuredData.headings);
|
|
427
|
+
data.contents.push(...frontmatter._openapi.structuredData.contents);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
376
430
|
visit2(node, types, (element) => {
|
|
377
431
|
if (element.type === "root") return;
|
|
378
432
|
const content = flattenNode(element).trim();
|
package/dist/server/index.js
CHANGED
package/dist/toc.js
CHANGED
|
@@ -36,12 +36,14 @@ function useAnchorObserver(watch) {
|
|
|
36
36
|
return f ?? watch[0];
|
|
37
37
|
});
|
|
38
38
|
},
|
|
39
|
-
{ rootMargin: `-
|
|
39
|
+
{ rootMargin: `-80px 0% -78% 0%`, threshold: 1 }
|
|
40
40
|
);
|
|
41
41
|
const scroll = () => {
|
|
42
42
|
const element = document.scrollingElement;
|
|
43
43
|
if (!element) return;
|
|
44
|
-
if (element.scrollTop
|
|
44
|
+
if (element.scrollTop === 0) {
|
|
45
|
+
setActiveAnchor(watch.at(0));
|
|
46
|
+
} else if (element.scrollTop >= // assume you have a 10px margin
|
|
45
47
|
element.scrollHeight - element.clientHeight - 10) {
|
|
46
48
|
setActiveAnchor(watch.at(-1));
|
|
47
49
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-core",
|
|
3
|
-
"version": "13.2.
|
|
3
|
+
"version": "13.2.2",
|
|
4
4
|
"description": "The library for building a documentation website in Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NextJs",
|
|
@@ -120,10 +120,11 @@
|
|
|
120
120
|
],
|
|
121
121
|
"dependencies": {
|
|
122
122
|
"@formatjs/intl-localematcher": "^0.5.4",
|
|
123
|
-
"@shikijs/rehype": "^1.
|
|
124
|
-
"@shikijs/transformers": "^1.
|
|
123
|
+
"@shikijs/rehype": "^1.12.1",
|
|
124
|
+
"@shikijs/transformers": "^1.12.1",
|
|
125
125
|
"flexsearch": "0.7.21",
|
|
126
126
|
"github-slugger": "^2.0.0",
|
|
127
|
+
"image-size": "^1.1.1",
|
|
127
128
|
"negotiator": "^0.6.3",
|
|
128
129
|
"npm-to-yarn": "^2.2.1",
|
|
129
130
|
"react-remove-scroll": "^2.5.10",
|
|
@@ -131,7 +132,7 @@
|
|
|
131
132
|
"remark-gfm": "^4.0.0",
|
|
132
133
|
"remark-mdx": "^3.0.1",
|
|
133
134
|
"scroll-into-view-if-needed": "^3.1.0",
|
|
134
|
-
"shiki": "^1.
|
|
135
|
+
"shiki": "^1.12.1",
|
|
135
136
|
"swr": "^2.2.5",
|
|
136
137
|
"unist-util-visit": "^5.0.0"
|
|
137
138
|
},
|