feat: migrate to starlight

This commit is contained in:
DuroCodes
2024-05-06 17:15:30 -04:00
parent 767acedea7
commit bb190f2d81
15140 changed files with 2828326 additions and 35408 deletions

View File

@@ -0,0 +1,70 @@
---
import { addClassName, toHtml } from 'rehype-expressive-code/hast'
import { getPageData } from './page-data'
import { getRenderer } from './renderer'
import type { CodeProps as Props, MarkerValueType } from './types'
function formatMessage(...messageParts: string[]) {
return messageParts.map((part) => part.replace(/\s+/g, ' ')).join('\n\n')
}
async function renderToHtml() {
const defaultSlotContent = await Astro.slots.render('default')
if (defaultSlotContent?.trim().length) {
throw new Error(
formatMessage(
`Unsupported child content was found inside the component.
The code to render must be passed to the \`code\` prop as a string.`,
`Please remove the following child content:\n${defaultSlotContent}`
)
)
}
let { code, lang = '', meta = '', locale, class: className, ...props } = Astro.props
if (!code || !code.trim().length) {
throw new Error('Missing code to render. The `code` prop must be set to a non-empty string.')
}
const pageData = getPageData(Astro.request)
// Note: It's important to store the incremented index in a local variable immediately,
// as the `pageData` object is shared between all components on the current page
// and can be changed by other Code components during the `await` calls below
const groupIndex = ++pageData.blockGroupIndex
const renderer = await getRenderer()
const { renderedGroupAst } = await renderer.ec.render({
code,
language: lang,
meta,
locale,
parentDocument: {
positionInDocument: {
groupIndex,
},
},
props,
})
if (renderedGroupAst?.type === 'element') {
if (className) {
const classNames = className.split(' ')
classNames.forEach((className) => addClassName(renderedGroupAst, className))
}
}
return toHtml(renderedGroupAst)
}
let html = ''
try {
html = await renderToHtml()
} catch (err) {
const prefix = `Failed to render a \`<Code>\` component on page ${Astro.request.url}:`
const error = err instanceof Error ? err : new Error(String(err))
throw new Error(`${prefix}\n\n${error.message}`, { cause: error })
}
---
<Fragment set:html={html} />

17
node_modules/astro-expressive-code/components/index.ts generated vendored Normal file
View File

@@ -0,0 +1,17 @@
import type { Component, CodeProps } from './types'
import { default as CodeComponent } from './Code.astro'
/**
* Renders a code block to HTML using [Expressive Code](https://expressive-code.com/).
*
* The code to be rendered must be passed to the `code` prop.
* Passing code as children is not supported to avoid escaping issues.
*
* To get syntax highlighted output, also set the `lang` prop to a valid
* [language identifier](https://expressive-code.com/key-features/syntax-highlighting/#supported-languages)
* (e.g. `js`, `ts`, `astro`, `html`, `bash`, or many others).
*
* You can also set the `meta` prop to a string. It supports the same syntax that you would use
* in fenced code blocks in markdown/MDX files after the language identifier.
*/
export const Code = CodeComponent as Component<CodeProps>

View File

@@ -0,0 +1,18 @@
export type PageData = {
url: string
blockGroupIndex: number
}
const pageDataMap = new Map<Request, PageData>()
export function getPageData(request: Request): PageData {
let data = pageDataMap.get(request)
if (!data) {
data = {
url: request.url,
blockGroupIndex: -1,
}
pageDataMap.set(request, data)
}
return data
}

View File

@@ -0,0 +1,37 @@
let cachedRenderer: ReturnType<typeof createRenderer> | undefined = undefined
export async function getRenderer() {
if (!cachedRenderer) {
cachedRenderer = createRenderer()
}
return await cachedRenderer
}
async function createRenderer() {
const { astroConfig, ecConfigFileOptions, ecIntegrationOptions = {} } = await import('virtual:astro-expressive-code/config')
const { createAstroRenderer } = await import('virtual:astro-expressive-code/api')
const strIntegrationOptions = JSON.stringify(ecIntegrationOptions)
if (strIntegrationOptions.includes('"[Function]"') || strIntegrationOptions.includes("'[Circular]'")) {
throw new Error(
`Your Astro config file contains Expressive Code options that are not serializable to JSON.
To use the \`<Code>\` component, please create a separate config file called \`ec.config.mjs\`
in your project root, move your Expressive Code options object into the config file,
and export it as the default export.`.replace(/\s+/g, ' ')
)
}
let mergedEcConfig = { ...ecConfigFileOptions, ...ecIntegrationOptions }
try {
const { default: preprocessEcConfig } = await import('virtual:astro-expressive-code/preprocess-config')
mergedEcConfig = (await preprocessEcConfig({ ecConfig: mergedEcConfig, astroConfig })) || mergedEcConfig
} catch (error) {
const msg = error instanceof Error ? error.message : (error as string)
throw new Error(`Failed to preprocess Expressive Code config for the Code component: ${msg}`, { cause: error })
}
return await createAstroRenderer({
astroConfig,
ecConfig: mergedEcConfig,
})
}

44
node_modules/astro-expressive-code/components/types.ts generated vendored Normal file
View File

@@ -0,0 +1,44 @@
import { ExpressiveCodeBlockProps } from 'rehype-expressive-code'
// This type helper is required to support component props in MDX files
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Component<T> = (_props: T) => any
export type MarkerValueType = string | number | RegExp | (string | number | RegExp)[]
export type PartialAllowUndefined<T> = {
[Key in keyof T]?: T[Key] | undefined
}
export interface CodeProps extends PartialAllowUndefined<ExpressiveCodeBlockProps> {
/**
* The plaintext contents of the code block.
*/
code: string
/**
* The code block's language.
*
* Please use a valid [language identifier](https://expressive-code.com/key-features/syntax-highlighting/#supported-languages)
* to ensure proper syntax highlighting.
*/
lang?: string | undefined
/**
* An optional meta string. In markdown or MDX documents, this is the part of the
* code block's opening fence that comes after the language name.
*/
meta?: string | undefined
/**
* The code block's locale (e.g. `en-US` or `de-DE`). This is used by plugins to display
* localized strings depending on the language of the containing page.
*
* If no locale is defined here, most Expressive Code integrations will attempt to auto-detect
* the block locale using the configured
* [`getBlockLocale`](https://expressive-code.com/reference/configuration/#getblocklocale)
* function, and finally fall back to the configured
* [`defaultLocale`](https://expressive-code.com/reference/configuration/#defaultlocale).
*/
locale?: string | undefined
/**
* The CSS class name(s) to apply to the code block's container element.
*/
class?: string | undefined
}