@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.
Files changed (130) hide show
  1. package/README.md +57 -2
  2. package/lib/createMDXLoader.d.ts +14 -0
  3. package/lib/createMDXLoader.d.ts.map +1 -0
  4. package/lib/createMDXLoader.js +52 -0
  5. package/lib/createMDXLoader.js.map +1 -0
  6. package/lib/format.d.ts +14 -0
  7. package/lib/format.d.ts.map +1 -0
  8. package/lib/format.js +41 -0
  9. package/lib/format.js.map +1 -0
  10. package/lib/frontMatter.d.ts +13 -0
  11. package/lib/frontMatter.d.ts.map +1 -0
  12. package/lib/frontMatter.js +23 -0
  13. package/lib/frontMatter.js.map +1 -0
  14. package/lib/index.d.ts +35 -0
  15. package/lib/index.d.ts.map +1 -0
  16. package/lib/index.js +15 -0
  17. package/lib/index.js.map +1 -0
  18. package/lib/loader.d.ts +11 -0
  19. package/lib/loader.d.ts.map +1 -0
  20. package/lib/loader.js +170 -0
  21. package/lib/loader.js.map +1 -0
  22. package/lib/options.d.ts +35 -0
  23. package/lib/options.d.ts.map +1 -0
  24. package/lib/options.js +9 -0
  25. package/lib/options.js.map +1 -0
  26. package/lib/preprocessor.d.ts +18 -0
  27. package/lib/preprocessor.d.ts.map +1 -0
  28. package/lib/preprocessor.js +34 -0
  29. package/lib/preprocessor.js.map +1 -0
  30. package/lib/processor.d.ts +49 -0
  31. package/lib/processor.d.ts.map +1 -0
  32. package/lib/processor.js +209 -0
  33. package/lib/processor.js.map +1 -0
  34. package/lib/remark/admonitions/index.d.ts +11 -0
  35. package/lib/remark/admonitions/index.d.ts.map +1 -0
  36. package/lib/remark/admonitions/index.js +107 -0
  37. package/lib/remark/admonitions/index.js.map +1 -0
  38. package/lib/remark/contentTitle/index.d.ts +13 -0
  39. package/lib/remark/contentTitle/index.d.ts.map +1 -0
  40. package/lib/remark/contentTitle/index.js +62 -0
  41. package/lib/remark/contentTitle/index.js.map +1 -0
  42. package/lib/remark/details/index.d.ts +10 -0
  43. package/lib/remark/details/index.d.ts.map +1 -0
  44. package/lib/remark/details/index.js +22 -0
  45. package/lib/remark/details/index.js.map +1 -0
  46. package/lib/remark/head/index.d.ts +10 -0
  47. package/lib/remark/head/index.d.ts.map +1 -0
  48. package/lib/remark/head/index.js +22 -0
  49. package/lib/remark/head/index.js.map +1 -0
  50. package/lib/remark/headings/index.d.ts +14 -0
  51. package/lib/remark/headings/index.d.ts.map +1 -0
  52. package/lib/remark/headings/index.js +126 -0
  53. package/lib/remark/headings/index.js.map +1 -0
  54. package/lib/remark/mdx1Compat/codeCompatPlugin.d.ts +11 -0
  55. package/lib/remark/mdx1Compat/codeCompatPlugin.d.ts.map +1 -0
  56. package/lib/remark/mdx1Compat/codeCompatPlugin.js +30 -0
  57. package/lib/remark/mdx1Compat/codeCompatPlugin.js.map +1 -0
  58. package/lib/remark/mermaid/index.d.ts +10 -0
  59. package/lib/remark/mermaid/index.d.ts.map +1 -0
  60. package/lib/remark/mermaid/index.js +34 -0
  61. package/lib/remark/mermaid/index.js.map +1 -0
  62. package/lib/remark/resolveMarkdownLinks/index.d.ts +33 -0
  63. package/lib/remark/resolveMarkdownLinks/index.d.ts.map +1 -0
  64. package/lib/remark/resolveMarkdownLinks/index.js +87 -0
  65. package/lib/remark/resolveMarkdownLinks/index.js.map +1 -0
  66. package/lib/remark/toc/index.d.ts +14 -0
  67. package/lib/remark/toc/index.d.ts.map +1 -0
  68. package/lib/remark/toc/index.js +115 -0
  69. package/lib/remark/toc/index.js.map +1 -0
  70. package/lib/remark/toc/types.d.ts +22 -0
  71. package/lib/remark/toc/types.d.ts.map +1 -0
  72. package/lib/remark/toc/types.js +9 -0
  73. package/lib/remark/toc/types.js.map +1 -0
  74. package/lib/remark/toc/utils.d.ts +26 -0
  75. package/lib/remark/toc/utils.d.ts.map +1 -0
  76. package/lib/remark/toc/utils.js +184 -0
  77. package/lib/remark/toc/utils.js.map +1 -0
  78. package/lib/remark/transformImage/index.d.ts +17 -0
  79. package/lib/remark/transformImage/index.d.ts.map +1 -0
  80. package/lib/remark/transformImage/index.js +187 -0
  81. package/lib/remark/transformImage/index.js.map +1 -0
  82. package/lib/remark/transformLinks/index.d.ts +17 -0
  83. package/lib/remark/transformLinks/index.d.ts.map +1 -0
  84. package/lib/remark/transformLinks/index.js +205 -0
  85. package/lib/remark/transformLinks/index.js.map +1 -0
  86. package/lib/remark/unusedDirectives/index.d.ts +9 -0
  87. package/lib/remark/unusedDirectives/index.d.ts.map +1 -0
  88. package/lib/remark/unusedDirectives/index.js +125 -0
  89. package/lib/remark/unusedDirectives/index.js.map +1 -0
  90. package/lib/remark/utils/index.d.ts +18 -0
  91. package/lib/remark/utils/index.d.ts.map +1 -0
  92. package/lib/remark/utils/index.js +93 -0
  93. package/lib/remark/utils/index.js.map +1 -0
  94. package/lib/serializeJS.d.ts +17 -0
  95. package/lib/serializeJS.d.ts.map +1 -0
  96. package/lib/serializeJS.js +24 -0
  97. package/lib/serializeJS.js.map +1 -0
  98. package/lib/utils.d.ts +35 -0
  99. package/lib/utils.d.ts.map +1 -0
  100. package/lib/utils.js +97 -0
  101. package/lib/utils.js.map +1 -0
  102. package/package.json +65 -4
  103. package/src/createMDXLoader.ts +65 -0
  104. package/src/format.ts +50 -0
  105. package/src/frontMatter.ts +31 -0
  106. package/src/index.ts +44 -0
  107. package/src/loader.ts +227 -0
  108. package/src/options.ts +37 -0
  109. package/src/preprocessor.ts +47 -0
  110. package/src/processor.ts +306 -0
  111. package/src/remark/admonitions/LICENSE +45 -0
  112. package/src/remark/admonitions/README.md +3 -0
  113. package/src/remark/admonitions/index.ts +138 -0
  114. package/src/remark/contentTitle/index.ts +76 -0
  115. package/src/remark/details/index.ts +23 -0
  116. package/src/remark/head/index.ts +23 -0
  117. package/src/remark/headings/index.ts +158 -0
  118. package/src/remark/mdx1Compat/codeCompatPlugin.ts +35 -0
  119. package/src/remark/mermaid/index.ts +35 -0
  120. package/src/remark/resolveMarkdownLinks/index.ts +137 -0
  121. package/src/remark/toc/index.ts +183 -0
  122. package/src/remark/toc/types.ts +29 -0
  123. package/src/remark/toc/utils.ts +243 -0
  124. package/src/remark/transformImage/index.ts +268 -0
  125. package/src/remark/transformLinks/index.ts +291 -0
  126. package/src/remark/unusedDirectives/index.ts +171 -0
  127. package/src/remark/utils/index.ts +99 -0
  128. package/src/serializeJS.ts +22 -0
  129. package/src/types.d.mts +40 -0
  130. 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
+ }
@@ -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
+ }