@astrojs/mdx 0.8.3 → 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 67cdf445a0fed367
2
- @astrojs/mdx:build: 
3
- @astrojs/mdx:build: > @astrojs/mdx@0.8.3 build /home/runner/work/astro/astro/packages/integrations/mdx
4
- @astrojs/mdx:build: > astro-scripts build "src/**/*.ts" && tsc
5
- @astrojs/mdx:build: 
1
+ @astrojs/mdx:build: cache hit, replaying output 5d04eed831bc49e1
2
+ @astrojs/mdx:build: 
3
+ @astrojs/mdx:build: > @astrojs/mdx@0.9.0 build /home/runner/work/astro/astro/packages/integrations/mdx
4
+ @astrojs/mdx:build: > astro-scripts build "src/**/*.ts" && tsc
5
+ @astrojs/mdx:build: 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
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
+
3
16
  ## 0.8.3
4
17
 
5
18
  ### Patch Changes
@@ -22,6 +22,8 @@ function rehypeApplyFrontmatterExport(pageFrontmatter) {
22
22
 
23
23
  export default function ({ children }) {
24
24
  const { layout, ...content } = frontmatter;
25
+ content.file = file;
26
+ content.url = url;
25
27
  content.astro = {};
26
28
  Object.defineProperty(content.astro, 'headings', {
27
29
  get() {
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;
@@ -93,6 +95,22 @@ export const url = ${JSON.stringify(fileUrl)};`;
93
95
  if (!moduleExports.includes("file")) {
94
96
  code += `
95
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;`;
96
114
  }
97
115
  if (command === "dev") {
98
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.3",
4
+ "version": "0.9.0",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "withastro",
@@ -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.3",
46
+ "astro": "1.0.4",
47
47
  "astro-scripts": "0.0.7",
48
48
  "chai": "^4.3.6",
49
49
  "linkedom": "^0.14.12",
@@ -28,6 +28,8 @@ export function rehypeApplyFrontmatterExport(pageFrontmatter: Record<string, any
28
28
 
29
29
  export default function ({ children }) {
30
30
  const { layout, ...content } = frontmatter;
31
+ content.file = file;
32
+ content.url = url;
31
33
  content.astro = {};
32
34
  Object.defineProperty(content.astro, 'headings', {
33
35
  get() {
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
 
@@ -127,6 +133,19 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
127
133
  if (!moduleExports.includes('file')) {
128
134
  code += `\nexport const file = ${JSON.stringify(fileId)};`;
129
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
+ }
130
149
 
131
150
  if (command === 'dev') {
132
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,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
  });
@@ -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
+ });