Skip to content
5 changes: 4 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@
},
"forwardPorts": [3000],
"containerUser": "vscode",
"containerEnv": {
"COREPACK_ENABLE_DOWNLOAD_PROMPT": "0" // Avoid waiting for a prompt in the postCreateCommand
},
"postCreateCommand": "pnpm install",
"waitFor": "postCreateCommand", // otherwise automated jest tests fail
"features": {
"node": {
"version": "22"
"version": "24"
},
"github-cli": "latest"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-plugin-content-blog/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@
},
"devDependencies": {
"@total-typescript/shoehorn": "^0.1.2",
"tree-node-cli": "^1.6.0"
"tree-node-cli": "^3.0.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
normalizePluginOptions,
getTagsFile,
} from '@docusaurus/utils-validation';
import tree from 'tree-node-cli';
import {tree} from 'tree-node-cli';
import {DEFAULT_OPTIONS, validateOptions} from '../options';
import {generateBlogPosts} from '../blogUtils';
import {createBlogFeedFiles} from '../feed';
Expand Down
24 changes: 12 additions & 12 deletions packages/docusaurus-theme-translations/locales/es/theme-common.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@
"theme.DocSidebarItem.expandCategoryAriaLabel": "Ampliar la categoría '{label}' de la barra lateral",
"theme.ErrorPageContent.title": "Esta página ha fallado.",
"theme.ErrorPageContent.tryAgain": "Intente de nuevo",
"theme.IconExternalLink.ariaLabel": "(opens in new tab)",
"theme.IconExternalLink.ariaLabel": "(se abre en una nueva pestaña)",
"theme.NavBar.navAriaLabel": "Principal",
"theme.NotFound.p1": "No pudimos encontrar lo que buscaba.",
"theme.NotFound.p2": "Comuníquese con el dueño del sitio que le proporcionó la URL original y hágale saber que su vínculo está roto.",
"theme.NotFound.title": "Página No Encontrada",
"theme.TOCCollapsible.toggleButtonLabel": "En esta página",
"theme.admonition.caution": "precaución",
"theme.admonition.danger": "peligro",
"theme.admonition.info": "info",
"theme.admonition.info": "información",
"theme.admonition.note": "nota",
"theme.admonition.tip": "tip",
"theme.admonition.tip": "consejo",
"theme.admonition.warning": "aviso",
"theme.blog.archive.description": "Archivo",
"theme.blog.archive.title": "Archivo",
"theme.blog.author.noPosts": "This author has not written any posts yet.",
"theme.blog.author.noPosts": "Este autor aún no ha escrito ninguna publicación.",
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
"theme.blog.authorsList.pageTitle": "Authors",
"theme.blog.authorsList.viewAll": "View All Authors",
"theme.blog.authorsList.pageTitle": "Autores",
"theme.blog.authorsList.viewAll": "Ver todos los autores",
"theme.blog.paginator.navAriaLabel": "Navegación por la página de la lista de blogs ",
"theme.blog.paginator.newerEntries": "Entradas más recientes",
"theme.blog.paginator.olderEntries": "Entradas más antiguas",
Expand All @@ -42,12 +42,12 @@
"theme.colorToggle.ariaLabel": "Cambiar entre modo oscuro y claro (actualmente {mode})",
"theme.colorToggle.ariaLabel.mode.dark": "modo oscuro",
"theme.colorToggle.ariaLabel.mode.light": "modo claro",
"theme.colorToggle.ariaLabel.mode.system": "system mode",
"theme.colorToggle.ariaLabel.mode.system": "modo del sistema",
"theme.common.editThisPage": "Editar esta página",
"theme.common.headingLinkTitle": "Enlace directo al {heading}",
"theme.common.skipToMainContent": "Saltar al contenido principal",
"theme.contentVisibility.draftBanner.message": "This page is a draft. It will only be visible in dev and be excluded from the production build.",
"theme.contentVisibility.draftBanner.title": "Draft page",
"theme.contentVisibility.draftBanner.message": "Esta página es un borrador. Solo será visible en desarrollo y será excluida de la compilación de producción.",
"theme.contentVisibility.draftBanner.title": "Página en borrador",
"theme.contentVisibility.unlistedBanner.message": "Esta página está sin clasificar. Los motores de búsqueda no la indexaran, y solo los usuarios con el enlace directo podrán acceder a esta.",
"theme.contentVisibility.unlistedBanner.title": "Página sin clasificar",
"theme.docs.DocCard.categoryDescription.plurals": "1 artículo|{count} artículos",
Expand All @@ -65,16 +65,16 @@
"theme.docs.sidebar.toggleSidebarButtonAriaLabel": "Alternar barra lateral",
"theme.docs.tagDocListPageTitle": "{nDocsTagged} con \"{tagName}\"",
"theme.docs.tagDocListPageTitle.nDocsTagged": "Un documento etiquetado|{count} documentos etiquetados",
"theme.docs.versionBadge.label": "Version: {versionLabel}",
"theme.docs.versionBadge.label": "Versión: {versionLabel}",
"theme.docs.versions.latestVersionLinkLabel": "última versión",
"theme.docs.versions.latestVersionSuggestionLabel": "Para la documentación actualizada, vea {latestVersionLink} ({versionLabel}).",
"theme.docs.versions.unmaintainedVersionLabel": "Esta es la documentación para {siteTitle} {versionLabel}, que ya no se mantiene activamente.",
"theme.docs.versions.unreleasedVersionLabel": "Esta es la documentación sin publicar para {siteTitle}, versión {versionLabel}.",
"theme.lastUpdated.atDate": " en {date}",
"theme.lastUpdated.byUser": " por {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Última actualización{atDate}{byUser}",
"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel": "Collapse the dropdown",
"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": "Expand the dropdown",
"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel": "Contraer el menú desplegable",
"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": "Expandir el menú desplegable",
"theme.navbar.mobileLanguageDropdown.label": "Idiomas",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Volver al menú principal",
"theme.navbar.mobileVersionsDropdown.label": "Versiones",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"theme.Playground.liveEditor": "Editor en vivo",
"theme.Playground.buttons.reset": "Reset",
"theme.Playground.buttons.reset": "Restablecer",
"theme.Playground.result": "Resultado"
}
2 changes: 1 addition & 1 deletion packages/docusaurus-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"file-loader": "^6.2.0",
"fs-extra": "^11.2.0",
"github-slugger": "^2.0.0",
"gray-matter": "^4.0.3",
"@11ty/gray-matter": "^2.0.0",
"jiti": "^2.7.0",
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
Expand Down
8 changes: 5 additions & 3 deletions packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -895,9 +895,11 @@ describe('parseMarkdownFile', () => {
---
`),
).rejects.toThrowErrorMatchingInlineSnapshot(`
[YAMLException: incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line at line 2, column 7:
foo: f: a
^]
[YAMLException: bad indentation of a mapping entry (2:7)

1 |
2 | foo: f: a
-----------^]
`);
});
});
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-utils/src/markdownUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import logger from '@docusaurus/logger';
import matter from 'gray-matter';
import matter from '@11ty/gray-matter';
import type {
ParseFrontMatter,
DefaultParseFrontMatter,
Expand Down
7 changes: 3 additions & 4 deletions packages/docusaurus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"combine-promises": "^1.1.0",
"commander": "^5.1.0",
"core-js": "^3.31.1",
"detect-port": "^1.5.1",
"detect-port": "^2.1.0",
"escape-html": "^1.0.3",
"eta": "^2.2.0",
"eval": "^0.1.8",
Expand All @@ -57,7 +57,7 @@
"html-webpack-plugin": "^5.6.7",
"leven": "^3.1.0",
"lodash": "^4.17.21",
"open": "^8.4.0",
"open": "^11.0.0",
"p-map": "^4.0.0",
"prompts": "^2.4.2",
"react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0",
Expand All @@ -80,7 +80,6 @@
"@docusaurus/module-type-aliases": "3.10.1",
"@docusaurus/types": "3.10.1",
"@total-typescript/shoehorn": "^0.1.2",
"@types/detect-port": "^1.3.3",
"@types/escape-html": "^1.0.4",
"@types/history": "^4.7.11",
"@types/react-dom": "^19.2.3",
Expand All @@ -90,7 +89,7 @@
"@types/update-notifier": "^6.0.4",
"@types/webpack-bundle-analyzer": "^4.7.0",
"@types/webpack-env": "^1.18.8",
"tree-node-cli": "^1.6.0"
"tree-node-cli": "^3.0.0"
},
"peerDependencies": {
"@docusaurus/faster": "*",
Expand Down
3 changes: 2 additions & 1 deletion packages/docusaurus/src/commands/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import openBrowser from './utils/openBrowser/openBrowser';
import {loadSiteConfig} from '../server/config';
import {build} from './build/build';
import {getHostPort, type HostPortOptions} from '../server/getHostPort';
import {listenToServer} from './utils/listenToServer';
import type {LoadContextParams} from '../server/site';

function redirect(res: http.ServerResponse, location: string) {
Expand Down Expand Up @@ -107,7 +108,7 @@ export async function serve(

const url = servingUrl + baseUrl;
logger.success`Serving path=${buildDir} directory at: url=${url}`;
server.listen(port);
await listenToServer({server, host, port});

if (cliOptions.open && !process.env.CI) {
await openBrowser(url);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import {describe, expect, it} from 'vitest';
import path from 'path';
import fs from 'fs-extra';
import tree from 'tree-node-cli';
import {tree} from 'tree-node-cli';
import {posixPath} from '@docusaurus/utils';
import {eject, wrap} from '../actions';
import {ThemePath, Components, createTempSiteDir} from './testUtils';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import {describe, expect, it, vi} from 'vitest';
import path from 'path';
import fs from 'fs-extra';
import tree from 'tree-node-cli';
import {tree} from 'tree-node-cli';
import {escapePath, Globby, posixPath} from '@docusaurus/utils';
import {ThemePath, createTempSiteDir, Components} from './testUtils';
import {swizzle} from '../index';
Expand Down
34 changes: 34 additions & 0 deletions packages/docusaurus/src/commands/utils/listenToServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {logger} from '@docusaurus/logger';

export async function listenToServer({
server,
port,
host,
}: {
server: import('node:http').Server;
port: number;
host: string;
}): Promise<void> {
return new Promise<void>((resolve, reject) => {
server.once('listening', () => resolve());
server.once('error', (err: NodeJS.ErrnoException) => {
if (err.code === 'EADDRINUSE') {
reject(
new Error(
logger.interpolate`Address in use, another server is already listening on the requested port number=${port} and host name=${host}`,
{cause: err},
),
);
} else {
reject(err);
}
});
server.listen(port, host);
});
}
23 changes: 14 additions & 9 deletions packages/docusaurus/src/commands/utils/openBrowser/openBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import {exec} from 'child_process';
import {promisify} from 'util';
import open from 'open';
import open, {openApp, apps, App, AppName} from 'open';
import {PerfLogger} from '@docusaurus/logger';

const execPromise = promisify(exec);
Expand Down Expand Up @@ -72,11 +72,16 @@ async function tryOpenWithAppleScript({
'|',
)})$"`;

const result = await Promise.try(() => execPromise(command)).catch(() => {
// Ignore all errors
// In particular grep errors when macOS user has no Chromium-based browser open
// See https://github.com/facebook/docusaurus/issues/11204
});
const result = await Promise
// TODO Docusaurus v4: use Promise.try()
// See why here https://github.com/facebook/docusaurus/issues/11204#issuecomment-3073480330
.resolve()
.then(() => execPromise(command))
.catch(() => {
// Ignore all errors
// In particular grep errors when macOS user has no Chromium-based browser open
// See https://github.com/facebook/docusaurus/issues/11204
});
if (!result) {
return [];
}
Expand Down Expand Up @@ -128,14 +133,14 @@ async function tryOpenWithAppleScript({
return false;
}

function toOpenApp(params: Params): open.App | undefined {
function toOpenApp(params: Params): App | undefined {
if (!params.browser) {
return undefined;
}
// Handles "cross-platform" shortcuts like "chrome", "firefox", "edge"
if (open.apps[params.browser as open.AppName]) {
if (apps[params.browser as AppName]) {
return {
name: open.apps[params.browser as open.AppName],
name: apps[params.browser as AppName],
arguments: params.browserArgs,
};
}
Expand Down
6 changes: 4 additions & 2 deletions packages/docusaurus/src/server/getHostPort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@ Would you like to run the app on another port instead?`),
})) as {shouldChangePort: boolean};
return shouldChangePort ? port : null;
} catch (err) {
logger.error`Could not find an open port at ${host}.`;
throw err;
throw new Error(
logger.interpolate`Could not find an open port at ${host}.`,
{cause: err},
);
}
}

Expand Down
Loading
Loading