Socket
Socket
Sign inDemoInstall

@astrojs/mdx

Package Overview
Dependencies
Maintainers
4
Versions
165
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@astrojs/mdx - npm Package Compare versions

Comparing version 0.11.1 to 0.11.2

dist/plugins.d.ts

8

CHANGELOG.md
# @astrojs/mdx
## 0.11.2
### Patch Changes
- [#4700](https://github.com/withastro/astro/pull/4700) [`e5f71142e`](https://github.com/withastro/astro/commit/e5f71142eb62bd72456e889dad5774347c3753f2) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Document MDXLayoutProps utility type
- [#4858](https://github.com/withastro/astro/pull/4858) [`58a2dca22`](https://github.com/withastro/astro/commit/58a2dca2286cb14f6211cf51267c02447e78433a) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Correctly parse import.meta.env in MDX files
## 0.11.1

@@ -4,0 +12,0 @@

14

dist/index.d.ts

@@ -0,3 +1,15 @@

import { PluggableList } from '@mdx-js/mdx/lib/core.js';
import type { AstroIntegration } from 'astro';
import type { MdxOptions } from './utils.js';
export declare type MdxOptions = {
remarkPlugins?: PluggableList;
rehypePlugins?: PluggableList;
/**
* Choose which remark and rehype plugins to inherit, if any.
*
* - "markdown" (default) - inherit your project’s markdown plugin config ([see Markdown docs](https://docs.astro.build/en/guides/markdown-content/#configuring-markdown))
* - "astroDefaults" - inherit Astro’s default plugins only ([see defaults](https://docs.astro.build/en/reference/configuration-reference/#markdownextenddefaultplugins))
* - false - do not inherit any plugins
*/
extendPlugins?: 'markdown' | 'astroDefaults' | false;
};
export default function mdx(mdxOptions?: MdxOptions): AstroIntegration;

30

dist/index.js

@@ -5,11 +5,11 @@ import { compile as mdxCompile } from "@mdx-js/mdx";

import { blue, bold } from "kleur/colors";
import fs from "node:fs/promises";
import { VFile } from "vfile";
import { rehypeApplyFrontmatterExport } from "./astro-data-utils.js";
import {
getFileInfo,
getRehypePlugins,
getRemarkPlugins,
handleExtendsNotSupported,
parseFrontmatter
} from "./utils.js";
recmaInjectImportMetaEnvPlugin,
rehypeApplyFrontmatterExport
} from "./plugins.js";
import { getFileInfo, handleExtendsNotSupported, parseFrontmatter } from "./utils.js";
const RAW_CONTENT_ERROR = "MDX does not support rawContent()! If you need to read the Markdown contents to calculate values (ex. reading time), we suggest injecting frontmatter via remark plugins. Learn more on our docs: https://docs.astro.build/en/guides/integrations-guide/mdx/#inject-frontmatter-via-remark-or-rehype-plugins";

@@ -46,2 +46,5 @@ const COMPILED_CONTENT_ERROR = "MDX does not support compiledContent()! If you need to read the HTML contents to calculate values (ex. reading time), we suggest injecting frontmatter via rehype plugins. Learn more on our docs: https://docs.astro.build/en/guides/integrations-guide/mdx/#inject-frontmatter-via-remark-or-rehype-plugins";

};
let importMetaEnv = {
SITE: config.site
};
updateConfig({

@@ -53,5 +56,10 @@ vite: {

...mdxPlugin(mdxPluginOpts),
async transform(code, id) {
configResolved(resolved) {
importMetaEnv = { ...importMetaEnv, ...resolved.env };
},
async transform(_, id) {
if (!id.endsWith("mdx"))
return;
const { fileId } = getFileInfo(id, config);
const code = await fs.readFile(fileId, "utf-8");
const { data: frontmatter, content: pageContent } = parseFrontmatter(code, id);

@@ -63,6 +71,7 @@ const compiled = await mdxCompile(new VFile({ value: pageContent, path: id }), {

() => rehypeApplyFrontmatterExport(frontmatter)
]
],
recmaPlugins: [() => recmaInjectImportMetaEnvPlugin({ importMetaEnv })]
});
return {
code: String(compiled.value),
code: escapeViteEnvReferences(String(compiled.value)),
map: compiled.map

@@ -111,3 +120,3 @@ };

}
return code;
return escapeViteEnvReferences(code);
}

@@ -122,4 +131,7 @@ }

}
function escapeViteEnvReferences(code) {
return code.replace(/import\.meta\.env/g, "import\\u002Emeta.env");
}
export {
mdx as default
};

