/
plugin-options.ts
134 lines (115 loc) · 4.16 KB
/
plugin-options.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import type { ProcessorOptions } from "@mdx-js/mdx"
import type { GatsbyCache, NodePluginArgs, PluginOptions, Store } from "gatsby"
import deepmerge from "deepmerge"
import type { IPluginInfo } from "gatsby-plugin-utils/types"
import { cachedImport } from "./cache-helpers"
import { getSourcePluginsAsRemarkPlugins } from "./get-source-plugins-as-remark-plugins"
import rehypeMdxMetadataExtractor from "./rehype-metadata-extractor"
import { remarkMdxHtmlPlugin } from "./remark-mdx-html-plugin"
import { remarkPathPlugin } from "./remark-path-prefix-plugin"
export interface IMdxPluginOptions {
extensions: [string]
mdxOptions: ProcessorOptions
gatsbyRemarkPlugins?: [IPluginInfo]
}
interface IHelpers {
getNode: NodePluginArgs["getNode"]
getNodesByType: NodePluginArgs["getNodesByType"]
pathPrefix: NodePluginArgs["pathPrefix"]
reporter: NodePluginArgs["reporter"]
cache: GatsbyCache
store: Store
}
type MdxDefaultOptions = (pluginOptions: PluginOptions) => IMdxPluginOptions
export const defaultOptions: MdxDefaultOptions = pluginOptions => {
const mdxOptions: ProcessorOptions = {
format: `mdx`,
useDynamicImport: true,
providerImportSource: `@mdx-js/react`,
}
const defaults = {
extensions: [`.mdx`],
mdxOptions,
}
const options = deepmerge(
defaults,
pluginOptions
) as unknown as IMdxPluginOptions
return options
}
type EnhanceMdxOptions = (
pluginOptions: PluginOptions,
helpers: IHelpers
) => Promise<ProcessorOptions>
export const enhanceMdxOptions: EnhanceMdxOptions = async (
pluginOptions,
helpers
) => {
const options = defaultOptions(pluginOptions)
const { default: remarkUnwrapImages } = await cachedImport<
typeof import("remark-unwrap-images")
>(`remark-unwrap-images`)
// Set jsxRuntime & jsxImportSource based on Gatsby project config
const { config } = helpers.store.getState()
const { jsxRuntime, jsxImportSource } = config
options.mdxOptions.jsxRuntime = jsxRuntime || `classic`
options.mdxOptions.jsxImportSource = jsxImportSource || `react`
if (!options.mdxOptions.remarkPlugins) {
options.mdxOptions.remarkPlugins = []
}
// The unwrapping has to happen before any other remark plugins are run (especially gatsby-remark-images)
// Otherwise remark-unwrap-images would operate on the already transformed images
options.mdxOptions.remarkPlugins.push(remarkUnwrapImages)
// Inject Gatsby path prefix if needed
if (helpers.pathPrefix) {
options.mdxOptions.remarkPlugins.push([
remarkPathPlugin,
{ pathPrefix: helpers.pathPrefix },
])
}
// Support gatsby-remark-* plugins
if (
options.gatsbyRemarkPlugins &&
Object.keys(options.gatsbyRemarkPlugins).length
) {
if (!options.mdxOptions.remarkPlugins) {
options.mdxOptions.remarkPlugins = []
}
// Parser plugins
for (const plugin of options.gatsbyRemarkPlugins) {
const requiredPlugin = plugin.module
if (typeof requiredPlugin.setParserPlugins === `function`) {
for (const parserPlugin of requiredPlugin.setParserPlugins(
plugin.pluginOptions || {}
)) {
if (Array.isArray(parserPlugin)) {
const [parser, parserPluginOptions] = parserPlugin
options.mdxOptions.remarkPlugins.push([parser, parserPluginOptions])
} else {
options.mdxOptions.remarkPlugins.push(parserPlugin)
}
}
}
}
// Transformer plugins
const gatsbyRemarkPlugins = await getSourcePluginsAsRemarkPlugins({
gatsbyRemarkPlugins: options.gatsbyRemarkPlugins,
...helpers,
})
if (gatsbyRemarkPlugins) {
options.mdxOptions.remarkPlugins.push(...gatsbyRemarkPlugins)
}
}
options.mdxOptions.remarkPlugins.push(remarkMdxHtmlPlugin)
if (!options.mdxOptions.rehypePlugins) {
options.mdxOptions.rehypePlugins = []
}
const passThrough = [`element`]
if (!options.mdxOptions.remarkRehypeOptions) {
options.mdxOptions.remarkRehypeOptions = {}
}
options.mdxOptions.remarkRehypeOptions.passThrough = passThrough
// Extract metadata generated from by rehype-infer-* and similar plugins
options.mdxOptions.rehypePlugins.push(rehypeMdxMetadataExtractor)
return options.mdxOptions
}