diff options
author | HiDeoo | 2024-09-07 00:19:29 +0200 |
---|---|---|
committer | GitHub | 2024-09-07 00:19:29 +0200 |
commit | 20cbf3b6a4d1598a62fdb176ebaa849bc7b978f7 (patch) | |
tree | 9b2fa0ab6b62df74078f295dd43d684f390f6db4 | |
parent | 756e85e8e814657c42c4a6f9c299b5bef32aee22 (diff) | |
download | IT.starlight-20cbf3b6a4d1598a62fdb176ebaa849bc7b978f7.tar.gz IT.starlight-20cbf3b6a4d1598a62fdb176ebaa849bc7b978f7.tar.bz2 IT.starlight-20cbf3b6a4d1598a62fdb176ebaa849bc7b978f7.zip |
Add Markdoc preset and example (#2249)
Co-authored-by: Chris Swithinbank <357379+delucis@users.noreply.github.com>
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
39 files changed, 970 insertions, 38 deletions
diff --git a/.changeset/selfish-chefs-tie.md b/.changeset/selfish-chefs-tie.md new file mode 100644 index 00000000..f8869194 --- /dev/null +++ b/.changeset/selfish-chefs-tie.md @@ -0,0 +1,7 @@ +--- +'@astrojs/starlight-markdoc': minor +--- + +Adds Starlight Markdoc preset. + +See the [“Markdoc”](https://starlight.astro.build/guides/authoring-content/#markdoc) guide to learn more on how to use this preset in a new or existing project. diff --git a/.github/labeler.yml b/.github/labeler.yml index 6049ae3c..4913a2e0 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -26,5 +26,8 @@ i18n: '🌟 tailwind': - packages/tailwind/** +'🌟 markdoc': + - packages/markdoc/** + '📚 docs': - docs/** diff --git a/docs/src/content/docs/guides/authoring-content.md b/docs/src/content/docs/guides/authoring-content.mdx index 2fe84815..58c6f081 100644 --- a/docs/src/content/docs/guides/authoring-content.md +++ b/docs/src/content/docs/guides/authoring-content.mdx @@ -203,8 +203,8 @@ A code block is indicated by a block with three backticks <code>```</code> at th ```js // Javascript code with syntax highlighting. var fun = function lang(l) { - dateformat.i18n = require('./lang/' + l); - return true; + dateformat.i18n = require('./lang/' + l); + return true; }; ``` @@ -212,8 +212,8 @@ var fun = function lang(l) { ```js // Javascript code with syntax highlighting. var fun = function lang(l) { - dateformat.i18n = require('./lang/' + l); - return true; + dateformat.i18n = require('./lang/' + l); + return true; }; ``` ```` @@ -241,16 +241,16 @@ Some of the most common examples are shown below: ```js {2-3} function demo() { - // This line (#2) and the next one are highlighted - return 'This is line #3 of this snippet'; + // This line (#2) and the next one are highlighted + return 'This is line #3 of this snippet'; } ``` ````md ```js {2-3} function demo() { - // This line (#2) and the next one are highlighted - return 'This is line #3 of this snippet'; + // This line (#2) and the next one are highlighted + return 'This is line #3 of this snippet'; } ``` ```` @@ -260,7 +260,7 @@ Some of the most common examples are shown below: ```js "Individual terms" /Even.*supported/ // Individual terms can be highlighted, too function demo() { - return 'Even regular expressions are supported'; + return 'Even regular expressions are supported'; } ``` @@ -268,7 +268,7 @@ Some of the most common examples are shown below: ```js "Individual terms" /Even.*supported/ // Individual terms can be highlighted, too function demo() { - return 'Even regular expressions are supported'; + return 'Even regular expressions are supported'; } ``` ```` @@ -277,18 +277,18 @@ Some of the most common examples are shown below: ```js "return true;" ins="inserted" del="deleted" function demo() { - console.log('These are inserted and deleted marker types'); - // The return statement uses the default marker type - return true; + console.log('These are inserted and deleted marker types'); + // The return statement uses the default marker type + return true; } ``` ````md ```js "return true;" ins="inserted" del="deleted" function demo() { - console.log('These are inserted and deleted marker types'); - // The return statement uses the default marker type - return true; + console.log('These are inserted and deleted marker types'); + // The return statement uses the default marker type + return true; } ``` ```` @@ -393,3 +393,118 @@ Starlight supports all other Markdown authoring syntax, such as lists and tables ## Advanced Markdown and MDX configuration Starlight uses Astro’s Markdown and MDX renderer built on remark and rehype. You can add support for custom syntax and behavior by adding `remarkPlugins` or `rehypePlugins` in your Astro config file. See [“Configuring Markdown and MDX”](https://docs.astro.build/en/guides/markdown-content/#configuring-markdown-and-mdx) in the Astro docs to learn more. + +## Markdoc + +Starlight supports authoring content in Markdoc using the experimental [Astro Markdoc integration](https://docs.astro.build/en/guides/integrations-guide/markdoc/) and the Starlight Markdoc preset. + +### Create a new project with Markdoc + +Start a new Starlight project with Markdoc pre-configured using `create astro`: + +import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; + +<Tabs syncKey="pkg"> +<TabItem label="npm"> + +```sh +npm create astro@latest -- --template starlight/markdoc +``` + +</TabItem> +<TabItem label="pnpm"> + +```sh +pnpm create astro --template starlight/markdoc +``` + +</TabItem> +<TabItem label="Yarn"> + +```sh +yarn create astro --template starlight/markdoc +``` + +</TabItem> +</Tabs> + +### Add Markdoc to an existing project + +If you already have a Starlight site and want to add Markdoc, follow these steps. + +<Steps> + +1. Add Astro’s Markdoc integration: + + <Tabs syncKey="pkg"> + + <TabItem label="npm"> + + ```sh + npx astro add markdoc + ``` + + </TabItem> + + <TabItem label="pnpm"> + + ```sh + pnpm astro add markdoc + ``` + + </TabItem> + + <TabItem label="Yarn"> + + ```sh + yarn astro add markdoc + ``` + + </TabItem> + + </Tabs> + +2. Install the Starlight Markdoc preset: + + <Tabs syncKey="pkg"> + + <TabItem label="npm"> + + ```sh + npm install @astrojs/starlight-markdoc + ``` + + </TabItem> + + <TabItem label="pnpm"> + + ```sh + pnpm add @astrojs/starlight-markdoc + ``` + + </TabItem> + + <TabItem label="Yarn"> + + ```sh + yarn add @astrojs/starlight-markdoc + ``` + + </TabItem> + + </Tabs> + +3. Create a Markdoc configuration file at `markdoc.config.mjs` and use the Starlight Markdoc preset: + + ```js + import { defineMarkdocConfig } from '@astrojs/markdoc/config'; + import starlightMarkdoc from '@astrojs/starlight-markdoc'; + + export default defineMarkdocConfig({ + extends: [starlightMarkdoc()], + }); + ``` + +</Steps> + +To learn more about the Markdoc syntax and features, see the [Markdoc documentation](https://markdoc.dev/docs/syntax) or the [Astro Markdoc integration guide](https://docs.astro.build/en/guides/integrations-guide/markdoc/). diff --git a/docs/src/content/docs/guides/pages.mdx b/docs/src/content/docs/guides/pages.mdx index f112a572..663bea68 100644 --- a/docs/src/content/docs/guides/pages.mdx +++ b/docs/src/content/docs/guides/pages.mdx @@ -14,7 +14,7 @@ This guide shows how page generation works in Starlight. ### File formats Starlight supports authoring content in Markdown and MDX with no configuration required. -You can add support for Markdoc by installing the experimental [Astro Markdoc integration](https://docs.astro.build/en/guides/integrations-guide/markdoc/). +You can add support for Markdoc by following the [“Markdoc” guide](/guides/authoring-content/#markdoc). ### Add pages diff --git a/examples/markdoc/.gitignore b/examples/markdoc/.gitignore new file mode 100644 index 00000000..6240da8b --- /dev/null +++ b/examples/markdoc/.gitignore @@ -0,0 +1,21 @@ +# build output +dist/ +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store diff --git a/examples/markdoc/.vscode/extensions.json b/examples/markdoc/.vscode/extensions.json new file mode 100644 index 00000000..a83595b1 --- /dev/null +++ b/examples/markdoc/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + "recommendations": ["astro-build.astro-vscode", "stripe.markdoc-language-support"], + "unwantedRecommendations": [] +} diff --git a/examples/markdoc/.vscode/launch.json b/examples/markdoc/.vscode/launch.json new file mode 100644 index 00000000..d6422097 --- /dev/null +++ b/examples/markdoc/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "command": "./node_modules/.bin/astro dev", + "name": "Development server", + "request": "launch", + "type": "node-terminal" + } + ] +} diff --git a/examples/markdoc/README.md b/examples/markdoc/README.md new file mode 100644 index 00000000..584fd88e --- /dev/null +++ b/examples/markdoc/README.md @@ -0,0 +1,56 @@ +# Starlight Starter Kit: Markdoc + +[](https://starlight.astro.build) + +``` +npm create astro@latest -- --template starlight/markdoc +``` + +[](https://stackblitz.com/github/withastro/starlight/tree/main/examples/markdoc) +[](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/markdoc) +[](https://app.netlify.com/start/deploy?repository=https://github.com/withastro/starlight&create_from_path=examples/markdoc) +[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fmarkdoc&project-name=my-starlight-docs&repository-name=my-starlight-docs) + +> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun! + +## 🚀 Project Structure + +Inside of your Astro + Starlight project, you'll see the following folders and files: + +``` +. +├── public/ +├── src/ +│ ├── assets/ +│ ├── content/ +│ │ ├── docs/ +│ │ └── config.ts +│ └── env.d.ts +├── astro.config.mjs +├── markdoc.config.mjs +├── package.json +└── tsconfig.json +``` + +Starlight looks for `.md`, `.mdx` or `.mdoc` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. + +Images can be added to `src/assets/` and embedded in Markdown with a relative link. + +Static assets, like favicons, can be placed in the `public/` directory. + +## 🧞 Commands + +All commands are run from the root of the project, from a terminal: + +| Command | Action | +| :------------------------ | :----------------------------------------------- | +| `npm install` | Installs dependencies | +| `npm run dev` | Starts local dev server at `localhost:4321` | +| `npm run build` | Build your production site to `./dist/` | +| `npm run preview` | Preview your build locally, before deploying | +| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | +| `npm run astro -- --help` | Get help using the Astro CLI | + +## 👀 Want to learn more? + +Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). diff --git a/examples/markdoc/astro.config.mjs b/examples/markdoc/astro.config.mjs new file mode 100644 index 00000000..03155ce5 --- /dev/null +++ b/examples/markdoc/astro.config.mjs @@ -0,0 +1,29 @@ +import { defineConfig } from 'astro/config'; +import starlight from '@astrojs/starlight'; +import markdoc from '@astrojs/markdoc'; + +// https://astro.build/config +export default defineConfig({ + integrations: [ + markdoc(), + starlight({ + title: 'My Docs', + social: { + github: 'https://github.com/withastro/starlight', + }, + sidebar: [ + { + label: 'Guides', + items: [ + // Each item here is one entry in the navigation menu. + { label: 'Example Guide', slug: 'guides/example' }, + ], + }, + { + label: 'Reference', + autogenerate: { directory: 'reference' }, + }, + ], + }), + ], +}); diff --git a/examples/markdoc/markdoc.config.mjs b/examples/markdoc/markdoc.config.mjs new file mode 100644 index 00000000..ecda158d --- /dev/null +++ b/examples/markdoc/markdoc.config.mjs @@ -0,0 +1,7 @@ +import { defineMarkdocConfig } from '@astrojs/markdoc/config'; +import starlightMarkdoc from '@astrojs/starlight-markdoc'; + +// https://docs.astro.build/en/guides/integrations-guide/markdoc/ +export default defineMarkdocConfig({ + extends: [starlightMarkdoc()], +}); diff --git a/examples/markdoc/package.json b/examples/markdoc/package.json new file mode 100644 index 00000000..d87a8ac6 --- /dev/null +++ b/examples/markdoc/package.json @@ -0,0 +1,20 @@ +{ + "name": "@example/starlight-markdoc", + "type": "module", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "astro dev", + "start": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro" + }, + "dependencies": { + "@astrojs/markdoc": "^0.11.4", + "@astrojs/starlight": "^0.26.1", + "@astrojs/starlight-markdoc": "^0.0.1", + "astro": "^4.15.3", + "sharp": "^0.32.5" + } +} diff --git a/examples/markdoc/public/favicon.svg b/examples/markdoc/public/favicon.svg new file mode 100644 index 00000000..cba5ac14 --- /dev/null +++ b/examples/markdoc/public/favicon.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill-rule="evenodd" d="M81 36 64 0 47 36l-1 2-9-10a6 6 0 0 0-9 9l10 10h-2L0 64l36 17h2L28 91a6 6 0 1 0 9 9l9-10 1 2 17 36 17-36v-2l9 10a6 6 0 1 0 9-9l-9-9 2-1 36-17-36-17-2-1 9-9a6 6 0 1 0-9-9l-9 10v-2Zm-17 2-2 5c-4 8-11 15-19 19l-5 2 5 2c8 4 15 11 19 19l2 5 2-5c4-8 11-15 19-19l5-2-5-2c-8-4-15-11-19-19l-2-5Z" clip-rule="evenodd"/><path d="M118 19a6 6 0 0 0-9-9l-3 3a6 6 0 1 0 9 9l3-3Zm-96 4c-2 2-6 2-9 0l-3-3a6 6 0 1 1 9-9l3 3c3 2 3 6 0 9Zm0 82c-2-2-6-2-9 0l-3 3a6 6 0 1 0 9 9l3-3c3-2 3-6 0-9Zm96 4a6 6 0 0 1-9 9l-3-3a6 6 0 1 1 9-9l3 3Z"/><style>path{fill:#000}@media (prefers-color-scheme:dark){path{fill:#fff}}</style></svg>
\ No newline at end of file diff --git a/examples/markdoc/src/assets/houston.webp b/examples/markdoc/src/assets/houston.webp Binary files differnew file mode 100644 index 00000000..930c1649 --- /dev/null +++ b/examples/markdoc/src/assets/houston.webp diff --git a/examples/markdoc/src/content/config.ts b/examples/markdoc/src/content/config.ts new file mode 100644 index 00000000..45f60b01 --- /dev/null +++ b/examples/markdoc/src/content/config.ts @@ -0,0 +1,6 @@ +import { defineCollection } from 'astro:content'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ schema: docsSchema() }), +}; diff --git a/examples/markdoc/src/content/docs/guides/example.mdoc b/examples/markdoc/src/content/docs/guides/example.mdoc new file mode 100644 index 00000000..ebd0f3bc --- /dev/null +++ b/examples/markdoc/src/content/docs/guides/example.mdoc @@ -0,0 +1,11 @@ +--- +title: Example Guide +description: A guide in my new Starlight docs site. +--- + +Guides lead a user through a specific task they want to accomplish, often with a sequence of steps. +Writing a good guide requires thinking about what your users are trying to do. + +## Further reading + +- Read [about how-to guides](https://diataxis.fr/how-to-guides/) in the Diátaxis framework diff --git a/examples/markdoc/src/content/docs/index.mdoc b/examples/markdoc/src/content/docs/index.mdoc new file mode 100644 index 00000000..814dc120 --- /dev/null +++ b/examples/markdoc/src/content/docs/index.mdoc @@ -0,0 +1,35 @@ +--- +title: Welcome to Starlight +description: Get started building your docs site with Starlight. +template: splash +hero: + title: Welcome to Starlight with Markdoc + tagline: Congrats on setting up a new Starlight project! + image: + file: ../../assets/houston.webp + actions: + - text: Example Guide + link: /guides/example/ + icon: right-arrow + - text: Read the Starlight docs + link: https://starlight.astro.build + icon: external + variant: minimal +--- + +## Next steps + +{% cardgrid stagger=true %} +{% card title="Update content" icon="pencil" %} +Edit `src/content/docs/index.mdoc` to see this page change. +{% /card %} +{% card title="Add new content" icon="add-document" %} +Add Markdoc files to `src/content/docs` to create new pages. +{% /card %} +{% card title="Configure your site" icon="setting" %} +Edit your `sidebar` and other config in `astro.config.mjs`. +{% /card %} +{% card title="Read the docs" icon="open-book" %} +Learn more in [the Starlight Docs](https://starlight.astro.build/). +{% /card %} +{% /cardgrid %} diff --git a/examples/markdoc/src/content/docs/reference/example.mdoc b/examples/markdoc/src/content/docs/reference/example.mdoc new file mode 100644 index 00000000..0224f096 --- /dev/null +++ b/examples/markdoc/src/content/docs/reference/example.mdoc @@ -0,0 +1,11 @@ +--- +title: Example Reference +description: A reference page in my new Starlight docs site. +--- + +Reference pages are ideal for outlining how things work in terse and clear terms. +Less concerned with telling a story or addressing a specific use case, they should give a comprehensive outline of what you're documenting. + +## Further reading + +- Read [about reference](https://diataxis.fr/reference/) in the Diátaxis framework diff --git a/examples/markdoc/src/env.d.ts b/examples/markdoc/src/env.d.ts new file mode 100644 index 00000000..e16c13c6 --- /dev/null +++ b/examples/markdoc/src/env.d.ts @@ -0,0 +1 @@ +/// <reference path="../.astro/types.d.ts" /> diff --git a/examples/markdoc/tsconfig.json b/examples/markdoc/tsconfig.json new file mode 100644 index 00000000..bcbf8b50 --- /dev/null +++ b/examples/markdoc/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "astro/tsconfigs/strict" +} diff --git a/packages/markdoc/.npmignore b/packages/markdoc/.npmignore new file mode 100644 index 00000000..c8740c5e --- /dev/null +++ b/packages/markdoc/.npmignore @@ -0,0 +1 @@ +__tests__/ diff --git a/packages/markdoc/Code.astro b/packages/markdoc/Code.astro new file mode 100644 index 00000000..8c8a0609 --- /dev/null +++ b/packages/markdoc/Code.astro @@ -0,0 +1,16 @@ +--- +import { Code as Default } from '@astrojs/starlight/components'; + +interface Props { + code: string; + lang?: string; +} + +/** + * This component is a basic wrapper for the `<Code>` component from Starlight used for Markdoc + * fenced code blocks that ensures that we do not pass any child content to the `<Code>` component + * which is an usage not supported by Expressive Code and would throw an error. + */ +--- + +<Default {...Astro.props} /> diff --git a/packages/markdoc/README.md b/packages/markdoc/README.md new file mode 100644 index 00000000..8141a004 --- /dev/null +++ b/packages/markdoc/README.md @@ -0,0 +1,18 @@ +# <img src="https://github.com/withastro/starlight/assets/357379/494fcd83-42aa-4891-87e0-87402fa0b6f3" alt="" align="left" width="40" height="40"> @astrojs/starlight-markdoc + +Markdoc preset for the [Starlight][starlight] documentation theme for [Astro][astro]. + +## Documentation + +See the [Starlight Markdoc docs][docs] for how to use this preset. + +## License + +MIT + +Copyright (c) 2024–present [Starlight contributors][contributors] + +[starlight]: https://starlight.astro.build/ +[astro]: https://astro.build/ +[docs]: https://starlight.astro.build/guides/authoring-content/#markdoc +[contributors]: https://github.com/withastro/starlight/graphs/contributors diff --git a/packages/markdoc/__tests__/markdoc.test-d.ts b/packages/markdoc/__tests__/markdoc.test-d.ts new file mode 100644 index 00000000..868f2c97 --- /dev/null +++ b/packages/markdoc/__tests__/markdoc.test-d.ts @@ -0,0 +1,127 @@ +import type { ComponentProps, HTMLAttributes } from 'astro/types'; +import { expectTypeOf, test } from 'vitest'; + +import { + Aside, + Badge, + Card, + CardGrid, + Code, + FileTree, + Icon, + LinkButton, + LinkCard, + Steps, + TabItem, + Tabs, +} from '@astrojs/starlight/components'; + +type UserComponents = keyof typeof import('@astrojs/starlight/components'); +type UserComponentProps<T extends (args: any) => any> = keyof RemoveIndexSignature< + ComponentProps<T> +>; + +type MarkdocPreset = typeof import('../index.mjs').StarlightMarkdocPreset; +type MarkdocTags = keyof MarkdocPreset['tags']; +type MarkdocTagAttributes<T extends MarkdocTags> = keyof MarkdocPreset['tags'][T]['attributes']; + +test('defines a tag for each user components', () => { + expectTypeOf<MarkdocTags>().toEqualTypeOf<Lowercase<UserComponents>>(); +}); + +test('defines all `<Aside>` component attributes', () => { + expectTypeOf<MarkdocTagAttributes<'aside'>>().toEqualTypeOf<UserComponentProps<typeof Aside>>(); +}); + +test('defines all `<Badge>` component attributes', () => { + /** + * Only supports a list of well-known `<span>` attributes. + * @see {@link file://./../html.mjs} + */ + type UnsupportedBadgeProps = Exclude<keyof HTMLAttributes<'span'>, WellKnownElementAttributes>; + + expectTypeOf<MarkdocTagAttributes<'badge'>>().toEqualTypeOf< + Exclude<UserComponentProps<typeof Badge>, UnsupportedBadgeProps> + >(); +}); + +test('defines all `<Card>` component attributes', () => { + expectTypeOf<MarkdocTagAttributes<'card'>>().toEqualTypeOf<UserComponentProps<typeof Card>>(); +}); + +test('defines all `<CardGrid>` component attributes', () => { + expectTypeOf<MarkdocTagAttributes<'cardgrid'>>().toEqualTypeOf< + UserComponentProps<typeof CardGrid> + >(); +}); + +test('defines all `<Code>` component attributes', () => { + /** @see {@link file://./../index.mjs} */ + type UnsupportedCodeProps = 'mark' | 'ins' | 'del'; + + expectTypeOf<MarkdocTagAttributes<'code'>>().toEqualTypeOf< + Exclude<UserComponentProps<typeof Code>, UnsupportedCodeProps> + >(); +}); + +test('defines all `<FileTree>` component attributes', () => { + expectTypeOf<MarkdocTagAttributes<'filetree'>>().toEqualTypeOf< + UserComponentProps<typeof FileTree> + >(); +}); + +test('defines all `<Icon>` component attributes', () => { + expectTypeOf<MarkdocTagAttributes<'icon'>>().toEqualTypeOf<UserComponentProps<typeof Icon>>(); +}); + +test('defines all `<LinkButton>` component attributes', () => { + /** + * Only supports a list of well-known `<a>` attributes. + * @see {@link file://./../html.mjs} + */ + type UnsupportedLinkButtonProps = Exclude<keyof HTMLAttributes<'a'>, WellKnownAnchorAttributes>; + + expectTypeOf<MarkdocTagAttributes<'linkbutton'>>().toEqualTypeOf< + Exclude<UserComponentProps<typeof LinkButton>, UnsupportedLinkButtonProps> + >(); +}); + +test('defines all `<LinkCard>` component attributes', () => { + /** + * Only supports a list of well-known `<a>` attributes. + * @see {@link file://./../html.mjs} + */ + type UnsupportedLinkCardProps = Exclude<keyof HTMLAttributes<'a'>, WellKnownAnchorAttributes>; + + expectTypeOf<MarkdocTagAttributes<'linkcard'>>().toEqualTypeOf< + Exclude<UserComponentProps<typeof LinkCard>, UnsupportedLinkCardProps> + >(); +}); + +test('defines all `<Steps>` component attributes', () => { + expectTypeOf<MarkdocTagAttributes<'steps'>>().toEqualTypeOf<UserComponentProps<typeof Steps>>(); +}); + +test('defines all `<TabItem>` component attributes', () => { + expectTypeOf<MarkdocTagAttributes<'tabitem'>>().toEqualTypeOf< + UserComponentProps<typeof TabItem> + >(); +}); + +test('defines all `<Tabs>` component attributes', () => { + expectTypeOf<MarkdocTagAttributes<'tabs'>>().toEqualTypeOf<UserComponentProps<typeof Tabs>>(); +}); + +type WellKnownElementAttributes = keyof typeof import('../html.mjs').WellKnownElementAttributes; +type WellKnownAnchorAttributes = keyof typeof import('../html.mjs').WellKnownAnchorAttributes; + +// https://stackoverflow.com/a/66252656/1945960 +type RemoveIndexSignature<T> = { + [K in keyof T as string extends K + ? never + : number extends K + ? never + : symbol extends K + ? never + : K]: T[K]; +}; diff --git a/packages/markdoc/components.ts b/packages/markdoc/components.ts new file mode 100644 index 00000000..62b21695 --- /dev/null +++ b/packages/markdoc/components.ts @@ -0,0 +1 @@ +export { default as Code } from './Code.astro'; diff --git a/packages/markdoc/html.mjs b/packages/markdoc/html.mjs new file mode 100644 index 00000000..259471a7 --- /dev/null +++ b/packages/markdoc/html.mjs @@ -0,0 +1,44 @@ +/** + * A list of well-known HTML element global attributes that can be used on any HTML element. + * + * @satisfies {HTMLElementTagAttributes<'span'>} + * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes + */ +export const WellKnownElementAttributes = { + class: { type: String }, + dir: { type: String, matches: ['ltr', 'rtl', 'auto'] }, + hidden: { type: String, matches: ['', 'hidden', 'until-found'] }, + id: { type: String }, + lang: { type: String }, + role: { type: String }, + style: { type: String }, + title: { type: String }, +}; + +/** + * A list of well-known HTML attributes that can be used on an `<a>` element. + * + * @satisfies {HTMLElementTagAttributes<'a'>} + * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes + */ +export const WellKnownAnchorAttributes = { + ...WellKnownElementAttributes, + download: { type: String }, + href: { type: String }, + hreflang: { type: String }, + media: { type: String }, + ping: { type: String }, + rel: { type: String }, + target: { type: String, matches: ['_self', '_blank', '_parent', '_top'] }, +}; + +/** + * The configuration of a tag attribute. + * @typedef {NonNullable<NonNullable<import('@astrojs/markdoc/config').AstroMarkdocConfig['tags']>[string]['attributes']>[string]} TagAttributeConfig + */ + +/** + * A map of HTML attributes for a specific HTML element with their associated attribute configuration. + * @typedef {Partial<Record<keyof import('astro/types').HTMLAttributes<T>, TagAttributeConfig>>} HTMLElementTagAttributes + * @template {import('astro/types').HTMLTag} T + */ diff --git a/packages/markdoc/index.mjs b/packages/markdoc/index.mjs new file mode 100644 index 00000000..8c959b5e --- /dev/null +++ b/packages/markdoc/index.mjs @@ -0,0 +1,264 @@ +import { component } from '@astrojs/markdoc/config'; +import { WellKnownElementAttributes, WellKnownAnchorAttributes } from './html.mjs'; + +/** + * The Markdoc preset for Starlight mapping Starlight components to Markdoc nodes and tags. + * + * - The icons are not using a `matches` to provide a list of supported icons as it is not possible + * to import a TypeScript file in this file (which can also not be a TypeScript file). When + * Starlight is bundled, this could be refactored to provide a list of supported icons. + * - Some components (`<Badge>`, `<LinkButton>`, and `<LinkCard>`) support extra attributes, e.g. + * all the attributes supported by the `<a>` tag. As Markdoc requires type definitions for each + * attribute, only some well-known attributes are supported in these tags. + * + * @satisfies {import('@astrojs/markdoc/config').AstroMarkdocConfig} + */ +export const StarlightMarkdocPreset = { + nodes: { + fence: { + render: component('@astrojs/starlight-markdoc/components', 'Code'), + attributes: { + content: { + type: String, + required: true, + render: 'code', + }, + language: { + type: String, + required: false, + render: 'lang', + }, + /** + * Markdoc ignores meta attributes (markers) after a fence block (e.g. + * ```js title="example.js" del={2} ins={3-4} {6} ). + * This means that Expressive Code markers defined after the fence block are ignored and + * users would need to use the `code` tag instead. + * + * @see https://github.com/withastro/astro/blob/9f943c1344671b569a0d1ddba683b3cca0068adc/packages/integrations/markdoc/src/extensions/shiki.ts#L15-L17 + */ + }, + }, + }, + tags: { + aside: { + render: component('@astrojs/starlight/components', 'Aside'), + attributes: { + title: { + type: String, + required: false, + }, + type: { + type: String, + required: false, + default: 'note', + matches: ['note', 'danger', 'caution', 'tip'], + }, + }, + }, + badge: { + render: component('@astrojs/starlight/components', 'Badge'), + attributes: { + ...WellKnownElementAttributes, + text: { + type: String, + required: true, + }, + size: { + type: String, + required: false, + default: 'small', + matches: ['small', 'medium', 'large'], + }, + variant: { + type: String, + required: false, + matches: ['note', 'tip', 'danger', 'caution', 'success'], + }, + }, + }, + card: { + render: component('@astrojs/starlight/components', 'Card'), + attributes: { + icon: { + type: String, + required: false, + }, + title: { + type: String, + required: true, + }, + }, + }, + cardgrid: { + render: component('@astrojs/starlight/components', 'CardGrid'), + attributes: { + stagger: { + type: Boolean, + required: false, + default: false, + }, + }, + }, + code: { + render: component('@astrojs/starlight/components', 'Code'), + attributes: { + class: { + type: String, + required: false, + }, + code: { + type: String, + required: true, + }, + lang: { + type: String, + required: false, + }, + meta: { + type: String, + required: false, + }, + locale: { + type: String, + required: false, + }, + frame: { + type: String, + required: false, + default: 'auto', + matches: ['auto', 'code', 'terminal', 'none'], + }, + preserveIndent: { + type: Boolean, + required: false, + default: true, + }, + title: { + type: String, + required: false, + }, + useDiffSyntax: { + type: Boolean, + required: false, + default: false, + }, + wrap: { + type: Boolean, + required: false, + default: false, + }, + /** + * `mark`, `ins`, and `del` are not supported as the Markdoc attribute validation syntax + * does not allow to describe properly all the possible values. + * Users should use the `meta` attribute instead. + * + * @see https://expressive-code.com/key-features/code-component/#mark--ins--del + */ + }, + }, + filetree: { + render: component('@astrojs/starlight/components', 'FileTree'), + attributes: {}, + }, + icon: { + render: component('@astrojs/starlight/components', 'Icon'), + attributes: { + class: { + type: String, + required: false, + }, + color: { + type: String, + required: false, + }, + label: { + type: String, + required: false, + }, + name: { + type: String, + required: true, + }, + size: { + type: String, + required: false, + }, + }, + }, + linkbutton: { + render: component('@astrojs/starlight/components', 'LinkButton'), + attributes: { + ...WellKnownAnchorAttributes, + href: { + type: String, + required: true, + }, + icon: { + type: String, + required: false, + }, + iconPlacement: { + type: String, + required: false, + default: 'end', + matches: ['start', 'end'], + }, + variant: { + type: String, + required: false, + default: 'primary', + matches: ['primary', 'secondary', 'minimal'], + }, + }, + }, + linkcard: { + render: component('@astrojs/starlight/components', 'LinkCard'), + attributes: { + ...WellKnownAnchorAttributes, + description: { + type: String, + required: false, + }, + href: { + type: String, + required: true, + }, + title: { + type: String, + required: true, + }, + }, + }, + steps: { + render: component('@astrojs/starlight/components', 'Steps'), + attributes: {}, + }, + tabitem: { + render: component('@astrojs/starlight/components', 'TabItem'), + attributes: { + icon: { + type: String, + required: false, + }, + label: { + type: String, + required: true, + }, + }, + }, + tabs: { + render: component('@astrojs/starlight/components', 'Tabs'), + attributes: { + syncKey: { + type: String, + required: false, + }, + }, + }, + }, +}; + +/** @return {import('@astrojs/markdoc/config').AstroMarkdocConfig} */ +export default function starlightMarkdoc() { + return StarlightMarkdocPreset; +} diff --git a/packages/markdoc/package.json b/packages/markdoc/package.json new file mode 100644 index 00000000..355c776c --- /dev/null +++ b/packages/markdoc/package.json @@ -0,0 +1,26 @@ +{ + "name": "@astrojs/starlight-markdoc", + "version": "0.0.1", + "description": "Markdoc preset for the Starlight documentation theme for Astro", + "author": "Chris Swithinbank <swithinbank@gmail.com>", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/withastro/starlight", + "directory": "packages/markdoc" + }, + "bugs": "https://github.com/withastro/starlight/issues", + "homepage": "https://starlight.astro.build", + "type": "module", + "exports": { + ".": "./index.mjs", + "./components": "./components.ts" + }, + "devDependencies": { + "vitest": "^1.6.0" + }, + "peerDependencies": { + "@astrojs/markdoc": "^0.11.4", + "@astrojs/starlight": ">=0.23.0" + } +} diff --git a/packages/starlight/__tests__/basics/navigation-labels.test.ts b/packages/starlight/__tests__/basics/navigation-labels.test.ts index a85b48cb..5e070d83 100644 --- a/packages/starlight/__tests__/basics/navigation-labels.test.ts +++ b/packages/starlight/__tests__/basics/navigation-labels.test.ts @@ -9,7 +9,7 @@ vi.mock('astro:content', async () => 'environmental-impact.md', { title: 'Eco-friendly docs', sidebar: { label: 'Environmental impact' } }, ], - ['guides/authoring-content.md', { title: 'Authoring Markdown' }], + ['guides/authoring-content.mdx', { title: 'Authoring Markdown' }], ['guides/components.mdx', { title: 'Using components', sidebar: { label: 'Components' } }], ], }) diff --git a/packages/starlight/__tests__/basics/navigation-order.test.ts b/packages/starlight/__tests__/basics/navigation-order.test.ts index 6bcd2186..39850e03 100644 --- a/packages/starlight/__tests__/basics/navigation-order.test.ts +++ b/packages/starlight/__tests__/basics/navigation-order.test.ts @@ -6,7 +6,7 @@ vi.mock('astro:content', async () => docs: [ ['index.mdx', { title: 'Home Page' }], ['environmental-impact.md', { title: 'Eco-friendly docs', sidebar: { order: 1 } }], - ['guides/authoring-content.md', { title: 'Authoring Markdown' }], + ['guides/authoring-content.mdx', { title: 'Authoring Markdown' }], ['guides/components.mdx', { title: 'Components', sidebar: { order: 0 } }], ], }) diff --git a/packages/starlight/__tests__/basics/navigation.test.ts b/packages/starlight/__tests__/basics/navigation.test.ts index 4492c95c..fb4d5110 100644 --- a/packages/starlight/__tests__/basics/navigation.test.ts +++ b/packages/starlight/__tests__/basics/navigation.test.ts @@ -6,7 +6,7 @@ vi.mock('astro:content', async () => docs: [ ['index.mdx', { title: 'Home Page' }], ['environmental-impact.md', { title: 'Eco-friendly docs' }], - ['guides/authoring-content.md', { title: 'Authoring Markdown' }], + ['guides/authoring-content.mdx', { title: 'Authoring Markdown' }], ['reference/frontmatter.md', { title: 'Frontmatter Reference', sidebar: { hidden: true } }], ['guides/components.mdx', { title: 'Components' }], ], diff --git a/packages/starlight/__tests__/basics/pagination-with-base.test.ts b/packages/starlight/__tests__/basics/pagination-with-base.test.ts index 6619a57b..031964dd 100644 --- a/packages/starlight/__tests__/basics/pagination-with-base.test.ts +++ b/packages/starlight/__tests__/basics/pagination-with-base.test.ts @@ -9,7 +9,7 @@ vi.mock('astro:content', async () => docs: [ ['index.mdx', { title: 'Home Page' }], ['environmental-impact.md', { title: 'Eco-friendly docs' }], - ['guides/authoring-content.md', { title: 'Authoring Markdown' }], + ['guides/authoring-content.mdx', { title: 'Authoring Markdown' }], ['guides/components.mdx', { title: 'Components' }], ['reference/frontmatter.md', { title: 'Frontmatter Reference' }], ], diff --git a/packages/starlight/__tests__/basics/routing.test.ts b/packages/starlight/__tests__/basics/routing.test.ts index 9805362f..37c3f9b0 100644 --- a/packages/starlight/__tests__/basics/routing.test.ts +++ b/packages/starlight/__tests__/basics/routing.test.ts @@ -8,7 +8,7 @@ vi.mock('astro:content', async () => docs: [ ['404.md', { title: 'Not found' }], ['index.mdx', { title: 'Home page' }], - ['guides/authoring-content.md', { title: 'Authoring content', draft: true }], + ['guides/authoring-content.mdx', { title: 'Authoring content', draft: true }], ], }) ); @@ -43,7 +43,7 @@ test('routes have locale data added', () => { }); test('routes includes drafts except in production', async () => { - expect(routes.find((route) => route.id === 'guides/authoring-content.md')).toBeTruthy(); + expect(routes.find((route) => route.id === 'guides/authoring-content.mdx')).toBeTruthy(); // Reset the modules registry so that re-importing `utils/routing.ts` re-evaluates the module and // re-computes the routes. Re-importing the module is necessary because top-level imports cannot @@ -54,7 +54,7 @@ test('routes includes drafts except in production', async () => { // Re-import the module to re-evaluate it. const { routes: prodRoutes } = await import('../../utils/routing'); - expect(prodRoutes.find((route) => route.id === 'guides/authoring-content.md')).toBeFalsy(); + expect(prodRoutes.find((route) => route.id === 'guides/authoring-content.mdx')).toBeFalsy(); vi.unstubAllEnvs(); vi.resetModules(); diff --git a/packages/starlight/__tests__/basics/starlight-page-route-data.test.ts b/packages/starlight/__tests__/basics/starlight-page-route-data.test.ts index 3592f09b..63ac6efd 100644 --- a/packages/starlight/__tests__/basics/starlight-page-route-data.test.ts +++ b/packages/starlight/__tests__/basics/starlight-page-route-data.test.ts @@ -15,7 +15,7 @@ vi.mock('astro:content', async () => docs: [ ['index.mdx', { title: 'Home Page' }], ['getting-started.mdx', { title: 'Getting Started' }], - ['guides/authoring-content.md', { title: 'Authoring Markdown' }], + ['guides/authoring-content.mdx', { title: 'Authoring Markdown' }], ['guides/components.mdx', { title: 'Components' }], ['reference/frontmatter.md', { title: 'Frontmatter Reference' }], ], diff --git a/packages/starlight/__tests__/i18n-root-locale/routing.test.ts b/packages/starlight/__tests__/i18n-root-locale/routing.test.ts index dd5b4505..824eebe3 100644 --- a/packages/starlight/__tests__/i18n-root-locale/routing.test.ts +++ b/packages/starlight/__tests__/i18n-root-locale/routing.test.ts @@ -14,7 +14,7 @@ vi.mock('astro:content', async () => // @ts-expect-error — Using a slug not present in Starlight docs site ['ar/index.mdx', { title: 'الصفحة الرئيسية' }], [ - 'guides/authoring-content.md', + 'guides/authoring-content.mdx', { title: 'Création de contenu en Markdown', lastUpdated: true }, ], ], @@ -61,8 +61,9 @@ test('fallback routes have fallback locale data in entryMeta', () => { }); test('fallback routes use their own locale data', () => { - const enGuide = routes.find((route) => route.id === 'en/guides/authoring-content.md'); - if (!enGuide) throw new Error('Expected to find English fallback route for authoring-content.md'); + const enGuide = routes.find((route) => route.id === 'en/guides/authoring-content.mdx'); + if (!enGuide) + throw new Error('Expected to find English fallback route for authoring-content.mdx'); expect(enGuide.locale).toBe('en'); expect(enGuide.lang).toBe('en-US'); }); @@ -70,7 +71,7 @@ test('fallback routes use their own locale data', () => { test('fallback routes use fallback entry last updated dates', () => { const getNewestCommitDate = vi.spyOn(git, 'getNewestCommitDate'); const route = routes.find((route) => route.entry.id === routes[4]!.id && route.locale === 'en'); - assert(route, 'Expected to find English fallback route for `guides/authoring-content.md`.'); + assert(route, 'Expected to find English fallback route for `guides/authoring-content.mdx`.'); generateRouteData({ props: { @@ -82,7 +83,7 @@ test('fallback routes use fallback entry last updated dates', () => { expect(getNewestCommitDate).toHaveBeenCalledOnce(); expect(getNewestCommitDate.mock.lastCall?.[0]).toMatch( - /src[/\\]content[/\\]docs[/\\]guides[/\\]authoring-content.md$/ + /src[/\\]content[/\\]docs[/\\]guides[/\\]authoring-content.mdx$/ // ^ no `en/` prefix ); diff --git a/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar-fallback-slug.test.ts b/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar-fallback-slug.test.ts index e67e558e..d6496d42 100644 --- a/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar-fallback-slug.test.ts +++ b/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar-fallback-slug.test.ts @@ -9,7 +9,7 @@ vi.mock('astro:content', async () => ['manual-setup.mdx', { title: 'Manual Setup' }], ['environmental-impact.md', { title: 'Eco-friendly docs' }], ['guides/pages.mdx', { title: 'Pages' }], - ['guides/authoring-content.md', { title: 'Authoring Content in Markdown' }], + ['guides/authoring-content.mdx', { title: 'Authoring Content in Markdown' }], ['resources/plugins.mdx', { title: 'Plugins and Integrations' }], ], }) diff --git a/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar.test.ts b/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar.test.ts index dad2b413..f70e4f1b 100644 --- a/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar.test.ts +++ b/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar.test.ts @@ -14,7 +14,7 @@ vi.mock('astro:content', async () => ['fr/environmental-impact.md', { title: 'Documents écologiques' }], ['guides/pages.mdx', { title: 'Pages' }], ['fr/guides/pages.mdx', { title: 'Pages' }], - ['guides/authoring-content.md', { title: 'Authoring Content in Markdown' }], + ['guides/authoring-content.mdx', { title: 'Authoring Content in Markdown' }], ['fr/guides/authoring-content.md', { title: 'Création de contenu en Markdown' }], ['resources/plugins.mdx', { title: 'Plugins and Integrations' }], ['fr/resources/plugins.mdx', { title: "Modules d'extension et outils" }], diff --git a/packages/starlight/__tests__/i18n-sidebar/sidebar-internal-link-error.test.ts b/packages/starlight/__tests__/i18n-sidebar/sidebar-internal-link-error.test.ts index 9489830b..8fda7600 100644 --- a/packages/starlight/__tests__/i18n-sidebar/sidebar-internal-link-error.test.ts +++ b/packages/starlight/__tests__/i18n-sidebar/sidebar-internal-link-error.test.ts @@ -12,7 +12,7 @@ vi.mock('astro:content', async () => ['fr/environmental-impact.md', { title: 'Documents écologiques' }], ['guides/pages.mdx', { title: 'Pages' }], ['fr/guides/pages.mdx', { title: 'Pages' }], - ['guides/authoring-content.md', { title: 'Authoring Content in Markdown' }], + ['guides/authoring-content.mdx', { title: 'Authoring Content in Markdown' }], ['fr/guides/authoring-content.md', { title: 'Création de contenu en Markdown' }], ['resources/plugins.mdx', { title: 'Plugins and Integrations' }], ['fr/resources/plugins.mdx', { title: "Modules d'extension et outils" }], diff --git a/packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts b/packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts index 002b7de5..64e482e7 100644 --- a/packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts +++ b/packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts @@ -5,7 +5,7 @@ vi.mock('astro:content', async () => (await import('../test-utils')).mockedAstroContent({ docs: [ ['index.mdx', { title: 'Accueil' }], - ['guides/authoring-content.md', { title: 'Authoring content' }], + ['guides/authoring-content.mdx', { title: 'Authoring content' }], // @ts-expect-error — Using a slug not present in Starlight docs site ['en/index.mdx', { title: 'Not the home page' }], ], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6d304172..c2911151 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -82,6 +82,24 @@ importers: specifier: ^0.32.5 version: 0.32.6 + examples/markdoc: + dependencies: + '@astrojs/markdoc': + specifier: ^0.11.4 + version: 0.11.4(astro@4.15.3) + '@astrojs/starlight': + specifier: ^0.26.1 + version: link:../../packages/starlight + '@astrojs/starlight-markdoc': + specifier: ^0.0.1 + version: link:../../packages/markdoc + astro: + specifier: ^4.15.3 + version: 4.15.3(@types/node@18.16.19)(typescript@5.4.5) + sharp: + specifier: ^0.32.5 + version: 0.32.6 + examples/tailwind: dependencies: '@astrojs/starlight': @@ -128,6 +146,19 @@ importers: specifier: ^1.3.8 version: 1.3.8 + packages/markdoc: + dependencies: + '@astrojs/markdoc': + specifier: ^0.11.4 + version: 0.11.4(astro@4.15.3) + '@astrojs/starlight': + specifier: '>=0.23.0' + version: link:../starlight + devDependencies: + vitest: + specifier: ^1.6.0 + version: 1.6.0(@types/node@18.16.19) + packages/starlight: dependencies: '@astrojs/mdx': @@ -471,6 +502,27 @@ packages: - typescript dev: true + /@astrojs/markdoc@0.11.4(astro@4.15.3): + resolution: {integrity: sha512-6s60ZpsODsEvws57TEpUPXq5Uo+eSHsTVUUAQbbkSL+nQHIy1tR7tI6vbbO2y/VOLj214kATAc18/iRjFp2TbQ==} + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0} + peerDependencies: + astro: ^3.0.0 || ^4.0.0 + dependencies: + '@astrojs/internal-helpers': 0.4.1 + '@astrojs/markdown-remark': 5.2.0 + '@astrojs/prism': 3.1.0 + '@markdoc/markdoc': 0.4.0 + astro: 4.15.3(@types/node@18.16.19)(typescript@5.4.5) + esbuild: 0.21.5 + github-slugger: 2.0.0 + gray-matter: 4.0.3 + htmlparser2: 9.1.0 + transitivePeerDependencies: + - '@types/react' + - react + - supports-color + dev: false + /@astrojs/markdown-remark@5.2.0: resolution: {integrity: sha512-vWGM24KZXz11jR3JO+oqYU3T2qpuOi4uGivJ9SQLCAI01+vEkHC60YJMRvHPc+hwd60F7euNs1PeOEixIIiNQw==} dependencies: @@ -1563,6 +1615,21 @@ packages: read-yaml-file: 1.1.0 dev: true + /@markdoc/markdoc@0.4.0: + resolution: {integrity: sha512-fSh4P3Y4E7oaKYc2oNzSIJVPDto7SMzAuQN1Iyx53UxzleA6QzRdNWRxmiPqtVDaDi5dELd2yICoG91csrGrAw==} + engines: {node: '>=14.7.0'} + peerDependencies: + '@types/react': '*' + react: '*' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + optionalDependencies: + '@types/markdown-it': 12.2.3 + dev: false + /@mdx-js/mdx@3.0.1: resolution: {integrity: sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==} dependencies: @@ -1889,11 +1956,32 @@ packages: dependencies: '@types/unist': 3.0.0 + /@types/linkify-it@5.0.0: + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + requiresBuild: true + dev: false + optional: true + + /@types/markdown-it@12.2.3: + resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} + requiresBuild: true + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + dev: false + optional: true + /@types/mdast@4.0.4: resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} dependencies: '@types/unist': 3.0.0 + /@types/mdurl@2.0.0: + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + requiresBuild: true + dev: false + optional: true + /@types/mdx@2.0.5: resolution: {integrity: sha512-76CqzuD6Q7LC+AtbPqrvD9AqsN0k8bsYo2bM2J8pmNldP1aIPAbzUQ7QbobyXL4eLr1wK5x8FZFe8eF/ubRuBg==} dev: false @@ -3019,18 +3107,15 @@ packages: domelementtype: 2.3.0 domhandler: 5.0.3 entities: 4.5.0 - dev: true /domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: true /domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} dependencies: domelementtype: 2.3.0 - dev: true /domutils@3.1.0: resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} @@ -3038,7 +3123,6 @@ packages: dom-serializer: 2.0.0 domelementtype: 2.3.0 domhandler: 5.0.3 - dev: true /dotenv@8.6.0: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} @@ -3990,6 +4074,15 @@ packages: entities: 4.5.0 dev: true + /htmlparser2@9.1.0: + resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + dev: false + /http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} |