@azerion/bunosaurus-mdx-loader 0.0.0-stage → 4.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/README.md +57 -2
- package/lib/createMDXLoader.d.ts +14 -0
- package/lib/createMDXLoader.d.ts.map +1 -0
- package/lib/createMDXLoader.js +52 -0
- package/lib/createMDXLoader.js.map +1 -0
- package/lib/format.d.ts +14 -0
- package/lib/format.d.ts.map +1 -0
- package/lib/format.js +41 -0
- package/lib/format.js.map +1 -0
- package/lib/frontMatter.d.ts +13 -0
- package/lib/frontMatter.d.ts.map +1 -0
- package/lib/frontMatter.js +23 -0
- package/lib/frontMatter.js.map +1 -0
- package/lib/index.d.ts +35 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +15 -0
- package/lib/index.js.map +1 -0
- package/lib/loader.d.ts +11 -0
- package/lib/loader.d.ts.map +1 -0
- package/lib/loader.js +170 -0
- package/lib/loader.js.map +1 -0
- package/lib/options.d.ts +35 -0
- package/lib/options.d.ts.map +1 -0
- package/lib/options.js +9 -0
- package/lib/options.js.map +1 -0
- package/lib/preprocessor.d.ts +18 -0
- package/lib/preprocessor.d.ts.map +1 -0
- package/lib/preprocessor.js +34 -0
- package/lib/preprocessor.js.map +1 -0
- package/lib/processor.d.ts +49 -0
- package/lib/processor.d.ts.map +1 -0
- package/lib/processor.js +209 -0
- package/lib/processor.js.map +1 -0
- package/lib/remark/admonitions/index.d.ts +11 -0
- package/lib/remark/admonitions/index.d.ts.map +1 -0
- package/lib/remark/admonitions/index.js +107 -0
- package/lib/remark/admonitions/index.js.map +1 -0
- package/lib/remark/contentTitle/index.d.ts +13 -0
- package/lib/remark/contentTitle/index.d.ts.map +1 -0
- package/lib/remark/contentTitle/index.js +62 -0
- package/lib/remark/contentTitle/index.js.map +1 -0
- package/lib/remark/details/index.d.ts +10 -0
- package/lib/remark/details/index.d.ts.map +1 -0
- package/lib/remark/details/index.js +22 -0
- package/lib/remark/details/index.js.map +1 -0
- package/lib/remark/head/index.d.ts +10 -0
- package/lib/remark/head/index.d.ts.map +1 -0
- package/lib/remark/head/index.js +22 -0
- package/lib/remark/head/index.js.map +1 -0
- package/lib/remark/headings/index.d.ts +14 -0
- package/lib/remark/headings/index.d.ts.map +1 -0
- package/lib/remark/headings/index.js +126 -0
- package/lib/remark/headings/index.js.map +1 -0
- package/lib/remark/mdx1Compat/codeCompatPlugin.d.ts +11 -0
- package/lib/remark/mdx1Compat/codeCompatPlugin.d.ts.map +1 -0
- package/lib/remark/mdx1Compat/codeCompatPlugin.js +30 -0
- package/lib/remark/mdx1Compat/codeCompatPlugin.js.map +1 -0
- package/lib/remark/mermaid/index.d.ts +10 -0
- package/lib/remark/mermaid/index.d.ts.map +1 -0
- package/lib/remark/mermaid/index.js +34 -0
- package/lib/remark/mermaid/index.js.map +1 -0
- package/lib/remark/resolveMarkdownLinks/index.d.ts +33 -0
- package/lib/remark/resolveMarkdownLinks/index.d.ts.map +1 -0
- package/lib/remark/resolveMarkdownLinks/index.js +87 -0
- package/lib/remark/resolveMarkdownLinks/index.js.map +1 -0
- package/lib/remark/toc/index.d.ts +14 -0
- package/lib/remark/toc/index.d.ts.map +1 -0
- package/lib/remark/toc/index.js +115 -0
- package/lib/remark/toc/index.js.map +1 -0
- package/lib/remark/toc/types.d.ts +22 -0
- package/lib/remark/toc/types.d.ts.map +1 -0
- package/lib/remark/toc/types.js +9 -0
- package/lib/remark/toc/types.js.map +1 -0
- package/lib/remark/toc/utils.d.ts +26 -0
- package/lib/remark/toc/utils.d.ts.map +1 -0
- package/lib/remark/toc/utils.js +184 -0
- package/lib/remark/toc/utils.js.map +1 -0
- package/lib/remark/transformImage/index.d.ts +17 -0
- package/lib/remark/transformImage/index.d.ts.map +1 -0
- package/lib/remark/transformImage/index.js +187 -0
- package/lib/remark/transformImage/index.js.map +1 -0
- package/lib/remark/transformLinks/index.d.ts +17 -0
- package/lib/remark/transformLinks/index.d.ts.map +1 -0
- package/lib/remark/transformLinks/index.js +205 -0
- package/lib/remark/transformLinks/index.js.map +1 -0
- package/lib/remark/unusedDirectives/index.d.ts +9 -0
- package/lib/remark/unusedDirectives/index.d.ts.map +1 -0
- package/lib/remark/unusedDirectives/index.js +125 -0
- package/lib/remark/unusedDirectives/index.js.map +1 -0
- package/lib/remark/utils/index.d.ts +18 -0
- package/lib/remark/utils/index.d.ts.map +1 -0
- package/lib/remark/utils/index.js +93 -0
- package/lib/remark/utils/index.js.map +1 -0
- package/lib/serializeJS.d.ts +17 -0
- package/lib/serializeJS.d.ts.map +1 -0
- package/lib/serializeJS.js +24 -0
- package/lib/serializeJS.js.map +1 -0
- package/lib/utils.d.ts +35 -0
- package/lib/utils.d.ts.map +1 -0
- package/lib/utils.js +97 -0
- package/lib/utils.js.map +1 -0
- package/package.json +65 -4
- package/src/createMDXLoader.ts +65 -0
- package/src/format.ts +50 -0
- package/src/frontMatter.ts +31 -0
- package/src/index.ts +44 -0
- package/src/loader.ts +227 -0
- package/src/options.ts +37 -0
- package/src/preprocessor.ts +47 -0
- package/src/processor.ts +306 -0
- package/src/remark/admonitions/LICENSE +45 -0
- package/src/remark/admonitions/README.md +3 -0
- package/src/remark/admonitions/index.ts +138 -0
- package/src/remark/contentTitle/index.ts +76 -0
- package/src/remark/details/index.ts +23 -0
- package/src/remark/head/index.ts +23 -0
- package/src/remark/headings/index.ts +158 -0
- package/src/remark/mdx1Compat/codeCompatPlugin.ts +35 -0
- package/src/remark/mermaid/index.ts +35 -0
- package/src/remark/resolveMarkdownLinks/index.ts +137 -0
- package/src/remark/toc/index.ts +183 -0
- package/src/remark/toc/types.ts +29 -0
- package/src/remark/toc/utils.ts +243 -0
- package/src/remark/transformImage/index.ts +268 -0
- package/src/remark/transformLinks/index.ts +291 -0
- package/src/remark/unusedDirectives/index.ts +171 -0
- package/src/remark/utils/index.ts +99 -0
- package/src/serializeJS.ts +22 -0
- package/src/types.d.mts +40 -0
- package/src/utils.ts +134 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import process from 'node:process';
|
|
9
|
+
import {visit} from 'unist-util-visit';
|
|
10
|
+
import logger from '@docusaurus/logger';
|
|
11
|
+
import {toMessageRelativeFilePath, posixPath} from '@docusaurus/utils';
|
|
12
|
+
import {formatNodePositionExtraMessage, transformNode} from '../utils';
|
|
13
|
+
import type {Root} from 'mdast';
|
|
14
|
+
import type {Parent} from 'unist';
|
|
15
|
+
import type {Transformer, Processor, Plugin} from 'unified';
|
|
16
|
+
import type {Directives, TextDirective} from 'mdast-util-directive';
|
|
17
|
+
import type {
|
|
18
|
+
MarkdownConfig,
|
|
19
|
+
OnUnusedMarkdownDirectivesFunction,
|
|
20
|
+
} from '@docusaurus/types';
|
|
21
|
+
|
|
22
|
+
type DirectiveType = Directives['type'];
|
|
23
|
+
|
|
24
|
+
const directiveTypes: DirectiveType[] = [
|
|
25
|
+
'containerDirective',
|
|
26
|
+
'leafDirective',
|
|
27
|
+
'textDirective',
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const directivePrefixMap: {[key in DirectiveType]: string} = {
|
|
31
|
+
textDirective: ':',
|
|
32
|
+
leafDirective: '::',
|
|
33
|
+
containerDirective: ':::',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function formatDirectiveName(directive: Directives) {
|
|
37
|
+
const prefix = directivePrefixMap[directive.type];
|
|
38
|
+
if (!prefix) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`unexpected, no prefix found for directive of type ${directive.type}`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
// To simplify we don't display the eventual label/props of directives
|
|
44
|
+
return `${prefix}${directive.name}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function formatUnusedDirectiveMessage(directive: Directives) {
|
|
48
|
+
const name = formatDirectiveName(directive);
|
|
49
|
+
return `- ${name}${formatNodePositionExtraMessage(directive)}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function formatUnusedDirectivesMessage({
|
|
53
|
+
directives,
|
|
54
|
+
filePath,
|
|
55
|
+
}: {
|
|
56
|
+
directives: Directives[];
|
|
57
|
+
filePath: string;
|
|
58
|
+
}): string {
|
|
59
|
+
const supportUrl = 'https://github.com/facebook/docusaurus/pull/9394';
|
|
60
|
+
const customPath = posixPath(path.relative(process.cwd(), filePath));
|
|
61
|
+
const warningTitle = logger.interpolate`Docusaurus found ${directives.length} unused Markdown directives in file path=${customPath}`;
|
|
62
|
+
const customSupportUrl = logger.interpolate`url=${supportUrl}`;
|
|
63
|
+
const warningMessages = directives
|
|
64
|
+
.map(formatUnusedDirectiveMessage)
|
|
65
|
+
.join('\n');
|
|
66
|
+
|
|
67
|
+
return `${warningTitle}
|
|
68
|
+
${warningMessages}
|
|
69
|
+
Your content might render in an unexpected way. Visit ${customSupportUrl} to find out why and how to fix it.`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type PluginOptions = {
|
|
73
|
+
onUnusedMarkdownDirectives: MarkdownConfig['hooks']['onUnusedMarkdownDirectives'];
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
function asFunction(
|
|
77
|
+
onUnusedMarkdownDirectives: PluginOptions['onUnusedMarkdownDirectives'],
|
|
78
|
+
): OnUnusedMarkdownDirectivesFunction {
|
|
79
|
+
if (typeof onUnusedMarkdownDirectives === 'string') {
|
|
80
|
+
const extraHelp =
|
|
81
|
+
onUnusedMarkdownDirectives === 'throw'
|
|
82
|
+
? logger.interpolate`\nTo ignore this error, use the code=${'siteConfig.markdown.hooks.onUnusedMarkdownDirectives'} option.`
|
|
83
|
+
: '';
|
|
84
|
+
return ({sourceFilePath, directives}) => {
|
|
85
|
+
const relativePath = toMessageRelativeFilePath(sourceFilePath);
|
|
86
|
+
logger.report(onUnusedMarkdownDirectives)`${formatUnusedDirectivesMessage(
|
|
87
|
+
{
|
|
88
|
+
directives,
|
|
89
|
+
filePath: relativePath,
|
|
90
|
+
},
|
|
91
|
+
)}${extraHelp}`;
|
|
92
|
+
};
|
|
93
|
+
} else {
|
|
94
|
+
return (params) =>
|
|
95
|
+
onUnusedMarkdownDirectives({
|
|
96
|
+
...params,
|
|
97
|
+
sourceFilePath: toMessageRelativeFilePath(params.sourceFilePath),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function isTextDirective(directive: Directives): directive is TextDirective {
|
|
103
|
+
return directive.type === 'textDirective';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// A simple text directive is one without any label/props
|
|
107
|
+
function isSimpleTextDirective(
|
|
108
|
+
directive: Directives,
|
|
109
|
+
): directive is TextDirective {
|
|
110
|
+
if (isTextDirective(directive)) {
|
|
111
|
+
// Attributes in MDAST = Directive props
|
|
112
|
+
const hasAttributes =
|
|
113
|
+
directive.attributes && Object.keys(directive.attributes).length > 0;
|
|
114
|
+
// Children in MDAST = Directive label
|
|
115
|
+
const hasChildren = directive.children.length > 0;
|
|
116
|
+
return !hasAttributes && !hasChildren;
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function transformSimpleTextDirectiveToString(textDirective: Directives) {
|
|
122
|
+
transformNode(textDirective, {
|
|
123
|
+
type: 'text',
|
|
124
|
+
value: `:${textDirective.name}`, // We ignore label/props on purpose here
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function isUnusedDirective(directive: Directives) {
|
|
129
|
+
// If directive data is set (notably hName/hProperties set by admonitions)
|
|
130
|
+
// this usually means the directive has been handled by another plugin
|
|
131
|
+
return !directive.data;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const plugin: Plugin<PluginOptions[], Root> = function plugin(
|
|
135
|
+
this: Processor,
|
|
136
|
+
options,
|
|
137
|
+
): Transformer<Root> {
|
|
138
|
+
const onUnusedMarkdownDirectives = asFunction(
|
|
139
|
+
options.onUnusedMarkdownDirectives,
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
return (tree, file) => {
|
|
143
|
+
const unusedDirectives: Directives[] = [];
|
|
144
|
+
|
|
145
|
+
// @ts-expect-error: TODO fix type
|
|
146
|
+
visit<Parent, Directives>(tree, directiveTypes, (directive: Directives) => {
|
|
147
|
+
// If directive data is set (hName/hProperties set by admonitions)
|
|
148
|
+
// this usually means the directive has been handled by another plugin
|
|
149
|
+
if (isUnusedDirective(directive)) {
|
|
150
|
+
if (isSimpleTextDirective(directive)) {
|
|
151
|
+
transformSimpleTextDirectiveToString(directive);
|
|
152
|
+
} else {
|
|
153
|
+
unusedDirectives.push(directive);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// We only process unused directives for the client compiler
|
|
159
|
+
// This avoids emitting duplicate errors/warnings in prod mode
|
|
160
|
+
// Note: the client compiler is used in both dev/prod modes
|
|
161
|
+
// Also: the client compiler is what gets used when using crossCompilerCache
|
|
162
|
+
if (file.data.compilerName === 'client' && unusedDirectives.length > 0) {
|
|
163
|
+
onUnusedMarkdownDirectives({
|
|
164
|
+
sourceFilePath: file.path!,
|
|
165
|
+
directives: unusedDirectives,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export default plugin;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import logger from '@docusaurus/logger';
|
|
9
|
+
import type {Node} from 'unist';
|
|
10
|
+
import type {MdxJsxAttributeValueExpression} from 'mdast-util-mdx';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Util to transform one node type to another node type
|
|
14
|
+
* The input node is mutated in place
|
|
15
|
+
* @param node the node to mutate
|
|
16
|
+
* @param newNode what the original node should become become
|
|
17
|
+
*/
|
|
18
|
+
export function transformNode<NewNode extends Node>(
|
|
19
|
+
node: Node,
|
|
20
|
+
newNode: NewNode,
|
|
21
|
+
): NewNode {
|
|
22
|
+
Object.keys(node).forEach((key) => {
|
|
23
|
+
// @ts-expect-error: unsafe but ok
|
|
24
|
+
delete node[key];
|
|
25
|
+
});
|
|
26
|
+
Object.keys(newNode).forEach((key) => {
|
|
27
|
+
// @ts-expect-error: unsafe but ok
|
|
28
|
+
node[key] = newNode[key];
|
|
29
|
+
});
|
|
30
|
+
return node as NewNode;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function assetRequireAttributeValue(
|
|
34
|
+
requireString: string,
|
|
35
|
+
hash: string,
|
|
36
|
+
): MdxJsxAttributeValueExpression {
|
|
37
|
+
return {
|
|
38
|
+
type: 'mdxJsxAttributeValueExpression',
|
|
39
|
+
value: `require("${requireString}").default${hash && ` + '${hash}'`}`,
|
|
40
|
+
data: {
|
|
41
|
+
estree: {
|
|
42
|
+
type: 'Program',
|
|
43
|
+
body: [
|
|
44
|
+
{
|
|
45
|
+
type: 'ExpressionStatement',
|
|
46
|
+
expression: {
|
|
47
|
+
type: 'BinaryExpression',
|
|
48
|
+
left: {
|
|
49
|
+
type: 'MemberExpression',
|
|
50
|
+
object: {
|
|
51
|
+
type: 'CallExpression',
|
|
52
|
+
callee: {
|
|
53
|
+
type: 'Identifier',
|
|
54
|
+
name: 'require',
|
|
55
|
+
},
|
|
56
|
+
arguments: [
|
|
57
|
+
{
|
|
58
|
+
type: 'Literal',
|
|
59
|
+
value: requireString,
|
|
60
|
+
raw: `"${requireString}"`,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
optional: false,
|
|
64
|
+
},
|
|
65
|
+
property: {
|
|
66
|
+
type: 'Identifier',
|
|
67
|
+
name: 'default',
|
|
68
|
+
},
|
|
69
|
+
computed: false,
|
|
70
|
+
optional: false,
|
|
71
|
+
},
|
|
72
|
+
operator: '+',
|
|
73
|
+
right: {
|
|
74
|
+
type: 'Literal',
|
|
75
|
+
value: hash,
|
|
76
|
+
raw: `"${hash}"`,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
sourceType: 'module',
|
|
82
|
+
comments: [],
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function formatNodePosition(node: Node): string | undefined {
|
|
89
|
+
return node.position?.start
|
|
90
|
+
? logger.interpolate`number=${node.position.start.line}:number=${node.position.start.column}`
|
|
91
|
+
: undefined;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Returns " (line:column)" when position info is available
|
|
95
|
+
// The initial space is useful to append easily to any existing message
|
|
96
|
+
export function formatNodePositionExtraMessage(node: Node): string {
|
|
97
|
+
const position = formatNodePosition(node);
|
|
98
|
+
return `${position ? ` (${position})` : ''}`;
|
|
99
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {generate} from 'astring';
|
|
9
|
+
import {valueToEstree} from 'estree-util-value-to-estree';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Serializes a value to a JS expression string, that can be inlined in the
|
|
13
|
+
* code of a generated JS module, such as the front matter of an MDX file:
|
|
14
|
+
*
|
|
15
|
+
* `export const frontMatter = ${serializeJS(frontMatter)};`
|
|
16
|
+
*
|
|
17
|
+
* Contrary to JSON, the output preserves values such as `undefined`, `NaN`,
|
|
18
|
+
* `Infinity` or `Date` instances.
|
|
19
|
+
*/
|
|
20
|
+
export function serializeJS(value: unknown): string {
|
|
21
|
+
return generate(valueToEstree(value, {instanceAsObject: true}));
|
|
22
|
+
}
|
package/src/types.d.mts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {WebpackCompilerName} from '@docusaurus/utils';
|
|
9
|
+
|
|
10
|
+
declare module 'vfile' {
|
|
11
|
+
/*
|
|
12
|
+
This map registers the type of the data key of a VFile (TypeScript type).
|
|
13
|
+
This type can be augmented to register custom data types.
|
|
14
|
+
See https://github.com/vfile/vfile#datamap
|
|
15
|
+
*/
|
|
16
|
+
interface DataMap {
|
|
17
|
+
frontMatter: {[key: string]: unknown};
|
|
18
|
+
compilerName: WebpackCompilerName;
|
|
19
|
+
contentTitle?: string;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
declare module 'unist' {
|
|
24
|
+
interface Data {
|
|
25
|
+
hName?: string;
|
|
26
|
+
hProperties?: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare module 'mdast' {
|
|
31
|
+
interface Data {
|
|
32
|
+
id?: string;
|
|
33
|
+
hName?: string;
|
|
34
|
+
hProperties?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface HeadingData {
|
|
38
|
+
hProperties?: {id?: string};
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import logger from '@docusaurus/logger';
|
|
9
|
+
import {escapePath, type WebpackCompilerName} from '@docusaurus/utils';
|
|
10
|
+
import {getProcessor, type SimpleProcessorResult} from './processor';
|
|
11
|
+
import {validateMDXFrontMatter} from './frontMatter';
|
|
12
|
+
import preprocessor from './preprocessor';
|
|
13
|
+
import type {Options} from './options';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Converts assets an object with Webpack require calls code.
|
|
17
|
+
* This is useful for mdx files to reference co-located assets using relative
|
|
18
|
+
* paths. Those assets should enter the Webpack assets pipeline and be hashed.
|
|
19
|
+
* For now, we only handle that for images and paths starting with `./`:
|
|
20
|
+
*
|
|
21
|
+
* `{image: "./myImage.png"}` => `{image: require("./myImage.png")}`
|
|
22
|
+
*/
|
|
23
|
+
export function createAssetsExportCode({
|
|
24
|
+
assets,
|
|
25
|
+
inlineMarkdownAssetImageFileLoader,
|
|
26
|
+
}: {
|
|
27
|
+
assets: unknown;
|
|
28
|
+
inlineMarkdownAssetImageFileLoader: string;
|
|
29
|
+
}): string {
|
|
30
|
+
if (
|
|
31
|
+
typeof assets !== 'object' ||
|
|
32
|
+
!assets ||
|
|
33
|
+
Object.keys(assets).length === 0
|
|
34
|
+
) {
|
|
35
|
+
return 'undefined';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// TODO implementation can be completed/enhanced
|
|
39
|
+
function createAssetValueCode(assetValue: unknown): string | undefined {
|
|
40
|
+
if (Array.isArray(assetValue)) {
|
|
41
|
+
const arrayItemCodes = assetValue.map(
|
|
42
|
+
(item: unknown) => createAssetValueCode(item) ?? 'undefined',
|
|
43
|
+
);
|
|
44
|
+
return `[${arrayItemCodes.join(', ')}]`;
|
|
45
|
+
}
|
|
46
|
+
// Only process string values starting with ./
|
|
47
|
+
// We could enhance this logic and check if file exists on disc?
|
|
48
|
+
if (typeof assetValue === 'string' && assetValue.startsWith('./')) {
|
|
49
|
+
// TODO do we have other use-cases than image assets?
|
|
50
|
+
// Probably not worth adding more support, as we want to move to Webpack 5 new asset system (https://github.com/facebook/docusaurus/pull/4708)
|
|
51
|
+
return `require("${inlineMarkdownAssetImageFileLoader}${escapePath(
|
|
52
|
+
assetValue,
|
|
53
|
+
)}").default`;
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const assetEntries = Object.entries(assets);
|
|
59
|
+
|
|
60
|
+
const codeLines = assetEntries
|
|
61
|
+
.map(([key, value]: [string, unknown]) => {
|
|
62
|
+
const assetRequireCode = createAssetValueCode(value);
|
|
63
|
+
return assetRequireCode ? `"${key}": ${assetRequireCode},` : undefined;
|
|
64
|
+
})
|
|
65
|
+
.filter(Boolean);
|
|
66
|
+
|
|
67
|
+
return `{\n${codeLines.join('\n')}\n}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* data.contentTitle is set by the remark contentTitle plugin
|
|
72
|
+
*/
|
|
73
|
+
export function extractContentTitleData(data: {
|
|
74
|
+
[key: string]: unknown;
|
|
75
|
+
}): string | undefined {
|
|
76
|
+
return data.contentTitle as string | undefined;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function compileToJSX({
|
|
80
|
+
filePath,
|
|
81
|
+
fileContent,
|
|
82
|
+
frontMatter,
|
|
83
|
+
options,
|
|
84
|
+
compilerName,
|
|
85
|
+
}: {
|
|
86
|
+
filePath: string;
|
|
87
|
+
fileContent: string;
|
|
88
|
+
frontMatter: Record<string, unknown>;
|
|
89
|
+
options: Options;
|
|
90
|
+
compilerName: WebpackCompilerName;
|
|
91
|
+
}): Promise<SimpleProcessorResult> {
|
|
92
|
+
const preprocessedFileContent = preprocessor({
|
|
93
|
+
fileContent,
|
|
94
|
+
filePath,
|
|
95
|
+
admonitions: options.admonitions,
|
|
96
|
+
markdownConfig: options.markdownConfig,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const mdxFrontMatter = validateMDXFrontMatter(frontMatter.mdx);
|
|
100
|
+
|
|
101
|
+
const processor = getProcessor({
|
|
102
|
+
filePath,
|
|
103
|
+
options,
|
|
104
|
+
mdxFrontMatter,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
return await processor.process({
|
|
109
|
+
content: preprocessedFileContent,
|
|
110
|
+
filePath,
|
|
111
|
+
frontMatter,
|
|
112
|
+
compilerName,
|
|
113
|
+
});
|
|
114
|
+
} catch (errorUnknown) {
|
|
115
|
+
const error = errorUnknown as Error;
|
|
116
|
+
|
|
117
|
+
// MDX can emit errors that have useful extra attributes
|
|
118
|
+
const errorJSON = JSON.stringify(error, null, 2);
|
|
119
|
+
const errorDetails =
|
|
120
|
+
errorJSON === '{}'
|
|
121
|
+
? // regular JS error case: print stacktrace
|
|
122
|
+
(error.stack ?? 'N/A')
|
|
123
|
+
: // MDX error: print extra attributes + stacktrace
|
|
124
|
+
`${errorJSON}\n${error.stack}`;
|
|
125
|
+
|
|
126
|
+
throw new Error(
|
|
127
|
+
`MDX compilation failed for file ${logger.path(filePath)}\nCause: ${
|
|
128
|
+
error.message
|
|
129
|
+
}\nDetails:\n${errorDetails}`,
|
|
130
|
+
// TODO error cause doesn't seem to be used by Webpack stats.errors :s
|
|
131
|
+
{cause: errorUnknown},
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|