@astrojs/mdx 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- @astrojs/mdx:build: cache hit, replaying output 628f5c9b87587320
1
+ @astrojs/mdx:build: cache hit, replaying output 5d04eed831bc49e1
2
2
  @astrojs/mdx:build: 
3
- @astrojs/mdx:build: > @astrojs/mdx@0.8.1 build /home/runner/work/astro/astro/packages/integrations/mdx
3
+ @astrojs/mdx:build: > @astrojs/mdx@0.9.0 build /home/runner/work/astro/astro/packages/integrations/mdx
4
4
  @astrojs/mdx:build: > astro-scripts build "src/**/*.ts" && tsc
5
5
  @astrojs/mdx:build: 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @astrojs/mdx
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#4268](https://github.com/withastro/astro/pull/4268) [`f7afdb889`](https://github.com/withastro/astro/commit/f7afdb889fe4e97177958c8ec92f80c5f6e5cb51) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Align MD with MDX on layout props and "glob" import results:
8
+ - Add `Content` to MDX
9
+ - Add `file` and `url` to MDX frontmatter (layout import only)
10
+ - Update glob types to reflect differences (lack of `rawContent` and `compiledContent`)
11
+
12
+ ### Patch Changes
13
+
14
+ - [#4272](https://github.com/withastro/astro/pull/4272) [`24d2f7a6e`](https://github.com/withastro/astro/commit/24d2f7a6e6700c10c863f826f37bb653d70e3a83) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Properly handle hydration for namespaced components
15
+
16
+ ## 0.8.3
17
+
18
+ ### Patch Changes
19
+
20
+ - [#4248](https://github.com/withastro/astro/pull/4248) [`869d00935`](https://github.com/withastro/astro/commit/869d0093596b709cfcc1a1a95ee631b48d6d1c26) Thanks [@svemat01](https://github.com/svemat01)! - Load builtin rehype plugins before user plugins instead of after
21
+
22
+ * [#4255](https://github.com/withastro/astro/pull/4255) [`411612808`](https://github.com/withastro/astro/commit/4116128082121ee276d51cb245bf8095be4728a1) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Pass injected frontmatter from remark and rehype plugins to layouts
23
+
24
+ * Updated dependencies [[`1f0dd31d9`](https://github.com/withastro/astro/commit/1f0dd31d9239b5e3dca99c88d021e7a9a3e2054d)]:
25
+ - @astrojs/prism@1.0.1
26
+
27
+ ## 0.8.2
28
+
29
+ ### Patch Changes
30
+
31
+ - [#4237](https://github.com/withastro/astro/pull/4237) [`9d5ab5508`](https://github.com/withastro/astro/commit/9d5ab55086964fbede17da3d78c209c6d8d13711) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Update "Astro.props.content" -> "Astro.props.frontmatter" in README
32
+
3
33
  ## 0.8.1
4
34
 
5
35
  ### Patch Changes
package/README.md CHANGED
@@ -195,19 +195,19 @@ title: 'My Blog Post'
195
195
  ---
196
196
  ```
197
197
 
198
- Then, you can retrieve all other frontmatter properties from your layout via the `content` property, and render your MDX using the default [`<slot />`](https://docs.astro.build/en/core-concepts/astro-components/#slots):
198
+ 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):
199
199
 
200
200
  ```astro
201
201
  ---
202
202
  // src/layouts/BaseLayout.astro
203
- const { content } = Astro.props;
203
+ const { frontmatter } = Astro.props;
204
204
  ---
205
205
  <html>
206
206
  <head>
207
- <title>{content.title}</title>
207
+ <title>{frontmatter.title}</title>
208
208
  </head>
209
209
  <body>
210
- <h1>{content.title}</h1>
210
+ <h1>{frontmatter.title}</h1>
211
211
  <!-- Rendered MDX will be passed into the default slot. -->
212
212
  <slot />
213
213
  </body>
@@ -14,6 +14,43 @@ function rehypeApplyFrontmatterExport(pageFrontmatter) {
14
14
  const exportNodes = [
15
15
  jsToTreeNode(`export const ${EXPORT_NAME} = ${JSON.stringify(frontmatter)};`)
16
16
  ];
17
+ if (frontmatter.layout) {
18
+ exportNodes.unshift(
19
+ jsToTreeNode(
20
+ `import { jsx as layoutJsx } from 'astro/jsx-runtime';
21
+ import Layout from ${JSON.stringify(frontmatter.layout)};
22
+
23
+ export default function ({ children }) {
24
+ const { layout, ...content } = frontmatter;
25
+ content.file = file;
26
+ content.url = url;
27
+ content.astro = {};
28
+ Object.defineProperty(content.astro, 'headings', {
29
+ get() {
30
+ throw new Error('The "astro" property is no longer supported! To access "headings" from your layout, try using "Astro.props.headings."')
31
+ }
32
+ });
33
+ Object.defineProperty(content.astro, 'html', {
34
+ get() {
35
+ throw new Error('The "astro" property is no longer supported! To access "html" from your layout, try using "Astro.props.compiledContent()."')
36
+ }
37
+ });
38
+ Object.defineProperty(content.astro, 'source', {
39
+ get() {
40
+ throw new Error('The "astro" property is no longer supported! To access "source" from your layout, try using "Astro.props.rawContent()."')
41
+ }
42
+ });
43
+ return layoutJsx(Layout, {
44
+ content,
45
+ frontmatter: content,
46
+ headings: getHeadings(),
47
+ 'server:root': true,
48
+ children,
49
+ });
50
+ };`
51
+ )
52
+ );
53
+ }
17
54
  tree.children = exportNodes.concat(tree.children);
18
55
  };
19
56
  }
package/dist/index.js CHANGED
@@ -15,6 +15,8 @@ const DEFAULT_REMARK_PLUGINS = [
15
15
  remarkSmartypants
16
16
  ];
17
17
  const DEFAULT_REHYPE_PLUGINS = [];
18
+ 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";
19
+ 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";
18
20
  function handleExtends(config, defaults = []) {
19
21
  if (Array.isArray(config))
20
22
  return config;
@@ -37,9 +39,9 @@ function getRemarkPlugins(mdxOptions, config) {
37
39
  function getRehypePlugins(mdxOptions, config) {
38
40
  let rehypePlugins = handleExtends(mdxOptions.rehypePlugins, DEFAULT_REHYPE_PLUGINS);
39
41
  if (config.markdown.syntaxHighlight === "shiki" || config.markdown.syntaxHighlight === "prism") {
40
- rehypePlugins.push([rehypeRaw, { passThrough: nodeTypes }]);
42
+ rehypePlugins.unshift([rehypeRaw, { passThrough: nodeTypes }]);
41
43
  }
42
- rehypePlugins.push(rehypeCollectHeadings);
44
+ rehypePlugins.unshift(rehypeCollectHeadings);
43
45
  return rehypePlugins;
44
46
  }
45
47
  function mdx(mdxOptions = {}) {
@@ -65,20 +67,7 @@ function mdx(mdxOptions = {}) {
65
67
  async transform(code, id) {
66
68
  if (!id.endsWith("mdx"))
67
69
  return;
68
- let { data: frontmatter, content: pageContent } = parseFrontmatter(code, id);
69
- if (frontmatter.layout) {
70
- const { layout, ...contentProp } = frontmatter;
71
- pageContent += `
72
-
73
- export default async function({ children }) {
74
- const Layout = (await import(${JSON.stringify(
75
- frontmatter.layout
76
- )})).default;
77
- const frontmatter=${JSON.stringify(
78
- contentProp
79
- )};
80
- return <Layout frontmatter={frontmatter} content={frontmatter} headings={getHeadings()}>{children}</Layout> }`;
81
- }
70
+ const { data: frontmatter, content: pageContent } = parseFrontmatter(code, id);
82
71
  const compiled = await mdxCompile(new VFile({ value: pageContent, path: id }), {
83
72
  ...mdxPluginOpts,
84
73
  rehypePlugins: [
@@ -106,6 +95,22 @@ export const url = ${JSON.stringify(fileUrl)};`;
106
95
  if (!moduleExports.includes("file")) {
107
96
  code += `
108
97
  export const file = ${JSON.stringify(fileId)};`;
98
+ }
99
+ if (!moduleExports.includes("rawContent")) {
100
+ code += `
101
+ export function rawContent() { throw new Error(${JSON.stringify(
102
+ RAW_CONTENT_ERROR
103
+ )}) };`;
104
+ }
105
+ if (!moduleExports.includes("compiledContent")) {
106
+ code += `
107
+ export function compiledContent() { throw new Error(${JSON.stringify(
108
+ COMPILED_CONTENT_ERROR
109
+ )}) };`;
110
+ }
111
+ if (!moduleExports.includes("Content")) {
112
+ code += `
113
+ export const Content = MDXContent;`;
109
114
  }
110
115
  if (command === "dev") {
111
116
  code += `
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@astrojs/mdx",
3
3
  "description": "Use MDX within Astro",
4
- "version": "0.8.1",
4
+ "version": "0.9.0",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "withastro",
@@ -23,7 +23,7 @@
23
23
  "./package.json": "./package.json"
24
24
  },
25
25
  "dependencies": {
26
- "@astrojs/prism": "^1.0.0",
26
+ "@astrojs/prism": "^1.0.1",
27
27
  "@mdx-js/mdx": "^2.1.2",
28
28
  "@mdx-js/rollup": "^2.1.1",
29
29
  "acorn": "^8.8.0",
@@ -43,7 +43,7 @@
43
43
  "@types/chai": "^4.3.1",
44
44
  "@types/mocha": "^9.1.1",
45
45
  "@types/yargs-parser": "^21.0.0",
46
- "astro": "1.0.0",
46
+ "astro": "1.0.4",
47
47
  "astro-scripts": "0.0.7",
48
48
  "chai": "^4.3.6",
49
49
  "linkedom": "^0.14.12",
@@ -19,6 +19,44 @@ export function rehypeApplyFrontmatterExport(pageFrontmatter: Record<string, any
19
19
  const exportNodes = [
20
20
  jsToTreeNode(`export const ${EXPORT_NAME} = ${JSON.stringify(frontmatter)};`),
21
21
  ];
22
+ if (frontmatter.layout) {
23
+ exportNodes.unshift(
24
+ jsToTreeNode(
25
+ /** @see 'vite-plugin-markdown' for layout props reference */
26
+ `import { jsx as layoutJsx } from 'astro/jsx-runtime';
27
+ import Layout from ${JSON.stringify(frontmatter.layout)};
28
+
29
+ export default function ({ children }) {
30
+ const { layout, ...content } = frontmatter;
31
+ content.file = file;
32
+ content.url = url;
33
+ content.astro = {};
34
+ Object.defineProperty(content.astro, 'headings', {
35
+ get() {
36
+ throw new Error('The "astro" property is no longer supported! To access "headings" from your layout, try using "Astro.props.headings."')
37
+ }
38
+ });
39
+ Object.defineProperty(content.astro, 'html', {
40
+ get() {
41
+ throw new Error('The "astro" property is no longer supported! To access "html" from your layout, try using "Astro.props.compiledContent()."')
42
+ }
43
+ });
44
+ Object.defineProperty(content.astro, 'source', {
45
+ get() {
46
+ throw new Error('The "astro" property is no longer supported! To access "source" from your layout, try using "Astro.props.rawContent()."')
47
+ }
48
+ });
49
+ return layoutJsx(Layout, {
50
+ content,
51
+ frontmatter: content,
52
+ headings: getHeadings(),
53
+ 'server:root': true,
54
+ children,
55
+ });
56
+ };`
57
+ )
58
+ );
59
+ }
22
60
  tree.children = exportNodes.concat(tree.children);
23
61
  };
24
62
  }
package/src/index.ts CHANGED
@@ -26,6 +26,12 @@ const DEFAULT_REMARK_PLUGINS: MdxRollupPluginOptions['remarkPlugins'] = [
26
26
  ];
27
27
  const DEFAULT_REHYPE_PLUGINS: MdxRollupPluginOptions['rehypePlugins'] = [];
28
28
 
29
+ const RAW_CONTENT_ERROR =
30
+ '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';
31
+
32
+ const COMPILED_CONTENT_ERROR =
33
+ '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';
34
+
29
35
  function handleExtends<T>(config: WithExtends<T[] | undefined>, defaults: T[] = []): T[] {
30
36
  if (Array.isArray(config)) return config;
31
37
 
@@ -62,10 +68,10 @@ function getRehypePlugins(
62
68
  let rehypePlugins = handleExtends(mdxOptions.rehypePlugins, DEFAULT_REHYPE_PLUGINS);
63
69
 
64
70
  if (config.markdown.syntaxHighlight === 'shiki' || config.markdown.syntaxHighlight === 'prism') {
65
- rehypePlugins.push([rehypeRaw, { passThrough: nodeTypes }]);
71
+ rehypePlugins.unshift([rehypeRaw, { passThrough: nodeTypes }]);
66
72
  }
67
73
  // getHeadings() is guaranteed by TS, so we can't allow user to override
68
- rehypePlugins.push(rehypeCollectHeadings);
74
+ rehypePlugins.unshift(rehypeCollectHeadings);
69
75
 
70
76
  return rehypePlugins;
71
77
  }
@@ -98,16 +104,7 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
98
104
  async transform(code, id) {
99
105
  if (!id.endsWith('mdx')) return;
100
106
 
101
- let { data: frontmatter, content: pageContent } = parseFrontmatter(code, id);
102
- if (frontmatter.layout) {
103
- const { layout, ...contentProp } = frontmatter;
104
- pageContent += `\n\nexport default async function({ children }) {\nconst Layout = (await import(${JSON.stringify(
105
- frontmatter.layout
106
- )})).default;\nconst frontmatter=${JSON.stringify(
107
- contentProp
108
- )};\nreturn <Layout frontmatter={frontmatter} content={frontmatter} headings={getHeadings()}>{children}</Layout> }`;
109
- }
110
-
107
+ const { data: frontmatter, content: pageContent } = parseFrontmatter(code, id);
111
108
  const compiled = await mdxCompile(new VFile({ value: pageContent, path: id }), {
112
109
  ...mdxPluginOpts,
113
110
  rehypePlugins: [
@@ -136,6 +133,19 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
136
133
  if (!moduleExports.includes('file')) {
137
134
  code += `\nexport const file = ${JSON.stringify(fileId)};`;
138
135
  }
136
+ if (!moduleExports.includes('rawContent')) {
137
+ code += `\nexport function rawContent() { throw new Error(${JSON.stringify(
138
+ RAW_CONTENT_ERROR
139
+ )}) };`;
140
+ }
141
+ if (!moduleExports.includes('compiledContent')) {
142
+ code += `\nexport function compiledContent() { throw new Error(${JSON.stringify(
143
+ COMPILED_CONTENT_ERROR
144
+ )}) };`;
145
+ }
146
+ if (!moduleExports.includes('Content')) {
147
+ code += `\nexport const Content = MDXContent;`;
148
+ }
139
149
 
140
150
  if (command === 'dev') {
141
151
  // TODO: decline HMR updates until we have a stable approach
@@ -0,0 +1,11 @@
1
+ ---
2
+ const components = await Astro.glob('../components/*.mdx');
3
+ ---
4
+
5
+ <div data-default-export>
6
+ {components.map(Component => <Component.default />)}
7
+ </div>
8
+
9
+ <div data-content-export>
10
+ {components.map(({ Content }) => <Content />)}
11
+ </div>
@@ -1,7 +1,11 @@
1
1
  ---
2
2
  const {
3
3
  content = { title: "content didn't work" },
4
- frontmatter = { title: "frontmatter didn't work" },
4
+ frontmatter = {
5
+ title: "frontmatter didn't work",
6
+ file: "file didn't work",
7
+ url: "url didn't work",
8
+ },
5
9
  headings = [],
6
10
  } = Astro.props;
7
11
  ---
@@ -18,6 +22,8 @@ const {
18
22
  <body>
19
23
  <p data-content-title>{content.title}</p>
20
24
  <p data-frontmatter-title>{frontmatter.title}</p>
25
+ <p data-frontmatter-file>{frontmatter.file}</p>
26
+ <p data-frontmatter-url>{frontmatter.url}</p>
21
27
  <p data-layout-rendered>Layout rendered!</p>
22
28
  <ul data-headings>
23
29
  {headings.map(heading => <li>{heading.slug}</li>)}
@@ -0,0 +1,17 @@
1
+ ---
2
+ const defaults = { title: 'Frontmatter not passed to layout!' }
3
+ const { frontmatter = defaults, content = defaults } = Astro.props;
4
+ ---
5
+
6
+ <!DOCTYPE html>
7
+ <html lang="en">
8
+ <head>
9
+ <meta charset="UTF-8">
10
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
11
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
12
+ <title>{frontmatter.title}</title>
13
+ </head>
14
+ <body>
15
+ <slot />
16
+ </body>
17
+ </html>
@@ -1,3 +1,7 @@
1
+ ---
2
+ layout: '../layouts/Base.astro'
3
+ ---
4
+
1
5
  # Page 1
2
6
 
3
7
  Look at that!
@@ -1,3 +1,7 @@
1
+ ---
2
+ layout: '../layouts/Base.astro'
3
+ ---
4
+
1
5
  # Page 2
2
6
 
3
7
  ## Table of contents
@@ -0,0 +1,6 @@
1
+ import mdx from '@astrojs/mdx';
2
+ import react from '@astrojs/react';
3
+
4
+ export default {
5
+ integrations: [react(), mdx()]
6
+ }
@@ -0,0 +1,17 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
6
+ esac
7
+
8
+ if [ -z "$NODE_PATH" ]; then
9
+ export NODE_PATH="/home/runner/work/astro/astro/node_modules/.pnpm/node_modules"
10
+ else
11
+ export NODE_PATH="$NODE_PATH:/home/runner/work/astro/astro/node_modules/.pnpm/node_modules"
12
+ fi
13
+ if [ -x "$basedir/node" ]; then
14
+ exec "$basedir/node" "$basedir/../../../../../../../astro/astro.js" "$@"
15
+ else
16
+ exec node "$basedir/../../../../../../../astro/astro.js" "$@"
17
+ fi
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "@test/mdx-namespace",
3
+ "dependencies": {
4
+ "astro": "workspace:*",
5
+ "@astrojs/mdx": "workspace:*",
6
+ "@astrojs/react": "workspace:*"
7
+ }
8
+ }
@@ -0,0 +1,6 @@
1
+ const Component = () => {
2
+ return <p id="component">Hello world</p>;
3
+ };
4
+ export const ns = {
5
+ Component
6
+ }
@@ -0,0 +1,3 @@
1
+ import * as mod from '../components/Component.jsx';
2
+
3
+ <mod.ns.Component client:load />
@@ -0,0 +1,3 @@
1
+ import { ns } from '../components/Component.jsx';
2
+
3
+ <ns.Component client:load />
@@ -19,7 +19,7 @@ describe('MDX Component', () => {
19
19
  await fixture.build();
20
20
  });
21
21
 
22
- it('works', async () => {
22
+ it('supports top-level imports', async () => {
23
23
  const html = await fixture.readFile('/index.html');
24
24
  const { document } = parseHTML(html);
25
25
 
@@ -29,6 +29,28 @@ describe('MDX Component', () => {
29
29
  expect(h1.textContent).to.equal('Hello component!');
30
30
  expect(foo.textContent).to.equal('bar');
31
31
  });
32
+
33
+ it('supports glob imports - <Component.default />', async () => {
34
+ const html = await fixture.readFile('/glob/index.html');
35
+ const { document } = parseHTML(html);
36
+
37
+ const h1 = document.querySelector('[data-default-export] h1');
38
+ const foo = document.querySelector('[data-default-export] #foo');
39
+
40
+ expect(h1.textContent).to.equal('Hello component!');
41
+ expect(foo.textContent).to.equal('bar');
42
+ });
43
+
44
+ it('supports glob imports - <Content />', async () => {
45
+ const html = await fixture.readFile('/glob/index.html');
46
+ const { document } = parseHTML(html);
47
+
48
+ const h1 = document.querySelector('[data-content-export] h1');
49
+ const foo = document.querySelector('[data-content-export] #foo');
50
+
51
+ expect(h1.textContent).to.equal('Hello component!');
52
+ expect(foo.textContent).to.equal('bar');
53
+ });
32
54
  });
33
55
 
34
56
  describe('dev', () => {
@@ -42,7 +64,7 @@ describe('MDX Component', () => {
42
64
  await devServer.stop();
43
65
  });
44
66
 
45
- it('works', async () => {
67
+ it('supports top-level imports', async () => {
46
68
  const res = await fixture.fetch('/');
47
69
 
48
70
  expect(res.status).to.equal(200);
@@ -56,5 +78,35 @@ describe('MDX Component', () => {
56
78
  expect(h1.textContent).to.equal('Hello component!');
57
79
  expect(foo.textContent).to.equal('bar');
58
80
  });
81
+
82
+ it('supports glob imports - <Component.default />', async () => {
83
+ const res = await fixture.fetch('/glob');
84
+
85
+ expect(res.status).to.equal(200);
86
+
87
+ const html = await res.text();
88
+ const { document } = parseHTML(html);
89
+
90
+ const h1 = document.querySelector('[data-default-export] h1');
91
+ const foo = document.querySelector('[data-default-export] #foo');
92
+
93
+ expect(h1.textContent).to.equal('Hello component!');
94
+ expect(foo.textContent).to.equal('bar');
95
+ });
96
+
97
+ it('supports glob imports - <Content />', async () => {
98
+ const res = await fixture.fetch('/glob');
99
+
100
+ expect(res.status).to.equal(200);
101
+
102
+ const html = await res.text();
103
+ const { document } = parseHTML(html);
104
+
105
+ const h1 = document.querySelector('[data-content-export] h1');
106
+ const foo = document.querySelector('[data-content-export] #foo');
107
+
108
+ expect(h1.textContent).to.equal('Hello component!');
109
+ expect(foo.textContent).to.equal('bar');
110
+ });
59
111
  });
60
112
  });
@@ -1,4 +1,5 @@
1
1
  import { expect } from 'chai';
2
+ import { parseHTML } from 'linkedom';
2
3
  import { loadFixture } from '../../../astro/test/test-utils.js';
3
4
 
4
5
  const FIXTURE_ROOT = new URL('./fixtures/mdx-frontmatter-injection/', import.meta.url);
@@ -41,4 +42,15 @@ describe('MDX frontmatter injection', () => {
41
42
  expect(titles).to.contain('Overridden title');
42
43
  expect(readingTimes).to.contain('1000 min read');
43
44
  });
45
+
46
+ it('passes injected frontmatter to layouts', async () => {
47
+ const html1 = await fixture.readFile('/page-1/index.html');
48
+ const html2 = await fixture.readFile('/page-2/index.html');
49
+
50
+ const title1 = parseHTML(html1).document.querySelector('title');
51
+ const title2 = parseHTML(html2).document.querySelector('title');
52
+
53
+ expect(title1.innerHTML).to.equal('Page 1');
54
+ expect(title2.innerHTML).to.equal('Page 2');
55
+ });
44
56
  });
@@ -56,4 +56,18 @@ describe('MDX frontmatter', () => {
56
56
  expect(headingSlugs).to.contain('section-1');
57
57
  expect(headingSlugs).to.contain('section-2');
58
58
  });
59
+
60
+ it('passes "file" and "url" to layout via frontmatter', async () => {
61
+ const html = await fixture.readFile('/with-headings/index.html');
62
+ const { document } = parseHTML(html);
63
+
64
+ const frontmatterFile = document.querySelector('[data-frontmatter-file]')?.textContent;
65
+ const frontmatterUrl = document.querySelector('[data-frontmatter-url]')?.textContent;
66
+
67
+ expect(frontmatterFile?.endsWith('with-headings.mdx')).to.equal(
68
+ true,
69
+ '"file" prop does not end with correct path or is undefined'
70
+ );
71
+ expect(frontmatterUrl).to.equal('/with-headings');
72
+ });
59
73
  });
@@ -0,0 +1,83 @@
1
+ import { expect } from 'chai';
2
+ import { parseHTML } from 'linkedom';
3
+ import { loadFixture } from '../../../astro/test/test-utils.js';
4
+
5
+ describe('MDX Namespace', () => {
6
+ let fixture;
7
+
8
+ before(async () => {
9
+ fixture = await loadFixture({
10
+ root: new URL('./fixtures/mdx-namespace/', import.meta.url),
11
+ });
12
+ });
13
+
14
+ describe('build', () => {
15
+ before(async () => {
16
+ await fixture.build();
17
+ });
18
+
19
+ it('works for object', async () => {
20
+ const html = await fixture.readFile('/object/index.html');
21
+ const { document } = parseHTML(html);
22
+
23
+ const island = document.querySelector('astro-island');
24
+ const component = document.querySelector('#component');
25
+
26
+ expect(island).not.undefined;
27
+ expect(component.textContent).equal('Hello world');
28
+ });
29
+
30
+ it('works for star', async () => {
31
+ const html = await fixture.readFile('/star/index.html');
32
+ const { document } = parseHTML(html);
33
+
34
+ const island = document.querySelector('astro-island');
35
+ const component = document.querySelector('#component');
36
+
37
+ expect(island).not.undefined;
38
+ expect(component.textContent).equal('Hello world');
39
+ });
40
+ });
41
+
42
+ describe('dev', () => {
43
+ let devServer;
44
+
45
+ before(async () => {
46
+ devServer = await fixture.startDevServer();
47
+ });
48
+
49
+ after(async () => {
50
+ await devServer.stop();
51
+ });
52
+
53
+ it('works for object', async () => {
54
+ const res = await fixture.fetch('/object');
55
+
56
+ expect(res.status).to.equal(200);
57
+
58
+ const html = await res.text();
59
+ const { document } = parseHTML(html);
60
+
61
+ const island = document.querySelector('astro-island');
62
+ const component = document.querySelector('#component');
63
+
64
+ expect(island).not.undefined;
65
+ expect(component.textContent).equal('Hello world');
66
+ });
67
+
68
+ it('works for star', async () => {
69
+ const res = await fixture.fetch('/star');
70
+
71
+ expect(res.status).to.equal(200);
72
+
73
+ const html = await res.text();
74
+ const { document } = parseHTML(html);
75
+
76
+ const island = document.querySelector('astro-island');
77
+ const component = document.querySelector('#component');
78
+
79
+ expect(island).not.undefined;
80
+ expect(component.textContent).equal('Hello world');
81
+ });
82
+ });
83
+ });