diff --git a/packages/docusaurus-mdx-loader/src/processor.ts b/packages/docusaurus-mdx-loader/src/processor.ts index f5120150eeaf..0035ab66c799 100644 --- a/packages/docusaurus-mdx-loader/src/processor.ts +++ b/packages/docusaurus-mdx-loader/src/processor.ts @@ -15,7 +15,7 @@ import details from './remark/details'; import head from './remark/head'; import mermaid from './remark/mermaid'; import transformAdmonitions from './remark/admonitions'; -import unusedDirectivesWarning from './remark/unusedDirectives'; +import unusedDirectives from './remark/unusedDirectives'; import codeCompatPlugin from './remark/mdx1Compat/codeCompatPlugin'; import {getFormat} from './format'; import type {WebpackCompilerName} from '@docusaurus/utils'; @@ -25,6 +25,7 @@ import type {AdmonitionOptions} from './remark/admonitions'; import type {PluginOptions as ResolveMarkdownLinksOptions} from './remark/resolveMarkdownLinks'; import type {PluginOptions as TransformLinksOptions} from './remark/transformLinks'; import type {PluginOptions as TransformImageOptions} from './remark/transformImage'; +import type {PluginOptions as UnusedDirectivesOptions} from './remark/unusedDirectives'; import type {ProcessorOptions} from '@mdx-js/mdx'; // TODO as of April 2023, no way to import/re-export this ESM type easily :/ @@ -151,7 +152,13 @@ async function createProcessorFactory() { gfm, options.markdownConfig.mdx1Compat.comments ? comment : null, ...(options.remarkPlugins ?? []), - unusedDirectivesWarning, + [ + unusedDirectives, + { + onUnusedMarkdownDirectives: + options.markdownConfig.hooks.onUnusedMarkdownDirectives, + } satisfies UnusedDirectivesOptions, + ], ].filter((plugin): plugin is MDXPlugin => Boolean(plugin)); // codeCompatPlugin needs to be applied last after user-provided plugins diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap index 5735ead56a93..9d8cd750bfe0 100644 --- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap @@ -58,6 +58,60 @@ exports[`directives remark plugin - client compiler > default behavior for text " `; +exports[`directives remark plugin - client compiler > onUnusedMarkdownDirectives > function form > if file contains unused container directive > result 1`] = ` +"

Take care of snowstorms...

+
+

:::NotAContainerDirective with a phrase after

+

:::

+

Phrase before :::NotAContainerDirective

+

:::

" +`; + +exports[`directives remark plugin - client compiler > onUnusedMarkdownDirectives > function form > if file contains unused leaf directive > result 1`] = ` +"
+

Leaf directive in a phrase ::NotALeafDirective

+

::NotALeafDirective with a phrase after

" +`; + +exports[`directives remark plugin - client compiler > onUnusedMarkdownDirectives > function form > if file contains unused text directive > result 1`] = ` +"

Simple: textDirective1

+
Simple: textDirectiveCode
+
+

Simple:textDirective2

+

Simple

+

Simple

+

Simple:textDirective5

+
Simple:textDirectiveCode
+
" +`; + +exports[`directives remark plugin - client compiler > onUnusedMarkdownDirectives > ignore > if file contains unused container directive > result 1`] = ` +"

Take care of snowstorms...

+

unused directive content

+

:::NotAContainerDirective with a phrase after

+

:::

+

Phrase before :::NotAContainerDirective

+

:::

" +`; + +exports[`directives remark plugin - client compiler > onUnusedMarkdownDirectives > ignore > if file contains unused leaf directive > result 1`] = ` +"
+

Leaf directive in a phrase ::NotALeafDirective

+

::NotALeafDirective with a phrase after

" +`; + +exports[`directives remark plugin - client compiler > onUnusedMarkdownDirectives > ignore > if file contains unused text directive > result 1`] = ` +"

Simple: textDirective1

+
Simple: textDirectiveCode
+
+

Simple:textDirective2

+

Simple

label

+

Simple

+

Simple:textDirective5

+
Simple:textDirectiveCode
+
" +`; + exports[`directives remark plugin - server compiler > default behavior for container directives > result 1`] = ` "

Take care of snowstorms...

unused directive content

diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts index e6eb8a8e3c43..b67f8356b78c 100644 --- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts @@ -10,38 +10,47 @@ import path from 'path'; import remark2rehype from 'remark-rehype'; import stringify from 'rehype-stringify'; import vfile from 'to-vfile'; -import plugin from '../index'; +import plugin, {type PluginOptions} from '../index'; import admonition from '../../admonitions'; import type {WebpackCompilerName} from '@docusaurus/utils'; +const getProcessor = async (options?: Partial) => { + const {remark} = await import('remark'); + const {default: directives} = await import('remark-directive'); + + return remark() + .use(directives) + .use(admonition) + .use(plugin, { + onUnusedMarkdownDirectives: 'warn', + ...options, + }) + .use(remark2rehype) + .use(stringify); +}; + const processFixture = async ( name: string, {compilerName}: {compilerName: WebpackCompilerName}, + options?: Partial, ) => { - const {remark} = await import('remark'); - const {default: directives} = await import('remark-directive'); + const processor = await getProcessor(options); const filePath = path.join(__dirname, '__fixtures__', `${name}.md`); const file = await vfile.read(filePath); file.data.compilerName = compilerName; - const result = await remark() - .use(directives) - .use(admonition) - .use(plugin) - .use(remark2rehype) - .use(stringify) - .process(file); + const result = await processor.process(file); return result.value; }; describe('directives remark plugin - client compiler', () => { - const options = {compilerName: 'client'} as const; + const fileData = {compilerName: 'client'} as const; it('default behavior for container directives', async () => { using warn = vi.spyOn(console, 'warn'); - const result = await processFixture('containerDirectives', options); + const result = await processFixture('containerDirectives', fileData); expect(result).toMatchSnapshot('result'); expect(warn).toHaveBeenCalledTimes(1); expect(warn.mock.calls).toMatchSnapshot('console'); @@ -49,7 +58,7 @@ describe('directives remark plugin - client compiler', () => { it('default behavior for leaf directives', async () => { using warn = vi.spyOn(console, 'warn'); - const result = await processFixture('leafDirectives', options); + const result = await processFixture('leafDirectives', fileData); expect(result).toMatchSnapshot('result'); expect(warn).toHaveBeenCalledTimes(1); expect(warn.mock.calls).toMatchSnapshot('console'); @@ -57,33 +66,260 @@ describe('directives remark plugin - client compiler', () => { it('default behavior for text directives', async () => { using warn = vi.spyOn(console, 'warn'); - const result = await processFixture('textDirectives', options); + const result = await processFixture('textDirectives', fileData); expect(result).toMatchSnapshot('result'); expect(warn).toHaveBeenCalledTimes(1); expect(warn.mock.calls).toMatchSnapshot('console'); }); + + describe('onUnusedMarkdownDirectives', () => { + describe('throws', () => { + const options = {onUnusedMarkdownDirectives: 'throw'} as const; + it('if file contains unused container directive', async () => { + await expect(processFixture('containerDirectives', fileData, options)) + .rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Docusaurus found 1 unused Markdown directives in file "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/containerDirectives.md" + - :::unusedDirective (7:1) + Your content might render in an unexpected way. Visit https://github.com/facebook/docusaurus/pull/9394 to find out why and how to fix it. + To ignore this error, use the \`siteConfig.markdown.hooks.onUnusedMarkdownDirectives\` option.] + `); + }); + it('if file contains unused leaf directive', async () => { + await expect(processFixture('leafDirectives', fileData, options)) + .rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Docusaurus found 1 unused Markdown directives in file "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/leafDirectives.md" + - ::unusedLeafDirective (1:1) + Your content might render in an unexpected way. Visit https://github.com/facebook/docusaurus/pull/9394 to find out why and how to fix it. + To ignore this error, use the \`siteConfig.markdown.hooks.onUnusedMarkdownDirectives\` option.] + `); + }); + it('if file contains unused text directive', async () => { + await expect(processFixture('textDirectives', fileData, options)) + .rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Docusaurus found 2 unused Markdown directives in file "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md" + - :textDirective3 (9:7) + - :textDirective4 (11:7) + Your content might render in an unexpected way. Visit https://github.com/facebook/docusaurus/pull/9394 to find out why and how to fix it. + To ignore this error, use the \`siteConfig.markdown.hooks.onUnusedMarkdownDirectives\` option.] + `); + }); + }); + + describe('function form', () => { + const options: PluginOptions = { + onUnusedMarkdownDirectives: (params) => { + console.log('onUnusedMarkdownDirectives called with', params); + // We can alter the AST Node + params.directives.forEach((directive) => { + directive.name = `fixed-${directive.name}`; + directive.children = []; + }); + }, + }; + it('if file contains unused container directive', async () => { + using log = vi.spyOn(console, 'log'); + const result = await processFixture( + 'containerDirectives', + fileData, + options, + ); + expect(result).toMatchSnapshot('result'); + expect(log).toHaveBeenCalledTimes(1); + expect(log.mock.calls).toMatchInlineSnapshot(` + [ + [ + "onUnusedMarkdownDirectives called with", + { + "directives": [ + { + "attributes": {}, + "children": [], + "name": "fixed-unusedDirective", + "position": { + "end": { + "column": 4, + "line": 11, + "offset": 93, + }, + "start": { + "column": 1, + "line": 7, + "offset": 44, + }, + }, + "type": "containerDirective", + }, + ], + "sourceFilePath": "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/containerDirectives.md", + }, + ], + ] + `); + }); + it('if file contains unused leaf directive', async () => { + using log = vi.spyOn(console, 'log'); + const result = await processFixture( + 'leafDirectives', + fileData, + options, + ); + expect(result).toMatchSnapshot('result'); + expect(log).toHaveBeenCalledTimes(1); + expect(log.mock.calls).toMatchInlineSnapshot(` + [ + [ + "onUnusedMarkdownDirectives called with", + { + "directives": [ + { + "attributes": {}, + "children": [], + "name": "fixed-unusedLeafDirective", + "position": { + "end": { + "column": 22, + "line": 1, + "offset": 21, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "leafDirective", + }, + ], + "sourceFilePath": "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/leafDirectives.md", + }, + ], + ] + `); + }); + it('if file contains unused text directive', async () => { + using log = vi.spyOn(console, 'log'); + const result = await processFixture( + 'textDirectives', + fileData, + options, + ); + expect(result).toMatchSnapshot('result'); + expect(log).toHaveBeenCalledTimes(1); + expect(log.mock.calls).toMatchInlineSnapshot(` + [ + [ + "onUnusedMarkdownDirectives called with", + { + "directives": [ + { + "attributes": {}, + "children": [], + "name": "fixed-textDirective3", + "position": { + "end": { + "column": 29, + "line": 9, + "offset": 112, + }, + "start": { + "column": 7, + "line": 9, + "offset": 90, + }, + }, + "type": "textDirective", + }, + { + "attributes": { + "age": "42", + }, + "children": [], + "name": "fixed-textDirective4", + "position": { + "end": { + "column": 30, + "line": 11, + "offset": 143, + }, + "start": { + "column": 7, + "line": 11, + "offset": 120, + }, + }, + "type": "textDirective", + }, + ], + "sourceFilePath": "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md", + }, + ], + ] + `); + }); + }); + + describe('ignore', () => { + const options = {onUnusedMarkdownDirectives: 'ignore'} as const; + it('if file contains unused container directive', async () => { + using warn = vi.spyOn(console, 'warn'); + using log = vi.spyOn(console, 'log'); + const result = await processFixture( + 'containerDirectives', + fileData, + options, + ); + expect(result).toMatchSnapshot('result'); + expect(log).toHaveBeenCalledTimes(0); + expect(warn).toHaveBeenCalledTimes(0); + }); + it('if file contains unused leaf directive', async () => { + using warn = vi.spyOn(console, 'warn'); + using log = vi.spyOn(console, 'log'); + const result = await processFixture( + 'leafDirectives', + fileData, + options, + ); + expect(result).toMatchSnapshot('result'); + expect(log).toHaveBeenCalledTimes(0); + expect(warn).toHaveBeenCalledTimes(0); + }); + it('if file contains unused text directive', async () => { + using warn = vi.spyOn(console, 'warn'); + using log = vi.spyOn(console, 'log'); + const result = await processFixture( + 'textDirectives', + fileData, + options, + ); + expect(result).toMatchSnapshot('result'); + expect(log).toHaveBeenCalledTimes(0); + expect(warn).toHaveBeenCalledTimes(0); + }); + }); + }); }); describe('directives remark plugin - server compiler', () => { - const options = {compilerName: 'server'} as const; + const fileData = {compilerName: 'server'} as const; it('default behavior for container directives', async () => { using warn = vi.spyOn(console, 'warn'); - const result = await processFixture('containerDirectives', options); + const result = await processFixture('containerDirectives', fileData); expect(result).toMatchSnapshot('result'); expect(warn).toHaveBeenCalledTimes(0); }); it('default behavior for leaf directives', async () => { using warn = vi.spyOn(console, 'warn'); - const result = await processFixture('leafDirectives', options); + const result = await processFixture('leafDirectives', fileData); expect(result).toMatchSnapshot('result'); expect(warn).toHaveBeenCalledTimes(0); }); it('default behavior for text directives', async () => { using warn = vi.spyOn(console, 'warn'); - const result = await processFixture('textDirectives', options); + const result = await processFixture('textDirectives', fileData); expect(result).toMatchSnapshot('result'); expect(warn).toHaveBeenCalledTimes(0); }); diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts index 29b458b19ce9..337a53cce590 100644 --- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts @@ -7,12 +7,16 @@ import path from 'path'; import process from 'process'; import logger from '@docusaurus/logger'; -import {posixPath} from '@docusaurus/utils'; +import {toMessageRelativeFilePath, posixPath} from '@docusaurus/utils'; import {formatNodePositionExtraMessage, transformNode} from '../utils'; import type {Root} from 'mdast'; import type {Parent} from 'unist'; import type {Transformer, Processor, Plugin} from 'unified'; import type {Directives, TextDirective} from 'mdast-util-directive'; +import type { + MarkdownConfig, + OnUnusedMarkdownDirectivesFunction, +} from '@docusaurus/types'; type DirectiveType = Directives['type']; @@ -64,19 +68,33 @@ ${warningMessages} Your content might render in an unexpected way. Visit ${customSupportUrl} to find out why and how to fix it.`; } -function logUnusedDirectivesWarning({ - directives, - filePath, -}: { - directives: Directives[]; - filePath: string; -}) { - if (directives.length > 0) { - const message = formatUnusedDirectivesMessage({ - directives, - filePath, - }); - logger.warn(message); +export type PluginOptions = { + onUnusedMarkdownDirectives: MarkdownConfig['hooks']['onUnusedMarkdownDirectives']; +}; + +function asFunction( + onUnusedMarkdownDirectives: PluginOptions['onUnusedMarkdownDirectives'], +): OnUnusedMarkdownDirectivesFunction { + if (typeof onUnusedMarkdownDirectives === 'string') { + const extraHelp = + onUnusedMarkdownDirectives === 'throw' + ? logger.interpolate`\nTo ignore this error, use the code=${'siteConfig.markdown.hooks.onUnusedMarkdownDirectives'} option.` + : ''; + return ({sourceFilePath, directives}) => { + const relativePath = toMessageRelativeFilePath(sourceFilePath); + logger.report(onUnusedMarkdownDirectives)`${formatUnusedDirectivesMessage( + { + directives, + filePath: relativePath, + }, + )}${extraHelp}`; + }; + } else { + return (params) => + onUnusedMarkdownDirectives({ + ...params, + sourceFilePath: toMessageRelativeFilePath(params.sourceFilePath), + }); } } @@ -112,9 +130,14 @@ function isUnusedDirective(directive: Directives) { return !directive.data; } -const plugin: Plugin = function plugin( +const plugin: Plugin = function plugin( this: Processor, + options, ): Transformer { + const onUnusedMarkdownDirectives = asFunction( + options.onUnusedMarkdownDirectives, + ); + return async (tree, file) => { const {visit} = await import('unist-util-visit'); @@ -133,14 +156,14 @@ const plugin: Plugin = function plugin( } }); - // We only enable these warnings for the client compiler - // This avoids emitting duplicate warnings in prod mode + // We only process unused directives for the client compiler + // This avoids emitting duplicate errors/warnings in prod mode // Note: the client compiler is used in both dev/prod modes // Also: the client compiler is what gets used when using crossCompilerCache - if (file.data.compilerName === 'client') { - logUnusedDirectivesWarning({ + if (file.data.compilerName === 'client' && unusedDirectives.length > 0) { + onUnusedMarkdownDirectives({ + sourceFilePath: file.path!, directives: unusedDirectives, - filePath: file.path, }); } }; diff --git a/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemapItem.test.ts b/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemapItem.test.ts index 339d9e45ae36..92e9384d3258 100644 --- a/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemapItem.test.ts +++ b/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemapItem.test.ts @@ -108,6 +108,15 @@ describe('createSitemapItem', () => { } `); }); + + it('lastmod from epoch (0) timestamp is not dropped', async () => { + await expect( + test({ + options: {lastmod: 'date'}, + route: {metadata: {lastUpdatedAt: 0}, path: '/routePath'}, + }), + ).resolves.toMatchObject({lastmod: '1970-01-01'}); + }); }); describe('read from git', () => { diff --git a/packages/docusaurus-plugin-sitemap/src/createSitemapItem.ts b/packages/docusaurus-plugin-sitemap/src/createSitemapItem.ts index 065306e3f493..0b1bc2ed1346 100644 --- a/packages/docusaurus-plugin-sitemap/src/createSitemapItem.ts +++ b/packages/docusaurus-plugin-sitemap/src/createSitemapItem.ts @@ -21,7 +21,7 @@ async function getRouteLastUpdatedAt( if (route.metadata?.lastUpdatedAt === null) { return null; } - if (route.metadata?.lastUpdatedAt) { + if (route.metadata?.lastUpdatedAt != null) { return route.metadata?.lastUpdatedAt; } if (route.metadata?.sourceFilePath) { @@ -59,7 +59,7 @@ async function getRouteLastmod({ return null; } const lastUpdatedAt = (await getRouteLastUpdatedAt(route, vcs)) ?? null; - return lastUpdatedAt ? formatLastmod(lastUpdatedAt, lastmod) : null; + return lastUpdatedAt != null ? formatLastmod(lastUpdatedAt, lastmod) : null; } export async function createSitemapItem({ diff --git a/packages/docusaurus-theme-mermaid/package.json b/packages/docusaurus-theme-mermaid/package.json index 03721229cff8..b20c179419ad 100644 --- a/packages/docusaurus-theme-mermaid/package.json +++ b/packages/docusaurus-theme-mermaid/package.json @@ -42,7 +42,7 @@ "tslib": "^2.6.0" }, "peerDependencies": { - "@mermaid-js/layout-elk": "^0.1.9", + "@mermaid-js/layout-elk": "^0.2.2", "react": "^19.2.5", "react-dom": "^19.2.5" }, diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 6dfca63d1f70..6cdd2f839bb1 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -28,6 +28,7 @@ export { ParseFrontMatter, OnBrokenMarkdownLinksFunction, OnBrokenMarkdownImagesFunction, + OnUnusedMarkdownDirectivesFunction, } from './markdown'; export {ReportingSeverity} from './reporting'; diff --git a/packages/docusaurus-types/src/markdown.d.ts b/packages/docusaurus-types/src/markdown.d.ts index e7904f46bcc1..7c2d84cd3fdf 100644 --- a/packages/docusaurus-types/src/markdown.d.ts +++ b/packages/docusaurus-types/src/markdown.d.ts @@ -7,6 +7,7 @@ import type {ProcessorOptions} from '@mdx-js/mdx'; import type {Image, Definition, Link} from 'mdast'; +import type {Directives} from 'mdast-util-directive'; import type {ReportingSeverity} from './reporting'; @@ -86,6 +87,21 @@ export type OnBrokenMarkdownImagesFunction = (params: { node: Image; }) => void | string; +export type OnUnusedMarkdownDirectivesFunction = (params: { + /** + * Path of the source file on which the unused directive was found + * Relative to the site dir. + * Example: "docs/category/myDoc.mdx" + */ + sourceFilePath: string; + + /** + * The Markdown directives that were unused. + * Example: "myDirective" + */ + directives: Directives[]; +}) => void | string; + export type MarkdownHooks = { /** * The behavior of Docusaurus when it detects any broken Markdown link. @@ -97,6 +113,10 @@ export type MarkdownHooks = { onBrokenMarkdownLinks: ReportingSeverity | OnBrokenMarkdownLinksFunction; onBrokenMarkdownImages: ReportingSeverity | OnBrokenMarkdownImagesFunction; + + onUnusedMarkdownDirectives: + | ReportingSeverity + | OnUnusedMarkdownDirectivesFunction; }; export type MarkdownConfig = { diff --git a/packages/docusaurus-utils-validation/src/validationSchemas.ts b/packages/docusaurus-utils-validation/src/validationSchemas.ts index f1c79abcf34f..e011681107f5 100644 --- a/packages/docusaurus-utils-validation/src/validationSchemas.ts +++ b/packages/docusaurus-utils-validation/src/validationSchemas.ts @@ -9,6 +9,7 @@ import { isValidPathname, DEFAULT_PLUGIN_ID, type FrontMatterTag, + type FrontMatterLastUpdate, } from '@docusaurus/utils'; import {addLeadingSlash} from '@docusaurus/utils-common'; import Joi from './Joi'; @@ -152,12 +153,13 @@ export type ContentVisibility = { unlisted: boolean; }; -export const ContentVisibilitySchema = JoiFrontMatter.object( - { - draft: JoiFrontMatter.boolean(), - unlisted: JoiFrontMatter.boolean(), - }, -) +export const ContentVisibilitySchema = JoiFrontMatter.object< + ContentVisibility, + true +>({ + draft: JoiFrontMatter.boolean(), + unlisted: JoiFrontMatter.boolean(), +}) .custom((frontMatter: ContentVisibility, helpers) => { if (frontMatter.draft && frontMatter.unlisted) { return helpers.error('frontMatter.draftAndUnlistedError'); @@ -173,9 +175,14 @@ export const ContentVisibilitySchema = JoiFrontMatter.object( export const FrontMatterLastUpdateErrorMessage = '{{#label}} does not look like a valid last update object. Please use an author key with a string or a date with a string or Date.'; -export const FrontMatterLastUpdateSchema = Joi.object({ +export const FrontMatterLastUpdateSchema = Joi.object< + FrontMatterLastUpdate, + true +>({ author: Joi.string(), - date: Joi.date().raw(), + // Joi doesn't like our "string | Date" union type + // It expects an "alternative" type, even when using date().raw() + date: Joi.alternatives().try(Joi.date().raw()), }) .or('author', 'date') .messages({ diff --git a/packages/docusaurus/src/client/BaseUrlIssueBanner/index.tsx b/packages/docusaurus/src/client/BaseUrlIssueBanner/index.tsx index e378195f72ad..326872fb2738 100644 --- a/packages/docusaurus/src/client/BaseUrlIssueBanner/index.tsx +++ b/packages/docusaurus/src/client/BaseUrlIssueBanner/index.tsx @@ -61,7 +61,7 @@ function insertBanner() { var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/' ? actualHomePagePath : actualHomePagePath + '/'; - suggestionContainer.innerHTML = suggestedBaseUrl; + suggestionContainer.textContent = suggestedBaseUrl; } `; } diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap index 229eb8ecc9d4..91cd600f31af 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap @@ -50,6 +50,7 @@ exports[`loadSiteConfig > website with .cjs siteConfig 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -137,6 +138,7 @@ exports[`loadSiteConfig > website with ts + js config 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -224,6 +226,7 @@ exports[`loadSiteConfig > website with valid JS CJS config 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -311,6 +314,7 @@ exports[`loadSiteConfig > website with valid JS ESM config 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -398,6 +402,7 @@ exports[`loadSiteConfig > website with valid TypeScript CJS config 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -485,6 +490,7 @@ exports[`loadSiteConfig > website with valid TypeScript ESM config 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -572,6 +578,7 @@ exports[`loadSiteConfig > website with valid async config 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -661,6 +668,7 @@ exports[`loadSiteConfig > website with valid async config creator function 1`] = "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -750,6 +758,7 @@ exports[`loadSiteConfig > website with valid config creator function 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -842,6 +851,7 @@ exports[`loadSiteConfig > website with valid siteConfig 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap index 0cda8a64877a..f2859430fdc3 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap @@ -138,6 +138,7 @@ exports[`loadSite > custom-i18n-site > loads site 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -305,6 +306,7 @@ exports[`loadSite > simple-site-with-baseUrl > loads site - custom config 1`] = "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -472,6 +474,7 @@ exports[`loadSite > simple-site-with-baseUrl > loads site - custom outDir 1`] = "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -639,6 +642,7 @@ exports[`loadSite > simple-site-with-baseUrl > loads site 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -872,6 +876,7 @@ exports[`loadSite > simple-site-with-baseUrl-i18n > loads site - locale fr + cu "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -1105,6 +1110,7 @@ exports[`loadSite > simple-site-with-baseUrl-i18n > loads site - custom outDir 1 "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -1338,6 +1344,7 @@ exports[`loadSite > simple-site-with-baseUrl-i18n > loads site - locale de 1`] = "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -1571,6 +1578,7 @@ exports[`loadSite > simple-site-with-baseUrl-i18n > loads site - locale en 1`] = "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -1804,6 +1812,7 @@ exports[`loadSite > simple-site-with-baseUrl-i18n > loads site - locale es 1`] = "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -2037,6 +2046,7 @@ exports[`loadSite > simple-site-with-baseUrl-i18n > loads site - locale fr 1`] = "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -2270,6 +2280,7 @@ exports[`loadSite > simple-site-with-baseUrl-i18n > loads site - locale it 1`] = "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, @@ -2503,6 +2514,7 @@ exports[`loadSite > simple-site-with-baseUrl-i18n > loads site 1`] = ` "hooks": { "onBrokenMarkdownImages": "throw", "onBrokenMarkdownLinks": "warn", + "onUnusedMarkdownDirectives": "warn", }, "mdx1Compat": { "admonitions": true, diff --git a/packages/docusaurus/src/server/__tests__/configValidation.test.ts b/packages/docusaurus/src/server/__tests__/configValidation.test.ts index 63dce02913f5..3f635fb0d1b6 100644 --- a/packages/docusaurus/src/server/__tests__/configValidation.test.ts +++ b/packages/docusaurus/src/server/__tests__/configValidation.test.ts @@ -130,6 +130,7 @@ describe('normalizeConfig', () => { hooks: { onBrokenMarkdownLinks: 'log', onBrokenMarkdownImages: 'log', + onUnusedMarkdownDirectives: 'log', }, }, }; @@ -330,24 +331,40 @@ describe('headTags', () => { ).not.toThrow(); }); - it("throws error if headTags doesn't have string attributes", () => { + it('throws error if headTags has invalid attribute values', () => { expect(() => { normalizeConfig({ headTags: [ { tagName: 'link', attributes: { - rel: false, + rel: 123, href: 'img/docusaurus.png', }, }, ], }); }).toThrowErrorMatchingInlineSnapshot(` - [Error: "headTags[0].attributes.rel" must be a string + [Error: "headTags[0].attributes.rel" must be one of [string, boolean] ] `); }); + + it('accepts headTags with boolean attributes', () => { + expect(() => { + normalizeConfig({ + headTags: [ + { + tagName: 'script', + attributes: { + src: '/analytics.js', + async: true, + }, + }, + ], + }); + }).not.toThrow(); + }); }); describe('css', () => { @@ -546,6 +563,7 @@ describe('markdown', () => { hooks: { onBrokenMarkdownLinks: 'log', onBrokenMarkdownImages: 'warn', + onUnusedMarkdownDirectives: 'warn', }, }; expect(normalizeMarkdown(markdown)).toEqual(markdown); @@ -818,6 +836,47 @@ describe('markdown', () => { `); }); }); + + describe('onUnusedMarkdownDirectives', () => { + function normalizeValue( + onUnusedMarkdownDirectives?: MarkdownHooks['onUnusedMarkdownDirectives'], + ) { + return normalizeHooks({ + onUnusedMarkdownDirectives, + }).onUnusedMarkdownDirectives; + } + + it('accepts undefined', () => { + expect(normalizeValue(undefined)).toBe('warn'); + }); + + it('accepts severity level', () => { + expect(normalizeValue('log')).toBe('log'); + }); + + it('rejects number', () => { + expect(() => + normalizeValue( + // @ts-expect-error: bad value + 42, + ), + ).toThrowErrorMatchingInlineSnapshot(` + [Error: "markdown.hooks.onUnusedMarkdownDirectives" does not match any of the allowed types + ] + `); + }); + + it('accepts function', () => { + expect(normalizeValue(() => {})).toBeInstanceOf(Function); + }); + + it('rejects null', () => { + expect(() => normalizeValue(null)).toThrowErrorMatchingInlineSnapshot(` + [Error: "markdown.hooks.onUnusedMarkdownDirectives" does not match any of the allowed types + ] + `); + }); + }); }); }); diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index 462e5b2274d6..0e083b355058 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -123,6 +123,7 @@ export const DEFAULT_FUTURE_CONFIG: FutureConfig = { export const DEFAULT_MARKDOWN_HOOKS: MarkdownHooks = { onBrokenMarkdownLinks: 'warn', onBrokenMarkdownImages: 'throw', + onUnusedMarkdownDirectives: 'warn', }; export const DEFAULT_MARKDOWN_MDX1COMPAT: MDX1CompatOptions = { @@ -469,7 +470,10 @@ export const ConfigSchema = Joi.object({ is: Joi.valid(true), then: Joi.optional(), otherwise: Joi.object() - .pattern(/[\w-]+/, Joi.string()) + .pattern( + /[\w-]+/, + Joi.alternatives().try(Joi.string(), Joi.boolean()), + ) .required(), }), customElement: Joi.bool().default(false), @@ -548,6 +552,12 @@ export const ConfigSchema = Joi.object({ Joi.function(), ) .default(DEFAULT_CONFIG.markdown.hooks.onBrokenMarkdownImages), + onUnusedMarkdownDirectives: Joi.alternatives() + .try( + Joi.string().equal('ignore', 'log', 'warn', 'throw'), + Joi.function(), + ) + .default(DEFAULT_CONFIG.markdown.hooks.onUnusedMarkdownDirectives), }).default(DEFAULT_CONFIG.markdown.hooks), }).default({ ...DEFAULT_CONFIG.markdown, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11579bd47527..57e3ec0d697a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,7 @@ importers: devDependencies: '@ai-sdk/react': specifier: ^3.0.177 - version: 3.0.177(react@19.2.6)(zod@4.4.3) + version: 3.0.219(react@19.2.6)(zod@4.4.3) '@crowdin/cli': specifier: ^4.14.2 version: 4.14.2(encoding@0.1.13) @@ -72,7 +72,7 @@ importers: version: 5.2.0(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) '@vitest/eslint-plugin': specifier: ^1.6.17 - version: 1.6.20(@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)(vitest@4.1.7(@opentelemetry/api@1.9.0)(@types/node@25.9.1)(jsdom@25.0.1(supports-color@7.2.0))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0))) + version: 1.6.20(@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)(vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(jsdom@25.0.1(supports-color@7.2.0))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0))) cross-env: specifier: ^10.1.0 version: 10.1.0 @@ -162,7 +162,7 @@ importers: version: 3.0.2 sharp: specifier: ^0.35.1 - version: 0.35.1 + version: 0.35.3(@types/node@25.9.1) strip-ansi: specifier: ^7.2.0 version: 7.2.0 @@ -186,7 +186,7 @@ importers: version: 8.60.0(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) vitest: specifier: ^4.0.0 - version: 4.1.7(@opentelemetry/api@1.9.0)(@types/node@25.9.1)(jsdom@25.0.1(supports-color@7.2.0))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) + version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(jsdom@25.0.1(supports-color@7.2.0))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) admin/new.docusaurus.io: dependencies: @@ -1190,7 +1190,7 @@ importers: version: link:../lqip-loader '@docusaurus/responsive-loader': specifier: ^1.7.1 - version: 1.7.1(jimp@1.6.1(supports-color@7.2.0))(sharp@0.35.1) + version: 1.7.1(jimp@1.6.1(supports-color@7.2.0))(sharp@0.35.3(@types/node@25.9.1)) '@docusaurus/theme-translations': specifier: 3.10.1 version: link:../docusaurus-theme-translations @@ -1211,7 +1211,7 @@ importers: version: 19.2.6(react@19.2.6) sharp: specifier: ^0.35.1 - version: 0.35.1 + version: 0.35.3(@types/node@25.9.1) tslib: specifier: ^2.6.0 version: 2.8.1 @@ -1312,7 +1312,7 @@ importers: version: link:../docusaurus-utils-validation '@rsdoctor/rspack-plugin': specifier: ^1.5.17 - version: 1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) + version: 1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@rspack/core@2.1.2)(supports-color@7.2.0)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) '@rsdoctor/webpack-plugin': specifier: ^1.5.17 version: 1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) @@ -1745,8 +1745,8 @@ importers: specifier: 3.10.1 version: link:../docusaurus-utils-validation '@mermaid-js/layout-elk': - specifier: ^0.1.9 - version: 0.1.9(mermaid@11.15.0) + specifier: ^0.2.2 + version: 0.2.2(mermaid@11.15.0) mermaid: specifier: '>=11.14.0' version: 11.15.0 @@ -2054,7 +2054,7 @@ importers: version: 4.18.1 sharp: specifier: ^0.35.1 - version: 0.35.1 + version: 0.35.3(@types/node@25.9.1) tslib: specifier: ^2.6.0 version: 2.8.1 @@ -2144,8 +2144,8 @@ importers: specifier: 3.10.1 version: link:../packages/docusaurus-utils-validation '@mermaid-js/layout-elk': - specifier: ^0.1.9 - version: 0.1.9(mermaid@11.15.0) + specifier: ^0.2.2 + version: 0.2.2(mermaid@11.15.0) clsx: specifier: ^2.0.0 version: 2.1.1 @@ -2171,8 +2171,8 @@ importers: specifier: ^19.2.5 version: 19.2.6(react@19.2.6) react-lite-youtube-embed: - specifier: ^2.3.52 - version: 2.6.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + specifier: ^3.6.0 + version: 3.6.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react-medium-image-zoom: specifier: ^5.1.6 version: 5.4.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -2226,24 +2226,24 @@ packages: '@adobe/css-tools@4.5.0': resolution: {integrity: sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==} - '@ai-sdk/gateway@3.0.110': - resolution: {integrity: sha512-sbv8+1L9/BRKydn8dMNwoMQKupA4iLJ9N+yvxgW6wMQ/94UepDf3FeYWMj/dLdzolAHZ6izRUP4s5WqQkmJ2Zg==} + '@ai-sdk/gateway@3.0.141': + resolution: {integrity: sha512-BVisCihanCq+rXJZHY+aKVOSHe+gQDEitSexnvU9UuRTX/P16fu4x31AZLDNIR/bWAShT3Ct+dDltO1enBPK6Q==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider-utils@4.0.26': - resolution: {integrity: sha512-CsKNLKsOpvPujRlIYvoz+Ybw+kGn7J4/fIZa/58+R7iWLLfwn6ifE2G6Yq8K9XvH/I/3bzaDAJ3NhRwEMsLBKQ==} + '@ai-sdk/provider-utils@4.0.34': + resolution: {integrity: sha512-VL3tE0RV1ZwrtC8grTfcveFoyy9X96blfnRzIx5ayeGlCyTKpsZ4U4Ej3XpjOppAyAXKNflYSHAktOHE6gTLiw==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider@3.0.10': - resolution: {integrity: sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw==} + '@ai-sdk/provider@3.0.13': + resolution: {integrity: sha512-ZPtVYt5QIJzOta1kdUiDuCx4HhFkvNPv/rvmZ2b1iXwybYjJsCnNYR4PAw4kW7rgVfDARvHXcU64efWuqNp6bw==} engines: {node: '>=18'} - '@ai-sdk/react@3.0.177': - resolution: {integrity: sha512-7K3bmj2ajbAkrqR7P8bByKp0w2iACGSIpahoEkeUhhZqVJO4/mxqk6Q5wcd12EaOi+5+86k2VH91BKgzCuCRaw==} + '@ai-sdk/react@3.0.219': + resolution: {integrity: sha512-yzU0HAlDo0tEm6jQD3jTGTKvDs0k6Bm3ls5dvUwuqxgZ0Hnt4NK3C8NOxljxUWNkJsQve595X5ifCH7Gxhyf1A==} engines: {node: '>=18'} peerDependencies: react: ^18 || ~19.0.1 || ~19.1.2 || ^19.2.1 @@ -3631,9 +3631,6 @@ packages: '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} - '@emnapi/runtime@1.11.0': - resolution: {integrity: sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==} - '@emnapi/runtime@1.11.1': resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} @@ -3766,75 +3763,150 @@ packages: cpu: [arm64] os: [darwin] + '@img/sharp-darwin-arm64@0.35.3': + resolution: {integrity: sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [darwin] + '@img/sharp-darwin-x64@0.35.1': resolution: {integrity: sha512-t1CPD0cr7XCHjwUj6tQ5MC0pCi866I+gUW6zbUX4aFPnKd1DFBtk0M+gWcjX8VeEzgfCNiSiNTVFZ6b7kvdbnQ==} engines: {node: '>=20.9.0'} cpu: [x64] os: [darwin] + '@img/sharp-darwin-x64@0.35.3': + resolution: {integrity: sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [darwin] + '@img/sharp-freebsd-wasm32@0.35.1': resolution: {integrity: sha512-MBSQXqNPThW9EcZ905H6N4sEdX5EwZEYzGx5EBq9ncDCGJALMiY1xPFJxNdzuB1iBjLOpIfxajM6YxdvwmQSLA==} engines: {node: '>=20.9.0'} os: [freebsd] + '@img/sharp-freebsd-wasm32@0.35.3': + resolution: {integrity: sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==} + engines: {node: '>=20.9.0'} + os: [freebsd] + '@img/sharp-libvips-darwin-arm64@1.3.0': resolution: {integrity: sha512-EKbmBKtyTH+GPFDRw2TgK2oV6hyxxlJVIar4hoTYSNmIwipgMFdxPQqR392GmfdsPGWga0mCFN1cCKjRb9cljw==} cpu: [arm64] os: [darwin] + '@img/sharp-libvips-darwin-arm64@1.3.2': + resolution: {integrity: sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==} + cpu: [arm64] + os: [darwin] + '@img/sharp-libvips-darwin-x64@1.3.0': resolution: {integrity: sha512-Pl2OmOvrJ42adUllESxBsG54PfXLo1OYg9i3c5/5Ln/qJ0gZuTM9YMhQJPIbXqwidLRc/c2zuHt4RsrymmNv7A==} cpu: [x64] os: [darwin] + '@img/sharp-libvips-darwin-x64@1.3.2': + resolution: {integrity: sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==} + cpu: [x64] + os: [darwin] + '@img/sharp-libvips-linux-arm64@1.3.0': resolution: {integrity: sha512-C0SqjoFKnszqa44EQ7xoaT48nnO0lOyXEULfXMWi8krrjOPGYkeK30Okzla6ATbBYsyZ0ySinK0FVkpv3DwzfQ==} cpu: [arm64] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-arm64@1.3.2': + resolution: {integrity: sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-arm@1.3.0': resolution: {integrity: sha512-A8UpHoUDW4DwnXoV6+q3C1s7QLRAHtPDEjWuNZjwHMyoCNZnm0GeNN8ls9f/bsEYTRQRW96C/n34XJQHJ2fT7A==} cpu: [arm] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-arm@1.3.2': + resolution: {integrity: sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==} + cpu: [arm] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-ppc64@1.3.0': resolution: {integrity: sha512-WOpkVxAjFd369iaIzEgNRreFD+gWdUMIGD5zplhNKNeqS6mm5dac3q2AFyCBmzYoAdouzZvRBgxy4z8QHZb4/A==} cpu: [ppc64] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-ppc64@1.3.2': + resolution: {integrity: sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-riscv64@1.3.0': resolution: {integrity: sha512-DRWw0mOHusrCCuw2rqP87oLg6PGlkomVDFqw2hIwsSfwWpu4k3XLcBPaKKl6ct/GtL/cwNkgwjV/tc0Mqht3VA==} cpu: [riscv64] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-riscv64@1.3.2': + resolution: {integrity: sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-s390x@1.3.0': resolution: {integrity: sha512-9APy+nFWhHS+kzLgWZfLcyrUd7YqnAQVa4BPOo4xkoHpdoktOAPG4cEr9+Jpl0TtqfVmcMJimNL5qNTyyOHZNA==} cpu: [s390x] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-s390x@1.3.2': + resolution: {integrity: sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-x64@1.3.0': resolution: {integrity: sha512-y9RNUYDe2A1UAdhLyfeOodGRszQdaEoe4nfOpp/sNVPl2CWIcUyFaDoCh4vPLPxu19803j2naLqZup2WxDXCLA==} cpu: [x64] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-x64@1.3.2': + resolution: {integrity: sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==} + cpu: [x64] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linuxmusl-arm64@1.3.0': resolution: {integrity: sha512-cC1wkC0Mlucd0KSiGrLkJnB/ZqPvZCntc/Lk7ZnYO5ZSbF2euNek4Xvxafojq+wN1q/W0eprdpUIjUr/EV2PBg==} cpu: [arm64] os: [linux] libc: [musl] + '@img/sharp-libvips-linuxmusl-arm64@1.3.2': + resolution: {integrity: sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==} + cpu: [arm64] + os: [linux] + libc: [musl] + '@img/sharp-libvips-linuxmusl-x64@1.3.0': resolution: {integrity: sha512-LiYMhUZicB1QG//+RvmYZpXJO8fYRENfp+MZUCnG9aw+AKvGAy9gPaCnuwsPcBFs8EV66M0NNxj9VHcNklE8zw==} cpu: [x64] os: [linux] libc: [musl] + '@img/sharp-libvips-linuxmusl-x64@1.3.2': + resolution: {integrity: sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==} + cpu: [x64] + os: [linux] + libc: [musl] + '@img/sharp-linux-arm64@0.35.1': resolution: {integrity: sha512-ErCRyGU7LeoaFBZ0xW8hhLlXzhAg80sc4vxePB86qvtEvW1jEhhmbiNBP4oEzZfPMnu6HwHXfzD2W2kBU+RnCw==} engines: {node: '>=20.9.0'} @@ -3842,6 +3914,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-arm64@0.35.3': + resolution: {integrity: sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@img/sharp-linux-arm@0.35.1': resolution: {integrity: sha512-jygmR02PpCYypt7xB7nst1vqjZp/BpRA/Kf9nK7qRponJ/KrLPaZWEG4G15z1d2FZ6XqI+T0350ha3RSnKx24A==} engines: {node: '>=20.9.0'} @@ -3849,6 +3928,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-arm@0.35.3': + resolution: {integrity: sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==} + engines: {node: '>=20.9.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + '@img/sharp-linux-ppc64@0.35.1': resolution: {integrity: sha512-LUWZ2+r2UoLCd8j0RLCwQ4gL6w47+Y7igxtVnPIDXOOEjV86LpBkAHq5VpJeg+GHbw0KN/JWlPJOdZjyZnFqFQ==} engines: {node: '>=20.9.0'} @@ -3856,6 +3942,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-ppc64@0.35.3': + resolution: {integrity: sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==} + engines: {node: '>=20.9.0'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@img/sharp-linux-riscv64@0.35.1': resolution: {integrity: sha512-i7x6J3mwF4JgT0sM4V4WlAWdJ0bucPtA9rzO1bTji1n5qgBq/W5nn87RvOQPleuuxahNoLdTngByD8/vDDLArw==} engines: {node: '>=20.9.0'} @@ -3863,6 +3956,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-riscv64@0.35.3': + resolution: {integrity: sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==} + engines: {node: '>=20.9.0'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@img/sharp-linux-s390x@0.35.1': resolution: {integrity: sha512-0zSaTUjTF0kIWTSYxD4EG/nvCU4jez53+3RdURtoY3HvbXtIQ98W90JnrGz/oLRFuEnfIy9+7xeq883euc0ZWw==} engines: {node: '>=20.9.0'} @@ -3870,6 +3970,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-s390x@0.35.3': + resolution: {integrity: sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==} + engines: {node: '>=20.9.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@img/sharp-linux-x64@0.35.1': resolution: {integrity: sha512-NbJD4mWdeyrNQKluO/tR/wBDOelcowSVGNBWxI0e3ZtlXc6F/UOVKDj1MLD4zl3oHTuvKW3s+MA9N54YTldAYw==} engines: {node: '>=20.9.0'} @@ -3877,6 +3984,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-x64@0.35.3': + resolution: {integrity: sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + '@img/sharp-linuxmusl-arm64@0.35.1': resolution: {integrity: sha512-VoW2sQCWI+0YIKQEmWJ8vzaQjTg9wIyfkFpvEfAS2h43X6iHu7GTk1hhOgB4IpSzCHe8UwQZIcx7b81VTaOrJA==} engines: {node: '>=20.9.0'} @@ -3884,6 +3998,13 @@ packages: os: [linux] libc: [musl] + '@img/sharp-linuxmusl-arm64@0.35.3': + resolution: {integrity: sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + '@img/sharp-linuxmusl-x64@0.35.1': resolution: {integrity: sha512-LjBoSd/c5JU0/K5MwzDMlgsSRP2bPn98JQGFFQAOLQ0bU/1z4ekxUdSKY9BmlwSh/cA+OrvpgsWqfZyYfVHBRw==} engines: {node: '>=20.9.0'} @@ -3891,33 +4012,67 @@ packages: os: [linux] libc: [musl] + '@img/sharp-linuxmusl-x64@0.35.3': + resolution: {integrity: sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [musl] + '@img/sharp-wasm32@0.35.1': resolution: {integrity: sha512-PCQUoQdZyE8tp3HpbevuihfUmgSP4qWI0FGEPWoeXqaS+cUrFfemabHQiebUmUmlUhCuNnQMxGrQ+CPqK4hnxg==} engines: {node: '>=20.9.0'} + '@img/sharp-wasm32@0.35.3': + resolution: {integrity: sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==} + engines: {node: '>=20.9.0'} + '@img/sharp-webcontainers-wasm32@0.35.1': resolution: {integrity: sha512-xU2ml2bU2OPxYVvW2A6ae4M1g5QKyhKG06P4FAt+YEaFQQO0919Qx+XxIZEUuWTMoDViLpMws2/dQwoe/VcA6A==} engines: {node: '>=20.9.0'} cpu: [wasm32] + '@img/sharp-webcontainers-wasm32@0.35.3': + resolution: {integrity: sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==} + engines: {node: '>=20.9.0'} + cpu: [wasm32] + '@img/sharp-win32-arm64@0.35.1': resolution: {integrity: sha512-IkmHwuFhYpd3bTsN5SAahjwhiAcyXPooBt8vEUgxY3T0IP70sSJ0nU1xiPzZY8AH/OB1XpV3j8aZSVSOSfTbdA==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [win32] + '@img/sharp-win32-arm64@0.35.3': + resolution: {integrity: sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [win32] + '@img/sharp-win32-ia32@0.35.1': resolution: {integrity: sha512-wQahqCi9MD8Yxzg4gVM4fNrZxh+r6vD55PyIg+WJPaM5ZRUyF35iQpwJCuma3r6viU9/8Pxlc+XHV+woVa6nCQ==} engines: {node: ^20.9.0} cpu: [ia32] os: [win32] + '@img/sharp-win32-ia32@0.35.3': + resolution: {integrity: sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==} + engines: {node: ^20.9.0} + cpu: [ia32] + os: [win32] + '@img/sharp-win32-x64@0.35.1': resolution: {integrity: sha512-WzBtkYtZHATLPe8XRharxZXxQ9cdLrQWHiwxt+BJ5rBsisQrKeeV86ErxPSVhcG6xCEuNhs0SqLpWr7XDa2k6w==} engines: {node: '>=20.9.0'} cpu: [x64] os: [win32] + '@img/sharp-win32-x64@0.35.3': + resolution: {integrity: sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [win32] + '@inquirer/ansi@1.0.2': resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} engines: {node: '>=18'} @@ -4364,8 +4519,8 @@ packages: '@types/react': '>=16' react: '>=16' - '@mermaid-js/layout-elk@0.1.9': - resolution: {integrity: sha512-HuvaqFZBr6yT9PpWYockvKAZPJVd89yn/UjOYPxhzbZxlybL2v+2BjVCg7MVH6vRs1irUohb/s42HEdec1CCZw==} + '@mermaid-js/layout-elk@0.2.2': + resolution: {integrity: sha512-vnH3gtqfhyBiRVKNpT8iDENTw18q/OF0GF/SfYfHN43KZpu+6eZDEOMHTfNYAkpmUWJNgtRQFIS6BTc7vH/DYQ==} peerDependencies: mermaid: ^11.0.2 @@ -4610,8 +4765,8 @@ packages: '@octokit/types@13.10.0': resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==} - '@opentelemetry/api@1.9.0': - resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + '@opentelemetry/api@1.9.1': + resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} '@oxc-project/types@0.132.0': @@ -6364,8 +6519,8 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} - ai@6.0.175: - resolution: {integrity: sha512-6fFFHzbh6FIZnYc31V6osOxq25ABJYCShfG0O6ajHiA4FB/DgnPi1mP8cO5aAU3HNSbQHiMazdlh9bIsp97mVA==} + ai@6.0.217: + resolution: {integrity: sha512-BCA/1sNqQwfmZ8RxK2i+oezgzwfo1IAYt+wxBVpZlRLFswyi+t5TU0/5GvV6Hic7A2/UlnMtljz/Q3F94+2WzA==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -8478,7 +8633,7 @@ packages: git-raw-commits@3.0.0: resolution: {integrity: sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==} engines: {node: '>=14'} - deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. + deprecated: Deprecated and no longer maintained. Use @conventional-changelog/git-client instead. hasBin: true git-remote-origin-url@2.0.0: @@ -8488,7 +8643,7 @@ packages: git-semver-tags@5.0.1: resolution: {integrity: sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==} engines: {node: '>=14'} - deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. + deprecated: Deprecated and no longer maintained. Use @conventional-changelog/git-client instead. hasBin: true git-up@7.0.0: @@ -11370,8 +11525,8 @@ packages: peerDependencies: react: ^18.0.0 || ^19.0.0 - react-lite-youtube-embed@2.6.0: - resolution: {integrity: sha512-IOz67PY67a/2hlEkiUIBJ9D6TYX7RQnJgCa5J2xgDWd9yhGxEacuamo4c3b5nV6+CwssyL6OCLtgFh2guaKsmw==} + react-lite-youtube-embed@3.6.0: + resolution: {integrity: sha512-LnMu5xtvIDe7BOgcSldClh3nQGjr0RsTCLDOhJwXG2sF79BPHniLaxz/qcQckfpV/k9mj06j8zPM5RAJ+AbNeA==} peerDependencies: react: '>=18.2.0' react-dom: '>=18.2.0' @@ -11815,11 +11970,6 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.8.4: - resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} - engines: {node: '>=10'} - hasBin: true - semver@7.8.5: resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} @@ -11870,6 +12020,15 @@ packages: resolution: {integrity: sha512-lW979AMi+ESidzMv/Lnv+F9bknzLyxLqFI05Sm433vOeRcltgxQmXpnfOOFIAlKtwXU/ksupm2srQoFCkR214g==} engines: {node: '>=20.9.0'} + sharp@0.35.3: + resolution: {integrity: sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==} + engines: {node: '>=20.9.0'} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -12295,8 +12454,8 @@ packages: '@swc/core': ^1.2.147 webpack: '>=2' - swr@2.4.1: - resolution: {integrity: sha512-2CC6CiKQtEwaEeNiqWTAw9PGykW8SR5zZX8MZk6TeAvEAnVS7Visz8WzphqgtQ8v2xz/4Q5K+j+SeMaKXeeQIA==} + swr@2.4.2: + resolution: {integrity: sha512-ej644Y2bvkIajfR32KGeSSdBXQW+ScjGjkybZgSE7kFpk9eGnV44XY9FJylXi+W75pavSX1PVNB57W5EbhGIYw==} peerDependencies: react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -13367,30 +13526,30 @@ snapshots: '@adobe/css-tools@4.5.0': {} - '@ai-sdk/gateway@3.0.110(zod@4.4.3)': + '@ai-sdk/gateway@3.0.141(zod@4.4.3)': dependencies: - '@ai-sdk/provider': 3.0.10 - '@ai-sdk/provider-utils': 4.0.26(zod@4.4.3) + '@ai-sdk/provider': 3.0.13 + '@ai-sdk/provider-utils': 4.0.34(zod@4.4.3) '@vercel/oidc': 3.2.0 zod: 4.4.3 - '@ai-sdk/provider-utils@4.0.26(zod@4.4.3)': + '@ai-sdk/provider-utils@4.0.34(zod@4.4.3)': dependencies: - '@ai-sdk/provider': 3.0.10 + '@ai-sdk/provider': 3.0.13 '@standard-schema/spec': 1.1.0 eventsource-parser: 3.1.0 zod: 4.4.3 - '@ai-sdk/provider@3.0.10': + '@ai-sdk/provider@3.0.13': dependencies: json-schema: 0.4.0 - '@ai-sdk/react@3.0.177(react@19.2.6)(zod@4.4.3)': + '@ai-sdk/react@3.0.219(react@19.2.6)(zod@4.4.3)': dependencies: - '@ai-sdk/provider-utils': 4.0.26(zod@4.4.3) - ai: 6.0.175(zod@4.4.3) + '@ai-sdk/provider-utils': 4.0.34(zod@4.4.3) + ai: 6.0.217(zod@4.4.3) react: 19.2.6 - swr: 2.4.1(react@19.2.6) + swr: 2.4.2(react@19.2.6) throttleit: 2.1.0 transitivePeerDependencies: - zod @@ -14991,12 +15150,12 @@ snapshots: '@types/react': 19.2.14 react: 19.2.6 - '@docusaurus/responsive-loader@1.7.1(jimp@1.6.1(supports-color@7.2.0))(sharp@0.35.1)': + '@docusaurus/responsive-loader@1.7.1(jimp@1.6.1(supports-color@7.2.0))(sharp@0.35.3(@types/node@25.9.1))': dependencies: loader-utils: 2.0.4 optionalDependencies: jimp: 1.6.1(supports-color@7.2.0) - sharp: 0.35.1 + sharp: 0.35.3(@types/node@25.9.1) '@emnapi/core@1.10.0': dependencies: @@ -15018,11 +15177,6 @@ snapshots: dependencies: tslib: 2.8.1 - '@emnapi/runtime@1.11.0': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.11.1': dependencies: tslib: 2.8.1 @@ -15155,89 +15309,179 @@ snapshots: '@img/sharp-libvips-darwin-arm64': 1.3.0 optional: true + '@img/sharp-darwin-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.3.2 + optional: true + '@img/sharp-darwin-x64@0.35.1': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.3.0 optional: true + '@img/sharp-darwin-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.3.2 + optional: true + '@img/sharp-freebsd-wasm32@0.35.1': dependencies: '@img/sharp-wasm32': 0.35.1 optional: true + '@img/sharp-freebsd-wasm32@0.35.3': + dependencies: + '@img/sharp-wasm32': 0.35.3 + optional: true + '@img/sharp-libvips-darwin-arm64@1.3.0': optional: true + '@img/sharp-libvips-darwin-arm64@1.3.2': + optional: true + '@img/sharp-libvips-darwin-x64@1.3.0': optional: true + '@img/sharp-libvips-darwin-x64@1.3.2': + optional: true + '@img/sharp-libvips-linux-arm64@1.3.0': optional: true + '@img/sharp-libvips-linux-arm64@1.3.2': + optional: true + '@img/sharp-libvips-linux-arm@1.3.0': optional: true + '@img/sharp-libvips-linux-arm@1.3.2': + optional: true + '@img/sharp-libvips-linux-ppc64@1.3.0': optional: true + '@img/sharp-libvips-linux-ppc64@1.3.2': + optional: true + '@img/sharp-libvips-linux-riscv64@1.3.0': optional: true + '@img/sharp-libvips-linux-riscv64@1.3.2': + optional: true + '@img/sharp-libvips-linux-s390x@1.3.0': optional: true + '@img/sharp-libvips-linux-s390x@1.3.2': + optional: true + '@img/sharp-libvips-linux-x64@1.3.0': optional: true + '@img/sharp-libvips-linux-x64@1.3.2': + optional: true + '@img/sharp-libvips-linuxmusl-arm64@1.3.0': optional: true + '@img/sharp-libvips-linuxmusl-arm64@1.3.2': + optional: true + '@img/sharp-libvips-linuxmusl-x64@1.3.0': optional: true + '@img/sharp-libvips-linuxmusl-x64@1.3.2': + optional: true + '@img/sharp-linux-arm64@0.35.1': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.3.0 optional: true + '@img/sharp-linux-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.3.2 + optional: true + '@img/sharp-linux-arm@0.35.1': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.3.0 optional: true + '@img/sharp-linux-arm@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.3.2 + optional: true + '@img/sharp-linux-ppc64@0.35.1': optionalDependencies: '@img/sharp-libvips-linux-ppc64': 1.3.0 optional: true + '@img/sharp-linux-ppc64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.3.2 + optional: true + '@img/sharp-linux-riscv64@0.35.1': optionalDependencies: '@img/sharp-libvips-linux-riscv64': 1.3.0 optional: true + '@img/sharp-linux-riscv64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.3.2 + optional: true + '@img/sharp-linux-s390x@0.35.1': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.3.0 optional: true + '@img/sharp-linux-s390x@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.3.2 + optional: true + '@img/sharp-linux-x64@0.35.1': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.3.0 optional: true + '@img/sharp-linux-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.3.2 + optional: true + '@img/sharp-linuxmusl-arm64@0.35.1': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.3.0 optional: true + '@img/sharp-linuxmusl-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.3.2 + optional: true + '@img/sharp-linuxmusl-x64@0.35.1': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.3.0 optional: true + '@img/sharp-linuxmusl-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.3.2 + optional: true + '@img/sharp-wasm32@0.35.1': dependencies: - '@emnapi/runtime': 1.11.0 + '@emnapi/runtime': 1.11.1 + optional: true + + '@img/sharp-wasm32@0.35.3': + dependencies: + '@emnapi/runtime': 1.11.1 optional: true '@img/sharp-webcontainers-wasm32@0.35.1': @@ -15245,15 +15489,29 @@ snapshots: '@img/sharp-wasm32': 0.35.1 optional: true + '@img/sharp-webcontainers-wasm32@0.35.3': + dependencies: + '@img/sharp-wasm32': 0.35.3 + optional: true + '@img/sharp-win32-arm64@0.35.1': optional: true + '@img/sharp-win32-arm64@0.35.3': + optional: true + '@img/sharp-win32-ia32@0.35.1': optional: true + '@img/sharp-win32-ia32@0.35.3': + optional: true + '@img/sharp-win32-x64@0.35.1': optional: true + '@img/sharp-win32-x64@0.35.3': + optional: true + '@inquirer/ansi@1.0.2': {} '@inquirer/checkbox@4.3.2(@types/node@25.9.1)': @@ -15836,7 +16094,7 @@ snapshots: '@types/react': 19.2.14 react: 19.2.6 - '@mermaid-js/layout-elk@0.1.9(mermaid@11.15.0)': + '@mermaid-js/layout-elk@0.2.2(mermaid@11.15.0)': dependencies: d3: 7.9.0 elkjs: 0.9.3 @@ -15925,7 +16183,7 @@ snapshots: proggy: 3.0.0 promise-all-reject-late: 1.0.1 promise-call-limit: 3.0.2 - semver: 7.8.1 + semver: 7.8.5 ssri: 12.0.0 treeverse: 3.0.0 walk-up-path: 4.0.0 @@ -15939,7 +16197,7 @@ snapshots: '@npmcli/fs@4.0.0': dependencies: - semver: 7.8.4 + semver: 7.8.5 '@npmcli/fs@5.0.0': dependencies: @@ -15953,7 +16211,7 @@ snapshots: npm-pick-manifest: 10.0.0 proc-log: 5.0.0 promise-retry: 2.0.1 - semver: 7.8.4 + semver: 7.8.5 which: 5.0.0 '@npmcli/git@7.0.2': @@ -15964,7 +16222,7 @@ snapshots: lru-cache: 11.5.1 npm-pick-manifest: 11.0.3 proc-log: 6.1.0 - semver: 7.8.4 + semver: 7.8.5 which: 6.0.1 '@npmcli/installed-package-contents@3.0.0': @@ -15990,7 +16248,7 @@ snapshots: json-parse-even-better-errors: 5.0.0 pacote: 21.5.0 proc-log: 6.1.0 - semver: 7.8.4 + semver: 7.8.5 transitivePeerDependencies: - supports-color @@ -16014,7 +16272,7 @@ snapshots: hosted-git-info: 9.0.3 json-parse-even-better-errors: 5.0.0 proc-log: 6.1.0 - semver: 7.8.1 + semver: 7.8.5 validate-npm-package-license: 3.0.4 '@npmcli/promise-spawn@8.0.3': @@ -16049,7 +16307,7 @@ snapshots: enquirer: 2.3.6 minimatch: 10.2.5 nx: 22.7.5(@swc/core@1.15.40) - semver: 7.8.1 + semver: 7.8.5 tslib: 2.8.1 yargs-parser: 21.1.1 @@ -16148,7 +16406,7 @@ snapshots: dependencies: '@octokit/openapi-types': 24.2.0 - '@opentelemetry/api@1.9.0': {} + '@opentelemetry/api@1.9.1': {} '@oxc-project/types@0.132.0': {} @@ -16519,7 +16777,7 @@ snapshots: dependencies: '@rsbuild/plugin-check-syntax': 1.6.1 '@rsdoctor/graph': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) - '@rsdoctor/sdk': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) + '@rsdoctor/sdk': 1.5.17(@rspack/core@2.1.2)(supports-color@7.2.0)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) '@rsdoctor/types': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) '@rsdoctor/utils': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) '@rspack/resolver': 0.2.8(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) @@ -16550,11 +16808,11 @@ snapshots: - '@rspack/core' - webpack - '@rsdoctor/rspack-plugin@1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15))': + '@rsdoctor/rspack-plugin@1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@rspack/core@2.1.2)(supports-color@7.2.0)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15))': dependencies: '@rsdoctor/core': 1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) '@rsdoctor/graph': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) - '@rsdoctor/sdk': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) + '@rsdoctor/sdk': 1.5.17(@rspack/core@2.1.2)(supports-color@7.2.0)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) '@rsdoctor/types': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) '@rsdoctor/utils': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) optionalDependencies: @@ -16568,7 +16826,7 @@ snapshots: - utf-8-validate - webpack - '@rsdoctor/sdk@1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15))': + '@rsdoctor/sdk@1.5.17(@rspack/core@2.1.2)(supports-color@7.2.0)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15))': dependencies: '@rsdoctor/client': 1.5.17 '@rsdoctor/graph': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) @@ -16576,7 +16834,7 @@ snapshots: '@rsdoctor/utils': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) launch-editor: 2.13.2 safer-buffer: 2.1.2 - socket.io: 4.8.1 + socket.io: 4.8.1(supports-color@7.2.0) tapable: 2.3.3 transitivePeerDependencies: - '@rspack/core' @@ -16620,7 +16878,7 @@ snapshots: dependencies: '@rsdoctor/core': 1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) '@rsdoctor/graph': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) - '@rsdoctor/sdk': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) + '@rsdoctor/sdk': 1.5.17(@rspack/core@2.1.2)(supports-color@7.2.0)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) '@rsdoctor/types': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) '@rsdoctor/utils': 1.5.17(@rspack/core@2.1.2)(webpack@5.107.2(@swc/core@1.15.40)(postcss@8.5.15)) webpack: 5.107.2(@swc/core@1.15.40)(postcss@8.5.15) @@ -17664,7 +17922,7 @@ snapshots: '@typescript-eslint/visitor-keys': 8.60.0 debug: 4.4.3(supports-color@7.2.0) minimatch: 10.2.5 - semver: 7.8.4 + semver: 7.8.5 tinyglobby: 0.2.16 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 @@ -17754,7 +18012,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/eslint-plugin@1.6.20(@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)(vitest@4.1.7(@opentelemetry/api@1.9.0)(@types/node@25.9.1)(jsdom@25.0.1(supports-color@7.2.0))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)))': + '@vitest/eslint-plugin@1.6.20(@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)(vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(jsdom@25.0.1(supports-color@7.2.0))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)))': dependencies: '@typescript-eslint/scope-manager': 8.62.1 '@typescript-eslint/utils': 8.62.1(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) @@ -17762,7 +18020,7 @@ snapshots: optionalDependencies: '@typescript-eslint/eslint-plugin': 8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(typescript@6.0.3) typescript: 6.0.3 - vitest: 4.1.7(@opentelemetry/api@1.9.0)(@types/node@25.9.1)(jsdom@25.0.1(supports-color@7.2.0))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) + vitest: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(jsdom@25.0.1(supports-color@7.2.0))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) transitivePeerDependencies: - supports-color @@ -17965,12 +18223,12 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - ai@6.0.175(zod@4.4.3): + ai@6.0.217(zod@4.4.3): dependencies: - '@ai-sdk/gateway': 3.0.110(zod@4.4.3) - '@ai-sdk/provider': 3.0.10 - '@ai-sdk/provider-utils': 4.0.26(zod@4.4.3) - '@opentelemetry/api': 1.9.0 + '@ai-sdk/gateway': 3.0.141(zod@4.4.3) + '@ai-sdk/provider': 3.0.13 + '@ai-sdk/provider-utils': 4.0.34(zod@4.4.3) + '@opentelemetry/api': 1.9.1 zod: 4.4.3 ajv-formats@2.1.1(ajv@8.20.0): @@ -18809,7 +19067,7 @@ snapshots: handlebars: 4.7.9 json-stringify-safe: 5.0.1 meow: 8.1.2 - semver: 7.8.4 + semver: 7.8.5 split: 1.0.1 conventional-commits-filter@3.0.0: @@ -19614,7 +19872,7 @@ snapshots: engine.io-parser@5.2.3: {} - engine.io@6.6.8: + engine.io@6.6.8(supports-color@7.2.0): dependencies: '@types/cors': 2.8.19 '@types/node': 25.9.1 @@ -20451,7 +20709,7 @@ snapshots: git-semver-tags@5.0.1: dependencies: meow: 8.1.2 - semver: 7.8.4 + semver: 7.8.5 git-up@7.0.0: dependencies: @@ -21038,7 +21296,7 @@ snapshots: npm-package-arg: 13.0.1 promzard: 2.0.0 read: 4.1.0 - semver: 7.8.1 + semver: 7.8.5 validate-npm-package-license: 3.0.4 validate-npm-package-name: 6.0.2 @@ -21669,7 +21927,7 @@ snapshots: npm-package-arg: 13.0.1 npm-registry-fetch: 19.1.0 proc-log: 5.0.0 - semver: 7.8.1 + semver: 7.8.5 sigstore: 4.1.1 ssri: 12.0.0 transitivePeerDependencies: @@ -22730,7 +22988,7 @@ snapshots: graceful-fs: 4.2.11 nopt: 9.0.0 proc-log: 6.1.0 - semver: 7.8.4 + semver: 7.8.5 tar: 7.5.16 tinyglobby: 0.2.16 undici: 6.26.0 @@ -22757,7 +23015,7 @@ snapshots: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.16.2 - semver: 7.8.4 + semver: 7.8.5 validate-npm-package-license: 3.0.4 normalize-path@3.0.0: {} @@ -22774,7 +23032,7 @@ snapshots: npm-install-checks@7.1.2: dependencies: - semver: 7.8.4 + semver: 7.8.5 npm-install-checks@8.0.0: dependencies: @@ -22795,7 +23053,7 @@ snapshots: dependencies: hosted-git-info: 9.0.3 proc-log: 5.0.0 - semver: 7.8.1 + semver: 7.8.5 validate-npm-package-name: 6.0.2 npm-packlist@10.0.3: @@ -22808,14 +23066,14 @@ snapshots: npm-install-checks: 7.1.2 npm-normalize-package-bin: 4.0.0 npm-package-arg: 12.0.2 - semver: 7.8.4 + semver: 7.8.5 npm-pick-manifest@11.0.3: dependencies: npm-install-checks: 8.0.0 npm-normalize-package-bin: 5.0.0 npm-package-arg: 13.0.1 - semver: 7.8.4 + semver: 7.8.5 npm-registry-fetch@19.1.0: dependencies: @@ -23223,7 +23481,7 @@ snapshots: got: 12.6.1 registry-auth-token: 5.1.1 registry-url: 6.0.1 - semver: 7.8.4 + semver: 7.8.5 package-manager-detector@1.6.0: {} @@ -24075,7 +24333,7 @@ snapshots: dependencies: react: 19.2.6 - react-lite-youtube-embed@2.6.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-lite-youtube-embed@3.6.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: react: 19.2.6 react-dom: 19.2.6(react@19.2.6) @@ -24660,7 +24918,7 @@ snapshots: semver-diff@4.0.0: dependencies: - semver: 7.8.4 + semver: 7.8.5 semver@5.7.2: {} @@ -24672,8 +24930,6 @@ snapshots: semver@7.8.1: {} - semver@7.8.4: {} - semver@7.8.5: {} send@0.19.2: @@ -24761,7 +25017,7 @@ snapshots: dependencies: '@img/colour': 1.1.0 detect-libc: 2.1.2 - semver: 7.8.4 + semver: 7.8.5 optionalDependencies: '@img/sharp-darwin-arm64': 0.35.1 '@img/sharp-darwin-x64': 0.35.1 @@ -24789,6 +25045,39 @@ snapshots: '@img/sharp-win32-ia32': 0.35.1 '@img/sharp-win32-x64': 0.35.1 + sharp@0.35.3(@types/node@25.9.1): + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.35.3 + '@img/sharp-darwin-x64': 0.35.3 + '@img/sharp-freebsd-wasm32': 0.35.3 + '@img/sharp-libvips-darwin-arm64': 1.3.2 + '@img/sharp-libvips-darwin-x64': 1.3.2 + '@img/sharp-libvips-linux-arm': 1.3.2 + '@img/sharp-libvips-linux-arm64': 1.3.2 + '@img/sharp-libvips-linux-ppc64': 1.3.2 + '@img/sharp-libvips-linux-riscv64': 1.3.2 + '@img/sharp-libvips-linux-s390x': 1.3.2 + '@img/sharp-libvips-linux-x64': 1.3.2 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.2 + '@img/sharp-libvips-linuxmusl-x64': 1.3.2 + '@img/sharp-linux-arm': 0.35.3 + '@img/sharp-linux-arm64': 0.35.3 + '@img/sharp-linux-ppc64': 0.35.3 + '@img/sharp-linux-riscv64': 0.35.3 + '@img/sharp-linux-s390x': 0.35.3 + '@img/sharp-linux-x64': 0.35.3 + '@img/sharp-linuxmusl-arm64': 0.35.3 + '@img/sharp-linuxmusl-x64': 0.35.3 + '@img/sharp-webcontainers-wasm32': 0.35.3 + '@img/sharp-win32-arm64': 0.35.3 + '@img/sharp-win32-ia32': 0.35.3 + '@img/sharp-win32-x64': 0.35.3 + '@types/node': 25.9.1 + shebang-command@1.2.0: dependencies: shebang-regex: 1.0.0 @@ -24909,7 +25198,7 @@ snapshots: dot-case: 3.0.4 tslib: 2.8.1 - socket.io-adapter@2.5.7: + socket.io-adapter@2.5.7(supports-color@7.2.0): dependencies: debug: 4.4.3(supports-color@7.2.0) ws: 8.20.1 @@ -24918,22 +25207,22 @@ snapshots: - supports-color - utf-8-validate - socket.io-parser@4.2.6: + socket.io-parser@4.2.6(supports-color@7.2.0): dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@7.2.0) transitivePeerDependencies: - supports-color - socket.io@4.8.1: + socket.io@4.8.1(supports-color@7.2.0): dependencies: accepts: 1.3.8 base64id: 2.0.0 cors: 2.8.5 debug: 4.3.7 - engine.io: 6.6.8 - socket.io-adapter: 2.5.7 - socket.io-parser: 4.2.6 + engine.io: 6.6.8(supports-color@7.2.0) + socket.io-adapter: 2.5.7(supports-color@7.2.0) + socket.io-parser: 4.2.6(supports-color@7.2.0) transitivePeerDependencies: - bufferutil - supports-color @@ -25330,7 +25619,7 @@ snapshots: '@swc/counter': 0.1.3 webpack: 5.107.2(@swc/core@1.15.40)(@swc/html@1.15.40)(lightningcss@1.32.0)(postcss@8.5.15) - swr@2.4.1(react@19.2.6): + swr@2.4.2(react@19.2.6): dependencies: dequal: 2.0.3 react: 19.2.6 @@ -25923,7 +26212,7 @@ snapshots: terser: 5.48.0 yaml: 2.9.0 - vitest@4.1.7(@opentelemetry/api@1.9.0)(@types/node@25.9.1)(jsdom@25.0.1(supports-color@7.2.0))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)): + vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(jsdom@25.0.1(supports-color@7.2.0))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.7 '@vitest/mocker': 4.1.7(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) @@ -25946,7 +26235,7 @@ snapshots: vite: 8.0.14(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: - '@opentelemetry/api': 1.9.0 + '@opentelemetry/api': 1.9.1 '@types/node': 25.9.1 jsdom: 25.0.1(supports-color@7.2.0) transitivePeerDependencies: diff --git a/project-words.txt b/project-words.txt index c1fc134eee5e..c923a1dc8104 100644 --- a/project-words.txt +++ b/project-words.txt @@ -16,6 +16,7 @@ atrule autogenerating autohide Autolinks +backgrounded Bartosz beforeinstallprompt Bhatt diff --git a/website/docs/api/docusaurus.config.js.mdx b/website/docs/api/docusaurus.config.js.mdx index 304235fa2f3e..339a6ede1f1d 100644 --- a/website/docs/api/docusaurus.config.js.mdx +++ b/website/docs/api/docusaurus.config.js.mdx @@ -661,7 +661,7 @@ type MarkdownAnchorsConfig = { type OnBrokenMarkdownLinksFunction = (params: { sourceFilePath: string; // MD/MDX source file relative to cwd url: string; // Link url - node: Link | Definition; // mdast Node + node: Link | Definition; // mdast node }) => void | string; type OnBrokenMarkdownImagesFunction = (params: { @@ -670,11 +670,19 @@ type OnBrokenMarkdownImagesFunction = (params: { node: Image; // mdast node }) => void | string; +type OnUnusedMarkdownDirectivesFunction = (params: { + sourceFilePath: string; // MD/MDX source file relative to cwd + directives: Directives[]; // mdast nodes +}) => void | string; + type ReportingSeverity = 'ignore' | 'log' | 'warn' | 'throw'; type MarkdownHooks = { onBrokenMarkdownLinks: ReportingSeverity | OnBrokenMarkdownLinksFunction; onBrokenMarkdownImages: ReportingSeverity | OnBrokenMarkdownImagesFunction; + onUnusedMarkdownDirectives: + | ReportingSeverity + | OnUnusedMarkdownDirectivesFunction; }; type MarkdownConfig = { @@ -718,6 +726,7 @@ export default { hooks: { onBrokenMarkdownLinks: 'warn', onBrokenMarkdownImages: 'throw', + onUnusedMarkdownDirectives: 'warn', }, }, }; @@ -740,6 +749,7 @@ export default { | `hooks` | `MarkdownHooks` | `object` | Make it possible to customize the MDX loader behavior with callbacks or built-in options. | | `hooks.onBrokenMarkdownLinks` | `ReportingSeverity \| OnBrokenMarkdownLinksFunction` | `'warn'` | Hook to customize the behavior when encountering a broken Markdown link URL. With the callback function, you can return a new link URL, or alter the link [mdast node](https://github.com/syntax-tree/mdast). | | `hooks.onBrokenMarkdownImages` | `ReportingSeverity \| OnBrokenMarkdownImagesFunction` | `'throw'` | Hook to customize the behavior when encountering a broken Markdown image URL. With the callback function, you can return a new image URL, or alter the image [mdast node](https://github.com/syntax-tree/mdast). | +| `hooks.onUnusedMarkdownDirectives` | `ReportingSeverity \| OnUnusedMarkdownDirectivesFunction` | `'warn'` | Hook to customize the behavior when encountering an unused [Markdown directive](https://github.com/remarkjs/remark-directive). Also accepts a callback function, giving you access to the raw `Directive` AST nodes. | ```mdx-code-block diff --git a/website/netlify.toml b/website/netlify.toml index e3ccbf35b257..d55c2649c735 100644 --- a/website/netlify.toml +++ b/website/netlify.toml @@ -16,15 +16,18 @@ NODE_OPTIONS = "--max_old_space_size=8192" # Note, we run build:packages and git backfill in parallel to speed up builds # We run "git backfill" here to ensure the full Git history is available fast # See https://github.com/facebook/docusaurus/pull/11553 +# Only git backfill is backgrounded; build:packages runs in the foreground so +# && catches its failure, and "wait $!" propagates the backfill's exit code +# (bare "wait" always exits 0, which would swallow failures) [context.production] -command = "(echo 'Build packages start' && pnpm --dir .. build:packages && echo 'Build packages end') & (echo 'Git backfill start' && git backfill && echo 'Git backfill end' ) & wait && pnpm netlify:build:production" +command = "(echo 'Git backfill start' && git backfill && echo 'Git backfill end') & (echo 'Build packages start' && pnpm --dir .. build:packages && echo 'Build packages end') && wait $! && pnpm netlify:build:production" [context.branch-deploy] -command = "(echo 'Build packages start' && pnpm --dir .. build:packages && echo 'Build packages end') & (echo 'Git backfill start' && git backfill && echo 'Git backfill end' ) & wait && pnpm netlify:build:branchDeploy" +command = "(echo 'Git backfill start' && git backfill && echo 'Git backfill end') & (echo 'Build packages start' && pnpm --dir .. build:packages && echo 'Build packages end') && wait $! && pnpm netlify:build:branchDeploy" [context.deploy-preview] -command = "(echo 'Build packages start' && pnpm --dir .. build:packages && echo 'Build packages end') & (echo 'Git backfill start' && git backfill && echo 'Git backfill end' ) & wait && pnpm netlify:build:deployPreview" +command = "(echo 'Git backfill start' && git backfill && echo 'Git backfill end') & (echo 'Build packages start' && pnpm --dir .. build:packages && echo 'Build packages end') && wait $! && pnpm netlify:build:deployPreview" [[plugins]] package = "netlify-plugin-cache" diff --git a/website/package.json b/website/package.json index 2ff2525c1965..d992d57db1c4 100644 --- a/website/package.json +++ b/website/package.json @@ -59,7 +59,7 @@ "@docusaurus/utils": "3.10.1", "@docusaurus/utils-common": "3.10.1", "@docusaurus/utils-validation": "3.10.1", - "@mermaid-js/layout-elk": "^0.1.9", + "@mermaid-js/layout-elk": "^0.2.2", "clsx": "^2.0.0", "color": "^4.2.3", "execa": "^5.1.1", @@ -68,7 +68,7 @@ "raw-loader": "^4.0.2", "react": "^19.2.5", "react-dom": "^19.2.5", - "react-lite-youtube-embed": "^2.3.52", + "react-lite-youtube-embed": "^3.6.0", "react-medium-image-zoom": "^5.1.6", "recma-mdx-displayname": "^0.4.1", "rehype-katex": "^7.0.0",