@@ -1,3 +0,1 @@

import type { PluggableList } from '@mdx-js/mdx/lib/core.js';
import type { Options as MdxRollupPluginOptions } from '@mdx-js/rollup';
import type { Options as AcornOpts } from 'acorn';

@@ -7,14 +5,2 @@ import type { AstroConfig } from 'astro';

import type { MdxjsEsm } from 'mdast-util-mdx';
export declare type MdxOptions = {
remarkPlugins?: PluggableList;
rehypePlugins?: PluggableList;
/**
* Choose which remark and rehype plugins to inherit, if any.
*
* - "markdown" (default) - inherit your project’s markdown plugin config ([see Markdown docs](https://docs.astro.build/en/guides/markdown-content/#configuring-markdown))
* - "astroDefaults" - inherit Astro’s default plugins only ([see defaults](https://docs.astro.build/en/reference/configuration-reference/#markdownextenddefaultplugins))
* - false - do not inherit any plugins
*/
extendPlugins?: 'markdown' | 'astroDefaults' | false;
};
interface FileInfo {

@@ -32,5 +18,3 @@ fileId: string;

export declare function jsToTreeNode(jsString: string, acornOpts?: AcornOpts): MdxjsEsm;
export declare function getRemarkPlugins(mdxOptions: MdxOptions, config: AstroConfig): Promise<MdxRollupPluginOptions['remarkPlugins']>;
export declare function getRehypePlugins(mdxOptions: MdxOptions, config: AstroConfig): MdxRollupPluginOptions['rehypePlugins'];
export declare function handleExtendsNotSupported(pluginConfig: any): void;
export {};

@@ -1,17 +0,6 @@

import { nodeTypes } from "@mdx-js/mdx";
import { parse } from "acorn";
import matter from "gray-matter";
import { bold, yellow } from "kleur/colors";
import rehypeRaw from "rehype-raw";
import remarkGfm from "remark-gfm";
import remarkSmartypants from "remark-smartypants";
import { remarkInitializeAstroData } from "./astro-data-utils.js";
import rehypeCollectHeadings from "./rehype-collect-headings.js";
import remarkPrism from "./remark-prism.js";
import remarkShiki from "./remark-shiki.js";
function appendForwardSlash(path) {
return path.endsWith("/") ? path : path + "/";
}
const DEFAULT_REMARK_PLUGINS = [remarkGfm, remarkSmartypants];
const DEFAULT_REHYPE_PLUGINS = [];
function getFileInfo(id, config) {

@@ -73,75 +62,2 @@ const sitePathname = appendForwardSlash(

}
async function getRemarkPlugins(mdxOptions, config) {
let remarkPlugins = [
remarkInitializeAstroData
];
switch (mdxOptions.extendPlugins) {
case false:
break;
case "astroDefaults":
remarkPlugins = [...remarkPlugins, ...DEFAULT_REMARK_PLUGINS];
break;
default:
remarkPlugins = [
...remarkPlugins,
...markdownShouldExtendDefaultPlugins(config) ? DEFAULT_REMARK_PLUGINS : [],
...ignoreStringPlugins(config.markdown.remarkPlugins ?? [])
];
break;
}
if (config.markdown.syntaxHighlight === "shiki") {
remarkPlugins.push([await remarkShiki(config.markdown.shikiConfig)]);
}
if (config.markdown.syntaxHighlight === "prism") {
remarkPlugins.push(remarkPrism);
}
remarkPlugins = [...remarkPlugins, ...mdxOptions.remarkPlugins ?? []];
return remarkPlugins;
}
function getRehypePlugins(mdxOptions, config) {
let rehypePlugins = [
rehypeCollectHeadings,
[rehypeRaw, { passThrough: nodeTypes }]
];
switch (mdxOptions.extendPlugins) {
case false:
break;
case "astroDefaults":
rehypePlugins = [...rehypePlugins, ...DEFAULT_REHYPE_PLUGINS];
break;
default:
rehypePlugins = [
...rehypePlugins,
...markdownShouldExtendDefaultPlugins(config) ? DEFAULT_REHYPE_PLUGINS : [],
...ignoreStringPlugins(config.markdown.rehypePlugins ?? [])
];
break;
}
rehypePlugins = [...rehypePlugins, ...mdxOptions.rehypePlugins ?? []];
return rehypePlugins;
}
function markdownShouldExtendDefaultPlugins(config) {
return config.markdown.extendDefaultPlugins || config.markdown.remarkPlugins.length === 0 && config.markdown.rehypePlugins.length === 0;
}
function ignoreStringPlugins(plugins) {
let validPlugins = [];
let hasInvalidPlugin = false;
for (const plugin of plugins) {
if (typeof plugin === "string") {
console.warn(yellow(`[MDX] ${bold(plugin)} not applied.`));
hasInvalidPlugin = true;
} else if (Array.isArray(plugin) && typeof plugin[0] === "string") {
console.warn(yellow(`[MDX] ${bold(plugin[0])} not applied.`));
hasInvalidPlugin = true;
} else {
validPlugins.push(plugin);
}
}
if (hasInvalidPlugin) {
console.warn(
`To inherit Markdown plugins in MDX, please use explicit imports in your config instead of "strings." See Markdown docs: https://docs.astro.build/en/guides/markdown-content/#markdown-plugins`
);
}
return validPlugins;
}
function handleExtendsNotSupported(pluginConfig) {

@@ -156,4 +72,2 @@ if (typeof pluginConfig === "object" && pluginConfig !== null && pluginConfig.hasOwnProperty("extends")) {

getFileInfo,
getRehypePlugins,
getRemarkPlugins,
handleExtendsNotSupported,

@@ -160,0 +74,0 @@ jsToTreeNode,

{
"name": "@astrojs/mdx",
"description": "Use MDX within Astro",
"version": "0.11.1",
"version": "0.11.2",
"type": "module",

@@ -31,2 +31,3 @@ "types": "./dist/index.d.ts",

"es-module-lexer": "^0.10.5",
"estree-util-visit": "^1.2.0",
"github-slugger": "^1.4.0",

@@ -45,6 +46,7 @@ "gray-matter": "^4.0.3",

"@types/chai": "^4.3.1",
"@types/estree": "^1.0.0",
"@types/mocha": "^9.1.1",
"@types/yargs-parser": "^21.0.0",
"astro": "1.1.4",
"astro-scripts": "0.0.7",
"astro": "1.3.1",
"astro-scripts": "0.0.8",
"chai": "^4.3.6",

@@ -51,0 +53,0 @@ "linkedom": "^0.14.12",

@@ -29,3 +29,3 @@ # @astrojs/mdx 📝

# Using NPM
npm run astro add mdx
npx astro add mdx
# Using Yarn

@@ -37,6 +37,4 @@ yarn astro add mdx

Then, restart the dev server by typing `CTRL-C` and then `npm run astro dev` in the terminal window that was running Astro.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
Because this command is new, it might not properly set things up. If that happens, [feel free to log an issue on our GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install

@@ -66,2 +64,12 @@

### Editor Integration
[VS Code](https://code.visualstudio.com/) supports Markdown by default. However, for MDX editor support, you may wish to add the following setting in your VSCode config. This ensures authoring MDX files provides a Markdown-like editor experience.
```json title=".vscode/settings.json"
"files.associations": {
"*.mdx": "markdown"
}
```
## Usage

@@ -76,3 +84,3 @@

- 💧 client-side hydration options, and
- 🪆 opportunities to mix and nest frameworks together
- 🤝 opportunities to mix and nest frameworks together

@@ -202,3 +210,3 @@ [**Client Directives**](https://docs.astro.build/en/reference/directives-reference/#client-directives) are still required in `.mdx` files.

Then, you can retrieve all other frontmatter properties from your layout via the `frontmatter` property, and render your MDX using the default [`<slot />`](https://docs.astro.build/en/core-concepts/astro-components/#slots):
Then, you can retrieve all other frontmatter properties from your layout via the `frontmatter` property, and render your MDX using the default [`<slot />`](https://docs.astro.build/en/core-concepts/astro-components/#slots). See [layout props](#layout-props) for a complete list of props available.

@@ -208,6 +216,7 @@ ```astro

// src/layouts/BaseLayout.astro
const { frontmatter } = Astro.props;
const { frontmatter, url } = Astro.props;
---
<html>
<head>
<meta rel="canonical" href={new URL(url, Astro.site).pathname}>
<title>{frontmatter.title}</title>

@@ -223,2 +232,44 @@ </head>

You can set a layout’s [`Props` type](/en/guides/typescript/#component-props) with the `MDXLayoutProps` helper.
:::note
`MDXLayoutProps` is the same as the `MarkdownLayoutProps` utility type with `rawContent()` and `compiledContent()` removed (since these are not available for `.mdx` files). Feel free to **use `MarkdownLayoutProps` instead** when sharing a layout across `.md` and `.mdx` files.
:::
```astro ins={2,4-9}
---
// src/layouts/BaseLayout.astro
import type { MDXLayoutProps } from 'astro';
type Props = MDXLayoutProps<{
// Define frontmatter props here
title: string;
author: string;
date: string;
}>;
// Now, `frontmatter`, `url`, and other MDX layout properties
// are accessible with type safety
const { frontmatter, url } = Astro.props;
---
<html>
<head>
<meta rel="canonical" href={new URL(url, Astro.site).pathname}>
<title>{frontmatter.title}</title>
</head>
<body>
<h1>{frontmatter.title}</h1>
<slot />
</body>
</html>
```
#### Layout props
All [exported properties](#exported-properties) are available from `Astro.props` in your layout, **with two key differences:**
- Heading information (i.e. `h1 -> h6` elements) is available via the `headings` array, rather than a `getHeadings()` function.
- `file` and `url` are _also_ available as nested `frontmatter` properties (i.e. `frontmatter.url` and `frontmatter.file`). This is consistent with Astro's Markdown layout properties.
Astro recommends using the `MDXLayoutProps` type (see previous section) to explore all available properties.
#### Importing layouts manually

@@ -470,3 +521,3 @@

For help, check out the `#support-threads` channel on [Discord](https://astro.build/chat). Our friendly Support Squad members are here to help!
For help, check out the `#support` channel on [Discord](https://astro.build/chat). Our friendly Support Squad members are here to help!

@@ -473,0 +524,0 @@ You can also check our [Astro Integration Documentation][astro-integration] for more on integrations.

import { compile as mdxCompile } from '@mdx-js/mdx';
import { PluggableList } from '@mdx-js/mdx/lib/core.js';
import mdxPlugin, { Options as MdxRollupPluginOptions } from '@mdx-js/rollup';

@@ -6,13 +7,12 @@ import type { AstroIntegration } from 'astro';

import { blue, bold } from 'kleur/colors';
import fs from 'node:fs/promises';
import { VFile } from 'vfile';
import type { Plugin as VitePlugin } from 'vite';
import { rehypeApplyFrontmatterExport } from './astro-data-utils.js';
import type { MdxOptions } from './utils.js';
import {
getFileInfo,
getRehypePlugins,
getRemarkPlugins,
handleExtendsNotSupported,
parseFrontmatter,
} from './utils.js';
recmaInjectImportMetaEnvPlugin,
rehypeApplyFrontmatterExport,
} from './plugins.js';
import { getFileInfo, handleExtendsNotSupported, parseFrontmatter } from './utils.js';

@@ -25,2 +25,15 @@ const RAW_CONTENT_ERROR =

export type MdxOptions = {
remarkPlugins?: PluggableList;
rehypePlugins?: PluggableList;
/**
* Choose which remark and rehype plugins to inherit, if any.
*
* - "markdown" (default) - inherit your project’s markdown plugin config ([see Markdown docs](https://docs.astro.build/en/guides/markdown-content/#configuring-markdown))
* - "astroDefaults" - inherit Astro’s default plugins only ([see defaults](https://docs.astro.build/en/reference/configuration-reference/#markdownextenddefaultplugins))
* - false - do not inherit any plugins
*/
extendPlugins?: 'markdown' | 'astroDefaults' | false;
};
export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {

@@ -63,2 +76,6 @@ return {

let importMetaEnv: Record<string, any> = {
SITE: config.site,
};
updateConfig({

@@ -70,7 +87,14 @@ vite: {

...mdxPlugin(mdxPluginOpts),
configResolved(resolved) {
importMetaEnv = { ...importMetaEnv, ...resolved.env };
},
// Override transform to alter code before MDX compilation
// ex. inject layouts
async transform(code, id) {
async transform(_, id) {
if (!id.endsWith('mdx')) return;
// Read code from file manually to prevent Vite from parsing `import.meta.env` expressions
const { fileId } = getFileInfo(id, config);
const code = await fs.readFile(fileId, 'utf-8');
const { data: frontmatter, content: pageContent } = parseFrontmatter(code, id);

@@ -83,6 +107,7 @@ const compiled = await mdxCompile(new VFile({ value: pageContent, path: id }), {

],
recmaPlugins: [() => recmaInjectImportMetaEnvPlugin({ importMetaEnv })],
});
return {
code: String(compiled.value),
code: escapeViteEnvReferences(String(compiled.value)),
map: compiled.map,

@@ -131,3 +156,3 @@ };

}
return code;
return escapeViteEnvReferences(code);
},

@@ -142,1 +167,8 @@ },

}
// Converts the first dot in `import.meta.env` to its Unicode escape sequence,
// which prevents Vite from replacing strings like `import.meta.env.SITE`
// in our JS representation of loaded Markdown files
function escapeViteEnvReferences(code: string) {
return code.replace(/import\.meta\.env/g, 'import\\u002Emeta.env');
}

@@ -1,4 +0,1 @@

import { nodeTypes } from '@mdx-js/mdx';
import type { PluggableList } from '@mdx-js/mdx/lib/core.js';
import type { Options as MdxRollupPluginOptions } from '@mdx-js/rollup';
import type { Options as AcornOpts } from 'acorn';

@@ -8,25 +5,4 @@ import { parse } from 'acorn';

import matter from 'gray-matter';
import { bold, yellow } from 'kleur/colors';
import type { MdxjsEsm } from 'mdast-util-mdx';
import rehypeRaw from 'rehype-raw';
import remarkGfm from 'remark-gfm';
import remarkSmartypants from 'remark-smartypants';
import { remarkInitializeAstroData } from './astro-data-utils.js';
import rehypeCollectHeadings from './rehype-collect-headings.js';
import remarkPrism from './remark-prism.js';
import remarkShiki from './remark-shiki.js';
export type MdxOptions = {
remarkPlugins?: PluggableList;
rehypePlugins?: PluggableList;
/**
* Choose which remark and rehype plugins to inherit, if any.
*
* - "markdown" (default) - inherit your project’s markdown plugin config ([see Markdown docs](https://docs.astro.build/en/guides/markdown-content/#configuring-markdown))
* - "astroDefaults" - inherit Astro’s default plugins only ([see defaults](https://docs.astro.build/en/reference/configuration-reference/#markdownextenddefaultplugins))
* - false - do not inherit any plugins
*/
extendPlugins?: 'markdown' | 'astroDefaults' | false;
};
function appendForwardSlash(path: string) {

@@ -41,5 +17,2 @@ return path.endsWith('/') ? path : path + '/';

const DEFAULT_REMARK_PLUGINS: PluggableList = [remarkGfm, remarkSmartypants];
const DEFAULT_REHYPE_PLUGINS: PluggableList = [];
/** @see 'vite-plugin-utils' for source */

@@ -115,93 +88,2 @@ export function getFileInfo(id: string, config: AstroConfig): FileInfo {

export async function getRemarkPlugins(
mdxOptions: MdxOptions,
config: AstroConfig
): Promise<MdxRollupPluginOptions['remarkPlugins']> {
let remarkPlugins: PluggableList = [
// Set "vfile.data.astro" for plugins to inject frontmatter
remarkInitializeAstroData,
];
switch (mdxOptions.extendPlugins) {
case false:
break;
case 'astroDefaults':
remarkPlugins = [...remarkPlugins, ...DEFAULT_REMARK_PLUGINS];
break;
default:
remarkPlugins = [
...remarkPlugins,
...(markdownShouldExtendDefaultPlugins(config) ? DEFAULT_REMARK_PLUGINS : []),
...ignoreStringPlugins(config.markdown.remarkPlugins ?? []),
];
break;
}
if (config.markdown.syntaxHighlight === 'shiki') {
remarkPlugins.push([await remarkShiki(config.markdown.shikiConfig)]);
}
if (config.markdown.syntaxHighlight === 'prism') {
remarkPlugins.push(remarkPrism);
}
remarkPlugins = [...remarkPlugins, ...(mdxOptions.remarkPlugins ?? [])];
return remarkPlugins;
}
export function getRehypePlugins(
mdxOptions: MdxOptions,
config: AstroConfig
): MdxRollupPluginOptions['rehypePlugins'] {
let rehypePlugins: PluggableList = [
// getHeadings() is guaranteed by TS, so we can't allow user to override
rehypeCollectHeadings,
// rehypeRaw allows custom syntax highlighters to work without added config
[rehypeRaw, { passThrough: nodeTypes }] as any,
];
switch (mdxOptions.extendPlugins) {
case false:
break;
case 'astroDefaults':
rehypePlugins = [...rehypePlugins, ...DEFAULT_REHYPE_PLUGINS];
break;
default:
rehypePlugins = [
...rehypePlugins,
...(markdownShouldExtendDefaultPlugins(config) ? DEFAULT_REHYPE_PLUGINS : []),
...ignoreStringPlugins(config.markdown.rehypePlugins ?? []),
];
break;
}
rehypePlugins = [...rehypePlugins, ...(mdxOptions.rehypePlugins ?? [])];
return rehypePlugins;
}
function markdownShouldExtendDefaultPlugins(config: AstroConfig): boolean {
return (
config.markdown.extendDefaultPlugins ||
(config.markdown.remarkPlugins.length === 0 && config.markdown.rehypePlugins.length === 0)
);
}
function ignoreStringPlugins(plugins: any[]) {
let validPlugins: PluggableList = [];
let hasInvalidPlugin = false;
for (const plugin of plugins) {
if (typeof plugin === 'string') {
console.warn(yellow(`[MDX] ${bold(plugin)} not applied.`));
hasInvalidPlugin = true;
} else if (Array.isArray(plugin) && typeof plugin[0] === 'string') {
console.warn(yellow(`[MDX] ${bold(plugin[0])} not applied.`));
hasInvalidPlugin = true;
} else {
validPlugins.push(plugin);
}
}
if (hasInvalidPlugin) {
console.warn(
`To inherit Markdown plugins in MDX, please use explicit imports in your config instead of "strings." See Markdown docs: https://docs.astro.build/en/guides/markdown-content/#markdown-plugins`
);
}
return validPlugins;
}
// TODO: remove for 1.0

@@ -208,0 +90,0 @@ export function handleExtendsNotSupported(pluginConfig: any) {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc