🎉 initiate project *astro_rewrite*

This commit is contained in:
sindrekjelsrud 2023-07-19 21:31:30 +02:00
parent ffd4d5e86c
commit 2ba37bfbe3
8658 changed files with 2268794 additions and 2538 deletions

45
node_modules/@mdx-js/mdx/lib/compile.d.ts generated vendored Normal file
View file

@ -0,0 +1,45 @@
/**
* Compile MDX to JS.
*
* @param {VFileCompatible} vfileCompatible
* MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be
* given to `vfile`).
* @param {CompileOptions | null | undefined} [compileOptions]
* Compile configuration.
* @return {Promise<VFile>}
* File.
*/
export function compile(vfileCompatible: VFileCompatible, compileOptions?: CompileOptions | null | undefined): Promise<VFile>;
/**
* Synchronously compile MDX to JS.
*
* @param {VFileCompatible} vfileCompatible
* MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be
* given to `vfile`).
* @param {CompileOptions | null | undefined} [compileOptions]
* Compile configuration.
* @return {VFile}
* File.
*/
export function compileSync(vfileCompatible: VFileCompatible, compileOptions?: CompileOptions | null | undefined): VFile;
export type VFile = import('vfile').VFile;
export type VFileCompatible = import('vfile').VFileCompatible;
export type PluginOptions = import('./core.js').PluginOptions;
export type BaseProcessorOptions = import('./core.js').BaseProcessorOptions;
/**
* Core configuration.
*/
export type CoreProcessorOptions = Omit<BaseProcessorOptions, 'format'>;
/**
* Extra configuration.
*/
export type ExtraOptions = {
/**
* Format of `file`.
*/
format?: 'detect' | 'mdx' | 'md' | null | undefined;
};
/**
* Configuration.
*/
export type CompileOptions = CoreProcessorOptions & PluginOptions & ExtraOptions;

54
node_modules/@mdx-js/mdx/lib/compile.js generated vendored Normal file
View file

@ -0,0 +1,54 @@
/**
* @typedef {import('vfile').VFile} VFile
* @typedef {import('vfile').VFileCompatible} VFileCompatible
* @typedef {import('./core.js').PluginOptions} PluginOptions
* @typedef {import('./core.js').BaseProcessorOptions} BaseProcessorOptions
*/
/**
* @typedef {Omit<BaseProcessorOptions, 'format'>} CoreProcessorOptions
* Core configuration.
*
* @typedef ExtraOptions
* Extra configuration.
* @property {'detect' | 'mdx' | 'md' | null | undefined} [format='detect']
* Format of `file`.
*
* @typedef {CoreProcessorOptions & PluginOptions & ExtraOptions} CompileOptions
* Configuration.
*/
import {createProcessor} from './core.js'
import {resolveFileAndOptions} from './util/resolve-file-and-options.js'
/**
* Compile MDX to JS.
*
* @param {VFileCompatible} vfileCompatible
* MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be
* given to `vfile`).
* @param {CompileOptions | null | undefined} [compileOptions]
* Compile configuration.
* @return {Promise<VFile>}
* File.
*/
export function compile(vfileCompatible, compileOptions) {
const {file, options} = resolveFileAndOptions(vfileCompatible, compileOptions)
return createProcessor(options).process(file)
}
/**
* Synchronously compile MDX to JS.
*
* @param {VFileCompatible} vfileCompatible
* MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be
* given to `vfile`).
* @param {CompileOptions | null | undefined} [compileOptions]
* Compile configuration.
* @return {VFile}
* File.
*/
export function compileSync(vfileCompatible, compileOptions) {
const {file, options} = resolveFileAndOptions(vfileCompatible, compileOptions)
return createProcessor(options).processSync(file)
}

1
node_modules/@mdx-js/mdx/lib/condition.browser.d.ts generated vendored Normal file
View file

@ -0,0 +1 @@
export const development: false;

1
node_modules/@mdx-js/mdx/lib/condition.browser.js generated vendored Normal file
View file

@ -0,0 +1 @@
export const development = false

1
node_modules/@mdx-js/mdx/lib/condition.d.ts generated vendored Normal file
View file

@ -0,0 +1 @@
export const development: boolean;

3
node_modules/@mdx-js/mdx/lib/condition.js generated vendored Normal file
View file

@ -0,0 +1,3 @@
import process from 'process'
export const development = process.env.NODE_ENV === 'development'

69
node_modules/@mdx-js/mdx/lib/core.d.ts generated vendored Normal file
View file

@ -0,0 +1,69 @@
/**
* Pipeline to:
*
* 1. Parse MDX (serialized markdown with embedded JSX, ESM, and expressions)
* 2. Transform through remark (mdast), rehype (hast), and recma (esast)
* 3. Serialize as JavaScript
*
* @param {ProcessorOptions | null | undefined} [options]
* Configuration.
* @return {Processor}
* Processor.
*/
export function createProcessor(options?: ProcessorOptions | null | undefined): Processor;
export type RemarkRehypeOptions = import('remark-rehype').Options;
export type PluggableList = import('unified').PluggableList;
export type Processor = import('unified').Processor;
export type RehypeRecmaOptions = import('./plugin/rehype-recma.js').Options;
export type RecmaDocumentOptions = import('./plugin/recma-document.js').RecmaDocumentOptions;
export type RecmaStringifyOptions = import('./plugin/recma-stringify.js').RecmaStringifyOptions;
export type RecmaJsxRewriteOptions = import('./plugin/recma-jsx-rewrite.js').RecmaJsxRewriteOptions;
/**
* Base configuration.
*/
export type BaseProcessorOptions = {
/**
* Whether to keep JSX.
*/
jsx?: boolean | null | undefined;
/**
* Format of the files to be processed.
*/
format?: 'mdx' | 'md' | null | undefined;
/**
* Whether to compile to a whole program or a function body..
*/
outputFormat?: "function-body" | "program" | undefined;
/**
* Extensions (with `.`) for markdown.
*/
mdExtensions?: Array<string> | null | undefined;
/**
* Extensions (with `.`) for MDX.
*/
mdxExtensions?: Array<string> | null | undefined;
/**
* List of recma (esast, JavaScript) plugins.
*/
recmaPlugins?: import("unified").PluggableList | null | undefined;
/**
* List of remark (mdast, markdown) plugins.
*/
remarkPlugins?: import("unified").PluggableList | null | undefined;
/**
* List of rehype (hast, HTML) plugins.
*/
rehypePlugins?: import("unified").PluggableList | null | undefined;
/**
* Options to pass through to `remark-rehype`.
*/
remarkRehypeOptions?: RemarkRehypeOptions | null | undefined;
};
/**
* Configuration for internal plugins.
*/
export type PluginOptions = Omit<RehypeRecmaOptions & RecmaDocumentOptions & RecmaStringifyOptions & RecmaJsxRewriteOptions, 'outputFormat'>;
/**
* Configuration for processor.
*/
export type ProcessorOptions = BaseProcessorOptions & PluginOptions;

157
node_modules/@mdx-js/mdx/lib/core.js generated vendored Normal file
View file

@ -0,0 +1,157 @@
/**
* @typedef {import('remark-rehype').Options} RemarkRehypeOptions
* @typedef {import('unified').PluggableList} PluggableList
* @typedef {import('unified').Processor} Processor
* @typedef {import('./plugin/rehype-recma.js').Options} RehypeRecmaOptions
* @typedef {import('./plugin/recma-document.js').RecmaDocumentOptions} RecmaDocumentOptions
* @typedef {import('./plugin/recma-stringify.js').RecmaStringifyOptions} RecmaStringifyOptions
* @typedef {import('./plugin/recma-jsx-rewrite.js').RecmaJsxRewriteOptions} RecmaJsxRewriteOptions
*/
/**
* @typedef BaseProcessorOptions
* Base configuration.
* @property {boolean | null | undefined} [jsx=false]
* Whether to keep JSX.
* @property {'mdx' | 'md' | null | undefined} [format='mdx']
* Format of the files to be processed.
* @property {'function-body' | 'program'} [outputFormat='program']
* Whether to compile to a whole program or a function body..
* @property {Array<string> | null | undefined} [mdExtensions]
* Extensions (with `.`) for markdown.
* @property {Array<string> | null | undefined} [mdxExtensions]
* Extensions (with `.`) for MDX.
* @property {PluggableList | null | undefined} [recmaPlugins]
* List of recma (esast, JavaScript) plugins.
* @property {PluggableList | null | undefined} [remarkPlugins]
* List of remark (mdast, markdown) plugins.
* @property {PluggableList | null | undefined} [rehypePlugins]
* List of rehype (hast, HTML) plugins.
* @property {RemarkRehypeOptions | null | undefined} [remarkRehypeOptions]
* Options to pass through to `remark-rehype`.
*
* @typedef {Omit<RehypeRecmaOptions & RecmaDocumentOptions & RecmaStringifyOptions & RecmaJsxRewriteOptions, 'outputFormat'>} PluginOptions
* Configuration for internal plugins.
*
* @typedef {BaseProcessorOptions & PluginOptions} ProcessorOptions
* Configuration for processor.
*/
import {unified} from 'unified'
import remarkMdx from 'remark-mdx'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import {recmaJsxBuild} from './plugin/recma-jsx-build.js'
import {recmaDocument} from './plugin/recma-document.js'
import {recmaJsxRewrite} from './plugin/recma-jsx-rewrite.js'
import {recmaStringify} from './plugin/recma-stringify.js'
import {rehypeRecma} from './plugin/rehype-recma.js'
import {rehypeRemoveRaw} from './plugin/rehype-remove-raw.js'
import {remarkMarkAndUnravel} from './plugin/remark-mark-and-unravel.js'
import {nodeTypes} from './node-types.js'
import {development as defaultDevelopment} from './condition.js'
const removedOptions = [
'filepath',
'compilers',
'hastPlugins',
'mdPlugins',
'skipExport',
'wrapExport'
]
/**
* Pipeline to:
*
* 1. Parse MDX (serialized markdown with embedded JSX, ESM, and expressions)
* 2. Transform through remark (mdast), rehype (hast), and recma (esast)
* 3. Serialize as JavaScript
*
* @param {ProcessorOptions | null | undefined} [options]
* Configuration.
* @return {Processor}
* Processor.
*/
export function createProcessor(options) {
const {
development,
jsx,
format,
outputFormat,
providerImportSource,
recmaPlugins,
rehypePlugins,
remarkPlugins,
remarkRehypeOptions,
elementAttributeNameCase,
stylePropertyNameCase,
SourceMapGenerator,
...rest
} = options || {}
const dev =
development === null || development === undefined
? defaultDevelopment
: development
let index = -1
while (++index < removedOptions.length) {
const key = removedOptions[index]
if (options && key in options) {
throw new Error(
'`options.' +
key +
'` is no longer supported. Please see <https://mdxjs.com/migrating/v2/> for more information'
)
}
}
// @ts-expect-error runtime exception for disallowed field here, which is
// allowed in `compile`.
if (format === 'detect') {
throw new Error(
"Incorrect `format: 'detect'`: `createProcessor` can support either `md` or `mdx`; it does not support detecting the format"
)
}
const pipeline = unified().use(remarkParse)
if (format !== 'md') {
pipeline.use(remarkMdx)
}
const extraNodeTypes = remarkRehypeOptions
? /* c8 ignore next */
remarkRehypeOptions.passThrough || []
: []
pipeline
.use(remarkMarkAndUnravel)
.use(remarkPlugins || [])
.use(remarkRehype, {
...remarkRehypeOptions,
allowDangerousHtml: true,
passThrough: [...extraNodeTypes, ...nodeTypes]
})
.use(rehypePlugins || [])
if (format === 'md') {
pipeline.use(rehypeRemoveRaw)
}
pipeline
.use(rehypeRecma, {elementAttributeNameCase, stylePropertyNameCase})
.use(recmaDocument, {...rest, outputFormat})
.use(recmaJsxRewrite, {
development: dev,
providerImportSource,
outputFormat
})
if (!jsx) {
pipeline.use(recmaJsxBuild, {development: dev, outputFormat})
}
pipeline.use(recmaStringify, {SourceMapGenerator}).use(recmaPlugins || [])
return pipeline
}

