diff --git a/.github/workflows/build-deploy-test.yml b/.github/workflows/build-deploy-test.yml index b6a571a3..eee6e9e1 100644 --- a/.github/workflows/build-deploy-test.yml +++ b/.github/workflows/build-deploy-test.yml @@ -131,6 +131,7 @@ jobs: build-systems/nx-rspack-mf build-systems/turborepo-rspack-mf module-federation/airbnb-clone + module-federation/react-rsbuild-monorepo module-federation/react-vite-rspack-webpack ) for example in "${standalone[@]}"; do diff --git a/.github/workflows/rsbuild-mf-live-fixture.yml b/.github/workflows/rsbuild-mf-live-fixture.yml new file mode 100644 index 00000000..08cd60ec --- /dev/null +++ b/.github/workflows/rsbuild-mf-live-fixture.yml @@ -0,0 +1,46 @@ +name: Rsbuild Module Federation live fixture + +on: + workflow_dispatch: + schedule: + - cron: '17 9 * * 1' + +permissions: + contents: read + +concurrency: + group: rsbuild-mf-live-fixture + cancel-in-progress: false + +jobs: + publish: + if: github.repository == 'ZephyrCloudIO/zephyr-examples' + runs-on: depot-ubuntu-latest + timeout-minutes: 30 + environment: rsbuild-mf-live-fixture + env: + ZE_SECRET_TOKEN: ${{ secrets.ZEPHYR_AUTH_TOKEN }} + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: 24 + + - uses: pnpm/action-setup@v4 + with: + version: 10.33.0 + run_install: false + + - name: Require the protected Zephyr credential + run: test -n "$ZE_SECRET_TOKEN" + + - name: Install pinned example dependencies + working-directory: module-federation/react-rsbuild-monorepo + run: pnpm install --frozen-lockfile + + - name: Publish remotes before host + working-directory: module-federation/react-rsbuild-monorepo + run: pnpm build diff --git a/.github/workflows/verify-rsbuild-mf-monorepo.yml b/.github/workflows/verify-rsbuild-mf-monorepo.yml new file mode 100644 index 00000000..4e48f4b6 --- /dev/null +++ b/.github/workflows/verify-rsbuild-mf-monorepo.yml @@ -0,0 +1,58 @@ +name: Verify Rsbuild Module Federation monorepo + +on: + workflow_dispatch: + pull_request: + paths: + - "module-federation/react-rsbuild-monorepo/**" + - ".github/workflows/verify-rsbuild-mf-monorepo.yml" + push: + branches: + - main + paths: + - "module-federation/react-rsbuild-monorepo/**" + - ".github/workflows/verify-rsbuild-mf-monorepo.yml" + +permissions: + contents: read + +concurrency: + group: verify-rsbuild-mf-monorepo-${{ github.ref }} + cancel-in-progress: true + +jobs: + verify: + runs-on: depot-ubuntu-latest + timeout-minutes: 30 + defaults: + run: + working-directory: module-federation/react-rsbuild-monorepo + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: 24 + + - uses: pnpm/action-setup@v4 + with: + version: 10.33.0 + run_install: false + + - name: Install pinned dependencies + run: pnpm install --frozen-lockfile + + - name: Verify official scaffold and integration commands + run: pnpm verify:scaffold + + - name: Build and diagnose the example + run: pnpm verify + + - name: Install Chromium + run: pnpm exec playwright install --with-deps chromium + + - name: Verify remotes in a browser + run: pnpm verify:browser diff --git a/README.md b/README.md index 6f7e9c22..f8e5aeef 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Micro-frontend architecture with Module Federation, Zephyr's core value proposit | [Angular + Rsbuild Module Federation](module-federation/angular-rsbuild) | angular | rsbuild | intermediate | | [Angular + Vite Module Federation](module-federation/angular-vite) | angular | vite | intermediate | | [React + Rsbuild Module Federation](module-federation/react-rsbuild) | react | rsbuild | intermediate | +| [React + Rsbuild Module Federation Monorepo](module-federation/react-rsbuild-monorepo) | react | rsbuild | advanced | | [React Multi-Bundler Module Federation](module-federation/react-vite-rspack-webpack) | react | webpack | advanced | | [React + Webpack Module Federation](module-federation/react-webpack) | react | webpack | intermediate | | [Tractor Store (Module Federation)](module-federation/tractor-sample) | react | rspack | advanced | diff --git a/module-federation/react-rsbuild-monorepo/.gitignore b/module-federation/react-rsbuild-monorepo/.gitignore new file mode 100644 index 00000000..03c8d5fc --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/.gitignore @@ -0,0 +1,6 @@ +.mf/ +apps/*/@mf-types/ +diagnostics/type-001/node_modules/ +diagnostics/type-001/outside.d.ts +playwright-report/ +test-results/ diff --git a/module-federation/react-rsbuild-monorepo/README.md b/module-federation/react-rsbuild-monorepo/README.md new file mode 100644 index 00000000..44e96617 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/README.md @@ -0,0 +1,78 @@ +--- +name: React + Rsbuild Module Federation Monorepo +slug: module-federation/react-rsbuild-monorepo +description: Verified React monorepo with an Rsbuild host, two federated remotes, Zephyr dependencies, DTS diagnostics, and browser tests +framework: react +bundler: rsbuild +features: [module-federation, monorepo, typescript] +complexity: advanced +--- + +# React + Rsbuild Module Federation Monorepo + +> A verified React monorepo with an Rsbuild host, two federated remotes, +> Zephyr dependencies, DTS diagnostics, watch-mode checks, and browser tests. + +## Tech Stack + +- React 19 +- Rsbuild +- Module Federation +- pnpm workspaces +- Zephyr Cloud +- Playwright + +## Architecture + +The example contains three independently buildable applications: + +- `apps/header` exposes `header/Header`; +- `apps/hero` exposes `hero/Hero`; +- `apps/host` consumes both remotes and declares the matching + `zephyr:dependencies`. + +The build runs the remotes before the host. The committed verification scripts +check declared, locked, installed, generated, and browser-observed state. The +`diagnostics/type-001` project preserves a reproducible DTS `TS6059` failure and +its expected diagnostic path. + +## Quick Start + +```bash +npx degit ZephyrCloudIO/zephyr-examples/module-federation/react-rsbuild-monorepo my-app +cd my-app +pnpm install --frozen-lockfile +pnpm dev +``` + +The local development and verification commands set +`ZEPHYR_EXAMPLE_OFFLINE=1`, which disables publishing while preserving the +Rsbuild and Module Federation configuration. + +## Verify + +```bash +pnpm verify:scaffold +pnpm verify +pnpm verify:browser +``` + +These checks verify the official scaffold and integration commands, package +pins, remote-first build order, federation manifests, exposed modules, web +watch behavior, DTS diagnostics, browser rendering, and a remote-only update. + +## Deploy + +Provide an authorized Zephyr credential, then build: + +```bash +pnpm build +``` + +The build publishes `header`, then `hero`, then `host`. + +## Learn More + +- [Rsbuild + React Module Federation monorepo guide](https://docs.zephyr-cloud.io/tutorials/rsbuild-react-mf-monorepo) +- [Zephyr Cloud documentation](https://docs.zephyr-cloud.io) +- [Module Federation documentation](https://module-federation.io) diff --git a/module-federation/react-rsbuild-monorepo/apps/header/package.json b/module-federation/react-rsbuild-monorepo/apps/header/package.json new file mode 100644 index 00000000..ee8db9be --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/header/package.json @@ -0,0 +1,26 @@ +{ + "name": "rsbuild-mf-monorepo-header", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "rsbuild build", + "dev": "rsbuild dev", + "inspect": "rsbuild inspect", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "react": "19.2.7", + "react-dom": "19.2.7" + }, + "devDependencies": { + "@module-federation/rsbuild-plugin": "2.8.0", + "@rsbuild/core": "2.1.8", + "@rsbuild/plugin-react": "2.1.0", + "@types/node": "24.5.2", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", + "typescript": "6.0.3", + "zephyr-rsbuild-plugin": "1.2.0" + } +} diff --git a/module-federation/react-rsbuild-monorepo/apps/header/rsbuild.config.ts b/module-federation/react-rsbuild-monorepo/apps/header/rsbuild.config.ts new file mode 100644 index 00000000..d74fcc58 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/header/rsbuild.config.ts @@ -0,0 +1,47 @@ +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; +import { withZephyr } from 'zephyr-rsbuild-plugin'; + +const exampleOffline = process.env['ZEPHYR_EXAMPLE_OFFLINE'] === '1'; + +export default defineConfig({ + source: { + entry: { + index: './src/index.ts', + }, + }, + server: { + port: 3001, + }, + output: { + assetPrefix: 'auto', + }, + plugins: [ + pluginReact(), + pluginModuleFederation({ + name: 'header', + filename: 'remoteEntry.js', + manifest: true, + exposes: { + './Header': './src/Header.tsx', + }, + shared: { + react: { + singleton: true, + requiredVersion: '19.2.7', + }, + 'react-dom': { + singleton: true, + requiredVersion: '19.2.7', + }, + }, + dts: { + generateTypes: { + tsConfigPath: './tsconfig.json', + }, + }, + }), + ...(!exampleOffline ? [withZephyr()] : []), + ], +}); diff --git a/module-federation/react-rsbuild-monorepo/apps/header/src/Header.tsx b/module-federation/react-rsbuild-monorepo/apps/header/src/Header.tsx new file mode 100644 index 00000000..1d2a9afe --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/header/src/Header.tsx @@ -0,0 +1,7 @@ +export default function Header() { + return ( +
+ Header fixture v1 +
+ ); +} diff --git a/module-federation/react-rsbuild-monorepo/apps/header/src/index.ts b/module-federation/react-rsbuild-monorepo/apps/header/src/index.ts new file mode 100644 index 00000000..5653319d --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/header/src/index.ts @@ -0,0 +1 @@ +export { default as Header } from './Header'; diff --git a/module-federation/react-rsbuild-monorepo/apps/header/tsconfig.json b/module-federation/react-rsbuild-monorepo/apps/header/tsconfig.json new file mode 100644 index 00000000..33e603b9 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/header/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/module-federation/react-rsbuild-monorepo/apps/hero/package.json b/module-federation/react-rsbuild-monorepo/apps/hero/package.json new file mode 100644 index 00000000..0754a9ed --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/hero/package.json @@ -0,0 +1,25 @@ +{ + "name": "rsbuild-mf-monorepo-hero", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "rsbuild build", + "dev": "rsbuild dev", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "react": "19.2.7", + "react-dom": "19.2.7" + }, + "devDependencies": { + "@module-federation/rsbuild-plugin": "2.8.0", + "@rsbuild/core": "2.1.8", + "@rsbuild/plugin-react": "2.1.0", + "@types/node": "24.5.2", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", + "typescript": "6.0.3", + "zephyr-rsbuild-plugin": "1.2.0" + } +} diff --git a/module-federation/react-rsbuild-monorepo/apps/hero/rsbuild.config.ts b/module-federation/react-rsbuild-monorepo/apps/hero/rsbuild.config.ts new file mode 100644 index 00000000..fb85e607 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/hero/rsbuild.config.ts @@ -0,0 +1,47 @@ +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; +import { withZephyr } from 'zephyr-rsbuild-plugin'; + +const exampleOffline = process.env['ZEPHYR_EXAMPLE_OFFLINE'] === '1'; + +export default defineConfig({ + source: { + entry: { + index: './src/index.ts', + }, + }, + server: { + port: 3002, + }, + output: { + assetPrefix: 'auto', + }, + plugins: [ + pluginReact(), + pluginModuleFederation({ + name: 'hero', + filename: 'remoteEntry.js', + manifest: true, + exposes: { + './Hero': './src/Hero.tsx', + }, + shared: { + react: { + singleton: true, + requiredVersion: '19.2.7', + }, + 'react-dom': { + singleton: true, + requiredVersion: '19.2.7', + }, + }, + dts: { + generateTypes: { + tsConfigPath: './tsconfig.json', + }, + }, + }), + ...(!exampleOffline ? [withZephyr()] : []), + ], +}); diff --git a/module-federation/react-rsbuild-monorepo/apps/hero/src/Hero.tsx b/module-federation/react-rsbuild-monorepo/apps/hero/src/Hero.tsx new file mode 100644 index 00000000..510e6db7 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/hero/src/Hero.tsx @@ -0,0 +1,8 @@ +export default function Hero() { + return ( +
+

Hero fixture

+

Rsbuild, Module Federation, and Zephyr Cloud are connected.

+
+ ); +} diff --git a/module-federation/react-rsbuild-monorepo/apps/hero/src/index.ts b/module-federation/react-rsbuild-monorepo/apps/hero/src/index.ts new file mode 100644 index 00000000..942f4b1b --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/hero/src/index.ts @@ -0,0 +1 @@ +export { default as Hero } from './Hero'; diff --git a/module-federation/react-rsbuild-monorepo/apps/hero/tsconfig.json b/module-federation/react-rsbuild-monorepo/apps/hero/tsconfig.json new file mode 100644 index 00000000..33e603b9 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/hero/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/module-federation/react-rsbuild-monorepo/apps/host/package.json b/module-federation/react-rsbuild-monorepo/apps/host/package.json new file mode 100644 index 00000000..2cb2ce9a --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/host/package.json @@ -0,0 +1,30 @@ +{ + "name": "rsbuild-mf-monorepo-host", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "rsbuild build", + "dev": "rsbuild dev", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "react": "19.2.7", + "react-dom": "19.2.7" + }, + "devDependencies": { + "@module-federation/rsbuild-plugin": "2.8.0", + "@rsbuild/core": "2.1.8", + "@rsbuild/plugin-react": "2.1.0", + "@types/node": "24.5.2", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", + "typescript": "6.0.3", + "zephyr-agent": "1.2.0", + "zephyr-rsbuild-plugin": "1.2.0" + }, + "zephyr:dependencies": { + "header": "rsbuild-mf-monorepo-header@workspace:*", + "hero": "rsbuild-mf-monorepo-hero@workspace:*" + } +} diff --git a/module-federation/react-rsbuild-monorepo/apps/host/rsbuild.config.ts b/module-federation/react-rsbuild-monorepo/apps/host/rsbuild.config.ts new file mode 100644 index 00000000..2bd07239 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/host/rsbuild.config.ts @@ -0,0 +1,42 @@ +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; +import { withZephyr } from 'zephyr-rsbuild-plugin'; + +const exampleOffline = process.env['ZEPHYR_EXAMPLE_OFFLINE'] === '1'; + +export default defineConfig({ + source: { + entry: { + index: './src/index.ts', + }, + }, + server: { + port: 3000, + }, + output: { + assetPrefix: 'auto', + }, + plugins: [ + pluginReact(), + pluginModuleFederation({ + name: 'host', + filename: 'remoteEntry.js', + remotes: { + header: 'header@http://localhost:3001/remoteEntry.js', + hero: 'hero@http://localhost:3002/remoteEntry.js', + }, + shared: { + react: { + singleton: true, + requiredVersion: '19.2.7', + }, + 'react-dom': { + singleton: true, + requiredVersion: '19.2.7', + }, + }, + }), + ...(!exampleOffline ? [withZephyr()] : []), + ], +}); diff --git a/module-federation/react-rsbuild-monorepo/apps/host/src/bootstrap.tsx b/module-federation/react-rsbuild-monorepo/apps/host/src/bootstrap.tsx new file mode 100644 index 00000000..6226a56c --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/host/src/bootstrap.tsx @@ -0,0 +1,17 @@ +import Header from 'header/Header'; +import Hero from 'hero/Hero'; +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; + +const rootElement = document.getElementById('root'); + +if (!rootElement) { + throw new Error('Expected Rsbuild to provide #root'); +} + +createRoot(rootElement).render( + +
+ + , +); diff --git a/module-federation/react-rsbuild-monorepo/apps/host/src/index.ts b/module-federation/react-rsbuild-monorepo/apps/host/src/index.ts new file mode 100644 index 00000000..8ce8ebb8 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/host/src/index.ts @@ -0,0 +1,3 @@ +import('./bootstrap').catch((error: unknown) => { + console.error('Host bootstrap failed', error); +}); diff --git a/module-federation/react-rsbuild-monorepo/apps/host/src/remotes.d.ts b/module-federation/react-rsbuild-monorepo/apps/host/src/remotes.d.ts new file mode 100644 index 00000000..525069a3 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/host/src/remotes.d.ts @@ -0,0 +1,13 @@ +declare module 'header/Header' { + import type { ComponentType } from 'react'; + + const Header: ComponentType; + export default Header; +} + +declare module 'hero/Hero' { + import type { ComponentType } from 'react'; + + const Hero: ComponentType; + export default Hero; +} diff --git a/module-federation/react-rsbuild-monorepo/apps/host/tsconfig.json b/module-federation/react-rsbuild-monorepo/apps/host/tsconfig.json new file mode 100644 index 00000000..33e603b9 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/host/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/module-federation/react-rsbuild-monorepo/apps/host/zephyr.config.ts b/module-federation/react-rsbuild-monorepo/apps/host/zephyr.config.ts new file mode 100644 index 00000000..4472a809 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/apps/host/zephyr.config.ts @@ -0,0 +1,5 @@ +import { defineConfig } from 'zephyr-agent'; + +export default defineConfig({ + dependencyUrlMode: 'version', +}); diff --git a/module-federation/react-rsbuild-monorepo/dependency-selectors.json b/module-federation/react-rsbuild-monorepo/dependency-selectors.json new file mode 100644 index 00000000..59d00ea7 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/dependency-selectors.json @@ -0,0 +1,11 @@ +{ + "sameProjectWorkspaceBuild": { + "header": "rsbuild-mf-monorepo-header@workspace:*" + }, + "sameProjectProductionEnvironment": { + "header": "rsbuild-mf-monorepo-header@production" + }, + "crossProjectProductionEnvironment": { + "header": "rsbuild-mf-monorepo-header.design-system.acme@production" + } +} diff --git a/module-federation/react-rsbuild-monorepo/diagnostics/type-001/outside.ts b/module-federation/react-rsbuild-monorepo/diagnostics/type-001/outside.ts new file mode 100644 index 00000000..8cdaee3b --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/diagnostics/type-001/outside.ts @@ -0,0 +1 @@ +export const fixtureValue = 'outside the configured rootDir'; diff --git a/module-federation/react-rsbuild-monorepo/diagnostics/type-001/rsbuild.config.ts b/module-federation/react-rsbuild-monorepo/diagnostics/type-001/rsbuild.config.ts new file mode 100644 index 00000000..db1bbfaa --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/diagnostics/type-001/rsbuild.config.ts @@ -0,0 +1,24 @@ +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; + +export default defineConfig({ + source: { + entry: { + index: './src/index.ts', + }, + }, + plugins: [ + pluginModuleFederation({ + name: 'type_001_fixture', + filename: 'remoteEntry.js', + exposes: { + './Broken': './src/index.ts', + }, + dts: { + generateTypes: { + tsConfigPath: './tsconfig.json', + }, + }, + }), + ], +}); diff --git a/module-federation/react-rsbuild-monorepo/diagnostics/type-001/src/index.ts b/module-federation/react-rsbuild-monorepo/diagnostics/type-001/src/index.ts new file mode 100644 index 00000000..03ebfece --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/diagnostics/type-001/src/index.ts @@ -0,0 +1 @@ +export { fixtureValue } from '../outside'; diff --git a/module-federation/react-rsbuild-monorepo/diagnostics/type-001/tsconfig.json b/module-federation/react-rsbuild-monorepo/diagnostics/type-001/tsconfig.json new file mode 100644 index 00000000..33e603b9 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/diagnostics/type-001/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/module-federation/react-rsbuild-monorepo/package.json b/module-federation/react-rsbuild-monorepo/package.json new file mode 100644 index 00000000..6d828e13 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/package.json @@ -0,0 +1,39 @@ +{ + "name": "zephyr-example-react-rsbuild-monorepo", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "pnpm run build:remotes && pnpm run build:host", + "build:header": "pnpm --filter './apps/header' build", + "build:hero": "pnpm --filter './apps/hero' build", + "build:host": "pnpm --filter './apps/host' build", + "build:remotes": "pnpm run build:header && pnpm run build:hero", + "build:offline": "ZEPHYR_EXAMPLE_OFFLINE=1 pnpm run build", + "browser:test": "playwright test", + "dev": "ZEPHYR_EXAMPLE_OFFLINE=1 pnpm --parallel --filter './apps/**' dev", + "inspect": "ZEPHYR_EXAMPLE_OFFLINE=1 pnpm --filter './apps/header' inspect", + "reproduce:type-001": "FEDERATION_DEBUG=true rsbuild build --root diagnostics/type-001 --config rsbuild.config.ts", + "typecheck": "pnpm --filter './apps/**' typecheck", + "verify": "pnpm typecheck && pnpm build:offline && pnpm inspect && node scripts/verify-fixture.mjs && node scripts/verify-web-watch.mjs && node scripts/expect-type-001.mjs", + "verify:browser": "pnpm exec playwright test", + "verify:scaffold": "node scripts/verify-scaffold.mjs", + "verify:web-watch": "node scripts/verify-web-watch.mjs" + }, + "devDependencies": { + "@module-federation/rsbuild-plugin": "2.8.0", + "@playwright/test": "1.61.1", + "@rsbuild/core": "2.1.8", + "@rsbuild/plugin-react": "2.1.0", + "@types/node": "24.5.2", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", + "typescript": "6.0.3", + "zephyr-cli": "1.2.0" + }, + "engines": { + "node": "24.x", + "pnpm": "10.x" + }, + "packageManager": "pnpm@10.33.0" +} diff --git a/module-federation/react-rsbuild-monorepo/playwright.config.ts b/module-federation/react-rsbuild-monorepo/playwright.config.ts new file mode 100644 index 00000000..84015513 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/playwright.config.ts @@ -0,0 +1,41 @@ +import { defineConfig } from '@playwright/test'; + +const offlineEnvironment = { + ...process.env, + ZEPHYR_EXAMPLE_OFFLINE: '1', +}; + +export default defineConfig({ + testDir: './tests', + timeout: 60_000, + use: { + baseURL: 'http://127.0.0.1:3000', + trace: 'retain-on-failure', + }, + webServer: [ + { + command: + "pnpm --filter './apps/header' exec rsbuild dev --host 127.0.0.1 --strict-port", + env: offlineEnvironment, + reuseExistingServer: false, + url: 'http://127.0.0.1:3001/remoteEntry.js', + timeout: 120_000, + }, + { + command: + "pnpm --filter './apps/hero' exec rsbuild dev --host 127.0.0.1 --strict-port", + env: offlineEnvironment, + reuseExistingServer: false, + url: 'http://127.0.0.1:3002/remoteEntry.js', + timeout: 120_000, + }, + { + command: + "pnpm --filter './apps/host' exec rsbuild dev --host 127.0.0.1 --strict-port", + env: offlineEnvironment, + reuseExistingServer: false, + url: 'http://127.0.0.1:3000', + timeout: 120_000, + }, + ], +}); diff --git a/module-federation/react-rsbuild-monorepo/pnpm-lock.yaml b/module-federation/react-rsbuild-monorepo/pnpm-lock.yaml new file mode 100644 index 00000000..14f1e14f --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/pnpm-lock.yaml @@ -0,0 +1,2117 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: 2.8.0 + version: 2.8.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)(webpack@5.109.2) + '@playwright/test': + specifier: 1.61.1 + version: 1.61.1 + '@rsbuild/core': + specifier: 2.1.8 + version: 2.1.8(@module-federation/runtime-tools@2.8.0) + '@rsbuild/plugin-react': + specifier: 2.1.0 + version: 2.1.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) + '@types/node': + specifier: 24.5.2 + version: 24.5.2 + '@types/react': + specifier: 19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: 19.2.3 + version: 19.2.3(@types/react@19.2.14) + typescript: + specifier: 6.0.3 + version: 6.0.3 + zephyr-cli: + specifier: 1.2.0 + version: 1.2.0(typescript@6.0.3) + + apps/header: + dependencies: + react: + specifier: 19.2.7 + version: 19.2.7 + react-dom: + specifier: 19.2.7 + version: 19.2.7(react@19.2.7) + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: 2.8.0 + version: 2.8.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)(webpack@5.109.2) + '@rsbuild/core': + specifier: 2.1.8 + version: 2.1.8(@module-federation/runtime-tools@2.8.0) + '@rsbuild/plugin-react': + specifier: 2.1.0 + version: 2.1.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) + '@types/node': + specifier: 24.5.2 + version: 24.5.2 + '@types/react': + specifier: 19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: 19.2.3 + version: 19.2.3(@types/react@19.2.14) + typescript: + specifier: 6.0.3 + version: 6.0.3 + zephyr-rsbuild-plugin: + specifier: 1.2.0 + version: 1.2.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.109.2) + + apps/hero: + dependencies: + react: + specifier: 19.2.7 + version: 19.2.7 + react-dom: + specifier: 19.2.7 + version: 19.2.7(react@19.2.7) + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: 2.8.0 + version: 2.8.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)(webpack@5.109.2) + '@rsbuild/core': + specifier: 2.1.8 + version: 2.1.8(@module-federation/runtime-tools@2.8.0) + '@rsbuild/plugin-react': + specifier: 2.1.0 + version: 2.1.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) + '@types/node': + specifier: 24.5.2 + version: 24.5.2 + '@types/react': + specifier: 19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: 19.2.3 + version: 19.2.3(@types/react@19.2.14) + typescript: + specifier: 6.0.3 + version: 6.0.3 + zephyr-rsbuild-plugin: + specifier: 1.2.0 + version: 1.2.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.109.2) + + apps/host: + dependencies: + react: + specifier: 19.2.7 + version: 19.2.7 + react-dom: + specifier: 19.2.7 + version: 19.2.7(react@19.2.7) + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: 2.8.0 + version: 2.8.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)(webpack@5.109.2) + '@rsbuild/core': + specifier: 2.1.8 + version: 2.1.8(@module-federation/runtime-tools@2.8.0) + '@rsbuild/plugin-react': + specifier: 2.1.0 + version: 2.1.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) + '@types/node': + specifier: 24.5.2 + version: 24.5.2 + '@types/react': + specifier: 19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: 19.2.3 + version: 19.2.3(@types/react@19.2.14) + typescript: + specifier: 6.0.3 + version: 6.0.3 + zephyr-agent: + specifier: 1.2.0 + version: 1.2.0 + zephyr-rsbuild-plugin: + specifier: 1.2.0 + version: 1.2.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.109.2) + +packages: + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@emnapi/core@1.11.2': + resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} + + '@emnapi/runtime@1.11.2': + resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} + + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@module-federation/automatic-vendor-federation@1.2.1': + resolution: {integrity: sha512-73wxkXM7pbRZ6GGM90JP5IPTPvY3fvrhQyTVdMCUx85cQRWqnbzbibcsz3pkOMOeXyYAO4tXXsG13yNaEEGhJA==} + peerDependencies: + webpack: ^5.0.0-beta.16 + + '@module-federation/bridge-react-webpack-plugin@2.8.0': + resolution: {integrity: sha512-7AaaiE4YOXFb+st6xlVDK65aNKZYR9S9ykH0q2mkHAHTgquXciAjypS8JuhmKn7Lob/2rkplMOc4YsGxG3Ng9Q==} + + '@module-federation/cli@2.8.0': + resolution: {integrity: sha512-yTxdWkCJPPo+IGASz+NqdW13cw3DhjSBEn9r85aYn1ahckDwB1WcZe0OjDWMqCcR6yi0BMLedk0SWrUeUj0fWw==} + engines: {node: '>=16.0.0'} + hasBin: true + + '@module-federation/dts-plugin@2.8.0': + resolution: {integrity: sha512-defjq4jOWMEfeejezPWLP5sc8kw0O6FqTT7/E5rbZPEVyjB1A0U3ynhW6GDE5/6hk9/TzdbWS+fBNi4MqUOY6Q==} + peerDependencies: + typescript: ^4.9.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + vue-tsc: '>=1.0.24' + peerDependenciesMeta: + vue-tsc: + optional: true + + '@module-federation/enhanced@2.8.0': + resolution: {integrity: sha512-h8vkLdhK7tlcSPmyYNGfGyt0pSzfDB0tYVYdyUt2tXwQRfaJAi3bsIpujMXElw3MXtOfSHESa6M/hPKrtWTHBw==} + hasBin: true + peerDependencies: + typescript: ^4.9.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + vue-tsc: '>=1.0.24' + webpack: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + vue-tsc: + optional: true + webpack: + optional: true + + '@module-federation/error-codes@2.8.0': + resolution: {integrity: sha512-Gaog9904EmxYOQV0hli3XQ7jXeFaADfh5bnBtTCtbZ37Qd/Sz9kQfd+gYQRyIj7RGmkv9DPiN/SsmrTMrTymKw==} + + '@module-federation/inject-external-runtime-core-plugin@2.8.0': + resolution: {integrity: sha512-fW3jD1ZVds6r/Ul8TtUA42RsB0LfT1yjo5KjqgirH9QrmEMH21x44e3e6BC6IN820XKawRDSmz2kFA5YHIQp7Q==} + peerDependencies: + '@module-federation/runtime-tools': 2.8.0 + + '@module-federation/managers@2.8.0': + resolution: {integrity: sha512-SnVBCwmi962WGg6hLFElxZUCnrRJdR6glE2ZKPBY/iK07AHUN2ZxuaBCBsVzyws+xLZGHZxBHmVstijTh8dSUA==} + + '@module-federation/manifest@2.8.0': + resolution: {integrity: sha512-wfVeBXc4/C2F70nRFSPqJhkcwbDgo+wQyEn3jbjJTDoUqxxhYBfHFs1ACBYOk3Qm97L7hHclHGtUG0/nvDEfAA==} + + '@module-federation/node@2.7.47': + resolution: {integrity: sha512-mifMvCjWmLl53GS+badQws0j2bsu1ICpdGzCbez4I6kSpaYA8v86L6dwcHtVHIZtkUC6cjAZBDcgpxs4fK3nFQ==} + peerDependencies: + webpack: ^5.40.0 + peerDependenciesMeta: + webpack: + optional: true + + '@module-federation/rsbuild-plugin@2.8.0': + resolution: {integrity: sha512-rul5OPvLx599rWoAhCtKJ3UYqyM3Dxg0RWEfad3JdnJFqkcSLBojZXgHJE1vbF7DRdGQNmNscKw34iEyn89NwQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@rsbuild/core': ^1.3.21 || ^2.0.0-0 + peerDependenciesMeta: + '@rsbuild/core': + optional: true + + '@module-federation/rspack@2.8.0': + resolution: {integrity: sha512-TPcrkHpaZgL25Vx3c8oSNwyv7/KktC7uo6HTQdVWlFzbq5RSoMMGkWoir5pY5124isae2/p6v5xAuqICi4r0Zg==} + peerDependencies: + '@rspack/core': ^0.7.0 || ^1.0.0 || ^2.0.0-0 + typescript: ^4.9.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + vue-tsc: '>=1.0.24' + peerDependenciesMeta: + typescript: + optional: true + vue-tsc: + optional: true + + '@module-federation/runtime-core@2.8.0': + resolution: {integrity: sha512-Tf98+epGGiPSHqmQHuXa2uXZMMvjGf1IqJDR1/FpXfmobv5ECN0mGZCjUHGNSyxvoDyXKIkKwJu7IwEoh0ouQA==} + + '@module-federation/runtime-tools@2.8.0': + resolution: {integrity: sha512-3yOqjdSHXxX4HA3GhlXg3hghGAXW2RJUsnwXCcik2/lTxOHizKI8f3RM+GGCKPxDVqtw43IShe3tA12jNL5A/A==} + + '@module-federation/runtime@2.8.0': + resolution: {integrity: sha512-cGtUBQ1/TVy7KrXy6xPgy3FEmOGyIYkBA2T4iGH3ZH5PNPPTmqN9jF2AfneTSOj0RtBr7Pxq3CUt81E/UCvK1A==} + + '@module-federation/sdk@2.8.0': + resolution: {integrity: sha512-yBP+9+0Z8nlvKEXAZS3AsQVy7bFbZf8eMivGk4q4ZdwG3TsLMlsPjb1dQb2i7gcAG6ux9y2LWLkj/0LVk74cnQ==} + + '@module-federation/third-party-dts-extractor@2.8.0': + resolution: {integrity: sha512-nAMlr74OKIylkfRwlunOhytQbmsgb3gCqdXWnPQhG+ZtqWXGELLfMT4a1Q1ht3cS+sRpWj2SZRqK2M7GadI6tA==} + + '@module-federation/webpack-bundler-runtime@2.8.0': + resolution: {integrity: sha512-82fDy9v+7qV5fiN8TKVhOdrxhmAZnUIX/IKivYX5ulCt8aoOzVFTiwm/P1GQUDD8z6dqR48xgJdZdf0548Mc9w==} + + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@playwright/test@1.61.1': + resolution: {integrity: sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==} + engines: {node: '>=18'} + hasBin: true + + '@rsbuild/core@2.1.8': + resolution: {integrity: sha512-Y70LMcCZspVoQ7Oip1W2Agu5wVhWZ2x3cYl4s9GLQG4VYphBud53DY/jkrqkyQF8ASYZDDDrW2KWNFj0kNLLuA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + core-js: '>= 3.0.0' + peerDependenciesMeta: + core-js: + optional: true + + '@rsbuild/plugin-react@2.1.0': + resolution: {integrity: sha512-RQTIAWB/CwPjoWt9iAl+8HixeQVgZ7kEIBrWPCixfITyHdiD84h0YpUTpEUuz6kGHw1KXT9mHZ3Rwy6WG7aRDA==} + peerDependencies: + '@rsbuild/core': ^2.0.0 + peerDependenciesMeta: + '@rsbuild/core': + optional: true + + '@rspack/binding-darwin-arm64@2.1.7': + resolution: {integrity: sha512-DwxzrXRctueP/3Pyom9JHcIsRShuEAlHb+mrE5OPT+4cdHI1UnJpbzEvEDLTo4IKJhDb3vjXdHLtjqtL0SYbeA==} + cpu: [arm64] + os: [darwin] + + '@rspack/binding-darwin-x64@2.1.7': + resolution: {integrity: sha512-kPbrYvR/XUHfAMgRVq3QnC71DW/qjwsPj+3hEUuEnRmlploPNy9u8Szf1IHKSVUSrVZBTgDyMoZQdxYLfhResw==} + cpu: [x64] + os: [darwin] + + '@rspack/binding-linux-arm64-gnu@2.1.7': + resolution: {integrity: sha512-VFB+YXM3kZ6IIuLV64H3vgnwqvQIIaqfR/aeGwuxYvwcZsrgblSBmXMeDULdgDjqP8Yr0VaFMBBiD9OtG5KdFw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rspack/binding-linux-arm64-musl@2.1.7': + resolution: {integrity: sha512-Mzbxyg0aJ+ITj526Iuz0enEDYY6WxhFIwEKXqwjQh+Vpd5v/+aPzPo83sSQVX/3puBV1sbmviTURbh6N9e1fvA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rspack/binding-linux-riscv64-gnu@2.1.7': + resolution: {integrity: sha512-mpazwgT/Pse1720mvEJsoXfPkJ+enj0xUqpbe/wL6aedwjGT+9jJNB8HTJXE4XBX0UO7umGqcJMeKA6YsD2CDA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rspack/binding-linux-riscv64-musl@2.1.7': + resolution: {integrity: sha512-oU/l3soPRsDEWn7KZic+npyTMM2N1kRdHjoJ+L5IUBXs8bjdTXPLoyTbTdIOza5ZSoT4+UeEiEryj4BB0tQE5w==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rspack/binding-linux-x64-gnu@2.1.7': + resolution: {integrity: sha512-7Gtpl3h3jtnOpk1mYQE8mRndXAO2ibI8mnAbs7klevdKey+ZHneWMoMi2yOMQhhI/ifWEFxDzyGJ8bdxo0XTsA==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rspack/binding-linux-x64-musl@2.1.7': + resolution: {integrity: sha512-w+whI2Uy+DYkGN+MVkzMFWweL7B/s1gMqX+nvTE1vhOy3hGV0VyA9H6lqWjSD3I+eGkpYhN9Pr244cYnLpZOUQ==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rspack/binding-wasm32-wasi@2.1.7': + resolution: {integrity: sha512-cDVgvzRdTgxaeM+a5Lx0+7/VAvunvwO0wNtQ3ATQGOtFCW5b7cUzhNPcytH5ZSJTnFWuxinlGwtar5yfcnkdZQ==} + cpu: [wasm32] + + '@rspack/binding-win32-arm64-msvc@2.1.7': + resolution: {integrity: sha512-JDd85+iYwUvaG9Zrt5X7oIxRZRiTW+76FwkRakoXNy/5VAWQW32Jq4ESjSVz6l6mh0KnZxPq3TLMugacCPnLjw==} + cpu: [arm64] + os: [win32] + + '@rspack/binding-win32-ia32-msvc@2.1.7': + resolution: {integrity: sha512-y9PKEs6v9BLHV0i/4eaIRtxpATvSgcf/VYQkMT8mp+qWlPjUwDQNwU2ueWVGpff6INO+YAa7zobzziNFRgO7Lg==} + cpu: [ia32] + os: [win32] + + '@rspack/binding-win32-x64-msvc@2.1.7': + resolution: {integrity: sha512-BjkOzcPY/K8YlRRvyywz0mDWk89MMxqAMhDmgBXCWorh1IjgKTsWDJ2lCGIM8M9CZXUG3khom8AfrOGwRT2I+g==} + cpu: [x64] + os: [win32] + + '@rspack/binding@2.1.7': + resolution: {integrity: sha512-wYqi8TY30hsIzLry503o/Uqu7y9Ec7pEwN5TVmB7Pb3xHrR2eHsQPzdpF/GkCLUjQSgD2Es3CDVV1mr6zO/78g==} + + '@rspack/core@2.1.7': + resolution: {integrity: sha512-d5Ju3zXzGgbqQWvlMlLUtek2eFPIzsFe2QOF4nwTAknxo/4OZ64t+kPT9nM6fr3aZX93VK0R3v02/kZYIRrV9Q==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@module-federation/runtime-tools': ^0.24.1 || ^2.0.0 + '@swc/helpers': ^0.5.23 + peerDependenciesMeta: + '@module-federation/runtime-tools': + optional: true + '@swc/helpers': + optional: true + + '@rspack/plugin-react-refresh@2.0.2': + resolution: {integrity: sha512-dGNZiCxQxgAUI9sah7gd8u+O7OJZRCmqtEJNDOd8xW5RqcieC86F7p5qcShyw6onH5pKf57evpr2VjGbaFGkZg==} + peerDependencies: + '@rspack/core': ^2.0.0 + react-refresh: '>=0.10.0 <1.0.0' + peerDependenciesMeta: + '@rspack/core': + optional: true + + '@swc/helpers@0.5.23': + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} + + '@toon-format/toon@0.9.0': + resolution: {integrity: sha512-BaMhGh1+/z8ceDrF2xL9Drd42hijbUJlivm/1goPR26RgCYsqlMkHbg48hx9a5UjZC7oZqxWPJ6ju5qvALi6Ag==} + + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@24.5.2': + resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + + '@types/parse-path@7.1.0': + resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} + deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + engines: {node: '>=0.4.0'} + hasBin: true + + adm-zip@0.5.10: + resolution: {integrity: sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==} + engines: {node: '>=6.0'} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios-retry@4.5.0: + resolution: {integrity: sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==} + peerDependencies: + axios: 0.x || 1.x + + axios@1.19.0: + resolution: {integrity: sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==} + + baseline-browser-mapping@2.11.7: + resolution: {integrity: sha512-APw5YuIQAg6L9w4sHDI6j26DGFJI6RpYOhnkMPdC9lWbkKvsyPHzDsve1yd73lk21yz7Y09Kci8B2Pp9FonzWA==} + engines: {node: '>=6.0.0'} + hasBin: true + + browserslist@4.28.7: + resolution: {integrity: sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001806: + resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + cosmiconfig@9.0.2: + resolution: {integrity: sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + electron-to-chromium@1.5.398: + resolution: {integrity: sha512-AsvhAxopJGh6museTDMIjn6JpDYOfgu4RLlygomt87MUwBUqTfd/1EiPtx10/LZE8xpTvkP2E9Gafq7lkLtodQ==} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + enhanced-resolve@5.24.4: + resolution: {integrity: sha512-GVoi+ICHocoOIU7qVVM48wOJziRsqrsyqlI0Ce0LdowRn6v3bcH2zUa9kp85ncx0nwIb9/HOCOLS3fdThDG/XQ==} + engines: {node: '>=10.13.0'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@2.3.1: + resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + eventsource-parser@3.1.0: + resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==} + engines: {node: '>=18.0.0'} + + eventsource@4.1.0: + resolution: {integrity: sha512-2GuF51iuHX6A9xdTccMTsNb7VO0lHZihApxhvQzJB5A03DvHDd2FQepodbMaztPBmBcE/ox7o2gqaxGhYB9LhQ==} + engines: {node: '>=20.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-uri@3.1.4: + resolution: {integrity: sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==} + + find-package-json@1.2.0: + resolution: {integrity: sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==} + + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} + engines: {node: '>= 6'} + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + git-up@8.1.1: + resolution: {integrity: sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==} + + git-url-parse@16.1.0: + resolution: {integrity: sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-ci@4.1.0: + resolution: {integrity: sha512-Ab9bQDQ11lWootZUI5qxgN2ZXwxNI5hTwnsvOc1wyxQ7zQ8OkEDw79mI0+9jI3x432NfwbVRru+3noJfXF6lSQ==} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-retry-allowed@2.2.0: + resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} + engines: {node: '>=10'} + + is-ssh@1.4.1: + resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + isomorphic-ws@5.0.0: + resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + peerDependencies: + ws: '*' + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + jose@5.10.0: + resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.3.0: + resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} + hasBin: true + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimizer-webpack-plugin@5.6.1: + resolution: {integrity: sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@minify-html/node': '*' + '@swc/core': '*' + '@swc/css': '*' + '@swc/html': '*' + clean-css: '*' + cssnano: '*' + csso: '*' + esbuild: '*' + html-minifier-terser: '*' + lightningcss: '*' + postcss: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@minify-html/node': + optional: true + '@swc/core': + optional: true + '@swc/css': + optional: true + '@swc/html': + optional: true + clean-css: + optional: true + cssnano: + optional: true + csso: + optional: true + esbuild: + optional: true + html-minifier-terser: + optional: true + lightningcss: + optional: true + postcss: + optional: true + uglify-js: + optional: true + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-persist@4.0.4: + resolution: {integrity: sha512-8sPAz/7tw1mCCc8xBG4f0wi+flHkSSgQeX998iQ75Pu27evA6UUWCjSE7xnrYTg2q33oU5leJ061EKPDv6BocQ==} + engines: {node: '>=10.12.0'} + + node-releases@2.0.51: + resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} + engines: {node: '>=18'} + + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-path@7.1.0: + resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} + + parse-url@9.2.0: + resolution: {integrity: sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==} + engines: {node: '>=14.13.0'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + playwright-core@1.61.1: + resolution: {integrity: sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.61.1: + resolution: {integrity: sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==} + engines: {node: '>=18'} + hasBin: true + + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + + protocols@2.0.2: + resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} + + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + + react-dom@19.2.7: + resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} + peerDependencies: + react: ^19.2.7 + + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + + react@19.2.7: + resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + schema-utils@4.3.0: + resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} + engines: {node: '>= 10.13.0'} + + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + terser@5.49.0: + resolution: {integrity: sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==} + engines: {node: '>=10'} + hasBin: true + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.12.0: + resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} + + undici@7.28.0: + resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} + engines: {node: '>=20.18.1'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + watchpack@2.5.2: + resolution: {integrity: sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==} + engines: {node: '>=10.13.0'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webpack-sources@3.5.1: + resolution: {integrity: sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==} + engines: {node: '>=10.13.0'} + + webpack@5.109.2: + resolution: {integrity: sha512-U9/cvLzxObKNEZ9+TtdqrHM5/9z3lgl2c+c4BzbqGxFQvQvBAq87yql5A8pQ+rrMbS496MZJeF5enVBndIy2hw==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zephyr-agent@1.2.0: + resolution: {integrity: sha512-peGy/FB1xHs1nzkvSuNjrr6DC4ZCfTz5NcRV+YYgjxV8povY2eWCZEU2t0ObYFtHrcj8UqejxLl6LqgJrqpiZw==} + + zephyr-cli@1.2.0: + resolution: {integrity: sha512-u0nwAAEd5Nv1rT+gMguO6UXfoul4zjNRoTuqMho2LrcInkywU+fcBrgkaryyEwPq9R6HmsGbNiSwDm3C5SMOOA==} + hasBin: true + + zephyr-edge-contract@1.2.0: + resolution: {integrity: sha512-RZlBTPmOwhHVh+RZcJKCWexN9ieehn/TyfHA8xAqvP8ti37rQSVETV4UYdVNhkkGRgueDRI7KIo2wQdrSTAy9A==} + + zephyr-rsbuild-plugin@1.2.0: + resolution: {integrity: sha512-AcAaMxUADTxbOmKz5uMROmotou6v//zX0Mv7XotUYvJZqp8CHp3T6+0zIlogbh+6Y6ZuSSsdkjzNH4KdqHb7+w==} + peerDependencies: + '@rsbuild/core': ^1.0.0 || ^2.0.0-0 + + zephyr-rspack-plugin@1.2.0: + resolution: {integrity: sha512-AlR8DvENac9qk++0AYQpDbjnmt6YysXZV0r2PvKWVtJ+tFwivOI2oQS6+uhmYmuZzE2Bz9KTEsOXzZ0GRoIz+Q==} + peerDependencies: + '@rspack/core': ^1.0.0 || ^2.0.0-0 + + zephyr-xpack-internal@1.2.0: + resolution: {integrity: sha512-1tSsb+uviOCWYYZNtQgWDiBBS3OMGoJyqJWQIXNKBC5S/oOQjK8y/pNOFvuNQbta/CVnDD0rhDgfylSRIJG3Wg==} + +snapshots: + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.29.7': {} + + '@emnapi/core@1.11.2': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@module-federation/automatic-vendor-federation@1.2.1(webpack@5.109.2)': + dependencies: + find-package-json: 1.2.0 + webpack: 5.109.2 + + '@module-federation/bridge-react-webpack-plugin@2.8.0': + dependencies: + '@module-federation/sdk': 2.8.0 + + '@module-federation/cli@2.8.0(typescript@6.0.3)': + dependencies: + '@module-federation/dts-plugin': 2.8.0(typescript@6.0.3) + '@module-federation/sdk': 2.8.0 + commander: 11.1.0 + jiti: 2.4.2 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - vue-tsc + + '@module-federation/dts-plugin@2.8.0(typescript@6.0.3)': + dependencies: + '@module-federation/error-codes': 2.8.0 + '@module-federation/managers': 2.8.0 + '@module-federation/sdk': 2.8.0 + '@module-federation/third-party-dts-extractor': 2.8.0 + adm-zip: 0.5.10 + isomorphic-ws: 5.0.0(ws@8.21.0) + typescript: 6.0.3 + undici: 7.28.0 + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@module-federation/enhanced@2.8.0(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)(webpack@5.109.2)': + dependencies: + '@module-federation/bridge-react-webpack-plugin': 2.8.0 + '@module-federation/cli': 2.8.0(typescript@6.0.3) + '@module-federation/dts-plugin': 2.8.0(typescript@6.0.3) + '@module-federation/error-codes': 2.8.0 + '@module-federation/inject-external-runtime-core-plugin': 2.8.0(@module-federation/runtime-tools@2.8.0) + '@module-federation/managers': 2.8.0 + '@module-federation/manifest': 2.8.0(typescript@6.0.3) + '@module-federation/rspack': 2.8.0(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3) + '@module-federation/runtime-tools': 2.8.0 + '@module-federation/sdk': 2.8.0 + '@module-federation/webpack-bundler-runtime': 2.8.0 + schema-utils: 4.3.0 + tapable: 2.3.0 + optionalDependencies: + typescript: 6.0.3 + webpack: 5.109.2 + transitivePeerDependencies: + - '@rspack/core' + - bufferutil + - utf-8-validate + + '@module-federation/error-codes@2.8.0': {} + + '@module-federation/inject-external-runtime-core-plugin@2.8.0(@module-federation/runtime-tools@2.8.0)': + dependencies: + '@module-federation/runtime-tools': 2.8.0 + + '@module-federation/managers@2.8.0': + dependencies: + '@module-federation/sdk': 2.8.0 + + '@module-federation/manifest@2.8.0(typescript@6.0.3)': + dependencies: + '@module-federation/dts-plugin': 2.8.0(typescript@6.0.3) + '@module-federation/managers': 2.8.0 + '@module-federation/sdk': 2.8.0 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - vue-tsc + + '@module-federation/node@2.7.47(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)(webpack@5.109.2)': + dependencies: + '@module-federation/enhanced': 2.8.0(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)(webpack@5.109.2) + '@module-federation/runtime': 2.8.0 + '@module-federation/sdk': 2.8.0 + encoding: 0.1.13 + node-fetch: 2.7.0(encoding@0.1.13) + tapable: 2.3.0 + optionalDependencies: + webpack: 5.109.2 + transitivePeerDependencies: + - '@rspack/core' + - bufferutil + - typescript + - utf-8-validate + - vue-tsc + + '@module-federation/rsbuild-plugin@2.8.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)(webpack@5.109.2)': + dependencies: + '@module-federation/enhanced': 2.8.0(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)(webpack@5.109.2) + '@module-federation/node': 2.7.47(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)(webpack@5.109.2) + '@module-federation/sdk': 2.8.0 + optionalDependencies: + '@rsbuild/core': 2.1.8(@module-federation/runtime-tools@2.8.0) + transitivePeerDependencies: + - '@rspack/core' + - bufferutil + - typescript + - utf-8-validate + - vue-tsc + - webpack + + '@module-federation/rspack@2.8.0(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@6.0.3)': + dependencies: + '@module-federation/bridge-react-webpack-plugin': 2.8.0 + '@module-federation/dts-plugin': 2.8.0(typescript@6.0.3) + '@module-federation/inject-external-runtime-core-plugin': 2.8.0(@module-federation/runtime-tools@2.8.0) + '@module-federation/managers': 2.8.0 + '@module-federation/manifest': 2.8.0(typescript@6.0.3) + '@module-federation/runtime-tools': 2.8.0 + '@module-federation/sdk': 2.8.0 + '@rspack/core': 2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@module-federation/runtime-core@2.8.0': + dependencies: + '@module-federation/error-codes': 2.8.0 + '@module-federation/sdk': 2.8.0 + + '@module-federation/runtime-tools@2.8.0': + dependencies: + '@module-federation/runtime': 2.8.0 + '@module-federation/webpack-bundler-runtime': 2.8.0 + + '@module-federation/runtime@2.8.0': + dependencies: + '@module-federation/error-codes': 2.8.0 + '@module-federation/runtime-core': 2.8.0 + '@module-federation/sdk': 2.8.0 + + '@module-federation/sdk@2.8.0': {} + + '@module-federation/third-party-dts-extractor@2.8.0': {} + + '@module-federation/webpack-bundler-runtime@2.8.0': + dependencies: + '@module-federation/error-codes': 2.8.0 + '@module-federation/runtime': 2.8.0 + '@module-federation/sdk': 2.8.0 + + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@playwright/test@1.61.1': + dependencies: + playwright: 1.61.1 + + '@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0)': + dependencies: + '@rspack/core': 2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) + '@swc/helpers': 0.5.23 + transitivePeerDependencies: + - '@module-federation/runtime-tools' + + '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))': + dependencies: + '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) + react-refresh: 0.18.0 + optionalDependencies: + '@rsbuild/core': 2.1.8(@module-federation/runtime-tools@2.8.0) + transitivePeerDependencies: + - '@rspack/core' + + '@rspack/binding-darwin-arm64@2.1.7': + optional: true + + '@rspack/binding-darwin-x64@2.1.7': + optional: true + + '@rspack/binding-linux-arm64-gnu@2.1.7': + optional: true + + '@rspack/binding-linux-arm64-musl@2.1.7': + optional: true + + '@rspack/binding-linux-riscv64-gnu@2.1.7': + optional: true + + '@rspack/binding-linux-riscv64-musl@2.1.7': + optional: true + + '@rspack/binding-linux-x64-gnu@2.1.7': + optional: true + + '@rspack/binding-linux-x64-musl@2.1.7': + optional: true + + '@rspack/binding-wasm32-wasi@2.1.7': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) + optional: true + + '@rspack/binding-win32-arm64-msvc@2.1.7': + optional: true + + '@rspack/binding-win32-ia32-msvc@2.1.7': + optional: true + + '@rspack/binding-win32-x64-msvc@2.1.7': + optional: true + + '@rspack/binding@2.1.7': + optionalDependencies: + '@rspack/binding-darwin-arm64': 2.1.7 + '@rspack/binding-darwin-x64': 2.1.7 + '@rspack/binding-linux-arm64-gnu': 2.1.7 + '@rspack/binding-linux-arm64-musl': 2.1.7 + '@rspack/binding-linux-riscv64-gnu': 2.1.7 + '@rspack/binding-linux-riscv64-musl': 2.1.7 + '@rspack/binding-linux-x64-gnu': 2.1.7 + '@rspack/binding-linux-x64-musl': 2.1.7 + '@rspack/binding-wasm32-wasi': 2.1.7 + '@rspack/binding-win32-arm64-msvc': 2.1.7 + '@rspack/binding-win32-ia32-msvc': 2.1.7 + '@rspack/binding-win32-x64-msvc': 2.1.7 + + '@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)': + dependencies: + '@rspack/binding': 2.1.7 + optionalDependencies: + '@module-federation/runtime-tools': 2.8.0 + '@swc/helpers': 0.5.23 + + '@rspack/plugin-react-refresh@2.0.2(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0)': + dependencies: + react-refresh: 0.18.0 + optionalDependencies: + '@rspack/core': 2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) + + '@swc/helpers@0.5.23': + dependencies: + tslib: 2.8.1 + + '@toon-format/toon@0.9.0': {} + + '@tybys/wasm-util@0.10.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/estree@1.0.9': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@24.5.2': + dependencies: + undici-types: 7.12.0 + + '@types/parse-path@7.1.0': + dependencies: + parse-path: 7.1.0 + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + acorn@8.18.0: {} + + adm-zip@0.5.10: {} + + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + agent-base@7.1.4: {} + + ajv-formats@2.1.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv-keywords@5.1.0(ajv@8.20.0): + dependencies: + ajv: 8.20.0 + fast-deep-equal: 3.1.3 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.4 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + argparse@2.0.1: {} + + asynckit@0.4.0: {} + + axios-retry@4.5.0(axios@1.19.0(debug@4.4.3)): + dependencies: + axios: 1.19.0(debug@4.4.3) + is-retry-allowed: 2.2.0 + + axios@1.19.0(debug@4.4.3): + dependencies: + follow-redirects: 1.16.0(debug@4.4.3) + form-data: 4.0.6 + https-proxy-agent: 5.0.1 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + - supports-color + + baseline-browser-mapping@2.11.7: {} + + browserslist@4.28.7: + dependencies: + baseline-browser-mapping: 2.11.7 + caniuse-lite: 1.0.30001806 + electron-to-chromium: 1.5.398 + node-releases: 2.0.51 + update-browserslist-db: 1.2.3(browserslist@4.28.7) + + buffer-from@1.1.2: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001806: {} + + chrome-trace-event@1.0.4: {} + + ci-info@4.4.0: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@11.1.0: {} + + commander@2.20.3: {} + + cosmiconfig@9.0.2(typescript@6.0.3): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.3.0 + parse-json: 5.2.0 + optionalDependencies: + typescript: 6.0.3 + + csstype@3.2.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + define-lazy-prop@3.0.0: {} + + delayed-stream@1.0.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + electron-to-chromium@1.5.398: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + + enhanced-resolve@5.24.4: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + env-paths@2.2.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@2.3.1: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + escalade@3.2.0: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + events@3.3.0: {} + + eventsource-parser@3.1.0: {} + + eventsource@4.1.0: + dependencies: + eventsource-parser: 3.1.0 + + fast-deep-equal@3.1.3: {} + + fast-uri@3.1.4: {} + + find-package-json@1.2.0: {} + + follow-redirects@1.16.0(debug@4.4.3): + optionalDependencies: + debug: 4.4.3 + + form-data@4.0.6: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.4 + mime-types: 2.1.35 + + fsevents@2.3.2: + optional: true + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + git-up@8.1.1: + dependencies: + is-ssh: 1.4.1 + parse-url: 9.2.0 + + git-url-parse@16.1.0: + dependencies: + git-up: 8.1.1 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + is-arrayish@0.2.1: {} + + is-ci@4.1.0: + dependencies: + ci-info: 4.4.0 + + is-docker@3.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-retry-allowed@2.2.0: {} + + is-ssh@1.4.1: + dependencies: + protocols: 2.0.2 + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + isomorphic-ws@5.0.0(ws@8.21.0): + dependencies: + ws: 8.21.0 + + jest-worker@27.5.1: + dependencies: + '@types/node': 24.5.2 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jiti@2.4.2: {} + + jiti@2.7.0: {} + + jose@5.10.0: {} + + js-tokens@4.0.0: {} + + js-yaml@4.3.0: + dependencies: + argparse: 2.0.1 + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@1.0.0: {} + + jsonc-parser@3.3.1: {} + + lines-and-columns@1.2.4: {} + + math-intrinsics@1.1.0: {} + + merge-stream@2.0.0: {} + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimizer-webpack-plugin@5.6.1(webpack@5.109.2): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.49.0 + webpack: 5.109.2 + + ms@2.1.3: {} + + neo-async@2.6.2: {} + + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-persist@4.0.4: + dependencies: + p-limit: 3.1.0 + + node-releases@2.0.51: {} + + open@10.2.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.7 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-path@7.1.0: + dependencies: + protocols: 2.0.2 + + parse-url@9.2.0: + dependencies: + '@types/parse-path': 7.1.0 + parse-path: 7.1.0 + + picocolors@1.1.1: {} + + playwright-core@1.61.1: {} + + playwright@1.61.1: + dependencies: + playwright-core: 1.61.1 + optionalDependencies: + fsevents: 2.3.2 + + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + + protocols@2.0.2: {} + + proxy-from-env@2.1.0: {} + + react-dom@19.2.7(react@19.2.7): + dependencies: + react: 19.2.7 + scheduler: 0.27.0 + + react-refresh@0.18.0: {} + + react@19.2.7: {} + + require-from-string@2.0.2: {} + + resolve-from@4.0.0: {} + + retry@0.12.0: {} + + run-applescript@7.1.0: {} + + safer-buffer@2.1.2: {} + + scheduler@0.27.0: {} + + schema-utils@4.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.20.0 + ajv-formats: 2.1.1(ajv@8.20.0) + ajv-keywords: 5.1.0(ajv@8.20.0) + + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.20.0 + ajv-formats: 2.1.1(ajv@8.20.0) + ajv-keywords: 5.1.0(ajv@8.20.0) + + signal-exit@3.0.7: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + tapable@2.3.0: {} + + tapable@2.3.3: {} + + terser@5.49.0: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.18.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + tr46@0.0.3: {} + + tslib@2.8.1: {} + + typescript@6.0.3: {} + + undici-types@7.12.0: {} + + undici@7.28.0: {} + + update-browserslist-db@1.2.3(browserslist@4.28.7): + dependencies: + browserslist: 4.28.7 + escalade: 3.2.0 + picocolors: 1.1.1 + + watchpack@2.5.2: + dependencies: + graceful-fs: 4.2.11 + + webidl-conversions@3.0.1: {} + + webpack-sources@3.5.1: {} + + webpack@5.109.2: + dependencies: + '@types/estree': 1.0.9 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.18.0 + browserslist: 4.28.7 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.24.4 + es-module-lexer: 2.3.1 + eslint-scope: 5.1.1 + events: 3.3.0 + graceful-fs: 4.2.11 + mime-db: 1.54.0 + minimizer-webpack-plugin: 5.6.1(webpack@5.109.2) + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + watchpack: 2.5.2 + webpack-sources: 3.5.1 + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + ws@8.21.0: {} + + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.1 + + yocto-queue@0.1.0: {} + + zephyr-agent@1.2.0: + dependencies: + '@toon-format/toon': 0.9.0 + axios: 1.19.0(debug@4.4.3) + axios-retry: 4.5.0(axios@1.19.0(debug@4.4.3)) + debug: 4.4.3 + eventsource: 4.1.0 + git-url-parse: 16.1.0 + https-proxy-agent: 7.0.6 + is-ci: 4.1.0 + jiti: 2.7.0 + jose: 5.10.0 + node-persist: 4.0.4 + open: 10.2.0 + proper-lockfile: 4.1.2 + zephyr-edge-contract: 1.2.0 + transitivePeerDependencies: + - supports-color + + zephyr-cli@1.2.0(typescript@6.0.3): + dependencies: + cosmiconfig: 9.0.2(typescript@6.0.3) + jsonc-parser: 3.3.1 + zephyr-agent: 1.2.0 + zephyr-edge-contract: 1.2.0 + transitivePeerDependencies: + - supports-color + - typescript + + zephyr-edge-contract@1.2.0: {} + + zephyr-rsbuild-plugin@1.2.0(@rsbuild/core@2.1.8(@module-federation/runtime-tools@2.8.0))(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.109.2): + dependencies: + '@rsbuild/core': 2.1.8(@module-federation/runtime-tools@2.8.0) + zephyr-agent: 1.2.0 + zephyr-rspack-plugin: 1.2.0(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.109.2) + zephyr-xpack-internal: 1.2.0(webpack@5.109.2) + transitivePeerDependencies: + - '@rspack/core' + - supports-color + - webpack + + zephyr-rspack-plugin@1.2.0(@rspack/core@2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.109.2): + dependencies: + '@rspack/core': 2.1.7(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) + zephyr-agent: 1.2.0 + zephyr-xpack-internal: 1.2.0(webpack@5.109.2) + transitivePeerDependencies: + - supports-color + - webpack + + zephyr-xpack-internal@1.2.0(webpack@5.109.2): + dependencies: + '@module-federation/automatic-vendor-federation': 1.2.1(webpack@5.109.2) + zephyr-agent: 1.2.0 + zephyr-edge-contract: 1.2.0 + transitivePeerDependencies: + - supports-color + - webpack diff --git a/module-federation/react-rsbuild-monorepo/pnpm-workspace.yaml b/module-federation/react-rsbuild-monorepo/pnpm-workspace.yaml new file mode 100644 index 00000000..7fff6c33 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/pnpm-workspace.yaml @@ -0,0 +1,8 @@ +packages: + - apps/* + +onlyBuiltDependencies: + - '@swc/core' + - core-js + - esbuild + - nx diff --git a/module-federation/react-rsbuild-monorepo/postcss.config.mjs b/module-federation/react-rsbuild-monorepo/postcss.config.mjs new file mode 100644 index 00000000..3e0d24c4 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/postcss.config.mjs @@ -0,0 +1,3 @@ +export default { + plugins: {}, +}; diff --git a/module-federation/react-rsbuild-monorepo/scripts/add-existing-dependencies.sh b/module-federation/react-rsbuild-monorepo/scripts/add-existing-dependencies.sh new file mode 100644 index 00000000..44d98405 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/scripts/add-existing-dependencies.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -euo pipefail + +app_directory=${1:?"Pass an existing Rsbuild application directory"} + +pnpm --dir "${app_directory}" --save-exact add \ + react@19.2.7 \ + react-dom@19.2.7 +pnpm --dir "${app_directory}" --save-exact add --save-dev \ + @module-federation/rsbuild-plugin@2.8.0 \ + @rsbuild/core@2.1.8 \ + @rsbuild/plugin-react@2.1.0 \ + @types/node@24.5.2 \ + @types/react@19.2.14 \ + @types/react-dom@19.2.3 \ + typescript@6.0.3 \ + zephyr-agent@1.2.0 \ + zephyr-rsbuild-plugin@1.2.0 + +# pnpm preserves existing scaffold prefixes while changing versions. Once the +# requested versions are installed, repeat those existing dependencies so -E +# normalizes their declarations to exact pins. +pnpm --dir "${app_directory}" --save-exact add \ + react@19.2.7 \ + react-dom@19.2.7 +pnpm --dir "${app_directory}" --save-exact add --save-dev \ + @rsbuild/core@2.1.8 \ + @rsbuild/plugin-react@2.1.0 \ + @types/node@24.5.2 \ + @types/react@19.2.14 \ + @types/react-dom@19.2.3 \ + typescript@6.0.3 diff --git a/module-federation/react-rsbuild-monorepo/scripts/expect-type-001.mjs b/module-federation/react-rsbuild-monorepo/scripts/expect-type-001.mjs new file mode 100644 index 00000000..7e5fb70d --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/scripts/expect-type-001.mjs @@ -0,0 +1,112 @@ +import { existsSync } from 'node:fs'; +import { readFile, rm } from 'node:fs/promises'; +import { join } from 'node:path'; +import { spawn, spawnSync } from 'node:child_process'; + +const fixtureRoot = new URL('../', import.meta.url); +const logDirectory = join(fixtureRoot.pathname, '.mf'); +const logPath = join(logDirectory, 'typesGenerate.log'); + +await rm(logDirectory, { recursive: true, force: true }); + +const result = spawnSync('pnpm', ['run', 'reproduce:type-001'], { + cwd: fixtureRoot, + encoding: 'utf8', +}); +const combinedOutput = `${result.stdout ?? ''}\n${result.stderr ?? ''}`; + +if (!combinedOutput.includes('TYPE-001')) { + throw new Error(`Expected TYPE-001 in build output.\n${combinedOutput}`); +} + +const reproductionCommand = combinedOutput.match( + /args: \{"cmd":"([^"]+)"\}/, +)?.[1]; +if (!reproductionCommand) { + throw new Error( + `TYPE-001 did not include its generated reproduction command.\n${combinedOutput}`, + ); +} + +const reproductionParts = reproductionCommand.split(' '); +const projectFlagIndex = reproductionParts.indexOf('--project'); +if (projectFlagIndex < 2 || !reproductionParts[projectFlagIndex + 1]) { + throw new Error(`Could not parse TYPE-001 command: ${reproductionCommand}`); +} + +const reproductionResult = spawnSync( + reproductionParts[0], + reproductionParts.slice(1), + { + cwd: fixtureRoot, + encoding: 'utf8', + }, +); +const reproductionOutput = `${reproductionResult.stdout ?? ''}\n${ + reproductionResult.stderr ?? '' +}`; +if (reproductionResult.status === 0 || !reproductionOutput.includes('TS6059')) { + throw new Error( + `Expected the generated TYPE-001 command to reproduce TS6059.\n${reproductionOutput}`, + ); +} + +const rsbuildBinary = join( + fixtureRoot.pathname, + 'node_modules', + '.bin', + 'rsbuild', +); +const devServer = spawn( + rsbuildBinary, + [ + 'dev', + '--root', + 'diagnostics/type-001', + '--config', + 'rsbuild.config.ts', + '--host', + '127.0.0.1', + '--port', + '3101', + '--strict-port', + ], + { + cwd: fixtureRoot, + env: { + ...process.env, + FEDERATION_DEBUG: 'true', + }, + stdio: 'ignore', + }, +); + +const logDeadline = Date.now() + 20_000; +while (Date.now() < logDeadline) { + if ( + existsSync(logPath) && + (await readFile(logPath, 'utf8')).includes('forkDevWorker') + ) { + break; + } + await new Promise((resolve) => setTimeout(resolve, 200)); +} + +devServer.kill('SIGINT'); +await Promise.race([ + new Promise((resolve) => devServer.once('close', resolve)), + new Promise((resolve) => setTimeout(resolve, 5_000)), +]); +if (devServer.exitCode === null) { + devServer.kill('SIGTERM'); +} + +if (!existsSync(logPath)) { + throw new Error(`Expected Module Federation debug log at ${logPath}.`); +} +const debugLog = await readFile(logPath, 'utf8'); +if (!debugLog.includes('forkDevWorker')) { + throw new Error('Expected dev-worker evidence in .mf/typesGenerate.log.'); +} + +console.log('Verified reproducible TYPE-001/TS6059 diagnostics.'); diff --git a/module-federation/react-rsbuild-monorepo/scripts/scaffold-new.sh b/module-federation/react-rsbuild-monorepo/scripts/scaffold-new.sh new file mode 100644 index 00000000..67b2daca --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/scripts/scaffold-new.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -euo pipefail + +target_root=${1:?"Pass an empty destination directory"} + +pnpm dlx create-rsbuild@2.1.8 "${target_root}/host" \ + --template react-ts \ + --packageName host +pnpm dlx create-rsbuild@2.1.8 "${target_root}/header" \ + --template react-ts \ + --packageName header +pnpm dlx create-rsbuild@2.1.8 "${target_root}/hero" \ + --template react-ts \ + --packageName hero diff --git a/module-federation/react-rsbuild-monorepo/scripts/verify-fixture.mjs b/module-federation/react-rsbuild-monorepo/scripts/verify-fixture.mjs new file mode 100644 index 00000000..d9f37010 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/scripts/verify-fixture.mjs @@ -0,0 +1,209 @@ +import { spawnSync } from 'node:child_process'; +import { existsSync } from 'node:fs'; +import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +const fixtureRoot = new URL('../', import.meta.url); +const fixturePath = fixtureRoot.pathname; + +const expectedVersions = { + '@module-federation/rsbuild-plugin': '2.8.0', + '@rsbuild/core': '2.1.8', + '@rsbuild/plugin-react': '2.1.0', + '@types/node': '24.5.2', + '@types/react': '19.2.14', + '@types/react-dom': '19.2.3', + react: '19.2.7', + 'react-dom': '19.2.7', + typescript: '6.0.3', + 'zephyr-agent': '1.2.0', + 'zephyr-cli': '1.2.0', + 'zephyr-rsbuild-plugin': '1.2.0', +}; + +async function readJson(relativePath) { + return JSON.parse(await readFile(new URL(relativePath, fixtureRoot), 'utf8')); +} + +async function installedVersion(packageName) { + for (const workspacePath of ['', 'apps/host', 'apps/header', 'apps/hero']) { + const packagePath = join( + fixturePath, + workspacePath, + 'node_modules', + packageName, + 'package.json', + ); + if (existsSync(packagePath)) { + const manifest = JSON.parse(await readFile(packagePath, 'utf8')); + if (manifest.name === packageName) { + return manifest.version; + } + } + } + + throw new Error(`Could not locate installed manifest for ${packageName}`); +} + +for (const [packageName, expectedVersion] of Object.entries(expectedVersions)) { + const actualVersion = await installedVersion(packageName); + if (actualVersion !== expectedVersion) { + throw new Error( + `Installed ${packageName}@${actualVersion}; expected ${expectedVersion}`, + ); + } +} + +const lockfile = await readFile(new URL('pnpm-lock.yaml', fixtureRoot), 'utf8'); +for (const [packageName, expectedVersion] of Object.entries(expectedVersions)) { + const escapedPackageName = packageName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const declaredAndLocked = new RegExp( + `['"]?${escapedPackageName}['"]?:[\\s\\S]{0,160}specifier: ${expectedVersion.replaceAll('.', '\\.')}`, + ); + if (!declaredAndLocked.test(lockfile)) { + throw new Error( + `Lockfile does not contain the declared ${packageName}@${expectedVersion} pin`, + ); + } +} + +const hostPackage = await readJson('apps/host/package.json'); +const dependencyAliases = Object.keys( + hostPackage['zephyr:dependencies'], +).sort(); +if (dependencyAliases.join(',') !== 'header,hero') { + throw new Error('Host Zephyr dependency aliases must be header and hero.'); +} +if ( + hostPackage['zephyr:dependencies'].header !== + 'rsbuild-mf-monorepo-header@workspace:*' || + hostPackage['zephyr:dependencies'].hero !== + 'rsbuild-mf-monorepo-hero@workspace:*' +) { + throw new Error('Host Zephyr aliases must map to the unique remote app UIDs.'); +} + +const hostConfig = await readFile( + new URL('apps/host/rsbuild.config.ts', fixtureRoot), + 'utf8', +); +const bootstrapSource = await readFile( + new URL('apps/host/src/bootstrap.tsx', fixtureRoot), + 'utf8', +); +for (const alias of dependencyAliases) { + const port = alias === 'header' ? 3001 : 3002; + if ( + !hostConfig.includes( + `${alias}: '${alias}@http://localhost:${port}/remoteEntry.js'`, + ) + ) { + throw new Error(`Host Module Federation remotes omit ${alias}.`); + } + const exposedName = alias === 'header' ? 'Header' : 'Hero'; + if (!bootstrapSource.includes(`from '${alias}/${exposedName}'`)) { + throw new Error(`Host source does not import ${alias}/${exposedName}.`); + } +} + +for (const remote of [ + { name: 'header', exposed: './Header' }, + { name: 'hero', exposed: './Hero' }, +]) { + const remoteConfig = await readFile( + new URL(`apps/${remote.name}/rsbuild.config.ts`, fixtureRoot), + 'utf8', + ); + for (const requiredFragment of [ + "entry: {\n index: './src/index.ts'", + "filename: 'remoteEntry.js'", + "assetPrefix: 'auto'", + remote.exposed, + 'withZephyr()', + ]) { + if (!remoteConfig.includes(requiredFragment)) { + throw new Error(`${remote.name} config is missing ${requiredFragment}`); + } + } + if ( + remoteConfig.indexOf('pluginModuleFederation(') > + remoteConfig.indexOf('withZephyr()') + ) { + throw new Error(`${remote.name} must apply withZephyr after federation.`); + } +} + +const selectorExamples = await readJson('dependency-selectors.json'); +if ( + selectorExamples.sameProjectWorkspaceBuild.header !== + 'rsbuild-mf-monorepo-header@workspace:*' || + selectorExamples.sameProjectProductionEnvironment.header !== + 'rsbuild-mf-monorepo-header@production' || + selectorExamples.crossProjectProductionEnvironment.header !== + 'rsbuild-mf-monorepo-header.design-system.acme@production' +) { + throw new Error('Dependency selector examples drifted from the guide.'); +} + +for (const artifactPath of [ + 'apps/header/dist/remoteEntry.js', + 'apps/header/dist/mf-manifest.json', + 'apps/hero/dist/remoteEntry.js', + 'apps/hero/dist/mf-manifest.json', + 'apps/host/dist/index.html', +]) { + if (!existsSync(join(fixturePath, artifactPath))) { + throw new Error(`Expected build artifact ${artifactPath}.`); + } +} + +for (const [remoteName, exposedModule] of [ + ['header', './Header'], + ['hero', './Hero'], +]) { + const manifest = await readJson(`apps/${remoteName}/dist/mf-manifest.json`); + if (!JSON.stringify(manifest).includes(exposedModule)) { + throw new Error( + `${remoteName} manifest does not advertise ${exposedModule}.`, + ); + } +} + +function commandOutput(command, args) { + const result = spawnSync(command, args, { + cwd: fixtureRoot, + encoding: 'utf8', + }); + const output = `${result.stdout ?? ''}\n${result.stderr ?? ''}`; + if (result.status !== 0) { + throw new Error(`${command} ${args.join(' ')} failed.\n${output}`); + } + return output; +} + +const zephyrHelp = commandOutput('pnpm', ['exec', 'ze-cli', '--help']); +for (const requiredFlag of [ + 'watch ', + '--target', + 'tap-app', + '--metadata ', +]) { + if (!zephyrHelp.includes(requiredFlag)) { + throw new Error(`ze-cli help no longer includes ${requiredFlag}.`); + } +} + +const rsbuildHelp = commandOutput('pnpm', [ + '--filter', + './apps/header', + 'exec', + 'rsbuild', + '--help', +]); +for (const requiredCommand of ['build', 'inspect']) { + if (!rsbuildHelp.includes(requiredCommand)) { + throw new Error(`Rsbuild help no longer includes ${requiredCommand}.`); + } +} + +console.log('Verified declared, locked, installed, and built fixture state.'); diff --git a/module-federation/react-rsbuild-monorepo/scripts/verify-scaffold.mjs b/module-federation/react-rsbuild-monorepo/scripts/verify-scaffold.mjs new file mode 100644 index 00000000..ec9fadba --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/scripts/verify-scaffold.mjs @@ -0,0 +1,66 @@ +import { mkdtemp, readFile, rm } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { spawnSync } from 'node:child_process'; + +const fixtureRoot = new URL('../', import.meta.url); +const scratchDirectory = await mkdtemp( + join(tmpdir(), 'zephyr-rsbuild-scaffold-'), +); + +function run(scriptName, args) { + const result = spawnSync( + 'bash', + [new URL(scriptName, fixtureRoot).pathname, ...args], + { + encoding: 'utf8', + stdio: 'pipe', + }, + ); + + if (result.status !== 0) { + throw new Error([result.stdout, result.stderr].filter(Boolean).join('\n')); + } +} + +try { + run('scripts/scaffold-new.sh', [scratchDirectory]); + run('scripts/add-existing-dependencies.sh', [join(scratchDirectory, 'host')]); + + for (const applicationName of ['host', 'header', 'hero']) { + const packageJson = JSON.parse( + await readFile( + join(scratchDirectory, applicationName, 'package.json'), + 'utf8', + ), + ); + if (packageJson.name !== applicationName) { + throw new Error( + `Expected scaffolded ${applicationName} package name, received ${packageJson.name}`, + ); + } + } + + const hostPackage = JSON.parse( + await readFile(join(scratchDirectory, 'host', 'package.json'), 'utf8'), + ); + const expectedPins = { + '@module-federation/rsbuild-plugin': '2.8.0', + '@rsbuild/core': '2.1.8', + '@rsbuild/plugin-react': '2.1.0', + 'zephyr-agent': '1.2.0', + 'zephyr-rsbuild-plugin': '1.2.0', + }; + + for (const [packageName, expectedVersion] of Object.entries(expectedPins)) { + if (hostPackage.devDependencies?.[packageName] !== expectedVersion) { + throw new Error( + `Expected ${packageName}@${expectedVersion} in scaffolded host`, + ); + } + } + + console.log('Verified create-rsbuild and pnpm add commands.'); +} finally { + await rm(scratchDirectory, { recursive: true, force: true }); +} diff --git a/module-federation/react-rsbuild-monorepo/scripts/verify-web-watch.mjs b/module-federation/react-rsbuild-monorepo/scripts/verify-web-watch.mjs new file mode 100644 index 00000000..534d8051 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/scripts/verify-web-watch.mjs @@ -0,0 +1,69 @@ +import { spawn } from 'node:child_process'; +import { readFile, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +const fixtureRoot = new URL('../', import.meta.url); +const headerDirectory = join(fixtureRoot.pathname, 'apps', 'header'); +const headerSourcePath = join(headerDirectory, 'src', 'Header.tsx'); +const rsbuildBinary = join( + fixtureRoot.pathname, + 'node_modules', + '.bin', + 'rsbuild', +); +const originalSource = await readFile(headerSourcePath, 'utf8'); +const updatedSource = originalSource.replace( + 'Header fixture v1', + 'Header fixture watch verification', +); +let output = ''; + +const watcher = spawn(rsbuildBinary, ['build', '--watch'], { + cwd: headerDirectory, + env: { + ...process.env, + ZEPHYR_EXAMPLE_OFFLINE: '1', + }, + stdio: ['ignore', 'pipe', 'pipe'], +}); +watcher.stdout.on('data', (chunk) => { + output += chunk.toString(); +}); +watcher.stderr.on('data', (chunk) => { + output += chunk.toString(); +}); + +async function waitForBuildCount(expectedCount) { + const deadline = Date.now() + 30_000; + while (Date.now() < deadline) { + const buildCount = output.match(/ready\s+built/g)?.length ?? 0; + if (buildCount >= expectedCount) { + return; + } + if (watcher.exitCode !== null) { + throw new Error(`Rsbuild watch exited early.\n${output}`); + } + await new Promise((resolve) => setTimeout(resolve, 200)); + } + throw new Error( + `Timed out waiting for Rsbuild watch build ${expectedCount}.\n${output}`, + ); +} + +try { + await waitForBuildCount(1); + await writeFile(headerSourcePath, updatedSource); + await waitForBuildCount(2); +} finally { + await writeFile(headerSourcePath, originalSource); + watcher.kill('SIGINT'); + await Promise.race([ + new Promise((resolve) => watcher.once('close', resolve)), + new Promise((resolve) => setTimeout(resolve, 5_000)), + ]); + if (watcher.exitCode === null) { + watcher.kill('SIGTERM'); + } +} + +console.log('Verified rsbuild build --watch rebuilds web output.'); diff --git a/module-federation/react-rsbuild-monorepo/tests/host.spec.ts b/module-federation/react-rsbuild-monorepo/tests/host.spec.ts new file mode 100644 index 00000000..e643123b --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/tests/host.spec.ts @@ -0,0 +1,73 @@ +import { readFile, writeFile } from 'node:fs/promises'; +import { fileURLToPath } from 'node:url'; +import { expect, test } from '@playwright/test'; + +const headerSourcePath = fileURLToPath( + new URL('../apps/header/src/Header.tsx', import.meta.url), +); + +test('loads both remotes and observes a subsequent header update', async ({ + page, + request, +}) => { + const browserErrors: string[] = []; + const failedRequests: string[] = []; + + page.on('console', (message) => { + if ( + message.type() === 'error' && + !message.text().toLowerCase().includes('favicon') + ) { + browserErrors.push(message.text()); + } + }); + page.on('pageerror', (error) => browserErrors.push(error.message)); + page.on('requestfailed', (requestEvent) => { + failedRequests.push( + `${requestEvent.method()} ${requestEvent.url()} ${ + requestEvent.failure()?.errorText ?? 'unknown failure' + }`, + ); + }); + + for (const [port, exposedModule] of [ + [3001, './Header'], + [3002, './Hero'], + ] as const) { + const remoteEntry = await request.get( + `http://127.0.0.1:${port}/remoteEntry.js`, + ); + expect(remoteEntry.ok()).toBeTruthy(); + + const manifestResponse = await request.get( + `http://127.0.0.1:${port}/mf-manifest.json`, + ); + expect(manifestResponse.ok()).toBeTruthy(); + expect(JSON.stringify(await manifestResponse.json())).toContain( + exposedModule, + ); + } + + await page.goto('/'); + await expect(page.getByTestId('header')).toHaveText('Header fixture v1'); + await expect(page.getByTestId('hero')).toContainText('Hero fixture'); + + const originalHeaderSource = await readFile(headerSourcePath, 'utf8'); + const updatedHeaderSource = originalHeaderSource.replace( + 'Header fixture v1', + 'Header fixture v2', + ); + + try { + await writeFile(headerSourcePath, updatedHeaderSource); + await expect(async () => { + await page.reload({ waitUntil: 'networkidle' }); + await expect(page.getByTestId('header')).toHaveText('Header fixture v2'); + }).toPass({ timeout: 30_000 }); + } finally { + await writeFile(headerSourcePath, originalHeaderSource); + } + + expect(browserErrors).toEqual([]); + expect(failedRequests).toEqual([]); +}); diff --git a/module-federation/react-rsbuild-monorepo/tsconfig.base.json b/module-federation/react-rsbuild-monorepo/tsconfig.base.json new file mode 100644 index 00000000..d4095681 --- /dev/null +++ b/module-federation/react-rsbuild-monorepo/tsconfig.base.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "jsx": "react-jsx", + "target": "ES2020", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "types": ["@rsbuild/core/types", "node"], + "useDefineForClassFields": true, + "module": "ESNext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "verbatimModuleSyntax": true, + "resolveJsonModule": true + } +} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 29f503b3..b81bf8b9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,6 +2,7 @@ packages: - bundlers/** - module-federation/** - "!module-federation/airbnb-clone/**" + - "!module-federation/react-rsbuild-monorepo/**" - "!module-federation/react-vite-rspack-webpack/**" - frameworks/** - "!frameworks/react-native-metro/**" diff --git a/scripts/src/tests/app-validations.ts b/scripts/src/tests/app-validations.ts index a483c803..f85648d6 100644 --- a/scripts/src/tests/app-validations.ts +++ b/scripts/src/tests/app-validations.ts @@ -193,6 +193,13 @@ export const APP_VALIDATIONS: Record = { "mf-react-rsbuild-provider": { uniqueText: ["Basic Host-Remote", "Provider button"], }, + "rsbuild-mf-monorepo-host": { + uniqueText: [ + "Header fixture v1", + "Hero fixture", + "Rsbuild, Module Federation, and Zephyr Cloud are connected.", + ], + }, "angular-rsbuild-host": { uniqueText: ["Angular + Rsbuild", "Remote loaded by the host"], required: true, diff --git a/templates.json b/templates.json index 76b82595..1933566b 100644 --- a/templates.json +++ b/templates.json @@ -109,6 +109,20 @@ "complexity": "intermediate", "path": "module-federation/react-rsbuild" }, + { + "name": "React + Rsbuild Module Federation Monorepo", + "slug": "module-federation/react-rsbuild-monorepo", + "description": "Verified React monorepo with an Rsbuild host, two federated remotes, Zephyr dependencies, DTS diagnostics, and browser tests", + "framework": "react", + "bundler": "rsbuild", + "features": [ + "module-federation", + "monorepo", + "typescript" + ], + "complexity": "advanced", + "path": "module-federation/react-rsbuild-monorepo" + }, { "name": "React Multi-Bundler Module Federation", "slug": "module-federation/react-vite-rspack-webpack",