@astrojs/markdoc 0.0.5 → 0.1.1

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.
Files changed (57) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/CHANGELOG.md +56 -0
  3. package/README.md +110 -146
  4. package/components/Renderer.astro +8 -11
  5. package/components/TreeNode.ts +14 -23
  6. package/dist/config.d.ts +2 -0
  7. package/dist/config.js +6 -0
  8. package/dist/default-config.d.ts +5 -0
  9. package/dist/default-config.js +13 -0
  10. package/dist/experimental-assets-config.d.ts +2 -0
  11. package/dist/experimental-assets-config.js +25 -0
  12. package/dist/index.d.ts +1 -2
  13. package/dist/index.js +43 -112
  14. package/dist/load-config.d.ts +14 -0
  15. package/dist/load-config.js +82 -0
  16. package/dist/utils.d.ts +0 -11
  17. package/dist/utils.js +1 -44
  18. package/package.json +8 -3
  19. package/src/config.ts +5 -0
  20. package/src/default-config.ts +18 -0
  21. package/src/experimental-assets-config.ts +29 -0
  22. package/src/index.ts +65 -143
  23. package/src/load-config.ts +102 -0
  24. package/src/utils.ts +0 -58
  25. package/template/content-module-types.d.ts +1 -3
  26. package/test/content-collections.test.js +24 -172
  27. package/test/fixtures/content-collections/package.json +0 -4
  28. package/test/fixtures/content-collections/src/content/blog/post-1.mdoc +7 -0
  29. package/test/fixtures/content-collections/src/content/blog/post-2.mdoc +7 -0
  30. package/test/fixtures/content-collections/src/content/blog/post-3.mdoc +7 -0
  31. package/test/fixtures/content-collections/src/pages/entry.json.js +1 -1
  32. package/test/fixtures/render-null/astro.config.mjs +7 -0
  33. package/test/fixtures/render-null/markdoc.config.mjs +26 -0
  34. package/test/fixtures/render-null/node_modules/.bin/astro +17 -0
  35. package/test/fixtures/render-null/package.json +9 -0
  36. package/test/fixtures/render-null/src/content/blog/render-null.mdoc +7 -0
  37. package/test/fixtures/render-null/src/pages/index.astro +19 -0
  38. package/test/fixtures/render-simple/astro.config.mjs +7 -0
  39. package/test/fixtures/render-simple/node_modules/.bin/astro +17 -0
  40. package/test/fixtures/render-simple/package.json +9 -0
  41. package/test/fixtures/{content-collections/src/pages/content-simple.astro → render-simple/src/pages/index.astro} +2 -1
  42. package/test/fixtures/render-with-components/astro.config.mjs +7 -0
  43. package/test/fixtures/render-with-components/markdoc.config.mjs +28 -0
  44. package/test/fixtures/render-with-components/node_modules/.bin/astro +17 -0
  45. package/test/fixtures/render-with-components/package.json +12 -0
  46. package/test/fixtures/{content-collections/src/pages/content-with-components.astro → render-with-components/src/pages/index.astro} +2 -6
  47. package/test/fixtures/render-with-config/astro.config.mjs +7 -0
  48. package/test/fixtures/render-with-config/markdoc.config.mjs +15 -0
  49. package/test/fixtures/render-with-config/node_modules/.bin/astro +17 -0
  50. package/test/fixtures/render-with-config/package.json +9 -0
  51. package/test/fixtures/{content-collections → render-with-config}/src/content/blog/with-config.mdoc +4 -0
  52. package/test/fixtures/{content-collections/src/pages/content-with-config.astro → render-with-config/src/pages/index.astro} +2 -2
  53. package/test/render.test.js +150 -0
  54. /package/test/fixtures/{content-collections → render-simple}/src/content/blog/simple.mdoc +0 -0
  55. /package/test/fixtures/{content-collections → render-with-components}/src/components/Code.astro +0 -0
  56. /package/test/fixtures/{content-collections → render-with-components}/src/components/CustomMarquee.astro +0 -0
  57. /package/test/fixtures/{content-collections → render-with-components}/src/content/blog/with-components.mdoc +0 -0
@@ -4,10 +4,6 @@
4
4
  "private": true,
5
5
  "dependencies": {
6
6
  "@astrojs/markdoc": "workspace:*",
7
- "@markdoc/markdoc": "^0.2.2",
8
7
  "astro": "workspace:*"
9
- },
10
- "devDependencies": {
11
- "shiki": "^0.11.1"
12
8
  }
