summaryrefslogtreecommitdiff
path: root/packages/integrations/markdoc/src/load-config.ts
diff options
context:
space:
mode:
authorGravatar Ben Holmes <hey@bholmes.dev> 2023-03-27 18:04:37 -0400
committerGravatar GitHub <noreply@github.com> 2023-03-27 18:04:37 -0400
commit7c439868a3bc7d466418da9af669966014f3d9fe (patch)
treeaf8a8624a96ed9988f475beaed840df28d864646 /packages/integrations/markdoc/src/load-config.ts
parentc13d428a7804b5b9809dbea94a1b17c36714a1e1 (diff)
downloadastro-7c439868a3bc7d466418da9af669966014f3d9fe.tar.gz
astro-7c439868a3bc7d466418da9af669966014f3d9fe.tar.zst
astro-7c439868a3bc7d466418da9af669966014f3d9fe.zip
[Markdoc] New config format with runtime variable support! (#6653)
* deps: esbuild * feat: support direct component imports for render! * deps: add devalue back * refactor: remove unused components prop * refactor: load experimental assets config separately * fix: upate Content type def to support props * refactor: replace astro stub with inline data * feat: pass through viteId to getRenderMod * fix: add back $entry var with defaults convention * chore: remove unneeded validateRenderProps * chore: remove uneeded validateComponents * fix: remove userMarkdocConfig prop * chore: add helpful error for legacy config * deps: kleur * fix: add back `isCapitalized` * fix: log instead of throw to avoid scary stacktrace * chore: delete more old logic (nice) * chore: delete MORE unused utils * chore: comment on separate assets config * chore: remove console.log * chore: general code cleanup * test: new render config * docs: new README * fix: add expect-error on astro:assets * feat: add defineMarkdocConfig helper * docs: update example README * test: add runtime variable * chore: lint * chore: changeset * chore: add component import deletion * docs: add notes on Vite fork * fix: astro check * chore: add `.mts` to markdoc config formats
Diffstat (limited to 'packages/integrations/markdoc/src/load-config.ts')
-rw-r--r--packages/integrations/markdoc/src/load-config.ts102
1 files changed, 102 insertions, 0 deletions
diff --git a/packages/integrations/markdoc/src/load-config.ts b/packages/integrations/markdoc/src/load-config.ts
new file mode 100644
index 000000000..db36edf25
--- /dev/null
+++ b/packages/integrations/markdoc/src/load-config.ts
@@ -0,0 +1,102 @@
+import type { AstroConfig } from 'astro';
+import type { Config as MarkdocConfig } from '@markdoc/markdoc';
+import { build as esbuild } from 'esbuild';
+import { fileURLToPath } from 'node:url';
+import * as fs from 'node:fs';
+
+const SUPPORTED_MARKDOC_CONFIG_FILES = [
+ 'markdoc.config.js',
+ 'markdoc.config.mjs',
+ 'markdoc.config.mts',
+ 'markdoc.config.ts',
+];
+
+export async function loadMarkdocConfig(astroConfig: Pick<AstroConfig, 'root'>) {
+ let markdocConfigUrl: URL | undefined;
+ for (const filename of SUPPORTED_MARKDOC_CONFIG_FILES) {
+ const filePath = new URL(filename, astroConfig.root);
+ if (!fs.existsSync(filePath)) continue;
+
+ markdocConfigUrl = filePath;
+ break;
+ }
+ if (!markdocConfigUrl) return;
+
+ const { code, dependencies } = await bundleConfigFile({
+ markdocConfigUrl,
+ astroConfig,
+ });
+ const config: MarkdocConfig = await loadConfigFromBundledFile(astroConfig.root, code);
+
+ return {
+ config,
+ fileUrl: markdocConfigUrl,
+ };
+}
+
+/**
+ * Forked from Vite's `bundleConfigFile` function
+ * with added handling for `.astro` imports,
+ * and removed unused Deno patches.
+ * @see https://github.com/vitejs/vite/blob/main/packages/vite/src/node/config.ts#L961
+ */
+async function bundleConfigFile({
+ markdocConfigUrl,
+ astroConfig,
+}: {
+ markdocConfigUrl: URL;
+ astroConfig: Pick<AstroConfig, 'root'>;
+}): Promise<{ code: string; dependencies: string[] }> {
+ const result = await esbuild({
+ absWorkingDir: fileURLToPath(astroConfig.root),
+ entryPoints: [fileURLToPath(markdocConfigUrl)],
+ outfile: 'out.js',
+ write: false,
+ target: ['node16'],
+ platform: 'node',
+ packages: 'external',
+ bundle: true,
+ format: 'esm',
+ sourcemap: 'inline',
+ metafile: true,
+ plugins: [
+ {
+ name: 'stub-astro-imports',
+ setup(build) {
+ build.onResolve({ filter: /.*\.astro$/ }, () => {
+ return {
+ // Stub with an unused default export
+ path: 'data:text/javascript,export default true',
+ external: true,
+ };
+ });
+ },
+ },
+ ],
+ });
+ const { text } = result.outputFiles[0];
+ return {
+ code: text,
+ dependencies: result.metafile ? Object.keys(result.metafile.inputs) : [],
+ };
+}
+
+/**
+ * Forked from Vite config loader, replacing CJS-based path concat
+ * with ESM only
+ * @see https://github.com/vitejs/vite/blob/main/packages/vite/src/node/config.ts#L1074
+ */
+async function loadConfigFromBundledFile(root: URL, code: string): Promise<MarkdocConfig> {
+ // Write it to disk, load it with native Node ESM, then delete the file.
+ const tmpFileUrl = new URL(`markdoc.config.timestamp-${Date.now()}.mjs`, root);
+ fs.writeFileSync(tmpFileUrl, code);
+ try {
+ return (await import(tmpFileUrl.pathname)).default;
+ } finally {
+ try {
+ fs.unlinkSync(tmpFileUrl);
+ } catch {
+ // already removed if this function is called twice simultaneously
+ }
+ }
+}