27
node_modules/@mdx-js/mdx/lib/evaluate.d.ts generated vendored Normal file
View file

@ -0,0 +1,27 @@
/**
* Evaluate MDX.
*
* @param {VFileCompatible} vfileCompatible
* MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be
* given to `vfile`).
* @param {EvaluateOptions} evaluateOptions
* Configuration for evaluation.
* @return {Promise<ExportMap>}
* Export map.
*/
export function evaluate(vfileCompatible: VFileCompatible, evaluateOptions: EvaluateOptions): Promise<ExportMap>;
/**
* Synchronously evaluate MDX.
*
* @param {VFileCompatible} vfileCompatible
* MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be
* given to `vfile`).
* @param {EvaluateOptions} evaluateOptions
* Configuration for evaluation.
* @return {ExportMap}
* Export map.
*/
export function evaluateSync(vfileCompatible: VFileCompatible, evaluateOptions: EvaluateOptions): ExportMap;
export type ExportMap = import('mdx/types.js').MDXModule;
export type VFileCompatible = import('vfile').VFileCompatible;
export type EvaluateOptions = import('./util/resolve-evaluate-options.js').EvaluateOptions;

41
node_modules/@mdx-js/mdx/lib/evaluate.js generated vendored Normal file
View file

@ -0,0 +1,41 @@
/**
* @typedef {import('mdx/types.js').MDXModule} ExportMap
* @typedef {import('vfile').VFileCompatible} VFileCompatible
* @typedef {import('./util/resolve-evaluate-options.js').EvaluateOptions} EvaluateOptions
*/
import {compile, compileSync} from './compile.js'
import {run, runSync} from './run.js'
import {resolveEvaluateOptions} from './util/resolve-evaluate-options.js'
/**
* Evaluate MDX.
*
* @param {VFileCompatible} vfileCompatible
* MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be
* given to `vfile`).
* @param {EvaluateOptions} evaluateOptions
* Configuration for evaluation.
* @return {Promise<ExportMap>}
* Export map.
*/
export async function evaluate(vfileCompatible, evaluateOptions) {
const {compiletime, runtime} = resolveEvaluateOptions(evaluateOptions)
return run(await compile(vfileCompatible, compiletime), runtime)
}
/**
* Synchronously evaluate MDX.
*
* @param {VFileCompatible} vfileCompatible
* MDX document to parse (`string`, `Buffer`, `vfile`, anything that can be
* given to `vfile`).
* @param {EvaluateOptions} evaluateOptions
* Configuration for evaluation.
* @return {ExportMap}
* Export map.
*/
export function evaluateSync(vfileCompatible, evaluateOptions) {
const {compiletime, runtime} = resolveEvaluateOptions(evaluateOptions)
return runSync(compileSync(vfileCompatible, compiletime), runtime)
}

5
node_modules/@mdx-js/mdx/lib/node-types.d.ts generated vendored Normal file
View file

@ -0,0 +1,5 @@
/**
* List of node types made by `mdast-util-mdx`, which have to be passed
* through untouched from the mdast tree to the hast tree.
*/
export const nodeTypes: string[];

11
node_modules/@mdx-js/mdx/lib/node-types.js generated vendored Normal file
View file

@ -0,0 +1,11 @@
/**
* List of node types made by `mdast-util-mdx`, which have to be passed
* through untouched from the mdast tree to the hast tree.
*/
export const nodeTypes = [
'mdxFlowExpression',
'mdxJsxFlowElement',
'mdxJsxTextElement',
'mdxTextExpression',
'mdxjsEsm'
]

View file

@ -0,0 +1,63 @@
export function recmaDocument(this: import("unified").Processor<void, import("estree").Program, void, void>, ...settings: [] | [RecmaDocumentOptions | null | undefined]): void | import("unified").Transformer<import("estree").Program, import("estree").Program>;
export type Directive = import('estree-jsx').Directive;
export type ExportAllDeclaration = import('estree-jsx').ExportAllDeclaration;
export type ExportDefaultDeclaration = import('estree-jsx').ExportDefaultDeclaration;
export type ExportNamedDeclaration = import('estree-jsx').ExportNamedDeclaration;
export type ExportSpecifier = import('estree-jsx').ExportSpecifier;
export type Expression = import('estree-jsx').Expression;
export type FunctionDeclaration = import('estree-jsx').FunctionDeclaration;
export type ImportDeclaration = import('estree-jsx').ImportDeclaration;
export type ImportDefaultSpecifier = import('estree-jsx').ImportDefaultSpecifier;
export type ImportExpression = import('estree-jsx').ImportExpression;
export type ImportSpecifier = import('estree-jsx').ImportSpecifier;
export type Literal = import('estree-jsx').Literal;
export type JSXElement = import('estree-jsx').JSXElement;
export type ModuleDeclaration = import('estree-jsx').ModuleDeclaration;
export type Node = import('estree-jsx').Node;
export type Program = import('estree-jsx').Program;
export type Property = import('estree-jsx').Property;
export type SimpleLiteral = import('estree-jsx').SimpleLiteral;
export type SpreadElement = import('estree-jsx').SpreadElement;
export type Statement = import('estree-jsx').Statement;
export type VariableDeclarator = import('estree-jsx').VariableDeclarator;
/**
* Configuration for internal plugin `recma-document`.
*/
export type RecmaDocumentOptions = {
/**
* Whether to use either `import` and `export` statements to get the runtime
* (and optionally provider) and export the content, or get values from
* `arguments` and return things.
*/
outputFormat?: 'function-body' | 'program' | null | undefined;
/**
* Whether to keep `import` (and `export … from`) statements or compile them
* to dynamic `import()` instead.
*/
useDynamicImport?: boolean | null | undefined;
/**
* Resolve `import`s (and `export … from`, and `import.meta.url`) relative to
* this URL.
*/
baseUrl?: string | null | undefined;
/**
* Pragma for JSX (used in classic runtime).
*/
pragma?: string | null | undefined;
/**
* Pragma for JSX fragments (used in classic runtime).
*/
pragmaFrag?: string | null | undefined;
/**
* Where to import the identifier of `pragma` from (used in classic runtime).
*/
pragmaImportSource?: string | null | undefined;
/**
* Place to import automatic JSX runtimes from (used in automatic runtime).
*/
jsxImportSource?: string | null | undefined;
/**
* JSX runtime to use.
*/
jsxRuntime?: 'automatic' | 'classic' | null | undefined;
};

604
node_modules/@mdx-js/mdx/lib/plugin/recma-document.js generated vendored Normal file
View file

@ -0,0 +1,604 @@
/**
* @typedef {import('estree-jsx').Directive} Directive
* @typedef {import('estree-jsx').ExportAllDeclaration} ExportAllDeclaration
* @typedef {import('estree-jsx').ExportDefaultDeclaration} ExportDefaultDeclaration
* @typedef {import('estree-jsx').ExportNamedDeclaration} ExportNamedDeclaration
* @typedef {import('estree-jsx').ExportSpecifier} ExportSpecifier
* @typedef {import('estree-jsx').Expression} Expression
* @typedef {import('estree-jsx').FunctionDeclaration} FunctionDeclaration
* @typedef {import('estree-jsx').ImportDeclaration} ImportDeclaration
* @typedef {import('estree-jsx').ImportDefaultSpecifier} ImportDefaultSpecifier
* @typedef {import('estree-jsx').ImportExpression} ImportExpression
* @typedef {import('estree-jsx').ImportSpecifier} ImportSpecifier
* @typedef {import('estree-jsx').Literal} Literal
* @typedef {import('estree-jsx').JSXElement} JSXElement
* @typedef {import('estree-jsx').ModuleDeclaration} ModuleDeclaration
* @typedef {import('estree-jsx').Node} Node
* @typedef {import('estree-jsx').Program} Program
* @typedef {import('estree-jsx').Property} Property
* @typedef {import('estree-jsx').SimpleLiteral} SimpleLiteral
* @typedef {import('estree-jsx').SpreadElement} SpreadElement
* @typedef {import('estree-jsx').Statement} Statement
* @typedef {import('estree-jsx').VariableDeclarator} VariableDeclarator
*/
/**
* @typedef RecmaDocumentOptions
* Configuration for internal plugin `recma-document`.
* @property {'function-body' | 'program' | null | undefined} [outputFormat='program']
* Whether to use either `import` and `export` statements to get the runtime
* (and optionally provider) and export the content, or get values from
* `arguments` and return things.
* @property {boolean | null | undefined} [useDynamicImport=false]
* Whether to keep `import` (and `export … from`) statements or compile them
* to dynamic `import()` instead.
* @property {string | null | undefined} [baseUrl]
* Resolve `import`s (and `export … from`, and `import.meta.url`) relative to
* this URL.
* @property {string | null | undefined} [pragma='React.createElement']
* Pragma for JSX (used in classic runtime).
* @property {string | null | undefined} [pragmaFrag='React.Fragment']
* Pragma for JSX fragments (used in classic runtime).
* @property {string | null | undefined} [pragmaImportSource='react']
* Where to import the identifier of `pragma` from (used in classic runtime).
* @property {string | null | undefined} [jsxImportSource='react']
* Place to import automatic JSX runtimes from (used in automatic runtime).
* @property {'automatic' | 'classic' | null | undefined} [jsxRuntime='automatic']
* JSX runtime to use.
*/
import {analyze} from 'periscopic'
import {stringifyPosition} from 'unist-util-stringify-position'
import {positionFromEstree} from 'unist-util-position-from-estree'
import {walk} from 'estree-walker'
import {create} from '../util/estree-util-create.js'
import {specifiersToDeclarations} from '../util/estree-util-specifiers-to-declarations.js'
import {declarationToExpression} from '../util/estree-util-declaration-to-expression.js'
import {isDeclaration} from '../util/estree-util-is-declaration.js'
/**
* A plugin to wrap the estree in `MDXContent`.
*
* @type {import('unified').Plugin<[RecmaDocumentOptions | null | undefined] | [], Program>}
*/
export function recmaDocument(options) {
// Always given inside `@mdx-js/mdx`
/* c8 ignore next */
const options_ = options || {}
const baseUrl = options_.baseUrl || undefined
const useDynamicImport = options_.useDynamicImport || undefined
const outputFormat = options_.outputFormat || 'program'
const pragma =
options_.pragma === undefined ? 'React.createElement' : options_.pragma
const pragmaFrag =
options_.pragmaFrag === undefined ? 'React.Fragment' : options_.pragmaFrag
const pragmaImportSource = options_.pragmaImportSource || 'react'
const jsxImportSource = options_.jsxImportSource || 'react'
const jsxRuntime = options_.jsxRuntime || 'automatic'
return (tree, file) => {
/** @type {Array<[string, string] | string>} */
const exportedIdentifiers = []
/** @type {Array<Directive | ModuleDeclaration | Statement>} */
const replacement = []
/** @type {Array<string>} */
const pragmas = []
let exportAllCount = 0
/** @type {ExportDefaultDeclaration | ExportSpecifier | undefined} */
let layout
/** @type {boolean | undefined} */
let content
/** @type {Node} */
let child
// Patch missing comments, which types say could occur.
/* c8 ignore next */
if (!tree.comments) tree.comments = []
if (jsxRuntime) {
pragmas.push('@jsxRuntime ' + jsxRuntime)
}
if (jsxRuntime === 'automatic' && jsxImportSource) {
pragmas.push('@jsxImportSource ' + jsxImportSource)
}
if (jsxRuntime === 'classic' && pragma) {
pragmas.push('@jsx ' + pragma)
}
if (jsxRuntime === 'classic' && pragmaFrag) {
pragmas.push('@jsxFrag ' + pragmaFrag)
}
if (pragmas.length > 0) {
tree.comments.unshift({type: 'Block', value: pragmas.join(' ')})
}
if (jsxRuntime === 'classic' && pragmaImportSource) {
if (!pragma) {
throw new Error(
'Missing `pragma` in classic runtime with `pragmaImportSource`'
)
}
handleEsm({
type: 'ImportDeclaration',
specifiers: [
{
type: 'ImportDefaultSpecifier',
local: {type: 'Identifier', name: pragma.split('.')[0]}
}
],
source: {type: 'Literal', value: pragmaImportSource}
})
}
// Find the `export default`, the JSX expression, and leave the rest
// (import/exports) as they are.
for (child of tree.body) {
// ```js
// export default props => <>{props.children}</>
// ```
//
// Treat it as an inline layout declaration.
if (child.type === 'ExportDefaultDeclaration') {
if (layout) {
file.fail(
'Cannot specify multiple layouts (previous: ' +
stringifyPosition(positionFromEstree(layout)) +
')',
positionFromEstree(child),
'recma-document:duplicate-layout'
)
}
layout = child
replacement.push({
type: 'VariableDeclaration',
kind: 'const',
declarations: [
{
type: 'VariableDeclarator',
id: {type: 'Identifier', name: 'MDXLayout'},
init: isDeclaration(child.declaration)
? declarationToExpression(child.declaration)
: child.declaration
}
]
})
}
// ```js
// export {a, b as c} from 'd'
// ```
else if (child.type === 'ExportNamedDeclaration' && child.source) {
const source = /** @type {SimpleLiteral} */ (child.source)
// Remove `default` or `as default`, but not `default as`, specifier.
child.specifiers = child.specifiers.filter((specifier) => {
if (specifier.exported.name === 'default') {
if (layout) {
file.fail(
'Cannot specify multiple layouts (previous: ' +
stringifyPosition(positionFromEstree(layout)) +
')',
positionFromEstree(child),
'recma-document:duplicate-layout'
)
}
layout = specifier
// Make it just an import: `import MDXLayout from '…'`.
/** @type {Array<ImportDefaultSpecifier | ImportSpecifier>} */
const specifiers = []
// Default as default / something else as default.
if (specifier.local.name === 'default') {
specifiers.push({
type: 'ImportDefaultSpecifier',
local: {type: 'Identifier', name: 'MDXLayout'}
})
} else {
/** @type {ImportSpecifier} */
const importSpecifier = {
type: 'ImportSpecifier',
imported: specifier.local,
local: {type: 'Identifier', name: 'MDXLayout'}
}
create(specifier.local, importSpecifier)
specifiers.push(importSpecifier)
}
/** @type {Literal} */
const from = {type: 'Literal', value: source.value}
create(source, from)
/** @type {ImportDeclaration} */
const declaration = {
type: 'ImportDeclaration',
specifiers,
source: from
}
create(specifier, declaration)
handleEsm(declaration)
return false
}
return true
})
// If there are other things imported, keep it.
if (child.specifiers.length > 0) {
handleExport(child)
}
}
// ```js
// export {a, b as c}
// export * from 'a'
// ```
else if (
child.type === 'ExportNamedDeclaration' ||
child.type === 'ExportAllDeclaration'
) {
handleExport(child)
} else if (child.type === 'ImportDeclaration') {
handleEsm(child)
} else if (
child.type === 'ExpressionStatement' &&
// @ts-expect-error types are wrong: `JSXFragment` is an `Expression`.
(child.expression.type === 'JSXFragment' ||
child.expression.type === 'JSXElement')
) {
content = true
replacement.push(...createMdxContent(child.expression, Boolean(layout)))
// The following catch-all branch is because plugins mightve added
// other things.
// Normally, we only have import/export/jsx, but just add whatevers
// there.
/* c8 ignore next 3 */
} else {
replacement.push(child)
}
}
// If there was no JSX content at all, add an empty function.
if (!content) {
replacement.push(...createMdxContent(undefined, Boolean(layout)))
}
exportedIdentifiers.push(['MDXContent', 'default'])
if (outputFormat === 'function-body') {
replacement.push({
type: 'ReturnStatement',
argument: {
type: 'ObjectExpression',
properties: [
...Array.from({length: exportAllCount}).map(
/**
* @param {undefined} _
* @param {number} index
* @returns {SpreadElement}
*/
(_, index) => ({
type: 'SpreadElement',
argument: {type: 'Identifier', name: '_exportAll' + (index + 1)}
})
),
...exportedIdentifiers.map((d) => {
/** @type {Property} */
const prop = {
type: 'Property',
kind: 'init',
method: false,
computed: false,
shorthand: typeof d === 'string',
key: {
type: 'Identifier',
name: typeof d === 'string' ? d : d[1]
},
value: {
type: 'Identifier',
name: typeof d === 'string' ? d : d[0]
}
}
return prop
})
]
}
})
} else {
replacement.push({
type: 'ExportDefaultDeclaration',
declaration: {type: 'Identifier', name: 'MDXContent'}
})
}
tree.body = replacement
if (baseUrl) {
walk(tree, {
enter(node) {
if (
node.type === 'MemberExpression' &&
'object' in node &&
node.object.type === 'MetaProperty' &&
node.property.type === 'Identifier' &&
node.object.meta.name === 'import' &&
node.object.property.name === 'meta' &&
node.property.name === 'url'
) {
/** @type {SimpleLiteral} */
const replacement = {type: 'Literal', value: baseUrl}
this.replace(replacement)
}
}
})
}
/**
* @param {ExportAllDeclaration | ExportNamedDeclaration} node
* @returns {void}
*/
function handleExport(node) {
if (node.type === 'ExportNamedDeclaration') {
// ```js
// export function a() {}
// export class A {}
// export var a = 1
// ```
if (node.declaration) {
exportedIdentifiers.push(
...analyze(node.declaration).scope.declarations.keys()
)
}
// ```js
// export {a, b as c}
// export {a, b as c} from 'd'
// ```
for (child of node.specifiers) {
exportedIdentifiers.push(child.exported.name)
}
}
handleEsm(node)
}
/**
* @param {ExportAllDeclaration | ExportNamedDeclaration | ImportDeclaration} node
* @returns {void}
*/
function handleEsm(node) {
// Rewrite the source of the `import` / `export … from`.
// See: <https://html.spec.whatwg.org/multipage/webappapis.html#resolve-a-module-specifier>
if (baseUrl && node.source) {
let value = String(node.source.value)
try {
// A full valid URL.
value = String(new URL(value))
} catch {
// Relative: `/example.js`, `./example.js`, and `../example.js`.
if (/^\.{0,2}\//.test(value)) {
value = String(new URL(value, baseUrl))
}
// Otherwise, its a bare specifiers.
// For example `some-package`, `@some-package`, and
// `some-package/path`.
// These are supported in Node and browsers plan to support them
// with import maps (<https://github.com/WICG/import-maps>).
}
/** @type {Literal} */
const literal = {type: 'Literal', value}
create(node.source, literal)
node.source = literal
}
/** @type {ModuleDeclaration | Statement | undefined} */
let replace
/** @type {Expression} */
let init
if (outputFormat === 'function-body') {
if (
// Always have a source:
node.type === 'ImportDeclaration' ||
node.type === 'ExportAllDeclaration' ||
// Source optional:
(node.type === 'ExportNamedDeclaration' && node.source)
) {
if (!useDynamicImport) {
file.fail(
'Cannot use `import` or `export … from` in `evaluate` (outputting a function body) by default: please set `useDynamicImport: true` (and probably specify a `baseUrl`)',
positionFromEstree(node),
'recma-document:invalid-esm-statement'
)
}
// Just for types.
/* c8 ignore next 3 */
if (!node.source) {
throw new Error('Expected `node.source` to be defined')
}
// ```
// import 'a'
// //=> await import('a')
// import a from 'b'
// //=> const {default: a} = await import('b')
// export {a, b as c} from 'd'
// //=> const {a, c: b} = await import('d')
// export * from 'a'
// //=> const _exportAll0 = await import('a')
// ```
/** @type {ImportExpression} */
const argument = {type: 'ImportExpression', source: node.source}
create(node, argument)
init = {type: 'AwaitExpression', argument}
if (
(node.type === 'ImportDeclaration' ||
node.type === 'ExportNamedDeclaration') &&
node.specifiers.length === 0
) {
replace = {type: 'ExpressionStatement', expression: init}
} else {
replace = {
type: 'VariableDeclaration',
kind: 'const',
declarations:
node.type === 'ExportAllDeclaration'
? [
{
type: 'VariableDeclarator',
id: {
type: 'Identifier',
name: '_exportAll' + ++exportAllCount
},
init
}
]
: specifiersToDeclarations(node.specifiers, init)
}
}
} else if (node.declaration) {
replace = node.declaration
} else {
/** @type {Array<VariableDeclarator>} */
const declarators = node.specifiers
.filter(
(specifier) => specifier.local.name !== specifier.exported.name
)
.map((specifier) => ({
type: 'VariableDeclarator',
id: specifier.exported,
init: specifier.local
}))
if (declarators.length > 0) {
replace = {
type: 'VariableDeclaration',
kind: 'const',
declarations: declarators
}
}
}
} else {
replace = node
}
if (replace) {
replacement.push(replace)
}
}
}
/**
* @param {Expression | undefined} [content]
* @param {boolean | undefined} [hasInternalLayout]
* @returns {Array<FunctionDeclaration>}
*/
function createMdxContent(content, hasInternalLayout) {
/** @type {JSXElement} */
const element = {
type: 'JSXElement',
openingElement: {
type: 'JSXOpeningElement',
name: {type: 'JSXIdentifier', name: 'MDXLayout'},
attributes: [
{
type: 'JSXSpreadAttribute',
argument: {type: 'Identifier', name: 'props'}
}
],
selfClosing: false
},
closingElement: {
type: 'JSXClosingElement',
name: {type: 'JSXIdentifier', name: 'MDXLayout'}
},
children: [
{
type: 'JSXElement',
openingElement: {
type: 'JSXOpeningElement',
name: {type: 'JSXIdentifier', name: '_createMdxContent'},
attributes: [
{
type: 'JSXSpreadAttribute',
argument: {type: 'Identifier', name: 'props'}
}
],
selfClosing: true
},
closingElement: null,
children: []
}
]
}
let result = /** @type {Expression} */ (element)
if (!hasInternalLayout) {
result = {
type: 'ConditionalExpression',
test: {type: 'Identifier', name: 'MDXLayout'},
consequent: result,
alternate: {
type: 'CallExpression',
callee: {type: 'Identifier', name: '_createMdxContent'},
arguments: [{type: 'Identifier', name: 'props'}],
optional: false
}
}
}
let argument = content || {type: 'Literal', value: null}
// Unwrap a fragment of a single element.
if (
argument &&
// @ts-expect-error: fine.
argument.type === 'JSXFragment' &&
// @ts-expect-error: fine.
argument.children.length === 1 &&
// @ts-expect-error: fine.
argument.children[0].type === 'JSXElement'
) {
// @ts-expect-error: fine.
argument = argument.children[0]
}
return [
{
type: 'FunctionDeclaration',
id: {type: 'Identifier', name: '_createMdxContent'},
params: [{type: 'Identifier', name: 'props'}],
body: {
type: 'BlockStatement',
body: [{type: 'ReturnStatement', argument}]
}
},
{
type: 'FunctionDeclaration',
id: {type: 'Identifier', name: 'MDXContent'},
params: [
{
type: 'AssignmentPattern',
left: {type: 'Identifier', name: 'props'},
right: {type: 'ObjectExpression', properties: []}
}
],
body: {
type: 'BlockStatement',
body: [{type: 'ReturnStatement', argument: result}]
}
}
]
}
}

