[MDX] Support YAML frontmatter (#3995)

* chore: remove old comment

* deps: add remark-frontmatter

* deps: add remark-mdx-frontmatter

* fix: handle null or undefined frontmatter key

* feat: configure frontmatter plugins with defaults

* test: frontmatter and custom frontmatter name

* docs: add frontmatterOptions config

* docs: add "variables" and "frontmatter" docs

* chore: excessible -> accessible

* chore: changeset

* chore: remove bad mdx comment
This commit is contained in:
Ben Holmes 2022-07-20 21:34:21 -04:00 committed by GitHub
parent 40a45e3ef6
commit b2b367c969
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 348 additions and 13 deletions

View file

@ -0,0 +1,6 @@
---
'@astrojs/mdx': minor
'astro': patch
---
Support YAML frontmatter in MDX files

View file

@ -59,7 +59,7 @@ function shouldSkipDraft(pageModule: ComponentInstance, astroConfig: AstroConfig
!astroConfig.markdown.drafts &&
// This is a draft post
'frontmatter' in pageModule &&
(pageModule as any).frontmatter.draft === true
(pageModule as any).frontmatter?.draft === true
);
}

View file

@ -78,6 +78,62 @@ To write your first MDX page in Astro, head to our [UI framework documentation][
Also check our [Astro Integration Documentation][astro-integration] for more on integrations.
### Variables
MDX supports `export` statements to add variables to your templates. These variables are accessible both from the template itself _and_ as named properties when importing the template somewhere else.
For instance, you can export a `title` field from an MDX page or component to use as a heading with `{JSX expressions}`:
```mdx
export const title = 'My first MDX post'
# {title}
```
This `title` will be accessible from `import` and [glob](https://docs.astro.build/en/reference/api-reference/#astroglob) statements as well:
```astro
---
// src/pages/index.astro
const posts = await Astro.glob('./*.mdx');
---
{posts.map(post => <p>{post.title}</p>)}
```
See [the official "how MDX works" guide](https://mdxjs.com/docs/using-mdx/#how-mdx-works) for more on MDX variables.
### Frontmatter
Astro also supports YAML-based frontmatter out-of-the-box using the [remark-mdx-frontmatter](https://github.com/remcohaszing/remark-mdx-frontmatter) plugin. By default, all variables declared in a frontmatter fence (`---`) will be accessible via the `frontmatter` export. See the `frontmatterOptions` configuration to customize this behavior.
For example, we can add a `title` and `publishDate` to an MDX page or component like so:
```mdx
---
title: 'My first MDX post'
publishDate: '21 September 2022'
---
# {frontmatter.title}
```
Now, this `title` and `publishDate` will be accessible from `import` and [glob](https://docs.astro.build/en/reference/api-reference/#astroglob) statements via the `frontmatter` property. This matches the behavior of [plain markdown in Astro](https://docs.astro.build/en/reference/api-reference/#markdown-files) as well!
```astro
---
// src/pages/index.astro
const posts = await Astro.glob('./*.mdx');
---
{posts.map(post => (
<Fragment>
<h2>{post.frontmatter.title}</h2>
<time>{post.frontmatter.publishDate}</time>
</Fragment>
))}
```
## Configuration
<details>
@ -140,6 +196,37 @@ export default {
```
</details>
<details>
<summary><strong>frontmatterOptions</strong></summary>
**Default:** `{ name: 'frontmatter' }`
We use [remark-mdx-frontmatter](https://github.com/remcohaszing/remark-mdx-frontmatter) to parse YAML-based frontmatter in your MDX files. If you want to override our default configuration or extend remark-mdx-frontmatter (ex. to [apply a custom frontmatter parser](https://github.com/remcohaszing/remark-mdx-frontmatter#parsers)), you can supply a `frontmatterOptions` configuration.
For example, say you want to access frontmatter as root-level variables without a nested `frontmatter` object. You can override the [`name` configuration option](https://github.com/remcohaszing/remark-mdx-frontmatter#name) like so:
```js
// astro.config.mjs
export default {
integrations: [mdx({
frontmatterOptions: {
name: '',
}
})],
}
```
```mdx
---
title: I'm just a variable now!
---
# {title}
```
See the [remark-mdx-frontmatter README](https://github.com/remcohaszing/remark-mdx-frontmatter#options) for a complete list of options.
</details>
## Examples
- The [Astro MDX example](https://github.com/withastro/astro/tree/latest/examples/with-mdx) shows how to use MDX files in your Astro project.

View file

@ -32,7 +32,9 @@
"dependencies": {
"@mdx-js/rollup": "^2.1.1",
"es-module-lexer": "^0.10.5",
"remark-frontmatter": "^4.0.1",
"remark-gfm": "^3.0.1",
"remark-mdx-frontmatter": "^2.0.2",
"remark-smartypants": "^2.0.0"
},
"devDependencies": {

View file

@ -1,8 +1,11 @@
import mdxPlugin, { Options as MdxRollupPluginOptions } from '@mdx-js/rollup';
import type { AstroIntegration } from 'astro';
import type { RemarkMdxFrontmatterOptions } from 'remark-mdx-frontmatter';
import { parse as parseESM } from 'es-module-lexer';
import remarkGfm from 'remark-gfm';
import remarkSmartypants from 'remark-smartypants';
import remarkFrontmatter from 'remark-frontmatter';
import remarkMdxFrontmatter from 'remark-mdx-frontmatter';
import { getFileInfo } from './utils.js';
type WithExtends<T> = T | { extends: T };
@ -10,14 +13,20 @@ type WithExtends<T> = T | { extends: T };
type MdxOptions = {
remarkPlugins?: WithExtends<MdxRollupPluginOptions['remarkPlugins']>;
rehypePlugins?: WithExtends<MdxRollupPluginOptions['rehypePlugins']>;
};
/**
* Configure the remark-mdx-frontmatter plugin
* @see https://github.com/remcohaszing/remark-mdx-frontmatter#options for a full list of options
* @default {{ name: 'frontmatter' }}
*/
frontmatterOptions?: RemarkMdxFrontmatterOptions;
}
const DEFAULT_REMARK_PLUGINS = [remarkGfm, remarkSmartypants];
function handleExtends<T>(
config: WithExtends<T[] | undefined>,
defaults: T[] = []
): T[] | undefined {
defaults: T[] = [],
): T[] {
if (Array.isArray(config)) return config;
return [...defaults, ...(config?.extends ?? [])];
@ -35,9 +44,18 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
{
enforce: 'pre',
...mdxPlugin({
remarkPlugins: handleExtends(mdxOptions.remarkPlugins, DEFAULT_REMARK_PLUGINS),
remarkPlugins: [
...handleExtends(mdxOptions.remarkPlugins, DEFAULT_REMARK_PLUGINS),
// Frontmatter plugins should always be applied!
// We can revisit this if a strong use case to *remove*
// YAML frontmatter via config is reported.
remarkFrontmatter,
[remarkMdxFrontmatter, {
name: 'frontmatter',
...mdxOptions.frontmatterOptions,
}],
],
rehypePlugins: handleExtends(mdxOptions.rehypePlugins),
// place these after so the user can't override
jsx: true,
jsxImportSource: 'astro',
// Note: disable `.md` support

View file

@ -0,0 +1,9 @@
export async function get() {
const mdxPages = await import.meta.glob('./*.mdx', { eager: true });
return {
body: JSON.stringify({
titles: Object.values(mdxPages ?? {}).map(v => v?.customFrontmatter?.title),
})
}
}

View file

@ -0,0 +1,6 @@
---
title: 'Using YAML frontmatter'
illThrowIfIDontExist: "Oh no, that's scary!"
---
# {customFrontmatter.illThrowIfIDontExist}

View file

@ -0,0 +1,9 @@
export async function get() {
const mdxPages = await import.meta.glob('./*.mdx', { eager: true });
return {
body: JSON.stringify({
titles: Object.values(mdxPages ?? {}).map(v => v?.frontmatter?.title),
})
}
}

View file

@ -0,0 +1,6 @@
---
title: 'Using YAML frontmatter'
illThrowIfIDontExist: "Oh no, that's scary!"
---
# {frontmatter.illThrowIfIDontExist}

View file

@ -0,0 +1,43 @@
import mdx from '@astrojs/mdx';
import { expect } from 'chai';
import { loadFixture } from '../../../astro/test/test-utils.js';
const FIXTURE_ROOT = new URL('./fixtures/mdx-frontmatter/', import.meta.url);
describe('MDX frontmatter', () => {
it('builds when "frontmatter.property" is in JSX expression', async () => {
const fixture = await loadFixture({
root: FIXTURE_ROOT,
integrations: [mdx()],
});
await fixture.build();
expect(true).to.equal(true);
});
it('extracts frontmatter to "frontmatter" export', async () => {
const fixture = await loadFixture({
root: FIXTURE_ROOT,
integrations: [mdx()],
});
await fixture.build();
const { titles } = JSON.parse(await fixture.readFile('/glob.json'));
expect(titles).to.include('Using YAML frontmatter');
});
it('extracts frontmatter to "customFrontmatter" export when configured', async () => {
const fixture = await loadFixture({
root: new URL('./fixtures/mdx-custom-frontmatter-name/', import.meta.url),
integrations: [mdx({
frontmatterOptions: {
name: 'customFrontmatter',
},
})],
});
await fixture.build();
const { titles } = JSON.parse(await fixture.readFile('/glob.json'));
expect(titles).to.include('Using YAML frontmatter');
});
});

View file

@ -2074,13 +2074,17 @@ importers:
es-module-lexer: ^0.10.5
linkedom: ^0.14.12
mocha: ^9.2.2
remark-frontmatter: ^4.0.1
remark-gfm: ^3.0.1
remark-mdx-frontmatter: ^2.0.2
remark-smartypants: ^2.0.0
remark-toc: ^8.0.1
dependencies:
'@mdx-js/rollup': 2.1.2
es-module-lexer: 0.10.5
remark-frontmatter: 4.0.1
remark-gfm: 3.0.1
remark-mdx-frontmatter: 2.0.2
remark-smartypants: 2.0.0
devDependencies:
'@types/chai': 4.3.1
@ -4260,6 +4264,10 @@ packages:
'@babel/helper-validator-identifier': 7.18.6
to-fast-properties: 2.0.0
/@bcoe/v8-coverage/0.2.3:
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
dev: false
/@builder.io/partytown/0.4.5:
resolution: {integrity: sha512-HcHlmMYSpOxfJ0lFVxgZrvgIjz1Q8knlGuWkBpvjIp68j+xVWg969+sn7BCfyKhcGaYlnVOY/CEBHapQBcl0jw==}
hasBin: true
@ -4759,6 +4767,11 @@ packages:
'@babel/runtime': 7.18.6
dev: false
/@istanbuljs/schema/0.1.3:
resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
engines: {node: '>=8'}
dev: false
/@jridgewell/gen-mapping/0.1.1:
resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==}
engines: {node: '>=6.0.0'}
@ -8108,6 +8121,10 @@ packages:
ci-info: 3.3.2
dev: true
/@types/istanbul-lib-coverage/2.0.4:
resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
dev: false
/@types/json-schema/7.0.11:
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
dev: true
@ -9174,6 +9191,25 @@ packages:
engines: {node: '>= 0.8'}
dev: true
/c8/7.12.0:
resolution: {integrity: sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==}
engines: {node: '>=10.12.0'}
hasBin: true
dependencies:
'@bcoe/v8-coverage': 0.2.3
'@istanbuljs/schema': 0.1.3
find-up: 5.0.0
foreground-child: 2.0.0
istanbul-lib-coverage: 3.2.0
istanbul-lib-report: 3.0.0
istanbul-reports: 3.1.5
rimraf: 3.0.2
test-exclude: 6.0.0
v8-to-istanbul: 9.0.1
yargs: 16.2.0
yargs-parser: 20.2.9
dev: false
/cac/6.7.12:
resolution: {integrity: sha512-rM7E2ygtMkJqD9c7WnFU6fruFcN3xe4FM5yUmgxhZzIKJk4uHl9U/fhwdajGFQbQuv43FAUo1Fe8gX/oIKDeSA==}
engines: {node: '>=8'}
@ -9374,7 +9410,6 @@ packages:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 7.0.0
dev: true
/clone/1.0.4:
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
@ -10390,6 +10425,13 @@ packages:
resolution: {integrity: sha512-rxZj1GkQhY4x1j/CSnybK9cGuMFQYFPLq0iNyopqf14aOVLFtMv7Esika+ObJWPWiOHuMOAHz3YkWoLYYRnzWQ==}
dev: false
/estree-util-value-to-estree/1.3.0:
resolution: {integrity: sha512-Y+ughcF9jSUJvncXwqRageavjrNPAI+1M/L3BI3PyLp1nmgYTGUXU6t5z1Y7OWuThoDdhPME07bQU+d5LxdJqw==}
engines: {node: '>=12.0.0'}
dependencies:
is-plain-obj: 3.0.0
dev: false
/estree-util-visit/1.1.0:
resolution: {integrity: sha512-3lXJ4Us9j8TUif9cWcQy81t9p5OLasnDuuhrFiqb+XstmKC1d1LmrQWYsY49/9URcfHE64mPypDBaNK9NwWDPQ==}
dependencies:
@ -10526,6 +10568,12 @@ packages:
dependencies:
reusify: 1.0.4
/fault/2.0.1:
resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
dependencies:
format: 0.2.2
dev: false
/fetch-blob/3.2.0:
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
engines: {node: ^12.20 || >= 14.13}
@ -10624,6 +10672,19 @@ packages:
is-callable: 1.2.4
dev: false
/foreground-child/2.0.0:
resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==}
engines: {node: '>=8.0.0'}
dependencies:
cross-spawn: 7.0.3
signal-exit: 3.0.7
dev: false
/format/0.2.2:
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
engines: {node: '>=0.4.x'}
dev: false
/formdata-polyfill/4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
@ -10749,7 +10810,6 @@ packages:
/get-caller-file/2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
dev: true
/get-func-name/2.0.0:
resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==}
@ -11134,6 +11194,10 @@ packages:
resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==}
dev: false
/html-escaper/2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
dev: false
/html-escaper/3.0.3:
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
@ -11483,6 +11547,11 @@ packages:
engines: {node: '>=8'}
dev: true
/is-plain-obj/3.0.0:
resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==}
engines: {node: '>=10'}
dev: false
/is-plain-obj/4.1.0:
resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
engines: {node: '>=12'}
@ -11596,6 +11665,28 @@ packages:
/isexe/2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
/istanbul-lib-coverage/3.2.0:
resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
engines: {node: '>=8'}
dev: false
/istanbul-lib-report/3.0.0:
resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==}
engines: {node: '>=8'}
dependencies:
istanbul-lib-coverage: 3.2.0
make-dir: 3.1.0
supports-color: 7.2.0
dev: false
/istanbul-reports/3.1.5:
resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==}
engines: {node: '>=8'}
dependencies:
html-escaper: 2.0.2
istanbul-lib-report: 3.0.0
dev: false
/jake/10.8.5:
resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==}
engines: {node: '>=10'}
@ -11969,6 +12060,12 @@ packages:
- supports-color
dev: false
/mdast-util-frontmatter/1.0.0:
resolution: {integrity: sha512-7itKvp0arEVNpCktOET/eLFAYaZ+0cNjVtFtIPxgQ5tV+3i+D4SDDTjTzPWl44LT59PC+xdx+glNTawBdF98Mw==}
dependencies:
micromark-extension-frontmatter: 1.0.0
dev: false
/mdast-util-gfm-autolink-literal/1.0.2:
resolution: {integrity: sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==}
dependencies:
@ -12179,6 +12276,14 @@ packages:
uvu: 0.5.6
dev: false
/micromark-extension-frontmatter/1.0.0:
resolution: {integrity: sha512-EXjmRnupoX6yYuUJSQhrQ9ggK0iQtQlpi6xeJzVD5xscyAI+giqco5fdymayZhJMbIFecjnE2yz85S9NzIgQpg==}
dependencies:
fault: 2.0.1
micromark-util-character: 1.1.0
micromark-util-symbol: 1.0.1
dev: false
/micromark-extension-gfm-autolink-literal/1.0.3:
resolution: {integrity: sha512-i3dmvU0htawfWED8aHMMAzAVp/F0Z+0bPh3YrbTPPL1v4YAlCZpy5rBO5p0LPYiZo0zFVkoYh7vDU7yQSiCMjg==}
dependencies:
@ -14080,6 +14185,15 @@ packages:
unist-util-visit: 1.4.1
dev: true
/remark-frontmatter/4.0.1:
resolution: {integrity: sha512-38fJrB0KnmD3E33a5jZC/5+gGAC2WKNiPw1/fdXJvijBlhA7RCsvJklrYJakS0HedninvaCYW8lQGf9C918GfA==}
dependencies:
'@types/mdast': 3.0.10
mdast-util-frontmatter: 1.0.0
micromark-extension-frontmatter: 1.0.0
unified: 10.1.2
dev: false
/remark-gfm/3.0.1:
resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==}
dependencies:
@ -14091,6 +14205,19 @@ packages:
- supports-color
dev: false
/remark-mdx-frontmatter/2.0.2:
resolution: {integrity: sha512-kxXltmWCo10x8JGtlaw16pJUF593R+b9UJILk/yp5mdU6PKfg9BLAZvoF5YVdP+sjzEDD0nGYVKcZDyJSbCHbw==}
engines: {node: '>=14.0.0'}
dependencies:
'@types/mdast': 3.0.10
c8: 7.12.0
estree-util-is-identifier-name: 2.0.1
estree-util-value-to-estree: 1.3.0
toml: 3.0.0
unified: 10.1.2
yaml: 2.1.1
dev: false
/remark-mdx/2.1.2:
resolution: {integrity: sha512-npQagPdczPAv0xN9F8GSi5hJfAe/z6nBjylyfOfjLOmz086ahWrIjlk4BulRfNhA+asutqWxyuT3DFVsxiTVHA==}
dependencies:
@ -14139,7 +14266,6 @@ packages:
/require-directory/2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
dev: true
/require-from-string/2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
@ -14981,6 +15107,15 @@ packages:
source-map-support: 0.5.21
dev: true
/test-exclude/6.0.0:
resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
engines: {node: '>=8'}
dependencies:
'@istanbuljs/schema': 0.1.3
glob: 7.2.3
minimatch: 3.1.2
dev: false
/text-table/0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true
@ -15019,6 +15154,10 @@ packages:
engines: {node: '>=0.6'}
dev: true
/toml/3.0.0:
resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==}
dev: false
/totalist/1.1.0:
resolution: {integrity: sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==}
engines: {node: '>=6'}
@ -15554,6 +15693,15 @@ packages:
resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
dev: true
/v8-to-istanbul/9.0.1:
resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==}
engines: {node: '>=10.12.0'}
dependencies:
'@jridgewell/trace-mapping': 0.3.14
'@types/istanbul-lib-coverage': 2.0.4
convert-source-map: 1.8.0
dev: false
/validate-npm-package-license/3.0.4:
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
dependencies:
@ -16017,7 +16165,6 @@ packages:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
dev: true
/wrap-ansi/8.0.1:
resolution: {integrity: sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==}
@ -16046,7 +16193,6 @@ packages:
/y18n/5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
dev: true
/yallist/2.1.2:
resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
@ -16078,7 +16224,11 @@ packages:
/yargs-parser/20.2.4:
resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==}
engines: {node: '>=10'}
dev: true
/yargs-parser/20.2.9:
resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
engines: {node: '>=10'}
dev: false
/yargs-parser/21.0.1:
resolution: {integrity: sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==}
@ -16122,7 +16272,6 @@ packages:
string-width: 4.2.3
y18n: 5.0.8
yargs-parser: 20.2.4
dev: true
/yargs/17.5.1:
resolution: {integrity: sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==}