13
9
  }
@@ -0,0 +1,7 @@
1
+ ---
2
+ title: Post 1
3
+ ---
4
+
5
+ ## Post 1
6
+
7
+ This is the contents of post 1.
@@ -0,0 +1,7 @@
1
+ ---
2
+ title: Post 2
3
+ ---
4
+
5
+ ## Post 2
6
+
7
+ This is the contents of post 2.
@@ -0,0 +1,7 @@
1
+ ---
2
+ title: Post 3
3
+ ---
4
+
5
+ ## Post 3
6
+
7
+ This is the contents of post 3.
@@ -3,7 +3,7 @@ import { stringify } from 'devalue';
3
3
  import { stripRenderFn } from '../../utils.js';
4
4
 
5
5
  export async function get() {
6
- const post = await getEntryBySlug('blog', 'simple');
6
+ const post = await getEntryBySlug('blog', 'post-1');
7
7
  return {
8
8
  body: stringify(stripRenderFn(post)),
9
9
  };
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from 'astro/config';
2
+ import markdoc from '@astrojs/markdoc';
3
+
4
+ // https://astro.build/config
5
+ export default defineConfig({
6
+ integrations: [markdoc()],
7
+ });
@@ -0,0 +1,26 @@
1
+ import { defineMarkdocConfig } from '@astrojs/markdoc/config';
2
+
3
+ export default defineMarkdocConfig({
4
+ nodes: {
5
+ document: {
6
+ render: null,
7
+
8
+ // Defaults from `Markdoc.nodes.document`
9
+ children: [
10
+ 'heading',
11
+ 'paragraph',
12
+ 'image',
13
+ 'table',
14
+ 'tag',
15
+ 'fence',
16
+ 'blockquote',
17
+ 'comment',
18
+ 'list',
19
+ 'hr',
20
+ ],
21
+ attributes: {
22
+ frontmatter: { render: false },
23
+ },
24
+ }
25
+ }
26
+ })
@@ -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,9 @@
1
+ {
2
+ "name": "@test/markdoc-render-null",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "dependencies": {
6
+ "@astrojs/markdoc": "workspace:*",
7
+ "astro": "workspace:*"
8
+ }
9
+ }
@@ -0,0 +1,7 @@
1
+ ---
2
+ title: Post with render null
3
+ ---
4
+
5
+ ## Post with render null
6
+
7
+ This should render the contents inside a fragment!
@@ -0,0 +1,19 @@
1
+ ---
2
+ import { getEntryBySlug } from "astro:content";
3
+
4
+ const post = await getEntryBySlug('blog', 'render-null');
5
+ const { Content } = await post.render();
6
+ ---
7
+
8
+ <!DOCTYPE html>
9
+ <html lang="en">
10
+ <head>
11
+ <meta charset="UTF-8">
12
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
13
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
14
+ <title>Content</title>
15
+ </head>
16
+ <body>
17
+ <Content />
18
+ </body>
19
+ </html>
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from 'astro/config';
2
+ import markdoc from '@astrojs/markdoc';
3
+
4
+ // https://astro.build/config
5
+ export default defineConfig({
6
+ integrations: [markdoc()],
7
+ });
@@ -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,9 @@
1
+ {
2
+ "name": "@test/markdoc-render-simple",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "dependencies": {
6
+ "@astrojs/markdoc": "workspace:*",
7
+ "astro": "workspace:*"
8
+ }
9
+ }
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  import { getEntryBySlug } from "astro:content";
3
+
3
4
  const post = await getEntryBySlug('blog', 'simple');
4
5
  const { Content } = await post.render();
5
6
  ---
@@ -10,7 +11,7 @@ const { Content } = await post.render();
10
11
  <meta charset="UTF-8">
11
12
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
12
13
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
13
- <title>Content - Simple</title>
14
+ <title>Content</title>
14
15
  </head>
15
16
  <body>
16
17
  <Content />
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from 'astro/config';
2
+ import markdoc from '@astrojs/markdoc';
3
+
4
+ // https://astro.build/config
5
+ export default defineConfig({
6
+ integrations: [markdoc()],
7
+ });
@@ -0,0 +1,28 @@
1
+ import Code from './src/components/Code.astro';
2
+ import CustomMarquee from './src/components/CustomMarquee.astro';
3
+ import { defineMarkdocConfig } from '@astrojs/markdoc/config';
4
+
5
+ export default defineMarkdocConfig({
6
+ nodes: {
7
+ fence: {
8
+ render: Code,
9
+ attributes: {
10
+ language: { type: String },
11
+ content: { type: String },
12
+ },
13
+ },
14
+ },
15
+ tags: {
16
+ mq: {
17
+ render: CustomMarquee,
18
+ attributes: {
19
+ direction: {
20
+ type: String,
21
+ default: 'left',
22
+ matches: ['left', 'right', 'up', 'down'],
23
+ errorLevel: 'critical',
24
+ },
25
+ },
26
+ },
27
+ },
28
+ })
@@ -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,12 @@
1
+ {
2
+ "name": "@test/markdoc-render-with-components",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "dependencies": {
6
+ "@astrojs/markdoc": "workspace:*",
7
+ "astro": "workspace:*"
8
+ },
9
+ "devDependencies": {
10
+ "shiki": "^0.11.1"
11
+ }
12
+ }
@@ -1,7 +1,5 @@
1
1
  ---
2
2
  import { getEntryBySlug } from "astro:content";
3
- import Code from '../components/Code.astro';
4
- import CustomMarquee from '../components/CustomMarquee.astro';
5
3
 
6
4
  const post = await getEntryBySlug('blog', 'with-components');
7
5
  const { Content } = await post.render();
@@ -13,11 +11,9 @@ const { Content } = await post.render();
13
11
  <meta charset="UTF-8">
14
12
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
15
13
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
16
- <title>Content - with components</title>
14
+ <title>Content</title>
17
15
  </head>
18
16
  <body>
19
- <Content
20
- components={{ CustomMarquee, Code }}
21
- />
17
+ <Content />
22
18
  </body>
23
19
  </html>
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from 'astro/config';
2
+ import markdoc from '@astrojs/markdoc';
3
+
4
+ // https://astro.build/config
5
+ export default defineConfig({
6
+ integrations: [markdoc()],
7
+ });
@@ -0,0 +1,15 @@
1
+ import { defineMarkdocConfig } from '@astrojs/markdoc/config';
2
+
3
+ export default defineMarkdocConfig({
4
+ variables: {
5
+ countries: ['ES', 'JP'],
6
+ },
7
+ functions: {
8
+ includes: {
9
+ transform(parameters) {
10
+ const [array, value] = Object.values(parameters);
11
+ return Array.isArray(array) ? array.includes(value) : false;
12
+ },
13
+ },
14
+ },
15
+ })
@@ -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,9 @@
1
+ {
2
+ "name": "@test/markdoc-render-with-config",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "dependencies": {
6
+ "@astrojs/markdoc": "workspace:*",
7
+ "astro": "workspace:*"
8
+ }
9
+ }
@@ -7,3 +7,7 @@ title: Post with config
7
7
  {% if includes($countries, "EN") %} Hello {% /if %}
8
8
  {% if includes($countries, "ES") %} Hola {% /if %}
9
9
  {% if includes($countries, "JP") %} Konnichiwa {% /if %}
10
+
11
+ ## Runtime variables
12
+
13
+ {% $runtimeVariable %} {% #runtime-variable %}
@@ -11,9 +11,9 @@ const { Content } = await post.render();
11
11
  <meta charset="UTF-8">
12
12
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
13
13
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
14
- <title>Content - with config</title>
14
+ <title>Content</title>
15
15
  </head>
16
16
  <body>
17
- <Content />
17
+ <Content runtimeVariable="working!" />
18
18
  </body>
19
19
  </html>
@@ -0,0 +1,150 @@
1
+ import { parseHTML } from 'linkedom';
2
+ import { expect } from 'chai';
3
+ import { loadFixture } from '../../../astro/test/test-utils.js';
4
+
5
+ async function getFixture(name) {
6
+ return await loadFixture({
7
+ root: new URL(`./fixtures/${name}/`, import.meta.url),
8
+ });
9
+ }
10
+
11
+ describe('Markdoc - render', () => {
12
+ describe('dev', () => {
13
+ it('renders content - simple', async () => {
14
+ const fixture = await getFixture('render-simple');
15
+ const server = await fixture.startDevServer();
16
+
17
+ const res = await fixture.fetch('/');
18
+ const html = await res.text();
19
+
20
+ renderSimpleChecks(html);
21
+
22
+ await server.stop();
23
+ });
24
+
25
+ it('renders content - with config', async () => {
26
+ const fixture = await getFixture('render-with-config');
27
+ const server = await fixture.startDevServer();
28
+
29
+ const res = await fixture.fetch('/');
30
+ const html = await res.text();
31
+
32
+ renderConfigChecks(html);
33
+
34
+ await server.stop();
35
+ });
36
+
37
+ it('renders content - with components', async () => {
38
+ const fixture = await getFixture('render-with-components');
39
+ const server = await fixture.startDevServer();
40
+
41
+ const res = await fixture.fetch('/');
42
+ const html = await res.text();
43
+
44
+ renderComponentsChecks(html);
45
+
46
+ await server.stop();
47
+ });
48
+
49
+ it('renders content - with `render: null` in document', async () => {
50
+ const fixture = await getFixture('render-null');
51
+ const server = await fixture.startDevServer();
52
+
53
+ const res = await fixture.fetch('/');
54
+ const html = await res.text();
55
+
56
+ renderNullChecks(html);
57
+
58
+ await server.stop();
59
+ });
60
+ });
61
+
62
+ describe('build', () => {
63
+ it('renders content - simple', async () => {
64
+ const fixture = await getFixture('render-simple');
65
+ await fixture.build();
66
+
67
+ const html = await fixture.readFile('/index.html');
68
+
69
+ renderSimpleChecks(html);
70
+ });
71
+
72
+ it('renders content - with config', async () => {
73
+ const fixture = await getFixture('render-with-config');
74
+ await fixture.build();
75
+
76
+ const html = await fixture.readFile('/index.html');
77
+
78
+ renderConfigChecks(html);
79
+ });
80
+
81
+ it('renders content - with components', async () => {
82
+ const fixture = await getFixture('render-with-components');
83
+ await fixture.build();
84
+
85
+ const html = await fixture.readFile('/index.html');
86
+
87
+ renderComponentsChecks(html);
88
+ });
89
+
90
+ it('renders content - with `render: null` in document', async () => {
91
+ const fixture = await getFixture('render-null');
92
+ await fixture.build();
93
+
94
+ const html = await fixture.readFile('/index.html');
95
+
96
+ renderNullChecks(html);
97
+ });
98
+ });
99
+ });
100
+
101
+ /**
102
+ * @param {string} html
103
+ */
104
+ function renderNullChecks(html) {
105
+ const { document } = parseHTML(html);
106
+ const h2 = document.querySelector('h2');
107
+ expect(h2.textContent).to.equal('Post with render null');
108
+ expect(h2.parentElement?.tagName).to.equal('BODY');
109
+ }
110
+
111
+ /** @param {string} html */
112
+ function renderComponentsChecks(html) {
113
+ const { document } = parseHTML(html);
114
+ const h2 = document.querySelector('h2');
115
+ expect(h2.textContent).to.equal('Post with components');
116
+
117
+ // Renders custom shortcode component
118
+ const marquee = document.querySelector('marquee');
119
+ expect(marquee).to.not.be.null;
120
+ expect(marquee.hasAttribute('data-custom-marquee')).to.equal(true);
121
+
122
+ // Renders Astro Code component
123
+ const pre = document.querySelector('pre');
124
+ expect(pre).to.not.be.null;
125
+ expect(pre.className).to.equal('astro-code');
126
+ }
127
+
128
+ /** @param {string} html */
129
+ function renderConfigChecks(html) {
130
+ const { document } = parseHTML(html);
131
+ const h2 = document.querySelector('h2');
132
+ expect(h2.textContent).to.equal('Post with config');
133
+ const textContent = html;
134
+
135
+ expect(textContent).to.not.include('Hello');
136
+ expect(textContent).to.include('Hola');
137
+ expect(textContent).to.include(`Konnichiwa`);
138
+
139
+ const runtimeVariable = document.querySelector('#runtime-variable');
140
+ expect(runtimeVariable?.textContent?.trim()).to.equal('working!');
141
+ }
142
+
143
+ /** @param {string} html */
144
+ function renderSimpleChecks(html) {
145
+ const { document } = parseHTML(html);
146
+ const h2 = document.querySelector('h2');
147
+ expect(h2.textContent).to.equal('Simple post');
148
+ const p = document.querySelector('p');
149
+ expect(p.textContent).to.equal('This is a simple Markdoc post.');
150
+ }