View file

@ -0,0 +1,14 @@
export function recmaJsxBuild(this: import("unified").Processor<void, import("estree").Program, void, void>, ...settings: [RecmaJsxBuildOptions | null | undefined] | []): void | import("unified").Transformer<import("estree").Program, import("estree").Program>;
export type Program = import('estree-jsx').Program;
export type BuildJsxOptions = import('estree-util-build-jsx').BuildJsxOptions;
/**
* Configuration for internal plugin `recma-jsx-build`.
*/
export type ExtraOptions = {
/**
* Whether to keep the import of the automatic runtime or get it from
* `arguments[0]` instead.
*/
outputFormat?: 'function-body' | 'program' | null | undefined;
};
export type RecmaJsxBuildOptions = BuildJsxOptions & ExtraOptions;

54
node_modules/@mdx-js/mdx/lib/plugin/recma-jsx-build.js generated vendored Normal file
View file

@ -0,0 +1,54 @@
/**
* @typedef {import('estree-jsx').Program} Program
* @typedef {import('estree-util-build-jsx').BuildJsxOptions} BuildJsxOptions
*/
/**
* @typedef ExtraOptions
* Configuration for internal plugin `recma-jsx-build`.
* @property {'function-body' | 'program' | null | undefined} [outputFormat='program']
* Whether to keep the import of the automatic runtime or get it from
* `arguments[0]` instead.
*
* @typedef {BuildJsxOptions & ExtraOptions} RecmaJsxBuildOptions
*/
import {buildJsx} from 'estree-util-build-jsx'
import {specifiersToDeclarations} from '../util/estree-util-specifiers-to-declarations.js'
import {toIdOrMemberExpression} from '../util/estree-util-to-id-or-member-expression.js'
/**
* A plugin to build JSX into function calls.
* `estree-util-build-jsx` does all the work for us!
*
* @type {import('unified').Plugin<[RecmaJsxBuildOptions | null | undefined] | [], Program>}
*/
export function recmaJsxBuild(options) {
// Always given inside `@mdx-js/mdx`
/* c8 ignore next */
const {development, outputFormat} = options || {}
return (tree, file) => {
buildJsx(tree, {development, filePath: file.history[0]})
// When compiling to a function body, replace the import that was just
// generated, and get `jsx`, `jsxs`, and `Fragment` from `arguments[0]`
// instead.
if (
outputFormat === 'function-body' &&
tree.body[0] &&
tree.body[0].type === 'ImportDeclaration' &&
typeof tree.body[0].source.value === 'string' &&
/\/jsx-(dev-)?runtime$/.test(tree.body[0].source.value)
) {
tree.body[0] = {
type: 'VariableDeclaration',
kind: 'const',
declarations: specifiersToDeclarations(
tree.body[0].specifiers,
toIdOrMemberExpression(['arguments', 0])
)
}
}
}
}

View file

@ -0,0 +1,50 @@
export function recmaJsxRewrite(this: import("unified").Processor<void, import("estree").Program, void, void>, ...settings: [] | [RecmaJsxRewriteOptions | null | undefined]): void | import("unified").Transformer<import("estree").Program, import("estree").Program>;
export type Expression = import('estree-jsx').Expression;
export type EstreeFunction = import('estree-jsx').Function;
export type Identifier = import('estree-jsx').Identifier;
export type ImportSpecifier = import('estree-jsx').ImportSpecifier;
export type JSXElement = import('estree-jsx').JSXElement;
export type ModuleDeclaration = import('estree-jsx').ModuleDeclaration;
export type Node = import('estree-jsx').Node;
export type ObjectPattern = import('estree-jsx').ObjectPattern;
export type Program = import('estree-jsx').Program;
export type Property = import('estree-jsx').Property;
export type Statement = import('estree-jsx').Statement;
export type VariableDeclarator = import('estree-jsx').VariableDeclarator;
export type Scope = import('periscopic').Scope & {
node: Node;
};
/**
* Configuration for internal plugin `recma-jsx-rewrite`.
*/
export type RecmaJsxRewriteOptions = {
/**
* Whether to use an import statement or `arguments[0]` to get the provider.
*/
outputFormat?: 'function-body' | 'program' | null | undefined;
/**
* Place to import a provider from.
*/
providerImportSource?: string | null | undefined;
/**
* Whether to add extra info to error messages in generated code.
*
* This also results in the development automatic JSX runtime
* (`/jsx-dev-runtime`, `jsxDEV`) being used, which passes positional info to
* nodes.
* The default can be set to `true` in Node.js through environment variables:
* set `NODE_ENV=development`.
*/
development?: boolean | null | undefined;
};
export type StackEntry = {
objects: Array<string>;
components: Array<string>;
tags: Array<string>;
references: Record<string, {
node: JSXElement;
component: boolean;
}>;
idToInvalidComponentName: Map<string | number, string>;
node: EstreeFunction;
};

View file

