@astrojs/markdoc 0.12.4 → 0.12.5

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,6 +1,6 @@
1
1
  ---
2
2
  //! astro-head-inject
3
- import type { Config } from '@markdoc/markdoc';
3
+ import type { Config, RenderableTreeNodes } from '@markdoc/markdoc';
4
4
  import Markdoc from '@markdoc/markdoc';
5
5
  import { ComponentNode, createTreeNode } from './TreeNode.js';
6
6
 
@@ -12,13 +12,12 @@ type Props = {
12
12
  const { stringifiedAst, config } = Astro.props as Props;
13
13
 
14
14
  const ast = Markdoc.Ast.fromJSON(stringifiedAst);
15
- const content = await Markdoc.transform(ast, config);
15
+ // The AST may be an array, and `transform` has overloads for arrays and non-array cases,
16
+ // However TypeScript seems to struggle to combine both overloads into a single signature.
17
+ // Also, `transform` returns a promise here but the types don't reflect that.
18
+ // @ts-expect-error
19
+ const content = (await Markdoc.transform(ast, config)) as RenderableTreeNodes;
20
+ const treeNode = await createTreeNode(content);
16
21
  ---
17
22
 
18
- {
19
- Array.isArray(content) ? (
20
- content.map(async (c) => <ComponentNode treeNode={await createTreeNode(c)} />)
21
- ) : (
22
- <ComponentNode treeNode={await createTreeNode(content)} />
23
- )
24
- }
23
+ <ComponentNode treeNode={treeNode} />
@@ -1,6 +1,6 @@
1
- import type { RenderableTreeNode } from '@markdoc/markdoc';
1
+ import type { RenderableTreeNodes } from '@markdoc/markdoc';
2
2
  import Markdoc from '@markdoc/markdoc';
3
- import type { AstroInstance } from 'astro';
3
+ import type { AstroInstance, SSRResult } from 'astro';
4
4
  import type { HTMLString } from 'astro/runtime/server/index.js';
5
5
  import {
6
6
  createComponent,
@@ -15,6 +15,9 @@ import {
15
15
  } from 'astro/runtime/server/index.js';
16
16
 
17
17
  export type TreeNode =
18
+ // Markdoc `if` tag often returns an array of nodes in the AST, which gets translated
19
+ // here as an array of `TreeNode`s, which we'll render all without a wrapper.
20
+ | TreeNode[]
18
21
  | {
19
22
  type: 'text';
20
23
  content: string | HTMLString;
@@ -35,75 +38,86 @@ export type TreeNode =
35
38
  children: TreeNode[];
36
39
  };
37
40
 
38
- export const ComponentNode = createComponent({
39
- factory(result: any, { treeNode }: { treeNode: TreeNode }) {
40
- if (treeNode.type === 'text') return render`${treeNode.content}`;
41
-
42
- const slots = {
43
- default: () =>
44
- render`${treeNode.children.map((child) =>
45
- renderComponent(result, 'ComponentNode', ComponentNode, { treeNode: child }),
46
- )}`,
47
- };
48
- if (treeNode.type === 'component') {
49
- let styles = '',
50
- links = '',
51
- scripts = '';
52
- if (Array.isArray(treeNode.collectedStyles)) {
53
- styles = treeNode.collectedStyles
54
- .map((style: any) =>
55
- renderUniqueStylesheet(result, {
56
- type: 'inline',
57
- content: style,
58
- }),
59
- )
60
- .join('');
61
- }
62
- if (Array.isArray(treeNode.collectedLinks)) {
63
- links = treeNode.collectedLinks
64
- .map((link: any) => {
65
- return renderUniqueStylesheet(result, {
66
- type: 'external',
67
- src: link[0] === '/' ? link : '/' + link,
68
- });
69
- })
70
- .join('');
71
- }
72
- if (Array.isArray(treeNode.collectedScripts)) {
73
- scripts = treeNode.collectedScripts
74
- .map((script: any) => renderScriptElement(script))
75
- .join('');
76
- }
77
-
78
- const head = unescapeHTML(styles + links + scripts);
79
-
80
- let headAndContent = createHeadAndContent(
81
- head,
82
- renderTemplate`${renderComponent(
83
- result,
84
- treeNode.component.name,
85
- treeNode.component,
86
- treeNode.props,
87
- slots,
88
- )}`,
89
- );
90
-
91
- // Let the runtime know that this component is being used.
92
- result._metadata.propagators.add({
93
- init() {
94
- return headAndContent;
95
- },
96
- });
97
-
98
- return headAndContent;
41
+ function renderTreeNodeToFactoryResult(result: SSRResult, treeNode: TreeNode) {
42
+ if (Array.isArray(treeNode)) {
43
+ return Promise.all(treeNode.map((node) => renderTreeNodeToFactoryResult(result, node)));
44
+ }
45
+
46
+ if (treeNode.type === 'text') return render`${treeNode.content}`;
47
+
48
+ const slots = {
49
+ default: () =>
50
+ render`${treeNode.children.map((child) =>
51
+ renderComponent(result, 'ComponentNode', ComponentNode, { treeNode: child }),
52
+ )}`,
53
+ };
54
+ if (treeNode.type === 'component') {
55
+ let styles = '',
56
+ links = '',
57
+ scripts = '';
58
+ if (Array.isArray(treeNode.collectedStyles)) {
59
+ styles = treeNode.collectedStyles
60
+ .map((style: any) =>
61
+ renderUniqueStylesheet(result, {
62
+ type: 'inline',
63
+ content: style,
64
+ }),
65
+ )
66
+ .join('');
67
+ }
68
+ if (Array.isArray(treeNode.collectedLinks)) {
69
+ links = treeNode.collectedLinks
70
+ .map((link: any) => {
71
+ return renderUniqueStylesheet(result, {
72
+ type: 'external',
73
+ src: link[0] === '/' ? link : '/' + link,
74
+ });
75
+ })
76
+ .join('');
99
77
  }
100
- return renderComponent(result, treeNode.tag, treeNode.tag, treeNode.attributes, slots);
78
+ if (Array.isArray(treeNode.collectedScripts)) {
79
+ scripts = treeNode.collectedScripts
80
+ .map((script: any) => renderScriptElement(script))
81
+ .join('');
82
+ }
83
+
84
+ const head = unescapeHTML(styles + links + scripts);
85
+
86
+ let headAndContent = createHeadAndContent(
87
+ head,
88
+ renderTemplate`${renderComponent(
89
+ result,
90
+ treeNode.component.name,
91
+ treeNode.component,
92
+ treeNode.props,
93
+ slots,
94
+ )}`,
95
+ );
96
+
97
+ // Let the runtime know that this component is being used.
98
+ // @ts-expect-error Astro only uses `init()` so specify it only (plus `_metadata` is internal)
99
+ result._metadata.propagators.add({
100
+ init() {
101
+ return headAndContent;
102
+ },
103
+ });
104
+
105
+ return headAndContent;
106
+ }
107
+ return renderComponent(result, treeNode.tag, treeNode.tag, treeNode.attributes, slots);
108
+ }
109
+
110
+ export const ComponentNode = createComponent({
111
+ factory(result: SSRResult, { treeNode }: { treeNode: TreeNode | TreeNode[] }) {
112
+ return renderTreeNodeToFactoryResult(result, treeNode);
101
113
  },
102
114
  propagation: 'self',
103
115
  });
104
116
 
105
- export async function createTreeNode(node: RenderableTreeNode): Promise<TreeNode> {
106
- if (isHTMLString(node)) {
117
+ export async function createTreeNode(node: RenderableTreeNodes): Promise<TreeNode> {
118
+ if (Array.isArray(node)) {
119
+ return Promise.all(node.map((child) => createTreeNode(child)));
120
+ } else if (isHTMLString(node)) {
107
121
  return { type: 'text', content: node as HTMLString };
108
122
  } else if (typeof node === 'string' || typeof node === 'number') {
109
123
  return { type: 'text', content: String(node) };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@astrojs/markdoc",
3
3
  "description": "Add support for Markdoc in your Astro site",
4
- "version": "0.12.4",
4
+ "version": "0.12.5",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "withastro",
@@ -59,7 +59,7 @@
59
59
  "@markdoc/markdoc": "^0.4.0",
60
60
  "esbuild": "^0.21.5",
61
61
  "github-slugger": "^2.0.0",
62
- "htmlparser2": "^9.1.0",
62
+ "htmlparser2": "^10.0.0",
63
63
  "@astrojs/internal-helpers": "0.4.2",
64
64
  "@astrojs/markdown-remark": "6.0.1",
65
65
  "@astrojs/prism": "3.2.0"
@@ -72,7 +72,7 @@
72
72
  "devalue": "^5.1.1",
73
73
  "linkedom": "^0.18.5",
74
74
  "vite": "^6.0.5",
75
- "astro": "5.1.1",
75
+ "astro": "5.1.5",
76
76
  "astro-scripts": "0.0.14"
77
77
  },
78
78
  "engines": {