chore: shiki velite migration (#51579)

## Problem

design-system, ui-library and learn highlight code through
`@shikijs/compat` and `rehype-pretty-code` 0.9, which both predate shiki
1

compat has no v4 release, so these apps were stuck on shiki 1.6 and
couldn't pick up the injection fix from the previous pr

## Solution

- drops `@shikijs/compat`
- moves all three apps to `rehype-pretty-code`

<!--
## Preview links

If relevant, include links to changed pages for easy review access.

Copy the preview base URL from the Vercel bot comment on this PR. Use
the following table as an example template.

| Site | Live | Preview | Search for |
| -------------- |
-------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------
| ----------------------------- |
| WWW | [/blog/your-post](https://supabase.com/blog/your-post) |
[/blog/your-post](https://zone-www-dot-com-git-branch-name-supabase.vercel.app/blog/your-post)
| unique phrase from the change |
| Docs |
[/docs/guides/your-page](https://supabase.com/docs/guides/your-page) |
[/docs/guides/your-page](https://docs-git-branch-name-supabase.vercel.app/docs/guides/your-page)
| unique phrase from the change |
| Studio | [/dashboard](https://supabase.com/dashboard) |
[/dashboard](https://studio-git-branch-name-supabase.vercel.app/dashboard)
| unique phrase from the change |
| Design system | [/design-system](https://supabase.com/design-system) |
[/design-system](https://design-system-git-branch-name-supabase.vercel.app/design-system)
| unique phrase from the change |
| UI library | [/library](https://supabase.com/library) |
[/library](https://ui-library-git-branch-name-supabase.vercel.app/library)
| unique phrase from the change |
| Knowledge base |
[/kb/guides/your-page](https://supabase.com/kb/guides/your-page) |
[/kb/guides/your-page](https://kb-git-branch-name-supabase.vercel.app/kb/guides/your-page)
| unique phrase from the change |
-->

<!-- ## Additional context

Optionally add any other context or screenshots.

-->

## Review instructions

1. open
[/design-system/docs/accessibility](https://design-system-gd7xzujta-supabase.vercel.app/design-system/docs/accessibility)
on the preview and on production side by side _ highlighted lines should
keep the left border and background, and line numbers should line up
2. open
[/design-system/docs/components/chart](https://design-system-gd7xzujta-supabase.vercel.app/design-system/docs/components/chart)
_ highlighted words should have the gray pill, with no yellow background
or black text + code blocks with titles should still show the title
above the block
3. toggle light and dark mode on both pages _ token colors and the block
background should match production
4. open [ui-library
preview](https://ui-library-hmuv1teie-supabase.vercel.app/library/docs/starters/nextjs-starter)
and do a copy check
5. open a learn lesson with code `/foundations/authentication` and
compare it with production.

## Checklist

Check all before review:

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
This commit is contained in:
Anthony Lio authored and GitHub committed 2026-10-14 12:46:03 +03:00
1 parent 4b93c5186d
commit 0fe320e5e3
12 files changed
+124 -247

No files matched your search

@@ -26,11 +26,11 @@ export function ComponentExample({
}: ComponentExampleProps) {
const [Example, Code, ...Children] = React.Children.toArray(children) as React.ReactElement<{
children: React.ReactNode
'data-rehype-pretty-code-fragment'?: unknown
'data-rehype-pretty-code-figure'?: unknown
}>[]
const codeString = React.useMemo(() => {
if (typeof Code?.props['data-rehype-pretty-code-fragment'] !== 'undefined') {
if (typeof Code?.props['data-rehype-pretty-code-figure'] !== 'undefined') {
const [, Button] = React.Children.toArray(Code.props.children) as React.ReactElement<{
value?: string
__rawString__?: string
+2 -3
View File
@@ -40,7 +40,7 @@
"react-wrap-balancer": "^1.1.0",
"recharts": "catalog:",
"rehype-autolink-headings": "^7.1.0",
"rehype-pretty-code": "^0.9.0",
"rehype-pretty-code": "catalog:",
"rehype-slug": "^6.0.0",
"remark": "^14.0.3",
"remark-code-import": "^1.2.0",
@@ -54,7 +54,6 @@
"zod": "catalog:"
},
"devDependencies": {
"@shikijs/compat": "^1.1.7",
"@types/lodash.template": "4.5.0",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
@@ -64,7 +63,7 @@
"npm-run-all": "^4.1.5",
"postcss": "catalog:",
"rimraf": "^4.1.3",
"shiki": "^1.1.7",
"shiki": "catalog:",
"tailwindcss": "catalog:",
"tsconfig": "workspace:*",
"tsx": "catalog:",
+12 -11
View File
@@ -16,25 +16,25 @@
display: block;
}
[data-rehype-pretty-code-fragment] {
[data-rehype-pretty-code-figure] {
@apply relative;
}
[data-rehype-pretty-code-fragment] code {
[data-rehype-pretty-code-figure] code {
@apply grid min-w-full break-words rounded-none border-0 bg-transparent p-0;
counter-reset: line;
box-decoration-break: clone;
}
[data-rehype-pretty-code-fragment] .line {
[data-rehype-pretty-code-figure] [data-line] {
@apply px-4 min-h-[1rem] py-0.5 w-full inline-block;
}
[data-rehype-pretty-code-fragment] [data-line-numbers] .line {
[data-rehype-pretty-code-figure] [data-line-numbers] [data-line] {
@apply px-2;
}
[data-rehype-pretty-code-fragment] [data-line-numbers] > .line::before {
[data-rehype-pretty-code-figure] [data-line-numbers] > [data-line]::before {
@apply text-foreground-muted text-xs;
counter-increment: line;
content: counter(line);
@@ -44,23 +44,24 @@
text-align: right;
}
[data-rehype-pretty-code-fragment] .line--highlighted {
[data-rehype-pretty-code-figure] .line--highlighted {
@apply relative bg-surface-200 dark:bg-surface-100;
}
[data-rehype-pretty-code-fragment] .line--highlighted {
[data-rehype-pretty-code-figure] .line--highlighted {
@apply border-foreground-muted border-l-2;
}
[data-rehype-pretty-code-fragment] .line-highlighted span {
[data-rehype-pretty-code-figure] .line-highlighted span {
@apply relative;
}
[data-rehype-pretty-code-fragment] .word--highlighted {
@apply rounded-md bg-zinc-700/50 border-zinc-700/70 p-1;
/* reset <mark> default text color */
[data-rehype-pretty-code-figure] .word--highlighted {
@apply rounded-md bg-zinc-700/50 border-zinc-700/70 p-1 text-inherit;
}
.dark [data-rehype-pretty-code-fragment] .word--highlighted {
.dark [data-rehype-pretty-code-figure] .word--highlighted {
@apply bg-zinc-900;
}
+14 -19
View File
@@ -1,7 +1,6 @@
/* eslint-disable turbo/no-undeclared-env-vars */
import { mkdir, rename, writeFile } from 'node:fs/promises'
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises'
import path from 'path'
import { getHighlighter, loadTheme } from '@shikijs/compat'
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
import rehypePrettyCode from 'rehype-pretty-code'
import rehypeSlug from 'rehype-slug'
@@ -14,6 +13,10 @@ import { rehypeComponent } from './lib/rehype-component'
const CODE_OUTPUT_DIR = '.velite/codes'
const codeTheme = JSON.parse(
await readFile(path.join(process.cwd(), 'lib/themes/supabase-2.json'), 'utf8')
)
function toCodeId(slugAsParams) {
if (!slugAsParams) return 'index'
return Buffer.from(slugAsParams, 'utf8').toString('base64url')
@@ -118,18 +121,9 @@ export default defineConfig({
[
rehypePrettyCode,
{
// Memoized so the (expensive) theme parse + oniguruma WASM init runs once
// for the whole build, instead of once per file — velite compiles every
// file concurrently, so without this every doc pays that cost redundantly.
getHighlighter: (() => {
let highlighterPromise
return () => {
highlighterPromise ??= loadTheme(
path.join(process.cwd(), '/lib/themes/supabase-2.json')
).then((theme) => getHighlighter({ theme }))
return highlighterPromise
}
})(),
// plugin shares one cached highlighter per theme, lazy language loading needs shiki >= 4.5 (shikijs/shiki#1318)
theme: codeTheme,
keepBackground: false,
onVisitLine(node) {
// Prevent lines from collapsing in `display: grid` mode, and allow empty
// lines to be copy/pasted
@@ -138,17 +132,18 @@ export default defineConfig({
}
},
onVisitHighlightedLine(node) {
node.properties.className.push('line--highlighted')
// the plugin strips the `line` class first, leaving className undefined
node.properties.className = [...(node.properties.className ?? []), 'line--highlighted']
},
onVisitHighlightedWord(node) {
onVisitHighlightedChars(node) {
node.properties.className = ['word--highlighted']
},
},
],
() => (tree) => {
visit(tree, (node) => {
if (node?.type === 'element' && node?.tagName === 'div') {
if (!('data-rehype-pretty-code-fragment' in node.properties)) {
if (node?.type === 'element' && node?.tagName === 'figure') {
if (!('data-rehype-pretty-code-figure' in node.properties)) {
return
}
@@ -157,7 +152,7 @@ export default defineConfig({
return
}
preElement.properties['__withMeta__'] = node.children.at(0).tagName === 'div'
preElement.properties['__withMeta__'] = node.children.at(0).tagName === 'figcaption'
preElement.properties['__rawString__'] = node.__rawString__
if (node.__src__) {
+2 -3
View File
@@ -28,7 +28,7 @@
"react-dom": "catalog:",
"react-wrap-balancer": "^1.1.0",
"rehype-autolink-headings": "^7.1.0",
"rehype-pretty-code": "^0.9.0",
"rehype-pretty-code": "catalog:",
"rehype-slug": "^6.0.0",
"remark": "^14.0.3",
"remark-code-import": "^1.2.0",
@@ -39,13 +39,12 @@
"velite": "catalog:"
},
"devDependencies": {
"@shikijs/compat": "^1.1.7",
"@types/react": "catalog:",
"config": "workspace:^",
"eslint-config-supabase": "workspace:*",
"mdast-util-toc": "^6.1.1",
"npm-run-all": "^4.1.5",
"shiki": "^1.1.7",
"shiki": "catalog:",
"tailwindcss": "catalog:",
"tsconfig": "workspace:*",
"tsx": "catalog:"
+12 -11
View File
@@ -8,25 +8,25 @@
display: block;
}
[data-rehype-pretty-code-fragment] {
[data-rehype-pretty-code-figure] {
@apply relative text-white;
}
[data-rehype-pretty-code-fragment] code {
[data-rehype-pretty-code-figure] code {
@apply grid min-w-full break-words rounded-none border-0 bg-transparent p-0;
counter-reset: line;
box-decoration-break: clone;
}
[data-rehype-pretty-code-fragment] .line {
[data-rehype-pretty-code-figure] [data-line] {
@apply px-4 min-h-[1rem] py-0.5 w-full inline-block;
}
[data-rehype-pretty-code-fragment] [data-line-numbers] .line {
[data-rehype-pretty-code-figure] [data-line-numbers] [data-line] {
@apply px-2;
}
[data-rehype-pretty-code-fragment] [data-line-numbers] > .line::before {
[data-rehype-pretty-code-figure] [data-line-numbers] > [data-line]::before {
@apply text-foreground-muted text-xs;
counter-increment: line;
content: counter(line);
@@ -36,23 +36,24 @@
text-align: right;
}
[data-rehype-pretty-code-fragment] .line--highlighted {
[data-rehype-pretty-code-figure] .line--highlighted {
@apply relative bg-surface-200 dark:bg-surface-100;
}
[data-rehype-pretty-code-fragment] .line--highlighted {
[data-rehype-pretty-code-figure] .line--highlighted {
@apply border-foreground-muted border-l-2;
}
[data-rehype-pretty-code-fragment] .line-highlighted span {
[data-rehype-pretty-code-figure] .line-highlighted span {
@apply relative;
}
[data-rehype-pretty-code-fragment] .word--highlighted {
@apply rounded-md bg-zinc-700/50 border-zinc-700/70 p-1;
/* reset <mark> default text color */
[data-rehype-pretty-code-figure] .word--highlighted {
@apply rounded-md bg-zinc-700/50 border-zinc-700/70 p-1 text-inherit;
}
.dark [data-rehype-pretty-code-fragment] .word--highlighted {
.dark [data-rehype-pretty-code-figure] .word--highlighted {
@apply bg-zinc-900;
}
+14 -10
View File
@@ -1,5 +1,5 @@
import { readFile } from 'node:fs/promises'
import path from 'path'
import { getHighlighter, loadTheme } from '@shikijs/compat'
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
import rehypePrettyCode from 'rehype-pretty-code'
import rehypeSlug from 'rehype-slug'
@@ -8,6 +8,10 @@ import remarkGfm from 'remark-gfm'
import { visit } from 'unist-util-visit'
import { defineConfig, s } from 'velite'
const codeTheme = JSON.parse(
await readFile(path.join(process.cwd(), 'lib/themes/supabase-2.json'), 'utf8')
)
const LinksProperties = s.object({
doc: s.string().optional(),
api: s.string().optional(),
@@ -106,10 +110,9 @@ export default defineConfig({
[
rehypePrettyCode,
{
getHighlighter: async () => {
const theme = await loadTheme(path.join(process.cwd(), '/lib/themes/supabase-2.json'))
return await getHighlighter({ theme })
},
// plugin shares one cached highlighter per theme, lazy language loading needs shiki >= 4.5 (shikijs/shiki#1318)
theme: codeTheme,
keepBackground: false,
onVisitLine(node) {
// Prevent lines from collapsing in `display: grid` mode, and allow empty
// lines to be copy/pasted
@@ -118,17 +121,18 @@ export default defineConfig({
}
},
onVisitHighlightedLine(node) {
node.properties.className.push('line--highlighted')
// the plugin strips the `line` class first, leaving className undefined
node.properties.className = [...(node.properties.className ?? []), 'line--highlighted']
},
onVisitHighlightedWord(node) {
onVisitHighlightedChars(node) {
node.properties.className = ['word--highlighted']
},
},
],
() => (tree) => {
visit(tree, (node) => {
if (node?.type === 'element' && node?.tagName === 'div') {
if (!('data-rehype-pretty-code-fragment' in node.properties)) {
if (node?.type === 'element' && node?.tagName === 'figure') {
if (!('data-rehype-pretty-code-figure' in node.properties)) {
return
}
@@ -137,7 +141,7 @@ export default defineConfig({
return
}
preElement.properties['__withMeta__'] = node.children.at(0).tagName === 'div'
preElement.properties['__withMeta__'] = node.children.at(0).tagName === 'figcaption'
preElement.properties['__rawString__'] = node.__rawString__
if (node.__src__) {
+2 -3
View File
@@ -54,7 +54,7 @@
"react-wrap-balancer": "^1.1.0",
"recharts": "catalog:",
"rehype-autolink-headings": "^7.1.0",
"rehype-pretty-code": "^0.9.0",
"rehype-pretty-code": "catalog:",
"rehype-slug": "^6.0.0",
"remark-code-import": "^1.2.0",
"remark-gfm": "^4.0.0",
@@ -73,7 +73,6 @@
"@babel/core": "*",
"@react-router/dev": "^7.17.1",
"@react-router/fs-routes": "^7.18.4",
"@shikijs/compat": "^1.1.7",
"@supabase/ssr": "catalog:",
"@supabase/supabase-js": "catalog:",
"@tanstack/react-router": "catalog:",
@@ -101,7 +100,7 @@
"react-router": "^7.13.2",
"rimraf": "^4.1.3",
"shadcn": "^4.0.0",
"shiki": "^1.1.7",
"shiki": "catalog:",
"tailwindcss": "catalog:",
"tsconfig": "workspace:*",
"tsx": "catalog:",
+12 -11
View File
@@ -8,25 +8,25 @@
display: block;
}
[data-rehype-pretty-code-fragment] {
[data-rehype-pretty-code-figure] {
@apply relative text-white;
}
[data-rehype-pretty-code-fragment] code {
[data-rehype-pretty-code-figure] code {
@apply grid min-w-full break-words rounded-none border-0 bg-transparent p-0;
counter-reset: line;
box-decoration-break: clone;
}
[data-rehype-pretty-code-fragment] .line {
[data-rehype-pretty-code-figure] [data-line] {
@apply px-4 min-h-[1rem] py-0.5 w-full inline-block;
}
[data-rehype-pretty-code-fragment] [data-line-numbers] .line {
[data-rehype-pretty-code-figure] [data-line-numbers] [data-line] {
@apply px-2;
}
[data-rehype-pretty-code-fragment] [data-line-numbers] > .line::before {
[data-rehype-pretty-code-figure] [data-line-numbers] > [data-line]::before {
@apply text-foreground-muted text-xs;
counter-increment: line;
content: counter(line);
@@ -36,23 +36,24 @@
text-align: right;
}
[data-rehype-pretty-code-fragment] .line--highlighted {
[data-rehype-pretty-code-figure] .line--highlighted {
@apply relative bg-surface-200 dark:bg-surface-100;
}
[data-rehype-pretty-code-fragment] .line--highlighted {
[data-rehype-pretty-code-figure] .line--highlighted {
@apply border-foreground-muted border-l-2;
}
[data-rehype-pretty-code-fragment] .line-highlighted span {
[data-rehype-pretty-code-figure] .line-highlighted span {
@apply relative;
}
[data-rehype-pretty-code-fragment] .word--highlighted {
@apply rounded-md bg-zinc-700/50 border-zinc-700/70 p-1;
/* reset <mark> default text color */
[data-rehype-pretty-code-figure] .word--highlighted {
@apply rounded-md bg-zinc-700/50 border-zinc-700/70 p-1 text-inherit;
}
.dark [data-rehype-pretty-code-fragment] .word--highlighted {
.dark [data-rehype-pretty-code-figure] .word--highlighted {
@apply bg-zinc-900;
}
+14 -10
View File
@@ -1,5 +1,5 @@
import { readFile } from 'node:fs/promises'
import path from 'path'
import { getHighlighter, loadTheme } from '@shikijs/compat'
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
import rehypePrettyCode from 'rehype-pretty-code'
import rehypeSlug from 'rehype-slug'
@@ -8,6 +8,10 @@ import remarkGfm from 'remark-gfm'
import { visit } from 'unist-util-visit'
import { defineConfig, s } from 'velite'
const codeTheme = JSON.parse(
await readFile(path.join(process.cwd(), 'lib/themes/supabase-2.json'), 'utf8')
)
const LinksProperties = s.object({
doc: s.string().optional(),
api: s.string().optional(),
@@ -103,10 +107,9 @@ export default defineConfig({
[
rehypePrettyCode,
{
getHighlighter: async () => {
const theme = await loadTheme(path.join(process.cwd(), '/lib/themes/supabase-2.json'))
return await getHighlighter({ theme })
},
// plugin shares one cached highlighter per theme, lazy language loading needs shiki >= 4.5 (shikijs/shiki#1318)
theme: codeTheme,
keepBackground: false,
onVisitLine(node) {
// Prevent lines from collapsing in `display: grid` mode, and allow empty
// lines to be copy/pasted
@@ -115,17 +118,18 @@ export default defineConfig({
}
},
onVisitHighlightedLine(node) {
node.properties.className.push('line--highlighted')
// the plugin strips the `line` class first, leaving className undefined
node.properties.className = [...(node.properties.className ?? []), 'line--highlighted']
},
onVisitHighlightedWord(node) {
onVisitHighlightedChars(node) {
node.properties.className = ['word--highlighted']
},
},
],
() => (tree) => {
visit(tree, (node) => {
if (node?.type === 'element' && node?.tagName === 'div') {
if (!('data-rehype-pretty-code-fragment' in node.properties)) {
if (node?.type === 'element' && node?.tagName === 'figure') {
if (!('data-rehype-pretty-code-figure' in node.properties)) {
return
}
@@ -134,7 +138,7 @@ export default defineConfig({
return
}
preElement.properties['__withMeta__'] = node.children.at(0).tagName === 'div'
preElement.properties['__withMeta__'] = node.children.at(0).tagName === 'figcaption'
preElement.properties['__rawString__'] = node.__rawString__
if (node.__src__) {
+37 -164
View File
@@ -84,6 +84,9 @@ catalogs:
recharts:
specifier: ^2.15.4
version: 2.15.4
rehype-pretty-code:
specifier: ^0.14.5
version: 0.14.5
shiki:
specifier: ^4.5.0
version: 4.5.0
@@ -266,8 +269,8 @@ importers:
specifier: ^7.1.0
version: 7.1.0
rehype-pretty-code:
specifier: ^0.9.0
version: 0.9.11(shiki@1.6.0)
specifier: 'catalog:'
version: 0.14.5(shiki@4.5.0)
rehype-slug:
specifier: ^6.0.0
version: 6.0.0
@@ -302,9 +305,6 @@ importers:
specifier: 'catalog:'
version: 3.25.76
devDependencies:
'@shikijs/compat':
specifier: ^1.1.7
version: 1.6.0
'@types/lodash.template':
specifier: 4.5.0
version: 4.5.0
@@ -333,8 +333,8 @@ importers:
specifier: ^4.1.3
version: 4.4.1
shiki:
specifier: ^1.1.7
version: 1.6.0
specifier: 'catalog:'
version: 4.5.0
tailwindcss:
specifier: 'catalog:'
version: 4.2.4
@@ -875,8 +875,8 @@ importers:
specifier: ^7.1.0
version: 7.1.0
rehype-pretty-code:
specifier: ^0.9.0
version: 0.9.11(shiki@1.6.0)
specifier: 'catalog:'
version: 0.14.5(shiki@4.5.0)
rehype-slug:
specifier: ^6.0.0
version: 6.0.0
@@ -902,9 +902,6 @@ importers:
specifier: 'catalog:'
version: 0.4.0(supports-color@8.1.1)
devDependencies:
'@shikijs/compat':
specifier: ^1.1.7
version: 1.6.0
'@types/react':
specifier: 'catalog:'
version: 19.2.14
@@ -921,8 +918,8 @@ importers:
specifier: ^4.1.5
version: 4.1.5
shiki:
specifier: ^1.1.7
version: 1.6.0
specifier: 'catalog:'
version: 4.5.0
tailwindcss:
specifier: 'catalog:'
version: 4.2.4
@@ -1658,8 +1655,8 @@ importers:
specifier: ^7.1.0
version: 7.1.0
rehype-pretty-code:
specifier: ^0.9.0
version: 0.9.11(shiki@1.6.0)
specifier: 'catalog:'
version: 0.14.5(shiki@4.5.0)
rehype-slug:
specifier: ^6.0.0
version: 6.0.0
@@ -1709,9 +1706,6 @@ importers:
'@react-router/fs-routes':
specifier: ^7.18.4
version: 7.18.4(@react-router/dev@7.18.4(@react-router/serve@7.18.4(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(supports-color@8.1.1)(typescript@6.0.2))(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.7.0)(lightningcss@1.33.0)(react-router@7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(yaml@2.9.0))(typescript@6.0.2)
'@shikijs/compat':
specifier: ^1.1.7
version: 1.6.0
'@supabase/ssr':
specifier: 'catalog:'
version: 0.12.7(@supabase/supabase-js@2.117.3(@opentelemetry/api@1.9.1))
@@ -1794,8 +1788,8 @@ importers:
specifier: ^4.0.0
version: 4.21.0(babel-plugin-macros@3.1.0)(supports-color@8.1.1)(typescript@6.0.2)
shiki:
specifier: ^1.1.7
version: 1.6.0
specifier: 'catalog:'
version: 4.5.0
tailwindcss:
specifier: 'catalog:'
version: 4.2.4
@@ -8049,19 +8043,9 @@ packages:
eslint:
optional: true
'@shikijs/compat@1.6.0':
resolution: {integrity: sha512-aiyhzBiQnUx2y327pYUneOFznNzGhE74pawWzzxpR8XhtBvia4G6HS72vCqFxfSN1fsKWr+59tMUn8ckbuATbg==}
'@shikijs/core@1.6.0':
resolution: {integrity: sha512-NIEAi5U5R7BLkbW1pG/ZKu3eb1lzc3/+jD0lFsuxMT7zjaf9bbNwdNyMr7zh/Zl8EXQtQ+MYBAt5G+JLu+5DlA==}
'@shikijs/core@3.13.0':
resolution: {integrity: sha512-3P8rGsg2Eh2qIHekwuQjzWhKI4jV97PhvYjYUzGqjvJfqdQPz+nMlfWahU24GZAyW1FxFI1sYjyhfh5CoLmIUA==}
'@shikijs/core@4.2.0':
resolution: {integrity: sha512-Hc87Ab1Ld/vEbZRCbwx344I5v+4RU8CVToUTRkqXL1+TjbuOp9U5Xa0M23V4GEWHxVn+yO5otb+HkQVm3ptWQQ==}
engines: {node: '>=20'}
'@shikijs/core@4.5.0':
resolution: {integrity: sha512-6CIgwq+bt2JZ3OSjb/nBkkwEf/CfpHcbam+Mg5Pllco7HAGRQ2/EFhZrrJtbyNTgKwknfVS+llsXGygiDGwJWw==}
engines: {node: '>=20'}
@@ -8069,10 +8053,6 @@ packages:
'@shikijs/engine-javascript@3.13.0':
resolution: {integrity: sha512-Ty7xv32XCp8u0eQt8rItpMs6rU9Ki6LJ1dQOW3V/56PKDcpvfHPnYFbsx5FFUP2Yim34m/UkazidamMNVR4vKg==}
'@shikijs/engine-javascript@4.2.0':
resolution: {integrity: sha512-fjETeq1k5ffyXqRgS6+3hpvqseLalp1kjNfRbXpUgWR8FpZ1CmQfiNHovc5lncYjt/Vg5JK/WJEmLahjwMa0og==}
engines: {node: '>=20'}
'@shikijs/engine-javascript@4.5.0':
resolution: {integrity: sha512-Ed6UdEj84LyYkwnxM5CvSMWAD+id9ExTYri0/+x41U9zrgNifPSS9lZm0JqBP0VfYI8yr8tY5nbNq9+p9R0kFA==}
engines: {node: '>=20'}
@@ -8080,10 +8060,6 @@ packages:
'@shikijs/engine-oniguruma@3.13.0':
resolution: {integrity: sha512-O42rBGr4UDSlhT2ZFMxqM7QzIU+IcpoTMzb3W7AlziI1ZF7R8eS2M0yt5Ry35nnnTX/LTLXFPUjRFCIW+Operg==}
'@shikijs/engine-oniguruma@4.2.0':
resolution: {integrity: sha512-hTorK1dffPkpbMUk6Z+828PgRo7d07HbnizoP0hNPFjhxMHctj0Px/qoHeGMYafc6ju+u9iMldN4JbVzNQM++g==}
engines: {node: '>=20'}
'@shikijs/engine-oniguruma@4.5.0':
resolution: {integrity: sha512-dKVmbJecVdB9recl8a/CU4jdpNXyjJQrIcesIkpS70s5HS02ohpnCSpMUbotPnEUzbAcLQ+S4hwZYbkBBiTcJw==}
engines: {node: '>=20'}
@@ -8091,18 +8067,10 @@ packages:
'@shikijs/langs@3.13.0':
resolution: {integrity: sha512-672c3WAETDYHwrRP0yLy3W1QYB89Hbpj+pO4KhxK6FzIrDI2FoEXNiNCut6BQmEApYLfuYfpgOZaqbY+E9b8wQ==}
'@shikijs/langs@4.2.0':
resolution: {integrity: sha512-bwrVRlJ0wUhZxAbVdvBbv2TTC9yLsh4C/IO5Ofz0T8MQntgDvyVnkbjw9vi50r1kx7RCIJdnJnjZAwmAsXFLZQ==}
engines: {node: '>=20'}
'@shikijs/langs@4.5.0':
resolution: {integrity: sha512-wwBTqwduXSz0X4v9Qa2EWeFaYJEw1clCncWjoRNQRbVDu3SPRTRWucnouYapKj3b8Q+sk/41Vbc4B5c8nuYzLA==}
engines: {node: '>=20'}
'@shikijs/primitive@4.2.0':
resolution: {integrity: sha512-NOq+DtUkVBJtZMVXL5A0vI0Xk8nvDYaXetFHSJFlOqjDZIVhIPRYFdGkSoElDqNuegikcc3A76SNUa8dTqtAYA==}
engines: {node: '>=20'}
'@shikijs/primitive@4.5.0':
resolution: {integrity: sha512-UM7ShlA8oz0OWxLLO8BmO9Ip6fVqdkt8yF0EH7nOCqHfrx1eEAzF0ZUVK7L+I8NEgeu1PEWSRlxaiPPeCb4iDg==}
engines: {node: '>=20'}
@@ -8110,24 +8078,13 @@ packages:
'@shikijs/themes@3.13.0':
resolution: {integrity: sha512-Vxw1Nm1/Od8jyA7QuAenaV78BG2nSr3/gCGdBkLpfLscddCkzkL36Q5b67SrLLfvAJTOUzW39x4FHVCFriPVgg==}
'@shikijs/themes@4.2.0':
resolution: {integrity: sha512-RX8IHYeLv8Cu2W6ruc3RxUqWn0IYCqSrMBzi/uRGAmfyDNOnNO5BF/Px7o97n4XTpmFTo5GbRaazuOWj+2ak2w==}
engines: {node: '>=20'}
'@shikijs/themes@4.5.0':
resolution: {integrity: sha512-zGb87H3UBbpuI4yoh5UguB1XbU+2BDU3kflM7UfZ+Cy2hWo9lBtqjSVK20gmLY6ukYl040hAypGXMgud9vul8Q==}
engines: {node: '>=20'}
'@shikijs/transformers@1.6.0':
resolution: {integrity: sha512-qGfHe1ECiqfE2STPWvfogIj/9Q0SK+MCRJdoITkW7AmFuB7DmbFnBT2US84+zklJOB51MzNO8RUXZiauWssJlQ==}
'@shikijs/types@3.13.0':
resolution: {integrity: sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==}
'@shikijs/types@4.2.0':
resolution: {integrity: sha512-VT/MKtlpOhEPZloSH3Pb9WCZEBDoQVMa9jedp5UAwmJOar1DVc9DRODAxmYPW9M93IK4ryuqRejFfmlvlVDemw==}
engines: {node: '>=20'}
'@shikijs/types@4.5.0':
resolution: {integrity: sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==}
engines: {node: '>=20'}
@@ -12961,10 +12918,6 @@ packages:
has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
hash-obj@4.0.0:
resolution: {integrity: sha512-FwO1BUVWkyHasWDW4S8o0ssQXjvyghLV2rfVhnN36b2bbcj45eGiuzdn9XOvOpjV3TKQD7Gm2BWNXdE9V4KKYg==}
engines: {node: '>=12'}
hasown@2.0.2:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
@@ -16591,11 +16544,14 @@ packages:
rehype-katex@7.0.1:
resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==}
rehype-pretty-code@0.9.11:
resolution: {integrity: sha512-Eq90eCYXQJISktfRZ8PPtwc5SUyH6fJcxS8XOMnHPUQZBtC6RYo67gGlley9X2nR8vlniPj0/7oCDEYHKQa/oA==}
engines: {node: '>=16'}
rehype-parse@9.0.1:
resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==}
rehype-pretty-code@0.14.5:
resolution: {integrity: sha512-+DhMMNMgOwmE0xu2RmagN63nR0GRObPIQ9TuoNdUYYIDcCr8nWXU1CJUG6yca7vg99Gp5d+62A/+ZvksmsQXjA==}
engines: {node: '>=18'}
peerDependencies:
shiki: '*'
shiki: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0
rehype-raw@7.0.0:
resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
@@ -17111,16 +17067,9 @@ packages:
engines: {node: '>=18'}
hasBin: true
shiki@1.6.0:
resolution: {integrity: sha512-P31ROeXcVgW/k3Z+vUUErcxoTah7ZRaimctOpzGuqAntqnnSmx1HOsvnbAB8Z2qfXPRhw61yptAzCsuKOhTHwQ==}
shiki@3.13.0:
resolution: {integrity: sha512-aZW4l8Og16CokuCLf8CF8kq+KK2yOygapU5m3+hoGw0Mdosc6fPitjM+ujYarppj5ZIKGyPDPP1vqmQhr+5/0g==}
shiki@4.2.0:
resolution: {integrity: sha512-hjNax6o/ylDy9lefQEaSDtzaT3iVNtZ3WmpQnbuQNoG4xvnSKf2kSKbihZVO4JRG1TTMejs7CmNRYlWgAL66pQ==}
engines: {node: '>=20'}
shiki@4.5.0:
resolution: {integrity: sha512-OcRW72ngQvc+MSVWBRIovC/BTW589iUE/Vxav7VeM4RcY9MUjqB+IR6ILG1k9nuW6LiG/nct9uma4/MBtnZbmQ==}
engines: {node: '>=20'}
@@ -17244,10 +17193,6 @@ packages:
react: ^18.0.0
react-dom: ^18.0.0
sort-keys@5.0.0:
resolution: {integrity: sha512-Pdz01AvCAottHTPQGzndktFNdbRA75BgOfeT1hH+AMnJFv8lynkPi42rfeEhpx1saTEI3YNMWxfqu0sFD1G8pw==}
engines: {node: '>=12'}
source-map-js@1.2.2:
resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==}
engines: {node: '>=0.10.0'}
@@ -17856,10 +17801,6 @@ packages:
resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==}
engines: {node: '>=8'}
type-fest@1.4.0:
resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==}
engines: {node: '>=10'}
type-fest@4.30.0:
resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==}
engines: {node: '>=16'}
@@ -19326,7 +19267,7 @@ snapshots:
js-yaml: 4.3.2
picomatch: 4.0.7
retext-smartypants: 6.2.0
shiki: 4.2.0
shiki: 4.5.0
smol-toml: 1.9.0
unified: 11.0.5
@@ -24994,14 +24935,6 @@ snapshots:
eslint: 9.37.0(jiti@2.7.0)(supports-color@8.1.1)
oxc-parser: 0.148.0
'@shikijs/compat@1.6.0':
dependencies:
'@shikijs/core': 1.6.0
'@shikijs/transformers': 1.6.0
shiki: 1.6.0
'@shikijs/core@1.6.0': {}
'@shikijs/core@3.13.0':
dependencies:
'@shikijs/types': 3.13.0
@@ -25009,14 +24942,6 @@ snapshots:
'@types/hast': 3.0.5
hast-util-to-html: 9.0.5
'@shikijs/core@4.2.0':
dependencies:
'@shikijs/primitive': 4.2.0
'@shikijs/types': 4.2.0
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.5
hast-util-to-html: 9.0.5
'@shikijs/core@4.5.0':
dependencies:
'@shikijs/primitive': 4.5.0
@@ -25031,12 +24956,6 @@ snapshots:
'@shikijs/vscode-textmate': 10.0.2
oniguruma-to-es: 4.3.3
'@shikijs/engine-javascript@4.2.0':
dependencies:
'@shikijs/types': 4.2.0
'@shikijs/vscode-textmate': 10.0.2
oniguruma-to-es: 4.3.6
'@shikijs/engine-javascript@4.5.0':
dependencies:
'@shikijs/types': 4.5.0
@@ -25048,11 +24967,6 @@ snapshots:
'@shikijs/types': 3.13.0
'@shikijs/vscode-textmate': 10.0.2
'@shikijs/engine-oniguruma@4.2.0':
dependencies:
'@shikijs/types': 4.2.0
'@shikijs/vscode-textmate': 10.0.2
'@shikijs/engine-oniguruma@4.5.0':
dependencies:
'@shikijs/types': 4.5.0
@@ -25062,20 +24976,10 @@ snapshots:
dependencies:
'@shikijs/types': 3.13.0
'@shikijs/langs@4.2.0':
dependencies:
'@shikijs/types': 4.2.0
'@shikijs/langs@4.5.0':
dependencies:
'@shikijs/types': 4.5.0
'@shikijs/primitive@4.2.0':
dependencies:
'@shikijs/types': 4.2.0
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.5
'@shikijs/primitive@4.5.0':
dependencies:
'@shikijs/types': 4.5.0
@@ -25086,28 +24990,15 @@ snapshots:
dependencies:
'@shikijs/types': 3.13.0
'@shikijs/themes@4.2.0':
dependencies:
'@shikijs/types': 4.2.0
'@shikijs/themes@4.5.0':
dependencies:
'@shikijs/types': 4.5.0
'@shikijs/transformers@1.6.0':
dependencies:
shiki: 1.6.0
'@shikijs/types@3.13.0':
dependencies:
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.5
'@shikijs/types@4.2.0':
dependencies:
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.5
'@shikijs/types@4.5.0':
dependencies:
'@shikijs/vscode-textmate': 10.0.2
@@ -27878,7 +27769,7 @@ snapshots:
piccolore: 0.1.3
picomatch: 4.0.5
semver: 7.8.5
shiki: 4.2.0
shiki: 4.5.0
smol-toml: 1.9.0
svgo: 4.1.0
tinyclip: 0.1.15
@@ -30978,12 +30869,6 @@ snapshots:
has-unicode@2.0.1: {}
hash-obj@4.0.0:
dependencies:
is-obj: 3.0.0
sort-keys: 5.0.0
type-fest: 1.4.0
hasown@2.0.2:
dependencies:
function-bind: 1.1.2
@@ -35747,12 +35632,21 @@ snapshots:
unist-util-visit-parents: 6.0.1
vfile: 6.0.3
rehype-pretty-code@0.9.11(shiki@1.6.0):
rehype-parse@9.0.1:
dependencies:
'@types/hast': 2.3.6
hash-obj: 4.0.0
'@types/hast': 3.0.5
hast-util-from-html: 2.0.3
unified: 11.0.5
rehype-pretty-code@0.14.5(shiki@4.5.0):
dependencies:
'@types/hast': 3.0.5
hast-util-to-string: 3.0.0
parse-numeric-range: 1.3.0
shiki: 1.6.0
rehype-parse: 9.0.1
shiki: 4.5.0
unified: 11.0.5
unist-util-visit: 5.1.0
rehype-raw@7.0.0:
dependencies:
@@ -36560,10 +36454,6 @@ snapshots:
interpret: 1.4.0
rechoir: 0.6.2
shiki@1.6.0:
dependencies:
'@shikijs/core': 1.6.0
shiki@3.13.0:
dependencies:
'@shikijs/core': 3.13.0
@@ -36575,17 +36465,6 @@ snapshots:
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.5
shiki@4.2.0:
dependencies:
'@shikijs/core': 4.2.0
'@shikijs/engine-javascript': 4.2.0
'@shikijs/engine-oniguruma': 4.2.0
'@shikijs/langs': 4.2.0
'@shikijs/themes': 4.2.0
'@shikijs/types': 4.2.0
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.5
shiki@4.5.0:
dependencies:
'@shikijs/core': 4.5.0
@@ -36741,10 +36620,6 @@ snapshots:
react: 19.2.6
react-dom: 19.2.6(react@19.2.6)
sort-keys@5.0.0:
dependencies:
is-plain-obj: 4.1.0
source-map-js@1.2.2: {}
source-map-support@0.5.21:
@@ -37358,8 +37233,6 @@ snapshots:
type-fest@0.7.1: {}
type-fest@1.4.0: {}
type-fest@4.30.0: {}
type-fest@5.6.0:
+1
View File
@@ -46,6 +46,7 @@ catalog:
react: ^19.2.6
react-dom: ^19.2.6
recharts: ^2.15.4
rehype-pretty-code: ^0.14.5
shiki: ^4.5.0
tailwindcss: ^4.2.4
tsx: ^4.22.0