summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Juan Martín Seery <me@juanm04.com> 2022-04-11 20:01:12 -0300
committerGravatar GitHub <noreply@github.com> 2022-04-11 16:01:12 -0700
commitb835e285defb4f31fc5ac1039c7f607c07f3c00b (patch)
tree71e4ba696d06e25fd6e42b556a384adf7e2d1a53
parent11766acec914ffc2639dfb228468ebab37de746d (diff)
downloadastro-b835e285defb4f31fc5ac1039c7f607c07f3c00b.tar.gz
astro-b835e285defb4f31fc5ac1039c7f607c07f3c00b.tar.zst
astro-b835e285defb4f31fc5ac1039c7f607c07f3c00b.zip
feat: markdown config typechecking (#2970)
* Added schemas to markdown plugin * Added new schemas to main package * Changesets * typeraw * Explaination about the weird type hack * Added markdown.mode to config * Added comment * Formatted * Moved validation to `astro` and added RemarkPlugin ad RehypePlugin * Removed the ability to have a custom markdown renderer internally * Fixed plugin type * Removed unused renderMarkdownWithFrontmatter * Added missing dependency * Dynamically import astro markdown * Cache import
-rw-r--r--.changeset/forty-plants-hope.md5
-rw-r--r--.changeset/small-months-speak.md5
-rw-r--r--packages/astro/package.json2
-rw-r--r--packages/astro/src/@types/astro.ts30
-rw-r--r--packages/astro/src/core/app/index.ts2
-rw-r--r--packages/astro/src/core/app/types.ts6
-rw-r--r--packages/astro/src/core/build/generate.ts3
-rw-r--r--packages/astro/src/core/build/vite-plugin-ssr.ts5
-rw-r--r--packages/astro/src/core/config.ts49
-rw-r--r--packages/astro/src/core/render/core.ts9
-rw-r--r--packages/astro/src/core/render/dev/index.ts3
-rw-r--r--packages/astro/src/core/render/result.ts46
-rw-r--r--packages/astro/src/vite-plugin-markdown/index.ts5
-rw-r--r--packages/markdown/remark/package.json4
-rw-r--r--packages/markdown/remark/src/index.ts28
-rw-r--r--packages/markdown/remark/src/load-plugins.ts5
-rw-r--r--packages/markdown/remark/src/remark-shiki.ts31
-rw-r--r--packages/markdown/remark/src/types.ts40
-rw-r--r--pnpm-lock.yaml13
19 files changed, 150 insertions, 141 deletions
diff --git a/.changeset/forty-plants-hope.md b/.changeset/forty-plants-hope.md
new file mode 100644
index 000000000..74da4d6b3
--- /dev/null
+++ b/.changeset/forty-plants-hope.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/markdown-remark': patch
+---
+
+Improved type checking
diff --git a/.changeset/small-months-speak.md b/.changeset/small-months-speak.md
new file mode 100644
index 000000000..c7626c39e
--- /dev/null
+++ b/.changeset/small-months-speak.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Improved markdown config type checking
diff --git a/packages/astro/package.json b/packages/astro/package.json
index 4997f3e33..3436ac823 100644
--- a/packages/astro/package.json
+++ b/packages/astro/package.json
@@ -100,6 +100,7 @@
"execa": "^6.1.0",
"fast-glob": "^3.2.11",
"fast-xml-parser": "^4.0.7",
+ "gray-matter": "^4.0.3",
"html-entities": "^2.3.3",
"html-escaper": "^3.0.3",
"htmlparser2": "^7.2.0",
@@ -156,6 +157,7 @@
"@types/resolve": "^1.20.1",
"@types/rimraf": "^3.0.2",
"@types/send": "^0.17.1",
+ "@types/unist": "^2.0.6",
"@types/yargs-parser": "^21.0.0",
"astro-scripts": "workspace:*",
"chai": "^4.3.6",
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index a8b76324e..bd45f5108 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -2,7 +2,7 @@ import type { AddressInfo } from 'net';
import type * as babel from '@babel/core';
import type * as vite from 'vite';
import { z } from 'zod';
-import type { ShikiConfig, Plugin } from '@astrojs/markdown-remark';
+import type { ShikiConfig, RemarkPlugins, RehypePlugins } from '@astrojs/markdown-remark';
import type { AstroConfigSchema } from '../core/config';
import type { AstroComponentFactory, Metadata } from '../runtime/server';
import type { ViteConfigWithSSR } from '../core/create-vite';
@@ -483,12 +483,22 @@ export interface AstroUserConfig {
/**
* @docs
+ * @name markdown.mode
+ * @type {'md' | 'mdx'}
+ * @default `mdx`
+ * @description
+ * Control wheater to allow components inside markdown files ('mdx') or not ('md').
+ */
+ mode?: 'md' | 'mdx';
+
+ /**
+ * @docs
* @name markdown.shikiConfig
- * @type {ShikiConfig}
+ * @typeraw {Partial<ShikiConfig>}
* @description
* Shiki configuration options. See [the markdown configuration docs](https://docs.astro.build/en/guides/markdown-content/#shiki-configuration) for usage.
*/
- shikiConfig?: ShikiConfig;
+ shikiConfig?: Partial<ShikiConfig>;
/**
* @docs
@@ -515,7 +525,7 @@ export interface AstroUserConfig {
/**
* @docs
* @name markdown.remarkPlugins
- * @type {Plugin[]}
+ * @type {RemarkPlugins}
* @description
* Pass a custom [Remark](https://github.com/remarkjs/remark) plugin to customize how your Markdown is built.
*
@@ -530,11 +540,11 @@ export interface AstroUserConfig {
* };
* ```
*/
- remarkPlugins?: Plugin[];
+ remarkPlugins?: RemarkPlugins;
/**
* @docs
* @name markdown.rehypePlugins
- * @type {Plugin[]}
+ * @type {RehypePlugins}
* @description
* Pass a custom [Rehype](https://github.com/remarkjs/remark-rehype) plugin to customize how your Markdown is built.
*
@@ -549,7 +559,7 @@ export interface AstroUserConfig {
* };
* ```
*/
- rehypePlugins?: Plugin[];
+ rehypePlugins?: RehypePlugins;
};
/**
@@ -757,12 +767,6 @@ export interface ManifestData {
routes: RouteData[];
}
-export type MarkdownRenderOptions = [string | MarkdownParser, Record<string, any>];
-export type MarkdownParser = (
- contents: string,
- options?: Record<string, any>
-) => MarkdownParserResponse | PromiseLike<MarkdownParserResponse>;
-
export interface MarkdownParserResponse {
frontmatter: {
[key: string]: any;
diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts
index 81e19f914..8f5113ca9 100644
--- a/packages/astro/src/core/app/index.ts
+++ b/packages/astro/src/core/app/index.ts
@@ -82,7 +82,7 @@ export class App {
legacyBuild: false,
links,
logging: this.#logging,
- markdownRender: manifest.markdown.render,
+ markdown: manifest.markdown,
mod,
origin: url.origin,
pathname: url.pathname,
diff --git a/packages/astro/src/core/app/types.ts b/packages/astro/src/core/app/types.ts
index 27af8b665..95ccfeba1 100644
--- a/packages/astro/src/core/app/types.ts
+++ b/packages/astro/src/core/app/types.ts
@@ -1,10 +1,10 @@
import type {
RouteData,
SerializedRouteData,
- MarkdownRenderOptions,
ComponentInstance,
SSRLoadedRenderer,
} from '../../@types/astro';
+import type { MarkdownRenderingOptions } from '@astrojs/markdown-remark';
export type ComponentPath = string;
@@ -22,9 +22,7 @@ export type SerializedRouteInfo = Omit<RouteInfo, 'routeData'> & {
export interface SSRManifest {
routes: RouteInfo[];
site?: string;
- markdown: {
- render: MarkdownRenderOptions;
- };
+ markdown: MarkdownRenderingOptions;
pageMap: Map<ComponentPath, ComponentInstance>;
renderers: SSRLoadedRenderer[];
entryModules: Record<string, string>;
diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts
index 974e2acd6..b1c03465b 100644
--- a/packages/astro/src/core/build/generate.ts
+++ b/packages/astro/src/core/build/generate.ts
@@ -1,4 +1,3 @@
-import astroRemark from '@astrojs/markdown-remark';
import fs from 'fs';
import { bgGreen, black, cyan, dim, green, magenta } from 'kleur/colors';
import npath from 'path';
@@ -197,7 +196,7 @@ async function generatePath(
legacyBuild: false,
links,
logging,
- markdownRender: [astroRemark, astroConfig.markdown],
+ markdown: astroConfig.markdown,
mod,
origin,
pathname,
diff --git a/packages/astro/src/core/build/vite-plugin-ssr.ts b/packages/astro/src/core/build/vite-plugin-ssr.ts
index c6e21b83a..3e7257f02 100644
--- a/packages/astro/src/core/build/vite-plugin-ssr.ts
+++ b/packages/astro/src/core/build/vite-plugin-ssr.ts
@@ -1,4 +1,3 @@
-import astroRemark from '@astrojs/markdown-remark';
import type { Plugin as VitePlugin } from 'vite';
import type { BuildInternals } from './internal.js';
import type { AstroAdapter } from '../../@types/astro';
@@ -110,9 +109,7 @@ function buildManifest(opts: StaticBuildOptions, internals: BuildInternals): Ser
const ssrManifest: SerializedSSRManifest = {
routes,
site: astroConfig.site,
- markdown: {
- render: [astroRemark, astroConfig.markdown],
- },
+ markdown: astroConfig.markdown,
pageMap: null as any,
renderers: [],
entryModules,
diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts
index a3350f134..e127131c5 100644
--- a/packages/astro/src/core/config.ts
+++ b/packages/astro/src/core/config.ts
@@ -1,11 +1,14 @@
import type { AstroConfig, AstroUserConfig, CLIFlags } from '../@types/astro';
import type { Arguments as Flags } from 'yargs-parser';
import type * as Postcss from 'postcss';
+import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki';
+import type { RemarkPlugin, RehypePlugin } from '@astrojs/markdown-remark';
import * as colors from 'kleur/colors';
import path from 'path';
import { pathToFileURL, fileURLToPath } from 'url';
import { mergeConfig as mergeViteConfig } from 'vite';
+import { BUNDLED_THEMES } from 'shiki';
import { z } from 'zod';
import load, { ProloadError } from '@proload/core';
import loadTypeScript from '@proload/plugin-tsm';
@@ -142,24 +145,42 @@ export const AstroConfigSchema = z.object({
.default({}),
markdown: z
.object({
- drafts: z.boolean().optional().default(false),
- mode: z
- .union([z.literal('md'), z.literal('mdx')])
- .optional()
- // NOTE: "mdx" allows us to parse/compile Astro components in markdown.
- // TODO: This should probably be updated to something more like "md" | "astro"
- .default('mdx'),
+ // NOTE: "mdx" allows us to parse/compile Astro components in markdown.
+ // TODO: This should probably be updated to something more like "md" | "astro"
+ mode: z.enum(['md', 'mdx']).default('mdx'),
+ drafts: z.boolean().default(false),
syntaxHighlight: z
.union([z.literal('shiki'), z.literal('prism'), z.literal(false)])
- .optional()
.default('shiki'),
- // TODO: add better type checking
- shikiConfig: z.any().optional().default({}),
- remarkPlugins: z.array(z.any()).optional().default([]),
- rehypePlugins: z.array(z.any()).optional().default([]),
+ shikiConfig: z
+ .object({
+ langs: z.custom<ILanguageRegistration>().array().default([]),
+ theme: z
+ .enum(BUNDLED_THEMES as [Theme, ...Theme[]])
+ .or(z.custom<IThemeRegistration>())
+ .default('github-dark'),
+ wrap: z.boolean().or(z.null()).default(false),
+ })
+ .default({}),
+ remarkPlugins: z
+ .union([
+ z.string(),
+ z.tuple([z.string(), z.any()]),
+ z.custom<RemarkPlugin>((data) => typeof data === 'function'),
+ z.tuple([z.custom<RemarkPlugin>((data) => typeof data === 'function'), z.any()]),
+ ])
+ .array()
+ .default([]),
+ rehypePlugins: z
+ .union([
+ z.string(),
+ z.tuple([z.string(), z.any()]),
+ z.custom<RehypePlugin>((data) => typeof data === 'function'),
+ z.tuple([z.custom<RehypePlugin>((data) => typeof data === 'function'), z.any()]),
+ ])
+ .array()
+ .default([]),
})
- .passthrough()
- .optional()
.default({}),
vite: z.any().optional().default({}),
experimental: z
diff --git a/packages/astro/src/core/render/core.ts b/packages/astro/src/core/render/core.ts
index 1be4cb0c2..59ae6f010 100644
--- a/packages/astro/src/core/render/core.ts
+++ b/packages/astro/src/core/render/core.ts
@@ -1,13 +1,12 @@
import type {
ComponentInstance,
- EndpointHandler,
- MarkdownRenderOptions,
Params,
Props,
SSRLoadedRenderer,
RouteData,
SSRElement,
} from '../../@types/astro';
+import type { MarkdownRenderingOptions } from '@astrojs/markdown-remark';
import type { LogOptions } from '../logger/core.js';
import { renderHead, renderPage } from '../../runtime/server/index.js';
@@ -70,7 +69,7 @@ export interface RenderOptions {
legacyBuild: boolean;
logging: LogOptions;
links: Set<SSRElement>;
- markdownRender: MarkdownRenderOptions;
+ markdown: MarkdownRenderingOptions;
mod: ComponentInstance;
origin: string;
pathname: string;
@@ -92,7 +91,7 @@ export async function render(
links,
logging,
origin,
- markdownRender,
+ markdown,
mod,
pathname,
scripts,
@@ -132,7 +131,7 @@ export async function render(
legacyBuild,
links,
logging,
- markdownRender,
+ markdown,
origin,
params,
pathname,
diff --git a/packages/astro/src/core/render/dev/index.ts b/packages/astro/src/core/render/dev/index.ts
index 39e3ad552..f245bc31a 100644
--- a/packages/astro/src/core/render/dev/index.ts
+++ b/packages/astro/src/core/render/dev/index.ts
@@ -1,4 +1,3 @@
-import astroRemark from '@astrojs/markdown-remark';
import { fileURLToPath } from 'url';
import type * as vite from 'vite';
import type {
@@ -164,7 +163,7 @@ export async function render(
legacyBuild: isLegacyBuild,
links,
logging,
- markdownRender: [astroRemark, astroConfig.markdown],
+ markdown: astroConfig.markdown,
mod,
origin,
pathname,
diff --git a/packages/astro/src/core/render/result.ts b/packages/astro/src/core/render/result.ts
index 241807a1f..8fd856084 100644
--- a/packages/astro/src/core/render/result.ts
+++ b/packages/astro/src/core/render/result.ts
@@ -2,13 +2,12 @@ import { bold } from 'kleur/colors';
import type {
AstroGlobal,
AstroGlobalPartial,
- MarkdownParser,
- MarkdownRenderOptions,
Params,
SSRElement,
SSRLoadedRenderer,
SSRResult,
} from '../../@types/astro';
+import type { MarkdownRenderingOptions } from '@astrojs/markdown-remark';
import { renderSlot } from '../../runtime/server/index.js';
import { LogOptions, warn } from '../logger/core.js';
import { createCanonicalURL, isCSSRequest } from './util.js';
@@ -26,7 +25,7 @@ export interface CreateResultArgs {
legacyBuild: boolean;
logging: LogOptions;
origin: string;
- markdownRender: MarkdownRenderOptions;
+ markdown: MarkdownRenderingOptions;
params: Params;
pathname: string;
renderers: SSRLoadedRenderer[];
@@ -99,8 +98,10 @@ class Slots {
}
}
+let renderMarkdown: any = null;
+
export function createResult(args: CreateResultArgs): SSRResult {
- const { legacyBuild, markdownRender, params, pathname, renderers, request, resolve, site } = args;
+ const { legacyBuild, markdown, params, pathname, renderers, request, resolve, site } = args;
const url = new URL(request.url);
const canonicalURL = createCanonicalURL('.' + pathname, site ?? url.origin);
@@ -179,31 +180,22 @@ ${extra}`
// Ensure this API is not exposed to users
enumerable: false,
writable: false,
- // TODO: remove 1. markdown parser logic 2. update MarkdownRenderOptions to take a function only
- // <Markdown> also needs the same `astroConfig.markdownOptions.render` as `.md` pages
- value: async function (content: string, opts: any) {
- let [mdRender, renderOpts] = markdownRender;
- let parser: MarkdownParser | null = null;
- //let renderOpts = {};
- if (Array.isArray(mdRender)) {
- renderOpts = mdRender[1];
- mdRender = mdRender[0];
- }
- // ['rehype-toc', opts]
- if (typeof mdRender === 'string') {
- const mod: { default: MarkdownParser } = await import(mdRender);
- parser = mod.default;
+ // TODO: Remove this hole "Deno" logic once our plugin gets Deno support
+ value: async function (content: string, opts: MarkdownRenderingOptions) {
+ // @ts-ignore
+ if (typeof Deno !== 'undefined') {
+ throw new Error('Markdown is not supported in Deno SSR');
}
- // [import('rehype-toc'), opts]
- else if (mdRender instanceof Promise) {
- const mod: { default: MarkdownParser } = await mdRender;
- parser = mod.default;
- } else if (typeof mdRender === 'function') {
- parser = mdRender;
- } else {
- throw new Error('No Markdown parser found.');
+
+ if (!renderMarkdown) {
+ // The package is saved in this variable because Vite is too smart
+ // and will try to inline it in buildtime
+ let astroRemark = '@astrojs/markdown-remark';
+
+ renderMarkdown = (await import(astroRemark)).renderMarkdown;
}
- const { code } = await parser(content, { ...renderOpts, ...(opts ?? {}) });
+
+ const { code } = await renderMarkdown(content, { ...markdown, ...(opts ?? {}) });
return code;
},
});
diff --git a/packages/astro/src/vite-plugin-markdown/index.ts b/packages/astro/src/vite-plugin-markdown/index.ts
index 615894fca..95747a402 100644
--- a/packages/astro/src/vite-plugin-markdown/index.ts
+++ b/packages/astro/src/vite-plugin-markdown/index.ts
@@ -1,4 +1,4 @@
-import astroRemark from '@astrojs/markdown-remark';
+import { renderMarkdown } from '@astrojs/markdown-remark';
import { transform } from '@astrojs/compiler';
import ancestor from 'common-ancestor-path';
import esbuild from 'esbuild';
@@ -118,7 +118,6 @@ export default function markdown({ config }: AstroPluginOptions): Plugin {
// This returns the compiled markdown -> astro component that renders to HTML.
if (id.endsWith('.md')) {
const source = await fs.promises.readFile(id, 'utf8');
- const render = astroRemark;
const renderOpts = config.markdown;
const filename = normalizeFilename(id);
@@ -128,7 +127,7 @@ export default function markdown({ config }: AstroPluginOptions): Plugin {
// Extract special frontmatter keys
const { data: frontmatter, content: markdownContent } = matter(source);
- let renderResult = await render(markdownContent, renderOpts);
+ let renderResult = await renderMarkdown(markdownContent, renderOpts);
let { code: astroResult, metadata } = renderResult;
const { layout = '', components = '', setup = '', ...content } = frontmatter;
content.astro = metadata;
diff --git a/packages/markdown/remark/package.json b/packages/markdown/remark/package.json
index 764f6ffb9..8a6f88c15 100644
--- a/packages/markdown/remark/package.json
+++ b/packages/markdown/remark/package.json
@@ -26,7 +26,6 @@
"@astrojs/prism": "^0.4.1",
"assert": "^2.0.0",
"github-slugger": "^1.4.0",
- "gray-matter": "^4.0.3",
"mdast-util-mdx-expression": "^1.2.0",
"mdast-util-mdx-jsx": "^1.2.0",
"mdast-util-to-string": "^3.1.0",
@@ -47,7 +46,10 @@
},
"devDependencies": {
"@types/github-slugger": "^1.3.0",
+ "@types/hast": "^2.3.4",
+ "@types/mdast": "^3.0.10",
"@types/prismjs": "^1.26.0",
+ "@types/unist": "^2.0.6",
"astro-scripts": "workspace:*"
}
}
diff --git a/packages/markdown/remark/src/index.ts b/packages/markdown/remark/src/index.ts
index dd9f95d58..2dfb81d23 100644
--- a/packages/markdown/remark/src/index.ts
+++ b/packages/markdown/remark/src/index.ts
@@ -1,4 +1,4 @@
-import type { AstroMarkdownOptions, MarkdownRenderingOptions, ShikiConfig, Plugin } from './types';
+import type { MarkdownRenderingOptions } from './types';
import createCollectHeaders from './rehype-collect-headers.js';
import scopedStyles from './remark-scoped-styles.js';
@@ -18,31 +18,17 @@ import markdown from 'remark-parse';
import markdownToHtml from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
import rehypeRaw from 'rehype-raw';
-import matter from 'gray-matter';
-
-export { AstroMarkdownOptions, MarkdownRenderingOptions, ShikiConfig, Plugin };
-
-/** Internal utility for rendering a full markdown file and extracting Frontmatter data */
-export async function renderMarkdownWithFrontmatter(
- contents: string,
- opts?: MarkdownRenderingOptions | null
-) {
- const { data: frontmatter, content } = matter(contents);
- const value = await renderMarkdown(content, opts);
- return { ...value, frontmatter };
-}
+
+export * from './types.js';
export const DEFAULT_REMARK_PLUGINS = ['remark-gfm', 'remark-smartypants'];
export const DEFAULT_REHYPE_PLUGINS = ['rehype-slug'];
/** Shared utility for rendering markdown */
-export async function renderMarkdown(content: string, opts?: MarkdownRenderingOptions | null) {
- let { remarkPlugins = [], rehypePlugins = [] } = opts ?? {};
- const scopedClassName = opts?.$?.scopedClassName;
- const mode = opts?.mode ?? 'mdx';
- const syntaxHighlight = opts?.syntaxHighlight ?? 'shiki';
- const shikiConfig = opts?.shikiConfig ?? {};
+export async function renderMarkdown(content: string, opts: MarkdownRenderingOptions) {
+ let { mode, syntaxHighlight, shikiConfig, remarkPlugins, rehypePlugins } = opts;
+ const scopedClassName = opts.$?.scopedClassName;
const isMDX = mode === 'mdx';
const { headers, rehypeCollectHeaders } = createCollectHeaders();
@@ -111,5 +97,3 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp
code: result.toString(),
};
}
-
-export default renderMarkdownWithFrontmatter;
diff --git a/packages/markdown/remark/src/load-plugins.ts b/packages/markdown/remark/src/load-plugins.ts
index 139eeaf19..c64d13543 100644
--- a/packages/markdown/remark/src/load-plugins.ts
+++ b/packages/markdown/remark/src/load-plugins.ts
@@ -1,5 +1,4 @@
import * as unified from 'unified';
-import type { Plugin } from './types';
async function importPlugin(p: string | unified.Plugin): Promise<unified.Plugin> {
if (typeof p === 'string') {
@@ -10,7 +9,9 @@ async function importPlugin(p: string | unified.Plugin): Promise<unified.Plugin>
return p;
}
-export function loadPlugins(items: Plugin[]): Promise<[unified.Plugin, any?]>[] {
+export function loadPlugins(
+ items: (string | [string, any] | unified.Plugin<any[], any> | [unified.Plugin<any[], any>, any])[]
+): Promise<[unified.Plugin, any?]>[] {
return items.map((p) => {
return new Promise((resolve, reject) => {
if (Array.isArray(p)) {
diff --git a/packages/markdown/remark/src/remark-shiki.ts b/packages/markdown/remark/src/remark-shiki.ts
index 314a0e38e..6f70bdf19 100644
--- a/packages/markdown/remark/src/remark-shiki.ts
+++ b/packages/markdown/remark/src/remark-shiki.ts
@@ -1,34 +1,7 @@
import type * as shiki from 'shiki';
import { getHighlighter } from 'shiki';
import { visit } from 'unist-util-visit';
-
-export interface ShikiConfig {
- /**
- * The languages loaded to Shiki.
- * Supports all languages listed here: https://github.com/shikijs/shiki/blob/main/docs/languages.md#all-languages
- * Instructions for loading a custom language: https://github.com/shikijs/shiki/blob/main/docs/languages.md#supporting-your-own-languages-with-shiki
- *
- * @default []
- */
- langs?: shiki.ILanguageRegistration[];
- /**
- * The styling theme.
- * Supports all themes listed here: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes
- * Instructions for loading a custom theme: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme
- *
- * @default "github-dark"
- */
- theme?: shiki.IThemeRegistration;
- /**
- * Enable word wrapping.
- * - true: enabled.
- * - false: enabled.
- * - null: All overflow styling removed. Code will overflow the element by default.
- *
- * @default false
- */
- wrap?: boolean | null;
-}
+import type { ShikiConfig } from './types.js';
/**
* getHighlighter() is the most expensive step of Shiki. Instead of calling it on every page,
@@ -38,7 +11,7 @@ export interface ShikiConfig {
const highlighterCacheAsync = new Map<string, Promise<shiki.Highlighter>>();
const remarkShiki = async (
- { langs = [], theme = 'github-dark', wrap = false }: ShikiConfig,
+ { langs, theme, wrap }: ShikiConfig,
scopedClassName?: string | null
) => {
const cacheID: string = typeof theme === 'string' ? theme : theme.name;
diff --git a/packages/markdown/remark/src/types.ts b/packages/markdown/remark/src/types.ts
index 43e8331b4..bba486921 100644
--- a/packages/markdown/remark/src/types.ts
+++ b/packages/markdown/remark/src/types.ts
@@ -1,18 +1,40 @@
import type * as unified from 'unified';
-import type { ShikiConfig } from './remark-shiki';
-export { ShikiConfig };
+import type * as mdast from 'mdast';
+import type * as hast from 'hast';
+import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki';
-export type Plugin = string | [string, any] | unified.Plugin | [unified.Plugin, any];
+export type { Node } from 'unist';
+
+export type RemarkPlugin<PluginParameters extends any[] = any[]> = unified.Plugin<
+ PluginParameters,
+ mdast.Root
+>;
+
+export type RemarkPlugins = (string | [string, any] | RemarkPlugin | [RemarkPlugin, any])[];
+
+export type RehypePlugin<PluginParameters extends any[] = any[]> = unified.Plugin<
+ PluginParameters,
+ hast.Root
+>;
+
+export type RehypePlugins = (string | [string, any] | RehypePlugin | [RehypePlugin, any])[];
+
+export interface ShikiConfig {
+ langs: ILanguageRegistration[];
+ theme: Theme | IThemeRegistration;
+ wrap: boolean | null;
+}
export interface AstroMarkdownOptions {
- mode?: 'md' | 'mdx';
- syntaxHighlight?: 'shiki' | 'prism' | false;
- shikiConfig?: ShikiConfig;
- remarkPlugins?: Plugin[];
- rehypePlugins?: Plugin[];
+ mode: 'md' | 'mdx';
+ drafts: boolean;
+ syntaxHighlight: 'shiki' | 'prism' | false;
+ shikiConfig: ShikiConfig;
+ remarkPlugins: RemarkPlugins;
+ rehypePlugins: RehypePlugins;
}
-export interface MarkdownRenderingOptions extends Partial<AstroMarkdownOptions> {
+export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
/** @internal */
$?: {
scopedClassName: string | null;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 508fcb87d..02ec1451a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -477,6 +477,7 @@ importers:
'@types/resolve': ^1.20.1
'@types/rimraf': ^3.0.2
'@types/send': ^0.17.1
+ '@types/unist': ^2.0.6
'@types/yargs-parser': ^21.0.0
'@web/parse5-utils': ^1.3.0
ast-types: ^0.14.2
@@ -495,6 +496,7 @@ importers:
execa: ^6.1.0
fast-glob: ^3.2.11
fast-xml-parser: ^4.0.7
+ gray-matter: ^4.0.3
html-entities: ^2.3.3
html-escaper: ^3.0.3
htmlparser2: ^7.2.0
@@ -558,6 +560,7 @@ importers:
execa: 6.1.0
fast-glob: 3.2.11
fast-xml-parser: 4.0.7
+ gray-matter: 4.0.3
html-entities: 2.3.3
html-escaper: 3.0.3
htmlparser2: 7.2.0
@@ -613,6 +616,7 @@ importers:
'@types/resolve': 1.20.1
'@types/rimraf': 3.0.2
'@types/send': 0.17.1
+ '@types/unist': 2.0.6
'@types/yargs-parser': 21.0.0
astro-scripts: link:../../scripts
chai: 4.3.6
@@ -1412,11 +1416,13 @@ importers:
specifiers:
'@astrojs/prism': ^0.4.1
'@types/github-slugger': ^1.3.0
+ '@types/hast': ^2.3.4
+ '@types/mdast': ^3.0.10
'@types/prismjs': ^1.26.0
+ '@types/unist': ^2.0.6
assert: ^2.0.0
astro-scripts: workspace:*
github-slugger: ^1.4.0
- gray-matter: ^4.0.3
mdast-util-mdx-expression: ^1.2.0
mdast-util-mdx-jsx: ^1.2.0
mdast-util-to-string: ^3.1.0
@@ -1438,7 +1444,6 @@ importers:
'@astrojs/prism': link:../../astro-prism
assert: 2.0.0
github-slugger: 1.4.0
- gray-matter: 4.0.3
mdast-util-mdx-expression: 1.2.0
mdast-util-mdx-jsx: 1.2.0
mdast-util-to-string: 3.1.0
@@ -1458,7 +1463,10 @@ importers:
unist-util-visit: 4.1.0
devDependencies:
'@types/github-slugger': 1.3.0
+ '@types/hast': 2.3.4
+ '@types/mdast': 3.0.10
'@types/prismjs': 1.26.0
+ '@types/unist': 2.0.6
astro-scripts: link:../../../scripts
packages/webapi:
@@ -3870,7 +3878,6 @@ packages:
resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==}
dependencies:
'@types/unist': 2.0.6
- dev: false
/@types/mdurl/1.0.2:
resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==}