@ -0,0 +1,616 @@
/**
* @typedef {import('estree-jsx').Expression} Expression
* @typedef {import('estree-jsx').Function} EstreeFunction
* @typedef {import('estree-jsx').Identifier} Identifier
* @typedef {import('estree-jsx').ImportSpecifier} ImportSpecifier
* @typedef {import('estree-jsx').JSXElement} JSXElement
* @typedef {import('estree-jsx').ModuleDeclaration} ModuleDeclaration
* @typedef {import('estree-jsx').Node} Node
* @typedef {import('estree-jsx').ObjectPattern} ObjectPattern
* @typedef {import('estree-jsx').Program} Program
* @typedef {import('estree-jsx').Property} Property
* @typedef {import('estree-jsx').Statement} Statement
* @typedef {import('estree-jsx').VariableDeclarator} VariableDeclarator
*
* @typedef {import('periscopic').Scope & {node: Node}} Scope
*/
/**
* @typedef RecmaJsxRewriteOptions
* Configuration for internal plugin `recma-jsx-rewrite`.
* @property {'function-body' | 'program' | null | undefined} [outputFormat='program']
* Whether to use an import statement or `arguments[0]` to get the provider.
* @property {string | null | undefined} [providerImportSource]
* Place to import a provider from.
* @property {boolean | null | undefined} [development=false]
* Whether to add extra info to error messages in generated code.
*
* This also results in the development automatic JSX runtime
* (`/jsx-dev-runtime`, `jsxDEV`) being used, which passes positional info to
* nodes.
* The default can be set to `true` in Node.js through environment variables:
* set `NODE_ENV=development`.
*
* @typedef StackEntry
* @property {Array<string>} objects
* @property {Array<string>} components
* @property {Array<string>} tags
* @property {Record<string, {node: JSXElement, component: boolean}>} references
* @property {Map<string|number, string>} idToInvalidComponentName
* @property {EstreeFunction} node
*/
import {stringifyPosition} from 'unist-util-stringify-position'
import {positionFromEstree} from 'unist-util-position-from-estree'
import {name as isIdentifierName} from 'estree-util-is-identifier-name'
import {walk} from 'estree-walker'
import {analyze} from 'periscopic'
import {specifiersToDeclarations} from '../util/estree-util-specifiers-to-declarations.js'
import {
toIdOrMemberExpression,
toJsxIdOrMemberExpression
} from '../util/estree-util-to-id-or-member-expression.js'
import {toBinaryAddition} from '../util/estree-util-to-binary-addition.js'
const own = {}.hasOwnProperty
/**
* A plugin that rewrites JSX in functions to accept components as
* `props.components` (when the function is called `_createMdxContent`), or from
* a provider (if there is one).
* It also makes sure that any undefined components are defined: either from
* received components or as a function that throws an error.
*
* @type {import('unified').Plugin<[RecmaJsxRewriteOptions | null | undefined] | [], Program>}
*/
export function recmaJsxRewrite(options) {
// Always given inside `@mdx-js/mdx`
/* c8 ignore next */
const {development, providerImportSource, outputFormat} = options || {}
return (tree, file) => {
// Find everything thats defined in the top-level scope.
const scopeInfo = analyze(tree)
/** @type {Array<StackEntry>} */
const fnStack = []
let importProvider = false
let createErrorHelper = false
/** @type {Scope | undefined} */
let currentScope
walk(tree, {
enter(node) {
const newScope = /** @type {Scope | undefined} */ (
scopeInfo.map.get(node)
)
if (
node.type === 'FunctionDeclaration' ||
node.type === 'FunctionExpression' ||
node.type === 'ArrowFunctionExpression'
) {
fnStack.push({
objects: [],
components: [],
tags: [],
references: {},
idToInvalidComponentName: new Map(),
node
})
// MDXContent only ever contains MDXLayout
if (
isNamedFunction(node, 'MDXContent') &&
newScope &&
!inScope(newScope, 'MDXLayout')
) {
fnStack[0].components.push('MDXLayout')
}
}
const fnScope = fnStack[0]
if (
!fnScope ||
(!isNamedFunction(fnScope.node, '_createMdxContent') &&
!providerImportSource)
) {
return
}
if (newScope) {
newScope.node = node
currentScope = newScope
}
if (currentScope && node.type === 'JSXElement') {
let name = node.openingElement.name
// `<x.y>`, `<Foo.Bar>`, `<x.y.z>`.
if (name.type === 'JSXMemberExpression') {
/** @type {Array<string>} */
const ids = []
// Find the left-most identifier.
while (name.type === 'JSXMemberExpression') {
ids.unshift(name.property.name)
name = name.object
}
ids.unshift(name.name)
const fullId = ids.join('.')
const id = name.name
const isInScope = inScope(currentScope, id)
if (!own.call(fnScope.references, fullId)) {
const parentScope = /** @type {Scope | undefined} */ (
currentScope.parent
)
if (
!isInScope ||
// If the parent scope is `_createMdxContent`, then this
// references a component we can add a check statement for.
(parentScope &&
parentScope.node.type === 'FunctionDeclaration' &&
isNamedFunction(parentScope.node, '_createMdxContent'))
) {
fnScope.references[fullId] = {node, component: true}
}
}
if (!fnScope.objects.includes(id) && !isInScope) {
fnScope.objects.push(id)
}
}
// `<xml:thing>`.
else if (name.type === 'JSXNamespacedName') {
// Ignore namespaces.
}
// If the name is a valid ES identifier, and it doesnt start with a
// lowercase letter, its a component.
// For example, `$foo`, `_bar`, `Baz` are all component names.
// But `foo` and `b-ar` are tag names.
else if (isIdentifierName(name.name) && !/^[a-z]/.test(name.name)) {
const id = name.name
if (!inScope(currentScope, id)) {
// No need to add an error for an undefined layout — we use an
// `if` later.
if (id !== 'MDXLayout' && !own.call(fnScope.references, id)) {
fnScope.references[id] = {node, component: true}
}
if (!fnScope.components.includes(id)) {
fnScope.components.push(id)
}
}
}
// @ts-expect-error Allow fields passed through from mdast through hast to
// esast.
else if (node.data && node.data._mdxExplicitJsx) {
// Do not turn explicit JSX into components from `_components`.
// As in, a given `h1` component is used for `# heading` (next case),
// but not for `<h1>heading</h1>`.
} else {
const id = name.name
if (!fnScope.tags.includes(id)) {
fnScope.tags.push(id)
}
/** @type {Array<string | number>} */
let jsxIdExpression = ['_components', id]
if (isIdentifierName(id) === false) {
let invalidComponentName =
fnScope.idToInvalidComponentName.get(id)
if (invalidComponentName === undefined) {
invalidComponentName = `_component${fnScope.idToInvalidComponentName.size}`
fnScope.idToInvalidComponentName.set(id, invalidComponentName)
}
jsxIdExpression = [invalidComponentName]
}
node.openingElement.name =
toJsxIdOrMemberExpression(jsxIdExpression)
if (node.closingElement) {
node.closingElement.name =
toJsxIdOrMemberExpression(jsxIdExpression)
}
}
}
},
leave(node) {
/** @type {Array<Property>} */
const defaults = []
/** @type {Array<string>} */
const actual = []
/** @type {Array<Expression>} */
const parameters = []
/** @type {Array<VariableDeclarator>} */
const declarations = []
if (currentScope && currentScope.node === node) {
// @ts-expect-error: `node`s were patched when entering.
currentScope = currentScope.parent
}
if (
node.type === 'FunctionDeclaration' ||
node.type === 'FunctionExpression' ||
node.type === 'ArrowFunctionExpression'
) {
const fn = node
const scope = fnStack[fnStack.length - 1]
/** @type {string} */
let name
for (name of scope.tags) {
defaults.push({
type: 'Property',
kind: 'init',
key: isIdentifierName(name)
? {type: 'Identifier', name}
: {type: 'Literal', value: name},
value: {type: 'Literal', value: name},
method: false,
shorthand: false,
computed: false
})
}
actual.push(...scope.components)
for (name of scope.objects) {
// In some cases, a component is used directly (`<X>`) but its also
// used as an object (`<X.Y>`).
if (!actual.includes(name)) {
actual.push(name)
}
}
/** @type {Array<Statement>} */
const statements = []
if (
defaults.length > 0 ||
actual.length > 0 ||
scope.idToInvalidComponentName.size > 0
) {
if (providerImportSource) {
importProvider = true
parameters.push({
type: 'CallExpression',
callee: {type: 'Identifier', name: '_provideComponents'},
arguments: [],
optional: false
})
}
// Accept `components` as a prop if this is the `MDXContent` or
// `_createMdxContent` function.
if (
isNamedFunction(scope.node, 'MDXContent') ||
isNamedFunction(scope.node, '_createMdxContent')
) {
parameters.push(toIdOrMemberExpression(['props', 'components']))
}
if (defaults.length > 0 || parameters.length > 1) {
parameters.unshift({
type: 'ObjectExpression',
properties: defaults
})
}
// If were getting components from several sources, merge them.
/** @type {Expression} */
let componentsInit =
parameters.length > 1
? {
type: 'CallExpression',
callee: toIdOrMemberExpression(['Object', 'assign']),
arguments: parameters,
optional: false
}
: parameters[0].type === 'MemberExpression'
? // If were only getting components from `props.components`,
// make sure its defined.
{
type: 'LogicalExpression',
operator: '||',
left: parameters[0],
right: {type: 'ObjectExpression', properties: []}
}
: parameters[0]
/** @type {ObjectPattern | undefined} */
let componentsPattern
// Add components to scope.
// For `['MyComponent', 'MDXLayout']` this generates:
// ```js
// const {MyComponent, wrapper: MDXLayout} = _components
// ```
// Note that MDXLayout is special as its taken from
// `_components.wrapper`.
if (actual.length > 0) {
componentsPattern = {
type: 'ObjectPattern',
properties: actual.map((name) => ({
type: 'Property',
kind: 'init',
key: {
type: 'Identifier',
name: name === 'MDXLayout' ? 'wrapper' : name
},
value: {type: 'Identifier', name},
method: false,
shorthand: name !== 'MDXLayout',
computed: false
}))
}
}
if (scope.tags.length > 0) {
declarations.push({
type: 'VariableDeclarator',
id: {type: 'Identifier', name: '_components'},
init: componentsInit
})
componentsInit = {type: 'Identifier', name: '_components'}
}
if (isNamedFunction(scope.node, '_createMdxContent')) {
for (const [
id,
componentName
] of scope.idToInvalidComponentName) {
// For JSX IDs that cant be represented as JavaScript IDs (as in,
// those with dashes, such as `custom-element`), generate a
// separate variable that is a valid JS ID (such as `_component0`),
// and takes it from components:
// `const _component0 = _components['custom-element']`
declarations.push({
type: 'VariableDeclarator',
id: {type: 'Identifier', name: componentName},
init: {
type: 'MemberExpression',
object: {type: 'Identifier', name: '_components'},
property: {type: 'Literal', value: id},
computed: true,
optional: false
}
})
}
}
if (componentsPattern) {
declarations.push({
type: 'VariableDeclarator',
id: componentsPattern,
init: componentsInit
})
}
if (declarations.length > 0) {
statements.push({
type: 'VariableDeclaration',
kind: 'const',
declarations
})
}
}
/** @type {string} */
let key
// Add partials (so for `x.y.z` itd generate `x` and `x.y` too).
for (key in scope.references) {
if (own.call(scope.references, key)) {
const parts = key.split('.')
let index = 0
while (++index < parts.length) {
const partial = parts.slice(0, index).join('.')
if (!own.call(scope.references, partial)) {
scope.references[partial] = {
node: scope.references[key].node,
component: false
}
}
}
}
}
const references = Object.keys(scope.references).sort()
let index = -1
while (++index < references.length) {
const id = references[index]
const info = scope.references[id]
const place = stringifyPosition(positionFromEstree(info.node))
/** @type {Array<Expression>} */
const parameters = [
{type: 'Literal', value: id},
{type: 'Literal', value: info.component}
]
createErrorHelper = true
if (development && place !== '1:1-1:1') {
parameters.push({type: 'Literal', value: place})
}
statements.push({
type: 'IfStatement',
test: {
type: 'UnaryExpression',
operator: '!',
prefix: true,
argument: toIdOrMemberExpression(id.split('.'))
},
consequent: {
type: 'ExpressionStatement',
expression: {
type: 'CallExpression',
callee: {type: 'Identifier', name: '_missingMdxReference'},
arguments: parameters,
optional: false
}
},
alternate: null
})
}
if (statements.length > 0) {
// Arrow functions with an implied return:
if (fn.body.type !== 'BlockStatement') {
fn.body = {
type: 'BlockStatement',
body: [{type: 'ReturnStatement', argument: fn.body}]
}
}
fn.body.body.unshift(...statements)
}
fnStack.pop()
}
}
})
// If a provider is used (and can be used), import it.
if (importProvider && providerImportSource) {
tree.body.unshift(
createImportProvider(providerImportSource, outputFormat)
)
}
// If potentially missing components are used.
if (createErrorHelper) {
/** @type {Array<Expression>} */
const message = [
{type: 'Literal', value: 'Expected '},
{
type: 'ConditionalExpression',
test: {type: 'Identifier', name: 'component'},
consequent: {type: 'Literal', value: 'component'},
alternate: {type: 'Literal', value: 'object'}
},
{type: 'Literal', value: ' `'},
{type: 'Identifier', name: 'id'},
{
type: 'Literal',
value:
'` to be defined: you likely forgot to import, pass, or provide it.'
}
]
/** @type {Array<Identifier>} */
const parameters = [
{type: 'Identifier', name: 'id'},
{type: 'Identifier', name: 'component'}
]
if (development) {
message.push({
type: 'ConditionalExpression',
test: {type: 'Identifier', name: 'place'},
consequent: toBinaryAddition([
{type: 'Literal', value: '\nIts referenced in your code at `'},
{type: 'Identifier', name: 'place'},
{
type: 'Literal',
value: (file.path ? '` in `' + file.path : '') + '`'
}
]),
alternate: {type: 'Literal', value: ''}
})
parameters.push({type: 'Identifier', name: 'place'})
}
tree.body.push({
type: 'FunctionDeclaration',
id: {type: 'Identifier', name: '_missingMdxReference'},
generator: false,
async: false,
params: parameters,
body: {
type: 'BlockStatement',
body: [
{
type: 'ThrowStatement',
argument: {
type: 'NewExpression',
callee: {type: 'Identifier', name: 'Error'},
arguments: [toBinaryAddition(message)]
}
}
]
}
})
}
}
}
/**
* @param {string} providerImportSource
* @param {RecmaJsxRewriteOptions['outputFormat']} outputFormat
* @returns {Statement | ModuleDeclaration}
*/
function createImportProvider(providerImportSource, outputFormat) {
/** @type {Array<ImportSpecifier>} */
const specifiers = [
{
type: 'ImportSpecifier',
imported: {type: 'Identifier', name: 'useMDXComponents'},
local: {type: 'Identifier', name: '_provideComponents'}
}
]
return outputFormat === 'function-body'
? {
type: 'VariableDeclaration',
kind: 'const',
declarations: specifiersToDeclarations(
specifiers,
toIdOrMemberExpression(['arguments', 0])
)
}
: {
type: 'ImportDeclaration',
specifiers,
source: {type: 'Literal', value: providerImportSource}
}
}
/**
* @param {EstreeFunction} node
* @param {string} name
* @returns {boolean}
*/
function isNamedFunction(node, name) {
return Boolean(node && 'id' in node && node.id && node.id.name === name)
}
/**
* @param {Scope} scope
* @param {string} id
* @returns {boolean}
*/
function inScope(scope, id) {
/** @type {Scope | undefined} */
let currentScope = scope
while (currentScope) {
if (currentScope.declarations.has(id)) {
return true
}
// @ts-expect-error: `node`s have been added when entering.
currentScope = currentScope.parent
}
return false
}

