diff --git a/.github/workflows/stage-build.yml b/.github/workflows/stage-build.yml
index 5169210175ae..e46f50d29432 100644
--- a/.github/workflows/stage-build.yml
+++ b/.github/workflows/stage-build.yml
@@ -151,6 +151,13 @@ jobs:
mv mdn/translated-content-de/files/de mdn/translated-content/files/
rm -rf mdn/translated-content-de
+ - name: Clean and commit de
+ if: ${{ ! vars.SKIP_BUILD || ! vars.SKIP_FUNCTION }}
+ working-directory: mdn/translated-content
+ run: |
+ git add files/de
+ git -c user.name='MDN' -c user.email='mdn-dev@mozilla.com' commit -m 'de'
+
- uses: actions/checkout@v4
if: ${{ ! vars.SKIP_BUILD }}
with:
@@ -168,7 +175,8 @@ jobs:
if: ${{ ! vars.SKIP_BUILD }}
run: yarn --frozen-lockfile
env:
- # https://github.com/microsoft/vscode-ripgrep#github-api-limit-note
+ # Use a GITHUB_TOKEN to bypass rate limiting for ripgrep and rari.
+ # See https://github.com/microsoft/vscode-ripgrep#github-api-limit-note
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install Python
@@ -214,6 +222,13 @@ jobs:
CURRICULUM_ROOT: ${{ github.workspace }}/mdn/curriculum
BASE_URL: "https://developer.allizom.org"
+ # rari
+ BUILD_OUT_ROOT: "client/build"
+ GENERIC_CONTENT_ROOT: "copy"
+ LIVE_SAMPLES_BASE_URL: https://live.mdnyalp.dev
+ INTERACTIVE_EXAMPLES_BASE_URL: https://interactive-examples.mdn.allizom.net
+ ADDITIONAL_LOCALES_FOR_GENERICS_AND_SPAS: de
+
# The default for this environment variable is geared for writers
# (aka. local development). Usually defaults are supposed to be for
# secure production but this is an exception and default
@@ -290,31 +305,14 @@ jobs:
echo "BLOG_ROOT=$BLOG_ROOT"
# Build the ServiceWorker first
yarn build:sw
- yarn build:prepare
-
- yarn tool sync-translated-content es fr ja ko pt-br ru zh-cn zh-tw
-
- # Build using one process per locale.
- # Note: We have 4 cores, but 9 processes is a reasonable number.
- for locale in en-us de es fr ja ko pt-br ru zh-cn zh-tw; do
- yarn build:docs --locale $locale 2>&1 | sed "s/^/[$locale] /" &
- pids+=($!)
- done
-
- for pid in "${pids[@]}"; do
- wait $pid
- done
-
- du -sh client/build
-
- # Build the blog
- yarn build:blog
+ yarn build:client
+ yarn build:ssr
+ yarn tool build-robots-txt
- # Build the curriculum
- yarn build:curriculum
+ yarn rari content sync-translated-content
+ yarn rari git-history
- # Generate sitemap index file
- yarn build --sitemap-index
+ yarn rari build --issues client/build/issues.json --templ-stats
# SSR all pages
yarn render:html
diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml
index 95d986565212..21fe49f08a9f 100644
--- a/.github/workflows/test-build.yml
+++ b/.github/workflows/test-build.yml
@@ -72,6 +72,26 @@ jobs:
# See matching warning for mdn/content checkout step
fetch-depth: 0
+ - name: Checkout (translated-content-de)
+ uses: actions/checkout@v4
+ if: ${{ ! vars.SKIP_BUILD || ! vars.SKIP_FUNCTION }}
+ with:
+ repository: mdn/translated-content-de
+ path: mdn/translated-content-de
+
+ - name: Move de into translated-content
+ if: ${{ ! vars.SKIP_BUILD || ! vars.SKIP_FUNCTION }}
+ run: |
+ mv mdn/translated-content-de/files/de mdn/translated-content/files/
+ rm -rf mdn/translated-content-de
+
+ - name: Clean and commit de
+ if: ${{ ! vars.SKIP_BUILD || ! vars.SKIP_FUNCTION }}
+ working-directory: mdn/translated-content
+ run: |
+ git add files/de
+ git -c user.name='MDN' -c user.email='mdn-dev@mozilla.com' commit -m 'de'
+
- uses: actions/checkout@v4
if: ${{ ! vars.SKIP_BUILD }}
with:
@@ -89,7 +109,8 @@ jobs:
if: ${{ ! vars.SKIP_BUILD }}
run: yarn --frozen-lockfile
env:
- # https://github.com/microsoft/vscode-ripgrep#github-api-limit-note
+ # Use a GITHUB_TOKEN to bypass rate limiting for ripgrep and rari.
+ # See https://github.com/microsoft/vscode-ripgrep#github-api-limit-note
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Print information about build
@@ -111,6 +132,13 @@ jobs:
CURRICULUM_ROOT: ${{ github.workspace }}/mdn/curriculum
BASE_URL: "https://test.developer.allizom.org"
+ # rari
+ BUILD_OUT_ROOT: "client/build"
+ GENERIC_CONTENT_ROOT: "copy"
+ LIVE_SAMPLES_BASE_URL: https://live.test.mdnyalp.dev
+ INTERACTIVE_EXAMPLES_BASE_URL: https://interactive-examples.mdn.allizom.net
+ ADDITIONAL_LOCALES_FOR_GENERICS_AND_SPAS: de
+
# The default for this environment variable is geared for writers
# (aka. local development). Usually defaults are supposed to be for
# secure production but this is an exception and default
@@ -155,7 +183,7 @@ jobs:
REACT_APP_PLACEMENT_ENABLED: true
# Playground
- REACT_APP_PLAYGROUND_BASE_HOST: play.test.mdn.allizom.net
+ REACT_APP_PLAYGROUND_BASE_HOST: test.mdnyalp.dev
# Observatory
REACT_APP_OBSERVATORY_API_URL: https://observatory-api.mdn.allizom.net
@@ -168,31 +196,14 @@ jobs:
echo "BLOG_ROOT=$BLOG_ROOT"
# Build the ServiceWorker first
yarn build:sw
- yarn build:prepare
-
- #yarn tool sync-translated-content
-
- # Build using one process per locale.
- # Note: We have 4 cores, but 9 processes is a reasonable number.
- for locale in en-us fr; do
- yarn build:docs --locale $locale 2>&1 | sed "s/^/[$locale] /" &
- pids+=($!)
- done
-
- for pid in "${pids[@]}"; do
- wait $pid
- done
-
- du -sh client/build
-
- # Build the blog
- yarn build:blog
+ yarn build:client
+ yarn build:ssr
+ yarn tool build-robots-txt
- # Build the curriculum
- yarn build:curriculum
+ yarn rari content sync-translated-content
+ yarn rari git-history
- # Generate sitemap index file
- yarn build --sitemap-index
+ yarn rari build --issues client/build/issues.json --templ-stats
# SSR all pages
yarn render:html
@@ -241,6 +252,7 @@ jobs:
run: |
npm ci
npm run build-redirects
+ npm run build-canonicals
- name: Deploy Function
if: ${{ ! vars.SKIP_FUNCTION }}
diff --git a/Procfile.rari b/Procfile.rari
new file mode 100644
index 000000000000..a39285dfe174
--- /dev/null
+++ b/Procfile.rari
@@ -0,0 +1,2 @@
+server: yarn start:rari-server
+web: yarn start:client
diff --git a/README.md b/README.md
index fab120f41c62..248cb0c20aaa 100644
--- a/README.md
+++ b/README.md
@@ -269,6 +269,14 @@ this, you can pick any unused port (e.g., 6000) and run the following:
echo SERVER_PORT=6000 >> .env
+### Problems running with rari on Windows
+
+Download and install:
+
+Microsoft Visual C++ Redistributable for Visual Studio 2019 (
+[x86](https://aka.ms/vs/16/release/VC_redist.x86.exe),
+[ARM64](https://aka.ms/vs/16/release/VC_redist.arm64.exe) )
+
### Yarn install errors
If you get errors while installing dependencies via yarn on a Mac, you may need
diff --git a/client/src/document/toolbar/flaws.tsx b/client/src/document/toolbar/flaws.tsx
index 191760550773..ea5698f7eb75 100644
--- a/client/src/document/toolbar/flaws.tsx
+++ b/client/src/document/toolbar/flaws.tsx
@@ -331,7 +331,7 @@ function Flaws({
/>
);
default:
- throw new Error(`Unknown flaw check '${flaw.name}'`);
+ return ;
}
})}
@@ -531,6 +531,20 @@ function BrokenLinks({
);
}
+function Unknown({ flaws }: { flaws: GenericFlaw[] }) {
+ return (
+
@@ -692,7 +706,9 @@ function Macros({
{humanizeFlawName("macros")}
{flaws.map((flaw) => {
- const inPrerequisiteMacro = !flaw.filepath.includes(sourceFilePath);
+ const inPrerequisiteMacro = flaw.filepath
+ ? !flaw.filepath.includes(sourceFilePath)
+ : false;
return (
{
popularities.set(url, value as number);
}
diff --git a/copy/community/community.md b/copy/community/community.md
index 1f851e99e660..a0f35e196761 100644
--- a/copy/community/community.md
+++ b/copy/community/community.md
@@ -1,3 +1,7 @@
+---
+title: Contribute to MDN
+---
+
# MDN Community
Where web enthusiasts learn, collaborate, and create
diff --git a/copy/config.json b/copy/config.json
new file mode 100644
index 000000000000..6438b35bbbc1
--- /dev/null
+++ b/copy/config.json
@@ -0,0 +1,29 @@
+{
+ "pages": {
+ "community": {
+ "titleSuffix": "Contribute to MDN"
+ },
+ "plus": {
+ "slugPrefix": "plus/docs",
+ "titleSuffix": "MDN Plus"
+ },
+ "observatory": {
+ "slugPrefix": "observatory/docs",
+ "titleSuffix": "HTTP Observatory"
+ }
+ },
+ "spas": {
+ "about": {
+ "slug": "about",
+ "pageTitle": "About MDN"
+ },
+ "advertising": {
+ "slug": "advertising",
+ "pageTitle": "Advertise with us"
+ },
+ "plus": {
+ "slug": "plus",
+ "pageTitle": "MDN Plus"
+ }
+ }
+}
diff --git a/deployer/src/deployer/search/__init__.py b/deployer/src/deployer/search/__init__.py
index dfdb286dbe7b..972b7f7d2184 100644
--- a/deployer/src/deployer/search/__init__.py
+++ b/deployer/src/deployer/search/__init__.py
@@ -248,7 +248,7 @@ def to_search(file, _index=None):
)
),
popularity=doc["popularity"],
- summary=doc["summary"],
+ summary=doc.get("summary", ""),
# Note! We're always lowercasing the 'slug'. This way we can search on it,
# still as a `keyword` index, but filtering by prefix.
# E.g. in kuma; ?slug_prefix=weB/Css
diff --git a/libs/env/index.d.ts b/libs/env/index.d.ts
index fec939592c93..f57b38a5ed1b 100644
--- a/libs/env/index.d.ts
+++ b/libs/env/index.d.ts
@@ -1,5 +1,6 @@
export const BUILD_OUT_ROOT: string;
export const DEFAULT_FLAW_LEVELS: string;
+export const RARI: boolean;
export const BASE_URL: string;
export const FILES: string;
export const FOLDERSEARCH: string;
@@ -27,6 +28,7 @@ export const STATIC_ROOT: string;
export const PROXY_HOSTNAME: string;
export const CONTENT_HOSTNAME: string;
export const FAKE_V1_API: boolean;
+export const EXTERNAL_DEV_SERVER: sting;
export const SENTRY_DSN_BUILD: string;
export const OPENAI_KEY: string;
export const PG_URI: string;
diff --git a/libs/env/index.js b/libs/env/index.js
index 253b341d7999..7f9e65be1a13 100644
--- a/libs/env/index.js
+++ b/libs/env/index.js
@@ -28,6 +28,7 @@ dotenv.config({
// build
// -----
+export const RARI = Boolean(parse(process.env.RARI || "false"));
export const BASE_URL = process.env.BASE_URL || "https://developer.mozilla.org";
export const BUILD_OUT_ROOT =
@@ -178,6 +179,8 @@ export const PROXY_HOSTNAME =
export const CONTENT_HOSTNAME = process.env.SERVER_CONTENT_HOST;
export const FAKE_V1_API = parse(process.env.SERVER_FAKE_V1_API || false);
+export const EXTERNAL_DEV_SERVER =
+ process.env.EXTERNAL_DEV_SERVER || "http://localhost:8083";
// ----
// tool
diff --git a/libs/types/document.ts b/libs/types/document.ts
index 1ccedcc18412..bec2c34d4856 100644
--- a/libs/types/document.ts
+++ b/libs/types/document.ts
@@ -110,6 +110,7 @@ export type Flaws = Partial<{
heading_links: HeadingLinksFlaw[];
translation_differences: TranslationDifferenceFlaw[];
unsafe_html: UnsafeHTMLFlaw[];
+ unknown: GenericFlaw[];
}>;
export type Translation = {
diff --git a/package.json b/package.json
index 4e64897b3939..7d278fd304aa 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"author": "MDN Web Docs",
"type": "module",
"bin": {
+ "rari-server": "server/cli.js",
"yari-build": "build/cli.js",
"yari-build-blog": "build/build-blog.js",
"yari-filecheck": "filecheck/cli.js",
@@ -14,36 +15,39 @@
"yari-tool": "tool/cli.js"
},
"scripts": {
- "ai-help-macros": "cross-env NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node scripts/ai-help-macros.ts",
+ "ai-help-macros": "cross-env NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node scripts/ai-help-macros.ts",
"analyze": "(test -f client/build/stats.json || cross-env ANALYZE_BUNDLE=true yarn build:client) && webpack-bundle-analyzer client/build/stats.json",
- "build": "cross-env NODE_ENV=production NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node build/cli.ts",
- "build:blog": "cross-env NODE_ENV=production NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node build/build-blog.ts",
+ "build": "cross-env NODE_ENV=production NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node build/cli.ts",
+ "build:blog": "cross-env NODE_ENV=production NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node build/build-blog.ts",
"build:client": "cd client && cross-env NODE_ENV=production BABEL_ENV=production node scripts/build.js",
- "build:curriculum": "cross-env NODE_ENV=production NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node build/build-curriculum.ts",
+ "build:curriculum": "cross-env NODE_ENV=production NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node build/build-curriculum.ts",
"build:dist": "tsc -p tsconfig.dist.json",
- "build:docs": "cross-env NODE_ENV=production NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node build/cli.ts -n",
+ "build:docs": "cross-env NODE_ENV=production NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node build/cli.ts -n",
"build:glean": "cd client && cross-env VIRTUAL_ENV=venv glean translate src/telemetry/metrics.yaml src/telemetry/pings.yaml -f typescript -o src/telemetry/generated",
"build:prepare": "yarn build:client && yarn build:ssr && yarn tool popularities && yarn tool spas && yarn tool gather-git-history && yarn tool build-robots-txt",
- "build:ssr": "cross-env NODE_ENV=production NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node ssr/prepare.ts && webpack --mode=production --config=ssr/webpack.config.js",
+ "build:ssr": "cross-env NODE_ENV=production NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node ssr/prepare.ts && webpack --mode=production --config=ssr/webpack.config.js",
"build:sw": "cd client/pwa && yarn && yarn build:prod",
"build:sw-dev": "cd client/pwa && yarn && yarn build",
"check:tsc": "find . -name 'tsconfig.json' ! -wholename '**/node_modules/**' -print0 | xargs -n1 -P 2 -0 sh -c 'cd `dirname $0` && echo \"🔄 $(pwd)\" && npx tsc --noEmit && echo \"☑️ $(pwd)\" || exit 255'",
"dev": "yarn build:prepare && nf -j Procfile.dev start",
"eslint": "eslint .",
- "filecheck": "cross-env NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node filecheck/cli.ts",
+ "filecheck": "cross-env NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node filecheck/cli.ts",
"install:all": "find . -mindepth 2 -name 'yarn.lock' ! -wholename '**/node_modules/**' -print0 | xargs -n1 -0 sh -cx 'yarn --cwd $(dirname $0) install'",
"install:all:npm": "find . -mindepth 2 -name 'package-lock.json' ! -wholename '**/node_modules/**' -print0 | xargs -n1 -0 sh -cx 'npm --prefix $(dirname $0) install'",
"jest": "node --experimental-vm-modules --expose-gc ./node_modules/.bin/jest --logHeapUsage",
- "m2h": "cross-env NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node markdown/m2h/cli.ts",
+ "m2h": "cross-env NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node markdown/m2h/cli.ts",
"prepack": "yarn render:html && yarn build:dist",
"prepare": "(husky || true) && yarn install:all && yarn install:all:npm",
"prettier-check": "prettier --check .",
"prettier-format": "prettier --write .",
- "render:html": "cross-env NODE_ENV=production NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node build/ssr-cli.ts",
+ "render:html": "cross-env NODE_ENV=production NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node build/ssr-cli.ts",
"start": "(test -f client/build/asset-manifest.json || yarn build:client) && (test -f ssr/dist/main.js || yarn build:ssr) && (test -f popularities.json || yarn tool popularities) && (test -d client/build/en-us/_spas || yarn tool spas) && (test -d client/build/en-us/_spas/404.html || yarn render:html -s) && nf -j Procfile.start start",
"start:client": "cd client && cross-env NODE_ENV=development BABEL_ENV=development PORT=3000 node scripts/start.js",
+ "start:rari": "(test -f client/build/asset-manifest.json || yarn build:client) && (test -f ssr/dist/main.js || yarn build:ssr) && cross-env RARI=true nf -j Procfile.rari start",
+ "start:rari-external": "(test -f client/build/asset-manifest.json || yarn build:client) && (test -f ssr/dist/main.js || yarn build:ssr) && cross-env RARI=true nf -j Procfile.start start",
+ "start:rari-server": "cross-env NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node server/cli.ts",
"start:server": "node-dev --experimental-loader ts-node/esm server/index.ts",
- "start:static-server": "cross-env NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node server/static.ts",
+ "start:static-server": "cross-env NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node server/static.ts",
"stylelint": "stylelint \"**/*.scss\"",
"test": "yarn prettier-check && yarn test:client && yarn test:kumascript && yarn test:libs && yarn test:content && yarn test:testing",
"test:client": "cd client && tsc --noEmit && cross-env NODE_ENV=test BABEL_ENV=test node scripts/test.js --env=jsdom",
@@ -54,7 +58,7 @@
"test:libs": "yarn jest --rootDir libs --env=node",
"test:prepare": "yarn build:prepare && yarn build:docs && yarn render:html && yarn start:static-server",
"test:testing": "yarn jest --rootDir testing",
- "tool": "cross-env NODE_OPTIONS='--no-warnings=ExperimentalWarning --loader ts-node/esm' node ./tool/cli.ts",
+ "tool": "cross-env NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --loader ts-node/esm\" node ./tool/cli.ts",
"watch:ssr": "webpack --mode=production --watch --config=ssr/webpack.config.js"
},
"resolutions": {
@@ -74,6 +78,7 @@
"@lit/react": "^1.0.6",
"@mdn/bcd-utils-api": "^0.0.7",
"@mdn/browser-compat-data": "^5.6.19",
+ "@mdn/rari": "^0.0.25",
"@mozilla/glean": "5.0.3",
"@sentry/node": "^8.41.0",
"@stripe/stripe-js": "^4.10.0",
@@ -88,6 +93,7 @@
"codemirror": "^6.0.1",
"compression": "^1.7.5",
"compute-baseline": "^0.1.1",
+ "concurrently": "^9.0.1",
"cookie": "^0.7.2",
"cookie-parser": "^1.4.7",
"css-tree": "^2.3.1",
diff --git a/server/cli.ts b/server/cli.ts
new file mode 100644
index 000000000000..799e0b04d1ab
--- /dev/null
+++ b/server/cli.ts
@@ -0,0 +1,42 @@
+#!/usr/bin/env node
+import { concurrently } from "concurrently";
+import { rariBin } from "@mdn/rari";
+import { filename } from "./filename.js";
+
+const { commands, result } = concurrently(
+ [
+ {
+ command: `node ${filename}`,
+ name: "server",
+ env: {
+ RARI: true,
+ },
+ prefixColor: "red",
+ },
+ {
+ command: `${rariBin} serve -vv`,
+ name: "rari",
+ prefixColor: "blue",
+ },
+ ],
+ {
+ killOthers: ["failure", "success"],
+ restartTries: 0,
+ handleInput: true,
+ inputStream: process.stdin,
+ }
+);
+
+const stop = new Promise((resolve, reject) => {
+ process.on("SIGINT", () => {
+ commands.forEach((cmd) => cmd.kill()); // Terminate all concurrently-run processes
+ reject();
+ });
+ result.finally(() => resolve(null));
+});
+try {
+ await stop;
+ console.log("All tasks completed successfully.");
+} catch {
+ console.log("Killed ☠️");
+}
diff --git a/server/filename.ts b/server/filename.ts
new file mode 100644
index 000000000000..abc56988399e
--- /dev/null
+++ b/server/filename.ts
@@ -0,0 +1,2 @@
+import { fileURLToPath } from "node:url";
+export const filename = fileURLToPath(import.meta.resolve("./index.js"));
diff --git a/server/index.ts b/server/index.ts
index f2e1535b9e2c..f9d94e6282a3 100644
--- a/server/index.ts
+++ b/server/index.ts
@@ -33,6 +33,8 @@ import {
CONTENT_TRANSLATED_ROOT,
BLOG_ROOT,
CURRICULUM_ROOT,
+ EXTERNAL_DEV_SERVER,
+ RARI,
} from "../libs/env/index.js";
import { PLAYGROUND_UNSAFE_CSP_VALUE } from "../libs/play/index.js";
@@ -55,28 +57,43 @@ import {
import { findCurriculumPageBySlug } from "../build/curriculum.js";
import { handleRunner } from "../libs/play/index.js";
+async function fetch_from_rari(path: string) {
+ const external_url = `${EXTERNAL_DEV_SERVER}${path}`;
+ console.log(`using ${external_url}`);
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins
+ return await (await fetch(external_url)).json();
+}
+
async function buildDocumentFromURL(url: string) {
try {
console.time(`buildDocumentFromURL(${url})`);
- const document = Document.findByURL(url);
- if (!document) {
- return null;
- }
- const documentOptions = {};
- if (CONTENT_TRANSLATED_ROOT) {
- // When you're running the dev server and build documents
- // every time a URL is requested, you won't have had the chance to do
- // the phase that happens when you do a regular `yarn build`.
- document.translations = findTranslations(
- document.metadata.slug,
- document.metadata.locale
- );
+ let built;
+ if (!RARI) {
+ const document = Document.findByURL(url);
+ if (!document) {
+ return null;
+ }
+ const documentOptions = {};
+ if (CONTENT_TRANSLATED_ROOT) {
+ // When you're running the dev server and build documents
+ // every time a URL is requested, you won't have had the chance to do
+ // the phase that happens when you do a regular `yarn build`.
+ document.translations = findTranslations(
+ document.metadata.slug,
+ document.metadata.locale
+ );
+ }
+ built = await buildDocument(document, documentOptions);
+ if (built) {
+ return { doc: built?.doc, url };
+ }
+ } else {
+ built = await fetch_from_rari(url);
+ if (built) {
+ return built;
+ }
}
- const built = await buildDocument(document, documentOptions);
-
- if (built) {
- return { doc: built?.doc, url };
- } else if (
+ if (
url.split("/")[1] &&
url.split("/")[1].toLowerCase() !== DEFAULT_LOCALE.toLowerCase() &&
!CONTENT_TRANSLATED_ROOT
@@ -97,19 +114,29 @@ async function buildDocumentFromURL(url: string) {
}
}
-function redirectOr404(res: express.Response, url, suffix = "") {
+async function redirectOr404(res: express.Response, url, suffix = "") {
const redirectURL = Redirect.resolve(url);
if (redirectURL !== url) {
// This was and is broken for redirects with anchors...
return res.redirect(301, redirectURL + suffix);
}
- return send404(res);
+ return await send404(res);
}
-function send404(res: express.Response) {
- return res
- .status(404)
- .sendFile(path.join(STATIC_ROOT, "en-us", "_spas", "404.html"));
+async function send404(res: express.Response) {
+ if (!RARI) {
+ return res
+ .status(404)
+ .sendFile(path.join(STATIC_ROOT, "en-us", "_spas", "404.html"));
+ } else {
+ try {
+ const index = await fetch_from_rari("/en-US/404");
+ res.header("Content-Security-Policy", CSP_VALUE);
+ return res.send(renderHTML(index));
+ } catch (error) {
+ return res.status(500).json(JSON.stringify(error.toString()));
+ }
+ }
}
const app = express();
@@ -250,29 +277,55 @@ app.get("/_open", (req, res) => {
res.status(200).send(`Tried to open ${spec} in ${process.env.EDITOR}`);
});
-app.use("/:locale/search-index.json", searchIndexRoute);
+if (!RARI) {
+ app.use("/:locale/search-index.json", searchIndexRoute);
+} else {
+ app.use("/:locale/search-index.json", async (req, res) => {
+ const { locale } = req.params;
+ try {
+ const json = await fetch_from_rari(`/${locale}/search-index.json`);
+ res.setHeader("Access-Control-Allow-Origin", "*");
+ return res.json(json);
+ } catch (error) {
+ return res.status(500).json(JSON.stringify(error.toString()));
+ }
+ });
+}
app.get("/_flaws", flawsRoute);
app.use("/_translations", translationsRouter);
app.get("/*/contributors.txt", async (req, res) => {
- const url = req.path.replace(/\/contributors\.txt$/, "");
- const document = Document.findByURL(url);
- res.setHeader("content-type", "text/plain");
- if (!document) {
- return res.status(404).send(`Document not found by URL (${url})`);
- }
- try {
- const { doc: builtDocument } = await buildDocument(document);
- res.send(
- renderContributorsTxt(
- document.metadata.contributors,
- builtDocument.source.github_url.replace("/blob/", "/commits/")
- )
- );
- } catch (error) {
- return res.status(500).json(JSON.stringify(error.toString()));
+ if (!RARI) {
+ const url = req.path.replace(/\/contributors\.txt$/, "");
+ const document = Document.findByURL(url);
+ res.setHeader("content-type", "text/plain");
+ if (!document) {
+ return res.status(404).send(`Document not found by URL (${url})`);
+ }
+ try {
+ const { doc: builtDocument } = await buildDocument(document);
+ res.send(
+ renderContributorsTxt(
+ document.metadata.contributors,
+ builtDocument.source.github_url.replace("/blob/", "/commits/")
+ )
+ );
+ } catch (error) {
+ return res.status(500).json(JSON.stringify(error.toString()));
+ }
+ } else {
+ try {
+ const external_url = `${EXTERNAL_DEV_SERVER}${req.path}`;
+ console.log(`contributors.txt: using ${external_url}`);
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins
+ const text = await (await fetch(external_url)).text();
+ res.setHeader("content-type", "text/plain");
+ return res.send(text);
+ } catch (error) {
+ return res.status(500).json(JSON.stringify(error.toString()));
+ }
}
});
@@ -287,8 +340,17 @@ if (CURRICULUM_ROOT) {
"/:locale/curriculum/index.json",
],
async (req, res) => {
- const { slug = "" } = req.params;
- const data = await findCurriculumPageBySlug(slug);
+ let data;
+ if (!RARI) {
+ const { slug = "" } = req.params;
+ data = await findCurriculumPageBySlug(slug);
+ } else {
+ try {
+ data = await fetch_from_rari(req.path);
+ } catch (error) {
+ return res.status(500).json(JSON.stringify(error.toString()));
+ }
+ }
if (!data) {
return res.status(404).send("Nothing here 🤷♂️");
}
@@ -296,19 +358,28 @@ if (CURRICULUM_ROOT) {
}
);
} else {
- app.get("/[^/]+/curriculum/*", (_, res) => {
+ app.get("/[^/]+/curriculum/*", async (_, res) => {
console.warn("'CURRICULUM_ROOT' not set in .env file");
- return send404(res);
+ return await send404(res);
});
}
if (BLOG_ROOT) {
- app.get("/:locale/blog/index.json", async (_, res) => {
- const posts = await allPostFrontmatter(
- { includeUnpublished: true },
- MEMOIZE_INVALIDATE
- );
- return res.json({ hyData: { posts } });
+ app.get("/:locale/blog/index.json", async (req, res) => {
+ if (!RARI) {
+ const posts = await allPostFrontmatter(
+ { includeUnpublished: true },
+ MEMOIZE_INVALIDATE
+ );
+ return res.json({ hyData: { posts } });
+ } else {
+ try {
+ const index = await fetch_from_rari(req.path);
+ return res.json(index);
+ } catch (error) {
+ return res.status(500).json(JSON.stringify(error.toString()));
+ }
+ }
});
app.get("/:locale/blog/author/:slug/:asset", async (req, res) => {
const { slug, asset } = req.params;
@@ -324,12 +395,21 @@ if (BLOG_ROOT) {
).pipe(res);
});
app.get("/:locale/blog/:slug/index.json", async (req, res) => {
- const { slug } = req.params;
- const data = await findPostBySlug(slug);
- if (!data) {
- return res.status(404).send("Nothing here 🤷♂️");
+ if (!RARI) {
+ const { slug } = req.params;
+ const data = await findPostBySlug(slug);
+ if (!data) {
+ return res.status(404).send("Nothing here 🤷♂️");
+ }
+ return res.json(data);
+ } else {
+ try {
+ const index = await fetch_from_rari(req.path);
+ return res.json(index);
+ } catch (error) {
+ return res.status(500).json(JSON.stringify(error.toString()));
+ }
}
- return res.json(data);
});
app.get("/:locale/blog/:slug/:asset", async (req, res) => {
const { slug, asset } = req.params;
@@ -343,9 +423,9 @@ if (BLOG_ROOT) {
return res.status(404).send("Nothing here 🤷♂️");
});
} else {
- app.get("/[^/]+/blog/*", (_, res) => {
+ app.get("/[^/]+/blog/*", async (_, res) => {
console.warn("'BLOG_ROOT' not set in .env file");
- return send404(res);
+ return await send404(res);
});
}
@@ -370,7 +450,7 @@ if (contentProxy) {
try {
const doc = await buildDocumentFromURL(url);
if (!doc) {
- return redirectOr404(res, url, "/index.json");
+ return await redirectOr404(res, url, "/index.json");
}
return res.json(doc);
} catch (error) {
@@ -381,7 +461,7 @@ if (contentProxy) {
const url = decodeURI(req.path.replace(/\/metadata.json$/, ""));
const doc = await buildDocumentFromURL(url);
if (!doc?.doc) {
- return redirectOr404(res, url, "/metadata.json");
+ return await redirectOr404(res, url, "/metadata.json");
}
const docString = JSON.stringify(doc);
@@ -410,7 +490,7 @@ if (contentProxy) {
try {
const doc = await buildDocumentFromURL(url);
if (!doc) {
- return redirectOr404(res, url);
+ return await redirectOr404(res, url);
}
res.header("Content-Security-Policy", CSP_VALUE);
return res.send(renderHTML(doc));
@@ -420,9 +500,35 @@ if (contentProxy) {
});
}
+if (RARI) {
+ app.get(
+ [
+ "/en-US/about",
+ "/en-US/about/index.json",
+ "/en-US/community",
+ "/en-US/community/index.json",
+ "/en-US/plus/docs/*",
+ "/en-US/observatory/docs/*",
+ "/:locale/",
+ ],
+ async (req, res) => {
+ try {
+ const index = await fetch_from_rari(req.path);
+ if (req.path.endsWith(".json")) {
+ return res.json(index);
+ }
+ res.header("Content-Security-Policy", CSP_VALUE);
+ return res.send(renderHTML(index));
+ } catch (error) {
+ return res.status(500).json(JSON.stringify(error.toString()));
+ }
+ }
+ );
+}
+
app.use(staticMiddlewares);
-app.get("/*", (_, res) => send404(res));
+app.get("/*", async (_, res) => await send404(res));
if (!fs.existsSync(path.resolve(CONTENT_ROOT))) {
throw new Error(`${path.resolve(CONTENT_ROOT)} does not exist!`);
diff --git a/tool/popularities.ts b/tool/popularities.ts
index 87a010ac7514..2b020ba4defb 100644
--- a/tool/popularities.ts
+++ b/tool/popularities.ts
@@ -69,7 +69,14 @@ export async function runMakePopularitiesFile({
pageviews.slice(0, maxUris).forEach(([uri, popularity]) => {
popularities[uri] = parseFloat(popularity.toFixed(5));
});
- fs.writeFileSync(outfile, JSON.stringify(popularities, null, 2));
+ fs.writeFileSync(
+ outfile,
+ JSON.stringify(
+ { popularities: popularities, date: new Date().toISOString() },
+ null,
+ 2
+ )
+ );
resolve({ rowCount, popularities, pageviews });
});
});
diff --git a/yarn.lock b/yarn.lock
index edcc94452aef..6f88cd98234b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10,6 +10,15 @@
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.24"
+"@apidevtools/json-schema-ref-parser@^11.5.5":
+ version "11.7.2"
+ resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.2.tgz#cdf3e0aded21492364a70e193b45b7cf4177f031"
+ integrity sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==
+ dependencies:
+ "@jsdevtools/ono" "^7.1.3"
+ "@types/json-schema" "^7.0.15"
+ js-yaml "^4.1.0"
+
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0":
version "7.26.2"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
@@ -1815,6 +1824,13 @@
wrap-ansi "^8.1.0"
wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
+"@isaacs/fs-minipass@^4.0.0":
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz#2d59ae3ab4b38fb4270bfa23d30f8e2e86c7fe32"
+ integrity sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==
+ dependencies:
+ minipass "^7.0.4"
+
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@@ -2079,6 +2095,11 @@
jsbi "^4.3.0"
tslib "^2.4.1"
+"@jsdevtools/ono@^7.1.3":
+ version "7.1.3"
+ resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796"
+ integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==
+
"@jsonjoy.com/base64@^1.1.1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@jsonjoy.com/base64/-/base64-1.1.2.tgz#cf8ea9dcb849b81c95f14fc0aaa151c6b54d2578"
@@ -2187,6 +2208,17 @@
resolved "https://registry.yarnpkg.com/@mdn/minimalist/-/minimalist-2.0.4.tgz#6488ab0cb65b059446dcd9bf542246b81febe241"
integrity sha512-jocePw/fsGcBxO67D+iWQLZ0TQjwNVonaME2BFN98QIm/e1kTY1/k2s4fOqH5MMa3QYURxa098bI4sChn6s/7Q==
+"@mdn/rari@^0.0.25":
+ version "0.0.25"
+ resolved "https://registry.yarnpkg.com/@mdn/rari/-/rari-0.0.25.tgz#719b6a72eb8239dca48b6bf090f1f38490380be7"
+ integrity sha512-5r1P9CAGLC93O6hZgc2fdO0Z4B/uI8PbAworRRlMthPlXUjyiyfIdzijwGCkr8JN5H6950oCLfjwJAEd4NGUPQ==
+ dependencies:
+ extract-zip "^2.0.1"
+ https-proxy-agent "^7.0.2"
+ json-schema-to-typescript "^15.0.0"
+ proxy-from-env "^1.1.0"
+ tar "^7.4.3"
+
"@mozilla/glean@5.0.3":
version "5.0.3"
resolved "https://registry.yarnpkg.com/@mozilla/glean/-/glean-5.0.3.tgz#eda7169f3e8f38a7d3019a1512b45778c4f05735"
@@ -3342,7 +3374,7 @@
"@types/tough-cookie" "*"
parse5 "^7.0.0"
-"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
+"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
@@ -3352,7 +3384,7 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
-"@types/lodash@^4.14.149":
+"@types/lodash@^4.14.149", "@types/lodash@^4.17.7":
version "4.17.13"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb"
integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==
@@ -3642,6 +3674,13 @@
dependencies:
"@types/yargs-parser" "*"
+"@types/yauzl@^2.9.1":
+ version "2.10.3"
+ resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999"
+ integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==
+ dependencies:
+ "@types/node" "*"
+
"@typescript-eslint/eslint-plugin@8.16.0":
version "8.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.16.0.tgz#ac56825bcdf3b392fc76a94b1315d4a162f201a6"
@@ -4991,6 +5030,11 @@ chokidar@^4.0.0:
dependencies:
readdirp "^4.0.1"
+chownr@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-3.0.0.tgz#9855e64ecd240a9cc4267ce8a4aa5d24a1da15e4"
+ integrity sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==
+
chrome-trace-event@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b"
@@ -5260,6 +5304,19 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
+concurrently@^9.0.1:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-9.0.1.tgz#01e171bf6c7af0c022eb85daef95bff04d8185aa"
+ integrity sha512-wYKvCd/f54sTXJMSfV6Ln/B8UrfLBKOYa+lzc6CHay3Qek+LorVSBdMVfyewFhRbH0Rbabsk4D+3PL/VjQ5gzg==
+ dependencies:
+ chalk "^4.1.2"
+ lodash "^4.17.21"
+ rxjs "^7.8.1"
+ shell-quote "^1.8.1"
+ supports-color "^8.1.1"
+ tree-kill "^1.2.2"
+ yargs "^17.7.2"
+
config-chain@^1.1.11:
version "1.1.13"
resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4"
@@ -6989,6 +7046,17 @@ external-editor@^3.0.3, external-editor@^3.1.0:
iconv-lite "^0.4.24"
tmp "^0.0.33"
+extract-zip@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
+ integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
+ dependencies:
+ debug "^4.1.1"
+ get-stream "^5.1.0"
+ yauzl "^2.10.0"
+ optionalDependencies:
+ "@types/yauzl" "^2.9.1"
+
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -7515,6 +7583,13 @@ get-stream@^4.0.0:
dependencies:
pump "^3.0.0"
+get-stream@^5.1.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
+ integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
+ dependencies:
+ pump "^3.0.0"
+
get-stream@^6.0.0, get-stream@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
@@ -7582,7 +7657,7 @@ glob-to-regexp@^0.4.1:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
-glob@^10.0.0:
+glob@^10.0.0, glob@^10.3.7:
version "10.4.5"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956"
integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
@@ -9597,6 +9672,21 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1:
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
+json-schema-to-typescript@^15.0.0:
+ version "15.0.3"
+ resolved "https://registry.yarnpkg.com/json-schema-to-typescript/-/json-schema-to-typescript-15.0.3.tgz#a58bc3e00e4480e76a8ee79471c01233494913be"
+ integrity sha512-iOKdzTUWEVM4nlxpFudFsWyUiu/Jakkga4OZPEt7CGoSEsAsUgdOZqR6pcgx2STBek9Gm4hcarJpXSzIvZ/hKA==
+ dependencies:
+ "@apidevtools/json-schema-ref-parser" "^11.5.5"
+ "@types/json-schema" "^7.0.15"
+ "@types/lodash" "^4.17.7"
+ is-glob "^4.0.3"
+ js-yaml "^4.1.0"
+ lodash "^4.17.21"
+ minimist "^1.2.8"
+ prettier "^3.2.5"
+ tinyglobby "^0.2.9"
+
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
@@ -10730,16 +10820,24 @@ minimist-options@4.1.0:
is-plain-obj "^1.1.0"
kind-of "^6.0.3"
-minimist@^1.2.0, minimist@^1.2.6:
+minimist@^1.2.0, minimist@^1.2.6, minimist@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
-"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2:
+"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4, minipass@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707"
integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
+minizlib@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-3.0.1.tgz#46d5329d1eb3c83924eff1d3b858ca0a31581012"
+ integrity sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==
+ dependencies:
+ minipass "^7.0.4"
+ rimraf "^5.0.5"
+
mkdirp@^0.5.1:
version "0.5.6"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
@@ -10747,6 +10845,11 @@ mkdirp@^0.5.1:
dependencies:
minimist "^1.2.6"
+mkdirp@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50"
+ integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==
+
module-details-from-path@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b"
@@ -12303,7 +12406,7 @@ prettier-plugin-packagejson@^2.5.6:
sort-package-json "2.12.0"
synckit "0.9.2"
-prettier@^3.4.1:
+prettier@^3.2.5, prettier@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.4.1.tgz#e211d451d6452db0a291672ca9154bc8c2579f7b"
integrity sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==
@@ -13051,6 +13154,13 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
+rimraf@^5.0.5:
+ version "5.0.10"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.10.tgz#23b9843d3dc92db71f96e1a2ce92e39fd2a8221c"
+ integrity sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==
+ dependencies:
+ glob "^10.3.7"
+
rough-notation@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/rough-notation/-/rough-notation-0.5.1.tgz#32abbb16b973fb00fba83ab96b18704e98620e95"
@@ -13085,6 +13195,13 @@ rxjs@^6.4.0:
dependencies:
tslib "^1.9.0"
+rxjs@^7.8.1:
+ version "7.8.1"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
+ integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==
+ dependencies:
+ tslib "^2.1.0"
+
safe-array-concat@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb"
@@ -14118,7 +14235,7 @@ supports-color@^7.0.0, supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
-supports-color@^8.0.0:
+supports-color@^8.0.0, supports-color@^8.1.1:
version "8.1.1"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
@@ -14233,6 +14350,18 @@ tar-stream@^1.5.2:
to-buffer "^1.1.1"
xtend "^4.0.0"
+tar@^7.4.3:
+ version "7.4.3"
+ resolved "https://registry.yarnpkg.com/tar/-/tar-7.4.3.tgz#88bbe9286a3fcd900e94592cda7a22b192e80571"
+ integrity sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==
+ dependencies:
+ "@isaacs/fs-minipass" "^4.0.0"
+ chownr "^3.0.0"
+ minipass "^7.1.2"
+ minizlib "^3.0.1"
+ mkdirp "^3.0.1"
+ yallist "^5.0.0"
+
temp-dir@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d"
@@ -14440,6 +14569,11 @@ tree-dump@^1.0.1:
resolved "https://registry.yarnpkg.com/tree-dump/-/tree-dump-1.0.2.tgz#c460d5921caeb197bde71d0e9a7b479848c5b8ac"
integrity sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==
+tree-kill@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
+ integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
+
trim-lines@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338"
@@ -14549,6 +14683,11 @@ tslib@^2.0.0, tslib@^2.0.3, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.1, tslib@^2.6
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
+tslib@^2.1.0:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b"
+ integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==
+
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
@@ -15545,6 +15684,11 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
+yallist@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/yallist/-/yallist-5.0.0.tgz#00e2de443639ed0d78fd87de0d27469fbcffb533"
+ integrity sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==
+
yaml@^1.10.0:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
@@ -15565,7 +15709,7 @@ yargs-parser@^21.1.1:
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
-yargs@^17.3.1:
+yargs@^17.3.1, yargs@^17.7.2:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
@@ -15578,7 +15722,7 @@ yargs@^17.3.1:
y18n "^5.0.5"
yargs-parser "^21.1.1"
-yauzl@^2.4.2, yauzl@^2.9.2:
+yauzl@^2.10.0, yauzl@^2.4.2, yauzl@^2.9.2:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==