@astrojs/markdoc 0.0.5 → 0.1.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.
- package/.turbo/turbo-build.log +5 -5
- package/CHANGELOG.md +47 -0
- package/README.md +110 -146
- package/components/Renderer.astro +8 -11
- package/components/TreeNode.ts +6 -23
- package/dist/config.d.ts +2 -0
- package/dist/config.js +6 -0
- package/dist/default-config.d.ts +5 -0
- package/dist/default-config.js +13 -0
- package/dist/experimental-assets-config.d.ts +2 -0
- package/dist/experimental-assets-config.js +25 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +43 -112
- package/dist/load-config.d.ts +14 -0
- package/dist/load-config.js +82 -0
- package/dist/utils.d.ts +0 -11
- package/dist/utils.js +1 -44
- package/package.json +8 -3
- package/src/config.ts +5 -0
- package/src/default-config.ts +18 -0
- package/src/experimental-assets-config.ts +29 -0
- package/src/index.ts +65 -143
- package/src/load-config.ts +102 -0
- package/src/utils.ts +0 -58
- package/template/content-module-types.d.ts +1 -3
- package/test/content-collections.test.js +24 -172
- package/test/fixtures/content-collections/package.json +0 -4
- package/test/fixtures/content-collections/src/content/blog/post-1.mdoc +7 -0
- package/test/fixtures/content-collections/src/content/blog/post-2.mdoc +7 -0
- package/test/fixtures/content-collections/src/content/blog/post-3.mdoc +7 -0
- package/test/fixtures/content-collections/src/pages/entry.json.js +1 -1
- package/test/fixtures/render-simple/astro.config.mjs +7 -0
- package/test/fixtures/render-simple/node_modules/.bin/astro +17 -0
- package/test/fixtures/render-simple/package.json +9 -0
- package/test/fixtures/{content-collections/src/pages/content-simple.astro → render-simple/src/pages/index.astro} +2 -1
- package/test/fixtures/render-with-components/astro.config.mjs +7 -0
- package/test/fixtures/render-with-components/markdoc.config.mjs +28 -0
- package/test/fixtures/render-with-components/node_modules/.bin/astro +17 -0
- package/test/fixtures/render-with-components/package.json +12 -0
- package/test/fixtures/{content-collections/src/pages/content-with-components.astro → render-with-components/src/pages/index.astro} +2 -6
- package/test/fixtures/render-with-config/astro.config.mjs +7 -0
- package/test/fixtures/render-with-config/markdoc.config.mjs +15 -0
- package/test/fixtures/render-with-config/node_modules/.bin/astro +17 -0
- package/test/fixtures/render-with-config/package.json +9 -0
- package/test/fixtures/{content-collections → render-with-config}/src/content/blog/with-config.mdoc +4 -0
- package/test/fixtures/{content-collections/src/pages/content-with-config.astro → render-with-config/src/pages/index.astro} +2 -2
- package/test/render.test.js +124 -0
- /package/test/fixtures/{content-collections → render-simple}/src/content/blog/simple.mdoc +0 -0
- /package/test/fixtures/{content-collections → render-with-components}/src/components/Code.astro +0 -0
- /package/test/fixtures/{content-collections → render-with-components}/src/components/CustomMarquee.astro +0 -0
- /package/test/fixtures/{content-collections → render-with-components}/src/content/blog/with-components.mdoc +0 -0
package/dist/index.js
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import Markdoc from "@markdoc/markdoc";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import {
|
|
5
|
-
getAstroConfigPath,
|
|
6
|
-
isValidUrl,
|
|
7
|
-
MarkdocError,
|
|
8
|
-
parseFrontmatter,
|
|
9
|
-
prependForwardSlash
|
|
10
|
-
} from "./utils.js";
|
|
4
|
+
import { isValidUrl, MarkdocError, parseFrontmatter, prependForwardSlash } from "./utils.js";
|
|
11
5
|
import { emitESMImage } from "astro/assets";
|
|
12
|
-
|
|
6
|
+
import { bold, red } from "kleur/colors";
|
|
7
|
+
import { applyDefaultConfig } from "./default-config.js";
|
|
8
|
+
import { loadMarkdocConfig } from "./load-config.js";
|
|
9
|
+
function markdocIntegration(legacyConfig) {
|
|
10
|
+
if (legacyConfig) {
|
|
11
|
+
console.log(
|
|
12
|
+
`${red(
|
|
13
|
+
bold("[Markdoc]")
|
|
14
|
+
)} Passing Markdoc config from your \`astro.config\` is no longer supported. Configuration should be exported from a \`markdoc.config.mjs\` file. See the configuration docs for more: https://docs.astro.build/en/guides/integrations-guide/markdoc/#configuration`
|
|
15
|
+
);
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
13
18
|
return {
|
|
14
19
|
name: "@astrojs/markdoc",
|
|
15
20
|
hooks: {
|
|
16
21
|
"astro:config:setup": async (params) => {
|
|
17
|
-
const {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
addContentEntryType
|
|
21
|
-
} = params;
|
|
22
|
-
updateConfig({
|
|
23
|
-
vite: {
|
|
24
|
-
plugins: [safeAssetsVirtualModulePlugin({ astroConfig })]
|
|
25
|
-
}
|
|
26
|
-
});
|
|
22
|
+
const { config: astroConfig, addContentEntryType } = params;
|
|
23
|
+
const configLoadResult = await loadMarkdocConfig(astroConfig);
|
|
24
|
+
const userMarkdocConfig = (configLoadResult == null ? void 0 : configLoadResult.config) ?? {};
|
|
27
25
|
function getEntryInfo({ fileUrl, contents }) {
|
|
28
26
|
const parsed = parseFrontmatter(contents, fileURLToPath(fileUrl));
|
|
29
27
|
return {
|
|
@@ -36,49 +34,45 @@ function markdocIntegration(userMarkdocConfig = {}) {
|
|
|
36
34
|
addContentEntryType({
|
|
37
35
|
extensions: [".mdoc"],
|
|
38
36
|
getEntryInfo,
|
|
39
|
-
async getRenderModule({ entry }) {
|
|
40
|
-
var _a;
|
|
41
|
-
validateRenderProperties(userMarkdocConfig, astroConfig);
|
|
37
|
+
async getRenderModule({ entry, viteId }) {
|
|
42
38
|
const ast = Markdoc.parse(entry.body);
|
|
43
39
|
const pluginContext = this;
|
|
44
|
-
const markdocConfig = {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
40
|
+
const markdocConfig = applyDefaultConfig(userMarkdocConfig, { entry });
|
|
41
|
+
const validationErrors = Markdoc.validate(ast, markdocConfig).filter((e) => {
|
|
42
|
+
return e.error.id !== "variable-undefined";
|
|
43
|
+
});
|
|
44
|
+
if (validationErrors.length) {
|
|
45
|
+
throw new MarkdocError({
|
|
46
|
+
message: [
|
|
47
|
+
`**${String(entry.collection)} \u2192 ${String(entry.id)}** failed to validate:`,
|
|
48
|
+
...validationErrors.map((e) => e.error.id)
|
|
49
|
+
].join("\n")
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (astroConfig.experimental.assets) {
|
|
52
53
|
await emitOptimizedImages(ast.children, {
|
|
53
54
|
astroConfig,
|
|
54
55
|
pluginContext,
|
|
55
56
|
filePath: entry._internal.filePath
|
|
56
57
|
});
|
|
57
|
-
markdocConfig.nodes ??= {};
|
|
58
|
-
markdocConfig.nodes.image = {
|
|
59
|
-
...Markdoc.nodes.image,
|
|
60
|
-
transform(node, config) {
|
|
61
|
-
const attributes = node.transformAttributes(config);
|
|
62
|
-
const children = node.transformChildren(config);
|
|
63
|
-
if (node.type === "image" && "__optimizedSrc" in node.attributes) {
|
|
64
|
-
const { __optimizedSrc, ...rest } = node.attributes;
|
|
65
|
-
return new Markdoc.Tag("Image", { ...rest, src: __optimizedSrc }, children);
|
|
66
|
-
} else {
|
|
67
|
-
return new Markdoc.Tag("img", attributes, children);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
58
|
}
|
|
72
|
-
const
|
|
73
|
-
return {
|
|
59
|
+
const code = {
|
|
74
60
|
code: `import { jsx as h } from 'astro/jsx-runtime';
|
|
61
|
+
import { applyDefaultConfig } from '@astrojs/markdoc/default-config';
|
|
75
62
|
import { Renderer } from '@astrojs/markdoc/components';
|
|
76
|
-
|
|
77
|
-
|
|
63
|
+
import * as entry from ${JSON.stringify(viteId + "?astroContent")};${configLoadResult ? `
|
|
64
|
+
import userConfig from ${JSON.stringify(configLoadResult.fileUrl.pathname)};` : ""}${astroConfig.experimental.assets ? `
|
|
65
|
+
import { experimentalAssetsConfig } from '@astrojs/markdoc/experimental-assets-config';` : ""}
|
|
66
|
+
const stringifiedAst = ${JSON.stringify(
|
|
67
|
+
/* Double stringify to encode *as* stringified JSON */
|
|
68
|
+
JSON.stringify(ast)
|
|
78
69
|
)};
|
|
79
|
-
export async function Content (
|
|
80
|
-
|
|
70
|
+
export async function Content (props) {
|
|
71
|
+
const config = applyDefaultConfig(${configLoadResult ? "{ ...userConfig, variables: { ...userConfig.variables, ...props } }" : "{ variables: props }"}, { entry });${astroConfig.experimental.assets ? `
|
|
72
|
+
config.nodes = { ...experimentalAssetsConfig.nodes, ...config.nodes };` : ""}
|
|
73
|
+
return h(Renderer, { stringifiedAst, config }); };`
|
|
81
74
|
};
|
|
75
|
+
return code;
|
|
82
76
|
},
|
|
83
77
|
contentModuleTypes: await fs.promises.readFile(
|
|
84
78
|
new URL("../template/content-module-types.d.ts", import.meta.url),
|
|
@@ -115,69 +109,6 @@ async function emitOptimizedImages(nodeChildren, ctx) {
|
|
|
115
109
|
function shouldOptimizeImage(src) {
|
|
116
110
|
return !isValidUrl(src) && !src.startsWith("/");
|
|
117
111
|
}
|
|
118
|
-
function validateRenderProperties(markdocConfig, astroConfig) {
|
|
119
|
-
const tags = markdocConfig.tags ?? {};
|
|
120
|
-
const nodes = markdocConfig.nodes ?? {};
|
|
121
|
-
for (const [name, config] of Object.entries(tags)) {
|
|
122
|
-
validateRenderProperty({ type: "tag", name, config, astroConfig });
|
|
123
|
-
}
|
|
124
|
-
for (const [name, config] of Object.entries(nodes)) {
|
|
125
|
-
validateRenderProperty({ type: "node", name, config, astroConfig });
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
function validateRenderProperty({
|
|
129
|
-
name,
|
|
130
|
-
config,
|
|
131
|
-
type,
|
|
132
|
-
astroConfig
|
|
133
|
-
}) {
|
|
134
|
-
if (typeof config.render === "string" && config.render.length === 0) {
|
|
135
|
-
throw new Error(
|
|
136
|
-
`Invalid ${type} configuration: ${JSON.stringify(
|
|
137
|
-
name
|
|
138
|
-
)}. The "render" property cannot be an empty string.`
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
if (typeof config.render === "string" && !isCapitalized(config.render)) {
|
|
142
|
-
const astroConfigPath = getAstroConfigPath(fs, fileURLToPath(astroConfig.root));
|
|
143
|
-
throw new MarkdocError({
|
|
144
|
-
message: `Invalid ${type} configuration: ${JSON.stringify(
|
|
145
|
-
name
|
|
146
|
-
)}. The "render" property must reference a capitalized component name.`,
|
|
147
|
-
hint: "If you want to render to an HTML element, see our docs on rendering Markdoc manually: https://docs.astro.build/en/guides/integrations-guide/markdoc/#render-markdoc-nodes--html-elements-as-astro-components",
|
|
148
|
-
location: astroConfigPath ? {
|
|
149
|
-
file: astroConfigPath
|
|
150
|
-
} : void 0
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
function isCapitalized(str) {
|
|
155
|
-
return str.length > 0 && str[0] === str[0].toUpperCase();
|
|
156
|
-
}
|
|
157
|
-
function safeAssetsVirtualModulePlugin({
|
|
158
|
-
astroConfig
|
|
159
|
-
}) {
|
|
160
|
-
const virtualModuleId = "astro:markdoc-assets";
|
|
161
|
-
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
162
|
-
return {
|
|
163
|
-
name: "astro:markdoc-safe-assets-virtual-module",
|
|
164
|
-
resolveId(id) {
|
|
165
|
-
if (id === virtualModuleId) {
|
|
166
|
-
return resolvedVirtualModuleId;
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
load(id) {
|
|
170
|
-
var _a;
|
|
171
|
-
if (id !== resolvedVirtualModuleId)
|
|
172
|
-
return;
|
|
173
|
-
if ((_a = astroConfig.experimental) == null ? void 0 : _a.assets) {
|
|
174
|
-
return `export { Image } from 'astro:assets';`;
|
|
175
|
-
} else {
|
|
176
|
-
return `export const Image = () => { throw new Error('Cannot use the Image component without the \`experimental.assets\` flag.'); }`;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
112
|
export {
|
|
182
113
|
markdocIntegration as default
|
|
183
114
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AstroConfig } from 'astro';
|
|
2
|
+
export declare function loadMarkdocConfig(astroConfig: Pick<AstroConfig, 'root'>): Promise<{
|
|
3
|
+
config: Readonly<Partial<{
|
|
4
|
+
nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Readonly<Partial<any>>, string>>>;
|
|
5
|
+
tags: Record<string, import("@markdoc/markdoc").Schema<Readonly<Partial<any>>, string>>;
|
|
6
|
+
variables: Record<string, any>;
|
|
7
|
+
functions: Record<string, import("@markdoc/markdoc").ConfigFunction>;
|
|
8
|
+
partials: Record<string, any>;
|
|
9
|
+
validation?: {
|
|
10
|
+
validateFunctions?: boolean | undefined;
|
|
11
|
+
} | undefined;
|
|
12
|
+
}>>;
|
|
13
|
+
fileUrl: URL;
|
|
14
|
+
} | undefined>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { build as esbuild } from "esbuild";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const SUPPORTED_MARKDOC_CONFIG_FILES = [
|
|
5
|
+
"markdoc.config.js",
|
|
6
|
+
"markdoc.config.mjs",
|
|
7
|
+
"markdoc.config.mts",
|
|
8
|
+
"markdoc.config.ts"
|
|
9
|
+
];
|
|
10
|
+
async function loadMarkdocConfig(astroConfig) {
|
|
11
|
+
let markdocConfigUrl;
|
|
12
|
+
for (const filename of SUPPORTED_MARKDOC_CONFIG_FILES) {
|
|
13
|
+
const filePath = new URL(filename, astroConfig.root);
|
|
14
|
+
if (!fs.existsSync(filePath))
|
|
15
|
+
continue;
|
|
16
|
+
markdocConfigUrl = filePath;
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
if (!markdocConfigUrl)
|
|
20
|
+
return;
|
|
21
|
+
const { code, dependencies } = await bundleConfigFile({
|
|
22
|
+
markdocConfigUrl,
|
|
23
|
+
astroConfig
|
|
24
|
+
});
|
|
25
|
+
const config = await loadConfigFromBundledFile(astroConfig.root, code);
|
|
26
|
+
return {
|
|
27
|
+
config,
|
|
28
|
+
fileUrl: markdocConfigUrl
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async function bundleConfigFile({
|
|
32
|
+
markdocConfigUrl,
|
|
33
|
+
astroConfig
|
|
34
|
+
}) {
|
|
35
|
+
const result = await esbuild({
|
|
36
|
+
absWorkingDir: fileURLToPath(astroConfig.root),
|
|
37
|
+
entryPoints: [fileURLToPath(markdocConfigUrl)],
|
|
38
|
+
outfile: "out.js",
|
|
39
|
+
write: false,
|
|
40
|
+
target: ["node16"],
|
|
41
|
+
platform: "node",
|
|
42
|
+
packages: "external",
|
|
43
|
+
bundle: true,
|
|
44
|
+
format: "esm",
|
|
45
|
+
sourcemap: "inline",
|
|
46
|
+
metafile: true,
|
|
47
|
+
plugins: [
|
|
48
|
+
{
|
|
49
|
+
name: "stub-astro-imports",
|
|
50
|
+
setup(build) {
|
|
51
|
+
build.onResolve({ filter: /.*\.astro$/ }, () => {
|
|
52
|
+
return {
|
|
53
|
+
// Stub with an unused default export
|
|
54
|
+
path: "data:text/javascript,export default true",
|
|
55
|
+
external: true
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
});
|
|
62
|
+
const { text } = result.outputFiles[0];
|
|
63
|
+
return {
|
|
64
|
+
code: text,
|
|
65
|
+
dependencies: result.metafile ? Object.keys(result.metafile.inputs) : []
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async function loadConfigFromBundledFile(root, code) {
|
|
69
|
+
const tmpFileUrl = new URL(`markdoc.config.timestamp-${Date.now()}.mjs`, root);
|
|
70
|
+
fs.writeFileSync(tmpFileUrl, code);
|
|
71
|
+
try {
|
|
72
|
+
return (await import(tmpFileUrl.pathname)).default;
|
|
73
|
+
} finally {
|
|
74
|
+
try {
|
|
75
|
+
fs.unlinkSync(tmpFileUrl);
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export {
|
|
81
|
+
loadMarkdocConfig
|
|
82
|
+
};
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import type { AstroInstance } from 'astro';
|
|
3
1
|
import matter from 'gray-matter';
|
|
4
|
-
import type fsMod from 'node:fs';
|
|
5
2
|
/**
|
|
6
3
|
* Match YAML exception handling from Astro core errors
|
|
7
4
|
* @see 'astro/src/core/errors.ts'
|
|
@@ -35,17 +32,9 @@ interface ErrorProperties {
|
|
|
35
32
|
stack?: string;
|
|
36
33
|
frame?: string;
|
|
37
34
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Matches `search` function used for resolving `astro.config` files.
|
|
40
|
-
* Used by Markdoc for error handling.
|
|
41
|
-
* @see 'astro/src/core/config/config.ts'
|
|
42
|
-
*/
|
|
43
|
-
export declare function getAstroConfigPath(fs: typeof fsMod, root: string): string | undefined;
|
|
44
35
|
/**
|
|
45
36
|
* @see 'astro/src/core/path.ts'
|
|
46
37
|
*/
|
|
47
38
|
export declare function prependForwardSlash(str: string): string;
|
|
48
|
-
export declare function validateComponentsProp(components: Record<string, AstroInstance['default']>): void;
|
|
49
|
-
export declare function isCapitalized(str: string): boolean;
|
|
50
39
|
export declare function isValidUrl(str: string): boolean;
|
|
51
40
|
export {};
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import z from "astro/zod";
|
|
2
1
|
import matter from "gray-matter";
|
|
3
|
-
import path from "node:path";
|
|
4
2
|
function parseFrontmatter(fileContents, filePath) {
|
|
5
3
|
try {
|
|
6
4
|
matter.clearCache();
|
|
@@ -43,47 +41,9 @@ class MarkdocError extends Error {
|
|
|
43
41
|
this.frame = frame;
|
|
44
42
|
}
|
|
45
43
|
}
|
|
46
|
-
function getAstroConfigPath(fs, root) {
|
|
47
|
-
const paths = [
|
|
48
|
-
"astro.config.mjs",
|
|
49
|
-
"astro.config.js",
|
|
50
|
-
"astro.config.ts",
|
|
51
|
-
"astro.config.mts",
|
|
52
|
-
"astro.config.cjs",
|
|
53
|
-
"astro.config.cts"
|
|
54
|
-
].map((p) => path.join(root, p));
|
|
55
|
-
for (const file of paths) {
|
|
56
|
-
if (fs.existsSync(file)) {
|
|
57
|
-
return file;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
44
|
function prependForwardSlash(str) {
|
|
62
45
|
return str[0] === "/" ? str : "/" + str;
|
|
63
46
|
}
|
|
64
|
-
function validateComponentsProp(components) {
|
|
65
|
-
try {
|
|
66
|
-
componentsPropValidator.parse(components);
|
|
67
|
-
} catch (e) {
|
|
68
|
-
throw new MarkdocError({
|
|
69
|
-
message: e instanceof z.ZodError ? e.issues[0].message : "Invalid `components` prop. Ensure you are passing an object of components to <Content />"
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
const componentsPropValidator = z.record(
|
|
74
|
-
z.string().min(1, "Invalid `components` prop. Component names cannot be empty!").refine(
|
|
75
|
-
(value) => isCapitalized(value),
|
|
76
|
-
(value) => ({
|
|
77
|
-
message: `Invalid \`components\` prop: ${JSON.stringify(
|
|
78
|
-
value
|
|
79
|
-
)}. Component name must be capitalized. If you want to render HTML elements as components, try using a Markdoc node (https://docs.astro.build/en/guides/integrations-guide/markdoc/#render-markdoc-nodes--html-elements-as-astro-components)`
|
|
80
|
-
})
|
|
81
|
-
),
|
|
82
|
-
z.any()
|
|
83
|
-
);
|
|
84
|
-
function isCapitalized(str) {
|
|
85
|
-
return str.length > 0 && str[0] === str[0].toUpperCase();
|
|
86
|
-
}
|
|
87
47
|
function isValidUrl(str) {
|
|
88
48
|
try {
|
|
89
49
|
new URL(str);
|
|
@@ -94,10 +54,7 @@ function isValidUrl(str) {
|
|
|
94
54
|
}
|
|
95
55
|
export {
|
|
96
56
|
MarkdocError,
|
|
97
|
-
getAstroConfigPath,
|
|
98
|
-
isCapitalized,
|
|
99
57
|
isValidUrl,
|
|
100
58
|
parseFrontmatter,
|
|
101
|
-
prependForwardSlash
|
|
102
|
-
validateComponentsProp
|
|
59
|
+
prependForwardSlash
|
|
103
60
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/markdoc",
|
|
3
3
|
"description": "Add support for Markdoc pages in your Astro site",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"author": "withastro",
|
|
@@ -21,21 +21,26 @@
|
|
|
21
21
|
"exports": {
|
|
22
22
|
".": "./dist/index.js",
|
|
23
23
|
"./components": "./components/index.ts",
|
|
24
|
+
"./default-config": "./dist/default-config.js",
|
|
25
|
+
"./config": "./dist/config.js",
|
|
26
|
+
"./experimental-assets-config": "./dist/experimental-assets-config.js",
|
|
24
27
|
"./package.json": "./package.json"
|
|
25
28
|
},
|
|
26
29
|
"dependencies": {
|
|
27
30
|
"@markdoc/markdoc": "^0.2.2",
|
|
31
|
+
"esbuild": "^0.17.12",
|
|
28
32
|
"gray-matter": "^4.0.3",
|
|
33
|
+
"kleur": "^4.1.5",
|
|
29
34
|
"zod": "^3.17.3"
|
|
30
35
|
},
|
|
31
36
|
"peerDependencies": {
|
|
32
|
-
"astro": "2.1.
|
|
37
|
+
"astro": "^2.1.8"
|
|
33
38
|
},
|
|
34
39
|
"devDependencies": {
|
|
35
|
-
"astro": "2.1.7",
|
|
36
40
|
"@types/chai": "^4.3.1",
|
|
37
41
|
"@types/html-escaper": "^3.0.0",
|
|
38
42
|
"@types/mocha": "^9.1.1",
|
|
43
|
+
"astro": "2.1.8",
|
|
39
44
|
"astro-scripts": "0.0.14",
|
|
40
45
|
"chai": "^4.3.6",
|
|
41
46
|
"devalue": "^4.2.0",
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ConfigType as MarkdocConfig } from '@markdoc/markdoc';
|
|
2
|
+
import type { ContentEntryModule } from 'astro';
|
|
3
|
+
|
|
4
|
+
export function applyDefaultConfig(
|
|
5
|
+
config: MarkdocConfig,
|
|
6
|
+
ctx: {
|
|
7
|
+
entry: ContentEntryModule;
|
|
8
|
+
}
|
|
9
|
+
): MarkdocConfig {
|
|
10
|
+
return {
|
|
11
|
+
...config,
|
|
12
|
+
variables: {
|
|
13
|
+
entry: ctx.entry,
|
|
14
|
+
...config.variables,
|
|
15
|
+
},
|
|
16
|
+
// TODO: heading ID calculation, Shiki syntax highlighting
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Config as MarkdocConfig } from '@markdoc/markdoc';
|
|
2
|
+
import Markdoc from '@markdoc/markdoc';
|
|
3
|
+
//@ts-expect-error Cannot find module 'astro:assets' or its corresponding type declarations.
|
|
4
|
+
import { Image } from 'astro:assets';
|
|
5
|
+
|
|
6
|
+
// Separate module to only import `astro:assets` when
|
|
7
|
+
// `experimental.assets` flag is set in a project.
|
|
8
|
+
// TODO: merge with `./default-config.ts` when `experimental.assets` is baselined.
|
|
9
|
+
export const experimentalAssetsConfig: MarkdocConfig = {
|
|
10
|
+
nodes: {
|
|
11
|
+
image: {
|
|
12
|
+
attributes: {
|
|
13
|
+
...Markdoc.nodes.image.attributes,
|
|
14
|
+
__optimizedSrc: { type: 'Object' },
|
|
15
|
+
},
|
|
16
|
+
transform(node, config) {
|
|
17
|
+
const attributes = node.transformAttributes(config);
|
|
18
|
+
const children = node.transformChildren(config);
|
|
19
|
+
|
|
20
|
+
if (node.type === 'image' && '__optimizedSrc' in node.attributes) {
|
|
21
|
+
const { __optimizedSrc, ...rest } = node.attributes;
|
|
22
|
+
return new Markdoc.Tag(Image, { ...rest, src: __optimizedSrc }, children);
|
|
23
|
+
} else {
|
|
24
|
+
return new Markdoc.Tag('img', attributes, children);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|