View file

@ -0,0 +1,13 @@
export function recmaStringify(this: import("unified").Processor<void, import("estree").Program, import("estree").Program, string>, ...settings: [] | [RecmaStringifyOptions | null | undefined]): void;
export type Program = import('estree-jsx').Program;
export type SourceMapGenerator = typeof import('source-map').SourceMapGenerator;
/**
* Configuration for internal plugin `recma-stringify`.
*/
export type RecmaStringifyOptions = {
/**
* Generate a source map by passing a `SourceMapGenerator` from `source-map`
* in.
*/
SourceMapGenerator?: SourceMapGenerator | null | undefined;
};

42
node_modules/@mdx-js/mdx/lib/plugin/recma-stringify.js generated vendored Normal file
View file

@ -0,0 +1,42 @@
/**
* @typedef {import('estree-jsx').Program} Program
* @typedef {typeof import('source-map').SourceMapGenerator} SourceMapGenerator
*
* @typedef RecmaStringifyOptions
* Configuration for internal plugin `recma-stringify`.
* @property {SourceMapGenerator | null | undefined} [SourceMapGenerator]
* Generate a source map by passing a `SourceMapGenerator` from `source-map`
* in.
*/
import {toJs, jsx} from 'estree-util-to-js'
/**
* A plugin that adds an esast compiler: a small wrapper around `astring` to add
* support for serializing JSX.
*
* @this {import('unified').Processor}
* @type {import('unified').Plugin<[RecmaStringifyOptions | null | undefined] | [], Program, string>}
*/
export function recmaStringify(options) {
// Always given inside `@mdx-js/mdx`
/* c8 ignore next */
const {SourceMapGenerator} = options || {}
Object.assign(this, {Compiler: compiler})
/** @type {import('unified').CompilerFunction<Program, string>} */
function compiler(tree, file) {
const result = SourceMapGenerator
? toJs(tree, {
filePath: file.path || 'unknown.mdx',
SourceMapGenerator,
handlers: jsx
})
: toJs(tree, {handlers: jsx})
file.map = result.map
return result.value
}
}

36
node_modules/@mdx-js/mdx/lib/plugin/rehype-recma.d.ts generated vendored Normal file
View file

@ -0,0 +1,36 @@
export function rehypeRecma(this: import("unified").Processor<void, import("hast").Root, void, void>, ...settings: [] | [Options | null | undefined]): void | import("unified").Transformer<import("hast").Root, import("estree").Program>;
export type Program = import('estree-jsx').Program;
export type Root = import('hast').Root;
/**
* Specify casing to use for attribute names.
*
* HTML casing is for example `class`, `stroke-linecap`, `xml:lang`.
* React casing is for example `className`, `strokeLinecap`, `xmlLang`.
*/
export type ElementAttributeNameCase = 'html' | 'react';
/**
* Casing to use for property names in `style` objects.
*
* CSS casing is for example `background-color` and `-webkit-line-clamp`.
* DOM casing is for example `backgroundColor` and `WebkitLineClamp`.
*/
export type StylePropertyNameCase = 'css' | 'dom';
/**
* Configuration for internal plugin `rehype-recma`.
*/
export type Options = {
/**
* Specify casing to use for attribute names.
*
* This casing is used for hast elements, not for embedded MDX JSX nodes
* (components that someone authored manually).
*/
elementAttributeNameCase?: ElementAttributeNameCase | null | undefined;
/**
* Specify casing to use for property names in `style` objects.
*
* This casing is used for hast elements, not for embedded MDX JSX nodes
* (components that someone authored manually).
*/
stylePropertyNameCase?: StylePropertyNameCase | null | undefined;
};

43
node_modules/@mdx-js/mdx/lib/plugin/rehype-recma.js generated vendored Normal file
View file

@ -0,0 +1,43 @@
/**
* @typedef {import('estree-jsx').Program} Program
* @typedef {import('hast').Root} Root
*/
/**
* @typedef {'html' | 'react'} ElementAttributeNameCase
* Specify casing to use for attribute names.
*
* HTML casing is for example `class`, `stroke-linecap`, `xml:lang`.
* React casing is for example `className`, `strokeLinecap`, `xmlLang`.
*
* @typedef {'css' | 'dom'} StylePropertyNameCase
* Casing to use for property names in `style` objects.
*
* CSS casing is for example `background-color` and `-webkit-line-clamp`.
* DOM casing is for example `backgroundColor` and `WebkitLineClamp`.
*
* @typedef Options
* Configuration for internal plugin `rehype-recma`.
* @property {ElementAttributeNameCase | null | undefined} [elementAttributeNameCase='react']
* Specify casing to use for attribute names.
*
* This casing is used for hast elements, not for embedded MDX JSX nodes
* (components that someone authored manually).
* @property {StylePropertyNameCase | null | undefined} [stylePropertyNameCase='dom']
* Specify casing to use for property names in `style` objects.
*
* This casing is used for hast elements, not for embedded MDX JSX nodes
* (components that someone authored manually).
*/
import {toEstree} from 'hast-util-to-estree'
/**
* A plugin to transform an HTML (hast) tree to a JS (estree).
* `hast-util-to-estree` does all the work for us!
*
* @type {import('unified').Plugin<[Options | null | undefined] | [], Root, Program>}
*/
export function rehypeRecma(options) {
return (tree) => toEstree(tree, options)
}

View file

@ -0,0 +1,3 @@
export function rehypeRemoveRaw(this: import("unified").Processor<void, import("hast").Root, void, void>): void | import("unified").Transformer<import("hast").Root, import("hast").Root>;
export type Root = import('hast').Root;
export type DoNotRemoveUsedToAddRawToNodeType = typeof import("mdast-util-to-hast");

View file

@ -0,0 +1,25 @@
/**
* @typedef {import('hast').Root} Root
* @typedef {import('mdast-util-to-hast')} DoNotRemoveUsedToAddRawToNodeType
*/
import {visit} from 'unist-util-visit'
/**
* A tiny plugin that removes raw HTML.
*
* This is needed if the format is `md` and `rehype-raw` was not used to parse
* dangerous HTML into nodes.
*
* @type {import('unified').Plugin<[], Root>}
*/
export function rehypeRemoveRaw() {
return (tree) => {
visit(tree, 'raw', (_, index, parent) => {
if (parent && typeof index === 'number') {
parent.children.splice(index, 1)
return index
}
})
}
}

View file

@ -0,0 +1,4 @@
export function remarkMarkAndUnravel(this: import("unified").Processor<void, import("mdast").Root, void, void>): void | import("unified").Transformer<import("mdast").Root, import("mdast").Root>;
export type Content = import('mdast').Content;
export type Root = import('mdast').Root;
export type DoNotTouchAsThisImportItIncludesMdxInTree = typeof import("remark-mdx");

View file

@ -0,0 +1,91 @@
/**
* @typedef {import('mdast').Content} Content
* @typedef {import('mdast').Root} Root
*
* @typedef {import('remark-mdx')} DoNotTouchAsThisImportItIncludesMdxInTree
*/
import {visit} from 'unist-util-visit'
/**
* A tiny plugin that unravels `<p><h1>x</h1></p>` but also
* `<p><Component /></p>` (so it has no knowledge of HTML).
*
* It also marks JSX as being explicitly JSX, so when a user passes a `h1`
* component, it is used for `# heading` but not for `<h1>heading</h1>`.
*
* @type {import('unified').Plugin<[], Root>}
*/
export function remarkMarkAndUnravel() {
return (tree) => {
visit(tree, (node, index, parent) => {
let offset = -1
let all = true
let oneOrMore = false
if (parent && typeof index === 'number' && node.type === 'paragraph') {
const children = node.children
while (++offset < children.length) {
const child = children[offset]
if (
child.type === 'mdxJsxTextElement' ||
child.type === 'mdxTextExpression'
) {
oneOrMore = true
} else if (
child.type === 'text' &&
/^[\t\r\n ]+$/.test(String(child.value))
) {
// Empty.
} else {
all = false
break
}
}
if (all && oneOrMore) {
offset = -1
/** @type {Array<Content>} */
const newChildren = []
while (++offset < children.length) {
const child = children[offset]
if (child.type === 'mdxJsxTextElement') {
// @ts-expect-error: content model is fine.
child.type = 'mdxJsxFlowElement'
}
if (child.type === 'mdxTextExpression') {
// @ts-expect-error: content model is fine.
child.type = 'mdxFlowExpression'
}
if (
child.type === 'text' &&
/^[\t\r\n ]+$/.test(String(child.value))
) {
// Empty.
} else {
newChildren.push(child)
}
}
parent.children.splice(index, 1, ...newChildren)
return index
}
}
if (
node.type === 'mdxJsxFlowElement' ||
node.type === 'mdxJsxTextElement'
) {
const data = node.data || (node.data = {})
data._mdxExplicitJsx = true
}
})
}
}

26
node_modules/@mdx-js/mdx/lib/run.d.ts generated vendored Normal file
View file

@ -0,0 +1,26 @@
/**
* Asynchronously run code.
*
* @param {{toString(): string}} file
* JS document to run.
* @param {unknown} options
* Parameter.
* @return {Promise<any>}
* Anthing.
*/
export function run(file: {
toString(): string;
}, options: unknown): Promise<any>;
/**
* Synchronously run code.
*
* @param {{toString(): string}} file
* JS document to run.
* @param {unknown} options
* Parameter.
* @return {any}
* Anthing.
*/
export function runSync(file: {
toString(): string;
}, options: unknown): any;

31
node_modules/@mdx-js/mdx/lib/run.js generated vendored Normal file
View file

@ -0,0 +1,31 @@
/** @type {new (code: string, ...args: Array<unknown>) => Function} **/
const AsyncFunction = Object.getPrototypeOf(run).constructor
/**
* Asynchronously run code.
*
* @param {{toString(): string}} file
* JS document to run.
* @param {unknown} options
* Parameter.
* @return {Promise<any>}
* Anthing.
*/
export async function run(file, options) {
return new AsyncFunction(String(file))(options)
}
/**
* Synchronously run code.
*
* @param {{toString(): string}} file
* JS document to run.
* @param {unknown} options
* Parameter.
* @return {any}
* Anthing.
*/
export function runSync(file, options) {
// eslint-disable-next-line no-new-func
return new Function(String(file))(options)
}

View file

