From a11b62ee1f5d524b0ba942818525b623a6d6eb99 Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Tue, 6 Jun 2023 14:48:54 -0400 Subject: [PATCH] Fix: Markdoc type errors (#7311) * fix: config, prism, shiki exports * fix: type error for `render` property * chore: use `.ts` files in select tests for type checks * fix: type error on shiki() promise * chore: changeset --- .changeset/khaki-dolls-nail.md | 5 ++++ packages/integrations/markdoc/package.json | 28 +++++++++++++++++-- packages/integrations/markdoc/src/config.ts | 26 +++++++++++++---- .../integrations/markdoc/src/heading-ids.ts | 13 +++++---- packages/integrations/markdoc/src/index.ts | 8 ++++-- .../integrations/markdoc/src/load-config.ts | 8 +++--- .../{markdoc.config.mjs => markdoc.config.ts} | 0 .../{markdoc.config.mjs => markdoc.config.ts} | 0 8 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 .changeset/khaki-dolls-nail.md rename packages/integrations/markdoc/test/fixtures/render-with-components/{markdoc.config.mjs => markdoc.config.ts} (100%) rename packages/integrations/markdoc/test/fixtures/render-with-config/{markdoc.config.mjs => markdoc.config.ts} (100%) diff --git a/.changeset/khaki-dolls-nail.md b/.changeset/khaki-dolls-nail.md new file mode 100644 index 000000000..2d5328b06 --- /dev/null +++ b/.changeset/khaki-dolls-nail.md @@ -0,0 +1,5 @@ +--- +'@astrojs/markdoc': patch +--- + +Fix Markdoc type errors for `render` and `defineMarkdocConfig()` when using a TypeScript Markdoc config file. diff --git a/packages/integrations/markdoc/package.json b/packages/integrations/markdoc/package.json index 14fd1dbf3..9049c52b5 100644 --- a/packages/integrations/markdoc/package.json +++ b/packages/integrations/markdoc/package.json @@ -19,15 +19,37 @@ "bugs": "https://github.com/withastro/astro/issues", "homepage": "https://docs.astro.build/en/guides/integrations-guide/markdoc/", "exports": { - "./prism": "./dist/extensions/prism.js", - "./shiki": "./dist/extensions/shiki.js", + "./prism": { + "types": "./dist/extensions/prism.d.ts", + "node": "./dist/extensions/prism.js" + }, + "./shiki": { + "types": "./dist/extensions/shiki.d.ts", + "node": "./dist/extensions/shiki.js" + }, + "./config": { + "types": "./dist/config.d.ts", + "node": "./dist/config.js" + }, ".": "./dist/index.js", "./components": "./components/index.ts", "./runtime": "./dist/runtime.js", - "./config": "./dist/config.js", "./experimental-assets-config": "./dist/experimental-assets-config.js", "./package.json": "./package.json" }, + "typesVersions": { + "*": { + "config": [ + "./dist/config.d.ts" + ], + "prism": [ + "./dist/extensions/prism.d.ts" + ], + "shiki": [ + "./dist/extensions/shiki.d.ts" + ] + } + }, "files": [ "components", "dist", diff --git a/packages/integrations/markdoc/src/config.ts b/packages/integrations/markdoc/src/config.ts index 23ff744f7..2c2f2c677 100644 --- a/packages/integrations/markdoc/src/config.ts +++ b/packages/integrations/markdoc/src/config.ts @@ -1,12 +1,26 @@ -import type { ConfigType as MarkdocConfig } from '@markdoc/markdoc'; +import type { AstroInstance } from 'astro'; +import type { + ConfigType as MarkdocConfig, + Config, + NodeType, + Schema, + MaybePromise, +} from '@markdoc/markdoc'; import _Markdoc from '@markdoc/markdoc'; import { heading } from './heading-ids.js'; -export type AstroMarkdocConfig = Record> = - MarkdocConfig & { - ctx?: C; - extends?: ResolvedAstroMarkdocConfig[]; - }; +type Render = AstroInstance['default'] | string; + +export type AstroMarkdocConfig = Record> = Omit< + MarkdocConfig, + 'tags' | 'nodes' +> & + Partial<{ + tags: Record>; + nodes: Partial>>; + ctx: C; + extends: MaybePromise[]; + }>; export type ResolvedAstroMarkdocConfig = Omit; diff --git a/packages/integrations/markdoc/src/heading-ids.ts b/packages/integrations/markdoc/src/heading-ids.ts index 5e54af9a7..41773250e 100644 --- a/packages/integrations/markdoc/src/heading-ids.ts +++ b/packages/integrations/markdoc/src/heading-ids.ts @@ -1,6 +1,9 @@ -import Markdoc, { type RenderableTreeNode, type Schema } from '@markdoc/markdoc'; +import Markdoc, { + type RenderableTreeNode, + type Schema, + type Config as MarkdocConfig, +} from '@markdoc/markdoc'; import Slugger from 'github-slugger'; -import type { AstroMarkdocConfig } from './config.js'; import { getTextContent } from './runtime.js'; import { MarkdocError } from './utils.js'; @@ -19,9 +22,9 @@ function getSlug( return slug; } -type HeadingIdConfig = AstroMarkdocConfig<{ - headingSlugger: Slugger; -}>; +type HeadingIdConfig = MarkdocConfig & { + ctx: { headingSlugger: Slugger }; +}; /* Expose standalone node for users to import in their config. diff --git a/packages/integrations/markdoc/src/index.ts b/packages/integrations/markdoc/src/index.ts index c2d3e8734..781ae392e 100644 --- a/packages/integrations/markdoc/src/index.ts +++ b/packages/integrations/markdoc/src/index.ts @@ -1,5 +1,5 @@ /* eslint-disable no-console */ -import type { Node } from '@markdoc/markdoc'; +import type { Config as MarkdocConfig, Node } from '@markdoc/markdoc'; import Markdoc from '@markdoc/markdoc'; import type { AstroConfig, AstroIntegration, ContentEntryType, HookParameters } from 'astro'; import fs from 'node:fs'; @@ -85,7 +85,11 @@ export default function markdocIntegration(legacyConfig?: any): AstroIntegration const filePath = fileURLToPath(fileUrl); - const validationErrors = Markdoc.validate(ast, markdocConfig).filter((e) => { + const validationErrors = Markdoc.validate( + ast, + /* Raised generics issue with Markdoc core https://github.com/markdoc/markdoc/discussions/400 */ + markdocConfig as MarkdocConfig + ).filter((e) => { return ( // Ignore `variable-undefined` errors. // Variables can be configured at runtime, diff --git a/packages/integrations/markdoc/src/load-config.ts b/packages/integrations/markdoc/src/load-config.ts index 4a8b2f9cd..e04cc441b 100644 --- a/packages/integrations/markdoc/src/load-config.ts +++ b/packages/integrations/markdoc/src/load-config.ts @@ -1,8 +1,8 @@ -import type { Config as MarkdocConfig } from '@markdoc/markdoc'; import type { AstroConfig } from 'astro'; import { build as esbuild } from 'esbuild'; import * as fs from 'node:fs'; import { fileURLToPath } from 'node:url'; +import type { AstroMarkdocConfig } from './config.js'; const SUPPORTED_MARKDOC_CONFIG_FILES = [ 'markdoc.config.js', @@ -12,7 +12,7 @@ const SUPPORTED_MARKDOC_CONFIG_FILES = [ ]; export type MarkdocConfigResult = { - config: MarkdocConfig; + config: AstroMarkdocConfig; fileUrl: URL; }; @@ -33,7 +33,7 @@ export async function loadMarkdocConfig( markdocConfigUrl, astroConfig, }); - const config: MarkdocConfig = await loadConfigFromBundledFile(astroConfig.root, code); + const config: AstroMarkdocConfig = await loadConfigFromBundledFile(astroConfig.root, code); return { config, @@ -93,7 +93,7 @@ async function bundleConfigFile({ * 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 { +async function loadConfigFromBundledFile(root: URL, code: string): Promise { // 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); diff --git a/packages/integrations/markdoc/test/fixtures/render-with-components/markdoc.config.mjs b/packages/integrations/markdoc/test/fixtures/render-with-components/markdoc.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-with-components/markdoc.config.mjs rename to packages/integrations/markdoc/test/fixtures/render-with-components/markdoc.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render-with-config/markdoc.config.mjs b/packages/integrations/markdoc/test/fixtures/render-with-config/markdoc.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-with-config/markdoc.config.mjs rename to packages/integrations/markdoc/test/fixtures/render-with-config/markdoc.config.ts