@ -0,0 +1,17 @@
/**
* Create smart processors to handle different formats.
*
* @param {CompileOptions | null | undefined} [compileOptions]
* configuration.
* @return {{extnames: Array<string>, process: process, processSync: processSync}}
* Smart processor.
*/
export function createFormatAwareProcessors(compileOptions?: CompileOptions | null | undefined): {
extnames: Array<string>;
process: (vfileCompatible: VFileCompatible) => Promise<VFile>;
processSync: (vfileCompatible: VFileCompatible) => VFile;
};
export type Processor = import('unified').Processor;
export type VFile = import('vfile').VFile;
export type VFileCompatible = import('vfile').VFileCompatible;
export type CompileOptions = import('../compile.js').CompileOptions;

View file

@ -0,0 +1,91 @@
/**
* @typedef {import('unified').Processor} Processor
* @typedef {import('vfile').VFile} VFile
* @typedef {import('vfile').VFileCompatible} VFileCompatible
* @typedef {import('../compile.js').CompileOptions} CompileOptions
*/
import {createProcessor} from '../core.js'
import {md, mdx} from './extnames.js'
import {resolveFileAndOptions} from './resolve-file-and-options.js'
/**
* Create smart processors to handle different formats.
*
* @param {CompileOptions | null | undefined} [compileOptions]
* configuration.
* @return {{extnames: Array<string>, process: process, processSync: processSync}}
* Smart processor.
*/
export function createFormatAwareProcessors(compileOptions) {
const compileOptions_ = compileOptions || {}
const mdExtensions = compileOptions_.mdExtensions || md
const mdxExtensions = compileOptions_.mdxExtensions || mdx
/** @type {Processor} */
let cachedMarkdown
/** @type {Processor} */
let cachedMdx
return {
extnames:
compileOptions_.format === 'md'
? mdExtensions
: compileOptions_.format === 'mdx'
? mdxExtensions
: mdExtensions.concat(mdxExtensions),
process,
processSync
}
/**
* Smart processor.
*
* @param {VFileCompatible} vfileCompatible
* MDX or markdown document.
* @return {Promise<VFile>}
* File.
*/
function process(vfileCompatible) {
const {file, processor} = split(vfileCompatible)
return processor.process(file)
}
/**
* Sync smart processor.
*
* @param {VFileCompatible} vfileCompatible
* MDX or markdown document.
* @return {VFile}
* File.
*/
// C8 does not cover `.cjs` files (this is only used for the require hook,
// which has to be CJS).
/* c8 ignore next 4 */
function processSync(vfileCompatible) {
const {file, processor} = split(vfileCompatible)
return processor.processSync(file)
}
/**
* Make a full vfile from whats given, and figure out which processor
* should be used for it.
* This caches processors (one for markdown and one for MDX) so that they do
* not have to be reconstructed for each file.
*
* @param {VFileCompatible} vfileCompatible
* MDX or markdown document.
* @return {{file: VFile, processor: Processor}}
* File and corresponding processor.
*/
function split(vfileCompatible) {
const {file, options} = resolveFileAndOptions(
vfileCompatible,
compileOptions_
)
const processor =
options.format === 'md'
? cachedMarkdown || (cachedMarkdown = createProcessor(options))
: cachedMdx || (cachedMdx = createProcessor(options))
return {file, processor}
}
}

View file

@ -0,0 +1,13 @@
/**
* @typedef {import('estree-jsx').Node} Node
*/
/**
* @param {Node} from
* Node to take from.
* @param {Node} to
* Node to add to.
* @returns {void}
* Nothing.
*/
export function create(from: Node, to: Node): void;
export type Node = import('estree-jsx').Node;

View file

@ -0,0 +1,27 @@
/**
* @typedef {import('estree-jsx').Node} Node
*/
/**
* @param {Node} from
* Node to take from.
* @param {Node} to
* Node to add to.
* @returns {void}
* Nothing.
*/
export function create(from, to) {
/** @type {Array<keyof Node>} */
// @ts-expect-error: `start`, `end`, `comments` are custom Acorn fields.
const fields = ['start', 'end', 'loc', 'range', 'comments']
let index = -1
while (++index < fields.length) {
const field = fields[index]
if (field in from) {
// @ts-expect-error: assume theyre settable.
to[field] = from[field]
}
}
}

View file

@ -0,0 +1,19 @@
/**
* @typedef {import('estree-jsx').Declaration} Declaration
* @typedef {import('estree-jsx').Expression} Expression
*/
/**
* Turn a declaration into an expression.
*
* Doesnt work for variable declarations, but thats fine for our use case
* because currently were using this utility for export default declarations,
* which cant contain variable declarations.
*
* @param {Declaration} declaration
* Declaration.
* @returns {Expression}
* Expression.
*/
export function declarationToExpression(declaration: Declaration): Expression;
export type Declaration = import('estree-jsx').Declaration;
export type Expression = import('estree-jsx').Expression;

View file

@ -0,0 +1,32 @@
/**
* @typedef {import('estree-jsx').Declaration} Declaration
* @typedef {import('estree-jsx').Expression} Expression
*/
/**
* Turn a declaration into an expression.
*
* Doesnt work for variable declarations, but thats fine for our use case
* because currently were using this utility for export default declarations,
* which cant contain variable declarations.
*
* @param {Declaration} declaration
* Declaration.
* @returns {Expression}
* Expression.
*/
export function declarationToExpression(declaration) {
if (declaration.type === 'FunctionDeclaration') {
return {...declaration, type: 'FunctionExpression'}
}
if (declaration.type === 'ClassDeclaration') {
return {...declaration, type: 'ClassExpression'}
/* Internal utility so the next shouldnt happen or a maintainer is making a
* mistake. */
/* c8 ignore next 4 */
}
// Probably `VariableDeclaration`.
throw new Error('Cannot turn `' + declaration.type + '` into an expression')
}

View file

@ -0,0 +1,15 @@
/**
* @typedef {import('estree-jsx').Node} Node
* @typedef {import('estree-jsx').Declaration} Declaration
*/
/**
* Check if `node` is a declaration.
*
* @param {Node} node
* Node to check.
* @returns {node is Declaration}
* Whether `node` is a declaration.
*/
export function isDeclaration(node: Node): node is import("estree").Declaration;
export type Node = import('estree-jsx').Node;
export type Declaration = import('estree-jsx').Declaration;

View file

@ -0,0 +1,20 @@
/**
* @typedef {import('estree-jsx').Node} Node
* @typedef {import('estree-jsx').Declaration} Declaration
*/
/**
* Check if `node` is a declaration.
*
* @param {Node} node
* Node to check.
* @returns {node is Declaration}
* Whether `node` is a declaration.
*/
export function isDeclaration(node) {
return Boolean(
node.type === 'FunctionDeclaration' ||
node.type === 'ClassDeclaration' ||
node.type === 'VariableDeclaration'
)
}

View file

@ -0,0 +1,14 @@
/**
* @param {Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier>} specifiers
* @param {Expression} init
* @returns {Array<VariableDeclarator>}
*/
export function specifiersToDeclarations(specifiers: Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier>, init: Expression): Array<VariableDeclarator>;
export type AssignmentProperty = import('estree-jsx').AssignmentProperty;
export type ExportSpecifier = import('estree-jsx').ExportSpecifier;
export type Expression = import('estree-jsx').Expression;
export type Identifier = import('estree-jsx').Identifier;
export type ImportDefaultSpecifier = import('estree-jsx').ImportDefaultSpecifier;
export type ImportNamespaceSpecifier = import('estree-jsx').ImportNamespaceSpecifier;
export type ImportSpecifier = import('estree-jsx').ImportSpecifier;
export type VariableDeclarator = import('estree-jsx').VariableDeclarator;

View file

@ -0,0 +1,90 @@
/**
* @typedef {import('estree-jsx').AssignmentProperty} AssignmentProperty
* @typedef {import('estree-jsx').ExportSpecifier} ExportSpecifier
* @typedef {import('estree-jsx').Expression} Expression
* @typedef {import('estree-jsx').Identifier} Identifier
* @typedef {import('estree-jsx').ImportDefaultSpecifier} ImportDefaultSpecifier
* @typedef {import('estree-jsx').ImportNamespaceSpecifier} ImportNamespaceSpecifier
* @typedef {import('estree-jsx').ImportSpecifier} ImportSpecifier
* @typedef {import('estree-jsx').VariableDeclarator} VariableDeclarator
*/
import {create} from './estree-util-create.js'
/**
* @param {Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier>} specifiers
* @param {Expression} init
* @returns {Array<VariableDeclarator>}
*/
export function specifiersToDeclarations(specifiers, init) {
let index = -1
/** @type {Array<VariableDeclarator>} */
const declarations = []
/** @type {Array<ImportSpecifier | ImportDefaultSpecifier | ExportSpecifier>} */
const otherSpecifiers = []
// Can only be one according to JS syntax.
/** @type {ImportNamespaceSpecifier | undefined} */
let importNamespaceSpecifier
while (++index < specifiers.length) {
const specifier = specifiers[index]
if (specifier.type === 'ImportNamespaceSpecifier') {
importNamespaceSpecifier = specifier
} else {
otherSpecifiers.push(specifier)
}
}
if (importNamespaceSpecifier) {
/** @type {VariableDeclarator} */
const declarator = {
type: 'VariableDeclarator',
id: importNamespaceSpecifier.local,
init
}
create(importNamespaceSpecifier, declarator)
declarations.push(declarator)
}
declarations.push({
type: 'VariableDeclarator',
id: {
type: 'ObjectPattern',
properties: otherSpecifiers.map((specifier) => {
/** @type {Identifier} */
let key =
specifier.type === 'ImportSpecifier'
? specifier.imported
: specifier.type === 'ExportSpecifier'
? specifier.exported
: {type: 'Identifier', name: 'default'}
let value = specifier.local
// Switch them around if were exporting.
if (specifier.type === 'ExportSpecifier') {
value = key
key = specifier.local
}
/** @type {AssignmentProperty} */
const property = {
type: 'Property',
kind: 'init',
shorthand: key.name === value.name,
method: false,
computed: false,
key,
value
}
create(specifier, property)
return property
})
},
init: importNamespaceSpecifier
? {type: 'Identifier', name: importNamespaceSpecifier.local.name}
: init
})
return declarations
}

View file

@ -0,0 +1,8 @@
/**
* @typedef {import('estree-jsx').Expression} Expression
*/
/**
* @param {Array<Expression>} expressions
*/
export function toBinaryAddition(expressions: Array<Expression>): import("estree").Expression;
export type Expression = import('estree-jsx').Expression;

View file

@ -0,0 +1,23 @@
/**
* @typedef {import('estree-jsx').Expression} Expression
*/
/**
* @param {Array<Expression>} expressions
*/
export function toBinaryAddition(expressions) {
let index = -1
/** @type {Expression | undefined} */
let left
while (++index < expressions.length) {
const right = expressions[index]
left = left ? {type: 'BinaryExpression', left, operator: '+', right} : right
}
// Just for types.
/* c8 ignore next */
if (!left) throw new Error('Expected non-empty `expressions` to be passed')
return left
}

View file

@ -0,0 +1,11 @@
/**
* @param {Array<string | number>} ids
* @returns {Identifier | MemberExpression}
*/
export function toIdOrMemberExpression(ids: Array<string | number>): Identifier | MemberExpression;
export function toJsxIdOrMemberExpression(ids: Array<string | number>): JSXIdentifier | JSXMemberExpression;
export type Identifier = import('estree-jsx').Identifier;
export type JSXIdentifier = import('estree-jsx').JSXIdentifier;
export type JSXMemberExpression = import('estree-jsx').JSXMemberExpression;
export type Literal = import('estree-jsx').Literal;
export type MemberExpression = import('estree-jsx').MemberExpression;

View file

@ -0,0 +1,108 @@
/**
* @typedef {import('estree-jsx').Identifier} Identifier
* @typedef {import('estree-jsx').JSXIdentifier} JSXIdentifier
* @typedef {import('estree-jsx').JSXMemberExpression} JSXMemberExpression
* @typedef {import('estree-jsx').Literal} Literal
* @typedef {import('estree-jsx').MemberExpression} MemberExpression
*/
import {
start as esStart,
cont as esCont,
name as isIdentifierName
} from 'estree-util-is-identifier-name'
export const toIdOrMemberExpression = toIdOrMemberExpressionFactory(
'Identifier',
'MemberExpression',
isIdentifierName
)
export const toJsxIdOrMemberExpression =
// @ts-expect-error: fine
/** @type {(ids: Array<string | number>) => JSXIdentifier | JSXMemberExpression)} */
(
toIdOrMemberExpressionFactory(
'JSXIdentifier',
'JSXMemberExpression',
isJsxIdentifierName
)
)
/**
* @param {string} idType
* @param {string} memberType
* @param {(value: string) => boolean} isIdentifier
*/
function toIdOrMemberExpressionFactory(idType, memberType, isIdentifier) {
return toIdOrMemberExpression
/**
* @param {Array<string | number>} ids
* @returns {Identifier | MemberExpression}
*/
function toIdOrMemberExpression(ids) {
let index = -1
/** @type {Identifier | Literal | MemberExpression | undefined} */
let object
while (++index < ids.length) {
const name = ids[index]
const valid = typeof name === 'string' && isIdentifier(name)
// A value of `asd.123` could be turned into `asd['123']` in the JS form,
// but JSX does not have a form for it, so throw.
/* c8 ignore next 3 */
if (idType === 'JSXIdentifier' && !valid) {
throw new Error('Cannot turn `' + name + '` into a JSX identifier')
}
/** @type {Identifier | Literal} */
// @ts-expect-error: JSX is fine.
const id = valid ? {type: idType, name} : {type: 'Literal', value: name}
// @ts-expect-error: JSX is fine.
object = object
? {
type: memberType,
object,
property: id,
computed: id.type === 'Literal',
optional: false
}
: id
}
// Just for types.
/* c8 ignore next 3 */
if (!object) throw new Error('Expected non-empty `ids` to be passed')
if (object.type === 'Literal')
throw new Error('Expected identifier as left-most value')
return object
}
}
/**
* Checks if the given string is a valid JSX identifier name.
* @param {string} name
*/
function isJsxIdentifierName(name) {
let index = -1
while (++index < name.length) {
// We currently receive valid input, but this catches bugs and is needed
// when externalized.
/* c8 ignore next */
if (!(index ? jsxCont : esStart)(name.charCodeAt(index))) return false
}
// `false` if `name` is empty.
return index > 0
}
/**
* Checks if the given character code can continue a JSX identifier.
* @param {number} code
*/
function jsxCont(code) {
return code === 45 /* `-` */ || esCont(code)
}

View file

@ -0,0 +1,9 @@
/**
* Utility to turn a list of extnames (*with* dots) into an expression.
*
* @param {Array<string>} extnames
* List of extnames.
* @returns {RegExp}
* Regex matching them.
*/
export function extnamesToRegex(extnames: Array<string>): RegExp;

14
node_modules/@mdx-js/mdx/lib/util/extnames-to-regex.js generated vendored Normal file
View file

@ -0,0 +1,14 @@
/**
* Utility to turn a list of extnames (*with* dots) into an expression.
*
* @param {Array<string>} extnames
* List of extnames.
* @returns {RegExp}
* Regex matching them.
*/
export function extnamesToRegex(extnames) {
// eslint-disable-next-line security/detect-non-literal-regexp
return new RegExp(
'\\.(' + extnames.map((d) => d.slice(1)).join('|') + ')([?#]|$)'
)
}

3
node_modules/@mdx-js/mdx/lib/util/extnames.d.ts generated vendored Normal file
View file

@ -0,0 +1,3 @@
export const mdx: string[];
/** @type {Array<string>} */
export const md: Array<string>;

6
node_modules/@mdx-js/mdx/lib/util/extnames.js generated vendored Normal file
View file

@ -0,0 +1,6 @@
// @ts-expect-error: untyped.
import markdownExtensions from 'markdown-extensions'
export const mdx = ['.mdx']
/** @type {Array<string>} */
export const md = markdownExtensions.map((/** @type {string} */ d) => '.' + d)

View file

@ -0,0 +1,66 @@
/**
* @typedef {import('../core.js').ProcessorOptions} ProcessorOptions
*
* @typedef RunnerOptions
* Configuration with JSX runtime.
* @property {any} Fragment
* Symbol to use for fragments.
* @property {any} [jsx]
* Function to generate an element with static children in production mode.
* @property {any} [jsxs]
* Function to generate an element with dynamic children in production mode.
* @property {any} [jsxDEV]
* Function to generate an element in development mode.
* @property {any} [useMDXComponents]
* Function to get `MDXComponents` from context.
*
* @typedef {Omit<ProcessorOptions, 'jsx' | 'jsxImportSource' | 'jsxRuntime' | 'pragma' | 'pragmaFrag' | 'pragmaImportSource' | 'providerImportSource' | 'outputFormat'> } EvaluateProcessorOptions
* Compile configuration without JSX options for evaluation.
*
* @typedef {EvaluateProcessorOptions & RunnerOptions} EvaluateOptions
* Configuration for evaluation.
*/
/**
* Split compiletime options from runtime options.
*
* @param {EvaluateOptions | null | undefined} options
* @returns {{compiletime: ProcessorOptions, runtime: RunnerOptions}}
*/
export function resolveEvaluateOptions(options: EvaluateOptions | null | undefined): {
compiletime: ProcessorOptions;
runtime: RunnerOptions;
};
export type ProcessorOptions = import('../core.js').ProcessorOptions;
/**
* Configuration with JSX runtime.
*/
export type RunnerOptions = {
/**
* Symbol to use for fragments.
*/
Fragment: any;
/**
* Function to generate an element with static children in production mode.
*/
jsx?: any;
/**
* Function to generate an element with dynamic children in production mode.
*/
jsxs?: any;
/**
* Function to generate an element in development mode.
*/
jsxDEV?: any;
/**
* Function to get `MDXComponents` from context.
*/
useMDXComponents?: any;
};
/**
* Compile configuration without JSX options for evaluation.
*/
export type EvaluateProcessorOptions = Omit<ProcessorOptions, 'jsx' | 'jsxImportSource' | 'jsxRuntime' | 'pragma' | 'pragmaFrag' | 'pragmaImportSource' | 'providerImportSource' | 'outputFormat'>;
/**
* Configuration for evaluation.
*/
export type EvaluateOptions = EvaluateProcessorOptions & RunnerOptions;

View file

@ -0,0 +1,51 @@
/**
* @typedef {import('../core.js').ProcessorOptions} ProcessorOptions
*
* @typedef RunnerOptions
* Configuration with JSX runtime.
* @property {any} Fragment
* Symbol to use for fragments.
* @property {any} [jsx]
* Function to generate an element with static children in production mode.
* @property {any} [jsxs]
* Function to generate an element with dynamic children in production mode.
* @property {any} [jsxDEV]
* Function to generate an element in development mode.
* @property {any} [useMDXComponents]
* Function to get `MDXComponents` from context.
*
* @typedef {Omit<ProcessorOptions, 'jsx' | 'jsxImportSource' | 'jsxRuntime' | 'pragma' | 'pragmaFrag' | 'pragmaImportSource' | 'providerImportSource' | 'outputFormat'> } EvaluateProcessorOptions
* Compile configuration without JSX options for evaluation.
*
* @typedef {EvaluateProcessorOptions & RunnerOptions} EvaluateOptions
* Configuration for evaluation.
*/
/**
* Split compiletime options from runtime options.
*
* @param {EvaluateOptions | null | undefined} options
* @returns {{compiletime: ProcessorOptions, runtime: RunnerOptions}}
*/
export function resolveEvaluateOptions(options) {
const {development, Fragment, jsx, jsxs, jsxDEV, useMDXComponents, ...rest} =
options || {}
if (!Fragment) throw new Error('Expected `Fragment` given to `evaluate`')
if (development) {
if (!jsxDEV) throw new Error('Expected `jsxDEV` given to `evaluate`')
} else {
if (!jsx) throw new Error('Expected `jsx` given to `evaluate`')
if (!jsxs) throw new Error('Expected `jsxs` given to `evaluate`')
}
return {
compiletime: {
...rest,
development,
outputFormat: 'function-body',
providerImportSource: useMDXComponents ? '#' : undefined
},
runtime: {Fragment, jsx, jsxs, jsxDEV, useMDXComponents}
}
}

View file

@ -0,0 +1,16 @@
/**
* Create a file and options from a given `vfileCompatible` and options that
* might contain `format: 'detect'`.
*
* @param {VFileCompatible} vfileCompatible
* @param {CompileOptions | null | undefined} [options]
* @returns {{file: VFile, options: ProcessorOptions}}
*/
export function resolveFileAndOptions(vfileCompatible: VFileCompatible, options?: CompileOptions | null | undefined): {
file: VFile;
options: ProcessorOptions;
};
export type VFileCompatible = import('vfile').VFileCompatible;
export type ProcessorOptions = import('../core.js').ProcessorOptions;
export type CompileOptions = import('../compile.js').CompileOptions;
import { VFile } from "vfile";

View file

@ -0,0 +1,48 @@
/**
* @typedef {import('vfile').VFileCompatible} VFileCompatible
* @typedef {import('../core.js').ProcessorOptions} ProcessorOptions
* @typedef {import('../compile.js').CompileOptions} CompileOptions
*/
import {VFile} from 'vfile'
import {md} from './extnames.js'
/**
* Create a file and options from a given `vfileCompatible` and options that
* might contain `format: 'detect'`.
*
* @param {VFileCompatible} vfileCompatible
* @param {CompileOptions | null | undefined} [options]
* @returns {{file: VFile, options: ProcessorOptions}}
*/
export function resolveFileAndOptions(vfileCompatible, options) {
const file = looksLikeAVFile(vfileCompatible)
? vfileCompatible
: new VFile(vfileCompatible)
const {format, ...rest} = options || {}
return {
file,
options: {
format:
format === 'md' || format === 'mdx'
? format
: file.extname && (rest.mdExtensions || md).includes(file.extname)
? 'md'
: 'mdx',
...rest
}
}
}
/**
* @param {VFileCompatible | null | undefined} [value]
* @returns {value is VFile}
*/
function looksLikeAVFile(value) {
return Boolean(
value &&
typeof value === 'object' &&
'message' in value &&
'messages' in value
)
}