diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b910aae2d..62fe6f4a8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -53,8 +53,8 @@ jobs:
- name: Build packages
run: pnpm build
- - name: Build sample
- run: pnpm build-sample
+ - name: Build samples
+ run: pnpm build-basic && pnpm build-endpoints
- name: Lint packages & sample
run: pnpm lint
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 17ef48611..b21679ab4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -7,7 +7,7 @@ The following documentation is only for the maintainers of this repository.
- [Installation](#installation)
- [Develop the shell packages](#develop-the-shell-packages)
- [Release the packages](#release-the-packages)
-- [Deploy the sample application](#deploy-the-sample-application)
+- [Deploy the sample applications](#deploy-the-sample-applications)
- [Available commands](#commands)
- [CI](#ci)
- [Add a new package to the monorepo](#add-a-new-package-to-the-monorepo)
@@ -22,7 +22,7 @@ The main difference to account for is that the `devDependencies` must now be ins
## Project overview
-This project is split into two major sections, [packages/](packages/) and [sample/](sample/).
+This project is split into two major sections, [packages/](packages/) and [samples/](samples/).
### Packages
@@ -32,25 +32,30 @@ Under [packages/](packages/) are the actual packages composing the federated app
[@squide/react-router](packages/react-router/) is a [React Router](https://reactrouter.com/en/main) implementation of the shell routing capabilities. This implementation is offered as a standalone package because the shell could eventually support alternative routing libraries like [TanStack router](https://tanstack.com/router/v1).
-[@squide/webpack-module-federation](packages/webpack-module-federation/) is module federation implementation for [webpack](https://webpack.js.org/concepts/module-federation/). This implementation is offered as a standalone package because not all application configurations will require module federation and the shell could eventually support alternative module federation application like [Rspack](https://www.rspack.dev/).
+[@squide/webpack-module-federation](packages/webpack-module-federation/) is a module federation implementation for [webpack](https://webpack.js.org/concepts/module-federation/). This implementation is offered as a standalone package because not all application will require module federation and the shell could eventually support alternative module federation application like [Rspack](https://www.rspack.dev/).
+
+[@squide/msw](packages/msw/) is a package including helpers to configure [Mock Service Worker](https://mswjs.io/) for a federated application.
[@squide/fakes](packages/fakes/) is a collection of fake implementations to facilitate the development of federated modules in isolation.
-### Sample
+### Samples
-Under [sample/](sample/) is a sample application to test the federation application shell functionalities while developing.
+Under [samples/](samples/) are applications to test the Squide functionalities while developing.
-In this sample application would find:
+You'll find two samples:
-- [An host application](sample/host/): http://locahost:8080
-- [A static module](sample/static-module/)
-- [A remote module](sample/remote-module/): http://localhost:8081
+- `basic`: A sample application showcasing the basic features or Squide.
+- `endpoints`: A more complexe sample application showcasing the different usecases related to data fetching and management.
## Installation
-This project uses PNPM, therefore, you must [install PNPM](https://pnpm.io/installation):
+This project uses PNPM, therefore, you must [install PNPM](https://pnpm.io/installation) first:
-To install the project, open a terminal at the root of the workspace and execute the following command:
+```bash
+npm install -g pnpm
+```
+
+To install the Squide project, open a terminal at the root of the workspace and execute the following command:
```bash
pnpm install
@@ -58,7 +63,9 @@ pnpm install
### Setup Retype
-[Retype](https://retype.com/) is the documentation platform that `workleap/web-configs` is using for the documentation. As this project is leveraging a few [Pro features](https://retype.com/pro/) of Retype, you must first setup your [Retype wallet](https://retype.com/guides/cli/#retype-wallet).
+[Retype](https://retype.com/) is the documentation platform that Squide is using for its documentation. As this project is leveraging a few [Pro features](https://retype.com/pro/) of Retype.
+
+Everything should work fine as-is but there are a few limitations to use Retype Pro features without a wallet with a licence. If you want to circumvent these limitations, you can optionally, setup your [Retype wallet](https://retype.com/guides/cli/#retype-wallet).
To do so, first make sure that you retrieve the Retype license from your Vault (or ask IT).
@@ -68,9 +75,9 @@ Then, open a terminal at the root of the workspace and execute the following com
npx retype wallet --add
```
-## Develop the shell packages
+## Develop the packages
-We recommend opening two [VSCode terminals](https://code.visualstudio.com/docs/terminal/basics#_managing-multiple-terminals) to develop the shell packages.
+We recommend opening two [VSCode terminals](https://code.visualstudio.com/docs/terminal/basics#_managing-multiple-terminals) to develop the packages.
With the first terminal, execute the following script:
@@ -78,19 +85,27 @@ With the first terminal, execute the following script:
pnpm dev
```
-With the second terminal, execute the following script:
+With the second terminal, start one of the sample application with either the following script:
+
+```bash
+pnpm dev-basic
+```
+
+or
```bash
-pnpm dev-sample
+pnpm dev-endpoints
```
-You can then open your favorite browser and navigate to `http://localhost:8080/` to get a live preview of your code. To test that the remote module is working correctly, navigate to `http://localhost:8081/remoteEntry.js`
+You can then open your favorite browser and navigate to `http://localhost:8080/` to get a live preview of your code.
+
+> To test that a remote module is working correctly, navigate to the remote module entry file. For a remote module hosted on the port `8081`, the URL should be `http://localhost:8081/remoteEntry.js`.
## Release the packages
When you are ready to release the packages, you must follow the following steps:
1. Run `pnpm changeset` and follow the prompt. For versioning, always follow the [SemVer standard](https://semver.org/).
-2. Commit the newly generated file in your branch and submit a new Pull Request(PR). Changesets will automatically detect the changes and post a message in your pull request telling you that once the PR closes, the versions will be released.
+2. Commit the newly generated file in your branch and submit a new Pull Request (PR). Changesets will automatically detect the changes and post a message in your pull request telling you that once the PR closes, the versions will be released.
3. Find someone to review your PR.
4. Merge the Pull request into `main`. A GitHub action will automatically trigger and update the version of the packages and publish them to [npm](https://www.npmjs.com/). A tag will also be created on GitHub tagging your PR merge commit.
@@ -100,7 +115,7 @@ When you are ready to release the packages, you must follow the following steps:
Make sure you're Git is clean (No pending changes).
-#### npm
+#### NPM
Make sure GitHub Action has **write access** to the selected npm packages.
@@ -118,21 +133,42 @@ By default, packages compilation output will be in their respective *dist* direc
If you got linting error, most of the time, they can be fixed automatically using `eslint . --fix`, if not, follow the report provided by `pnpm lint`.
-## Deploy the sample application
+## Deploy the sample applications
+
+### The "basic" sample application
+
+The sites for this sample application are hosted on [Netlify](https://www.netlify.com/):
+
+- [host](https://squide-basic-host.netlify.app/)
+- [remote-module](https://squide-basic-remote-module.netlify.app)
+- [another-remote-module](https://squide-basic-another-remote-module.netlify.app)
+
+To deploy the sample application, open a terminal at the root of the repository and execute the following script:
+
+```bash
+deploy-basic
+```
+
+A prompt with a few questions will appear and then the sits will automatically be deployed to production.
+
+### The sample application with "endpoints"
+
+The sites for this sample application are hosted on [Netlify](https://www.netlify.com/):
-The sample application is hosted on [Netlify](https://www.netlify.com/). 2 sites are available, one for the host application (https://squide-host.netlify.app/) and one for the remote module application (https://squide-remote-module.netlify.app).
+- [host](https://squide-endpoints-host.netlify.app/)
+- [remote-module](https://squide-endpoints-remote-module.netlify.app)
-To deploy both websites, open a terminal at the root of the repository and execute the following script:
+To deploy the sample application, open a terminal at the root of the repository and execute the following script:
```bash
-deploy-sample
+deploy-endpoints
```
-It will automatically deploy both sites to production.
+A prompt with a few questions will appear and then the sites will automatically be deployed to production.
## Commands
-From the project root, you have access to many commands the main ones are:
+From the project root, you have access to many commands. The most important ones are:
### dev
@@ -142,17 +178,25 @@ Build the shell packages for development and start the watch processes.
pnpm dev
```
-### dev-sample
+### dev-basic
-Build the sample application for development and start the dev servers.
+Build the sample "basic" application for development and start the dev servers.
```bash
-pnpm dev-sample
+pnpm dev-basic
+```
+
+### dev-endpoints
+
+Build the sample "application with "endpoints" for development and start the dev servers.
+
+```bash
+pnpm dev-endpoints
```
### dev-docs
-Build the docs application for development and start the dev servers.
+Build the [Retype](https://retype.com/) documentation for development and start the Retype dev server. If you are experiencing issue with the license, refer to the [setup Retype section](#setup-retype).
```bash
pnpm dev-docs
@@ -166,28 +210,36 @@ Build the packages for release.
pnpm build
```
-### build-sample
+### build-basic
-Build the sample application for release.
+Build the sample "basic" application for release.
```bash
-pnpm build-sample
+pnpm build-basic
```
-### serve-sample
+### build-endpoints
-Build the sample application for deployment and start a local web server to serve the application.
+Build the sample application with "endpoints" for release.
```bash
-pnpm serve-sample
+pnpm build-endpoints
```
-### dev-docs
+### serve-basic
-Build the [Retype](https://retype.com/) documentation for development and start the Retype dev server. If you are experiencing issue with the license, refer to the [setup Retype section](#setup-retype).
+Build the sample "basic" application for deployment and start a local web server to serve the application.
```bash
-pnpm dev-docs
+pnpm serve-basic
+```
+
+### serve-endpoints
+
+Build the sample application with "endpoints" for deployment and start a local web server to serve the application.
+
+```bash
+pnpm serve-endpoints
```
### test
diff --git a/README.md b/README.md
index 68a333edf..c481330e8 100644
--- a/README.md
+++ b/README.md
@@ -20,9 +20,10 @@ To ask a question or propose an idea, feel free to start a new [discussion](http
View the [user's documentation](https://gsoft-inc.github.io/wl-squide/).
-## Live sample
+## Live samples
-A sample application is hosted at https://squide-host.netlify.app.
+- A [basic sample application](https://squide-basic-host.netlify.app) hosted on Netlify.
+- A [sample application with endpoints](https://squide-endpoints-host.netlify.app) hosted on Netlify.
## π€ Contributing
diff --git a/docs/getting-started/create-host.md b/docs/getting-started/create-host.md
index 8c534f46c..376eeb8a1 100644
--- a/docs/getting-started/create-host.md
+++ b/docs/getting-started/create-host.md
@@ -29,7 +29,7 @@ npm install @squide/core @squide/react-router @squide/webpack-module-federation
+++
!!!warning
-While you can use any package manager to develop an application with Squide, it is highly recommended that you use [PNPM](https://pnpm.io/) as the following guide has been developed and tested with PNPM.
+While you can use any package manager to develop an application with Squide, it is highly recommended that you use [PNPM](https://pnpm.io/) as the guides has been developed and tested with PNPM.
!!!
## Setup the application
@@ -43,9 +43,10 @@ host
βββ src
βββββ App.tsx
βββββ RootLayout.tsx
-βββββ Home.tsx
+βββββ HomePage.tsx
βββββ bootstrap.tsx
βββββ index.ts
+βββββ register.tsx
βββ .browserslistrc
βββ swc.dev.js
βββ swc.build.js
@@ -80,8 +81,7 @@ export {};
Next, to register the modules, instanciate the shell [Runtime](/reference/runtime/runtime-class.md) and register the remote module with the [registerRemoteModules](/reference/registration/registerRemoteModules.md) function (the configuration of the remote module will be covered in the [next section](create-remote-module.md)):
-```tsx !#14-16,19-21,24 host/src/bootstrap.tsx
-import { Suspense } from "react";
+```tsx !#13-15,18-20,23 host/src/bootstrap.tsx
import { createRoot } from "react-dom/client";
import { ConsoleLogger, RuntimeContext, Runtime } from "@squide/react-router";
import { registerRemoteModules, type RemoteDefinition } from "@squide/webpack-module-federation";
@@ -110,9 +110,7 @@ const root = createRoot(document.getElementById("root")!);
root.render(
- Loading...}>
-
-
+
);
```
@@ -129,39 +127,24 @@ import { Home } from "./Home.tsx";
export function App() {
// Re-render the application once the remote modules are registered.
- const isReady = useAreModulesReady();
+ const areModulesReady = useAreModulesReady();
// Retrieve the routes registered by the remote modules.
const routes = useRoutes();
- // Create the router instance with an home page and the remote module routes.
+ // Create the router instance with the registered routes.
const router = useMemo(() => {
- return createBrowserRouter([
- {
- path: "/",
- element: ,
- children: [
- {
- index: true,
- element:
- },
- ...routes
- ]
- }
- ]);
+ return createBrowserRouter(routes);
}, [routes]);
// Display a loading until the remote modules are registered.
- if (!isReady) {
+ if (!areModulesReady) {
return Loading...
;
}
// Render the router.
return (
- Loading...}
- />
+
);
}
```
@@ -171,7 +154,7 @@ export function App() {
Next, create a layout component to [render the navigation items](/reference/routing/useRenderedNavigationItems.md):
```tsx !#38,41 host/src/RootLayout.tsx
-import type { ReactNode } from "react";
+import { Suspense, type ReactNode } from "react";
import { Link, Outlet } from "react-router-dom";
import {
useNavigationItems,
@@ -216,7 +199,9 @@ export function RootLayout() {
return (
<>
{navigationElements}
-
+ Loading...}>
+
+
>
);
}
@@ -224,16 +209,101 @@ export function RootLayout() {
### Homepage
-Finally, create the `Home` component that will serve as the homepage for this guide application:
+Next, create the `HomePage` component that will serve as the homepage for this application:
-```tsx host/src/Home.tsx
-export function Home() {
+```tsx host/src/HomePage.tsx
+export function HomePage() {
return (
Hello from the Home page!
);
}
```
+Then, add a local module at the root of the host application to register the homepage:
+
+```tsx host/src/register.tsx
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { HomePage } from "./HomePage.tsx";
+
+export const registerHost: ModuleRegisterFunction = runtime => {
+ runtime.registerRoute({
+ index: true,
+ element:
+ });
+};
+```
+
+And an [hoisted route](../reference/runtime/runtime-class.md#register-an-hoisted-route) to render the `RootLayout` and the [ManagedRoutes](../reference/routing/ManagedRoutes.md) placeholder:
+
+```tsx !#8,12,15 host/src/register.tsx
+import { ManagedRoutes, type ModuleRegisterFunction, type Runtime } from "@squide/react-router";
+import { HomePage } from "./HomePage.tsx";
+import { RootLayout } from "./RootLayout.tsx";
+
+export const registerHost: ModuleRegisterFunction = runtime => {
+ runtime.registerRoute({
+ // Pathless route to declare a root layout.
+ element: ,
+ children: [
+ // Placeholder to indicate where managed routes (routes that are not hoisted or nested)
+ // will be rendered.
+ ManagedRoutes
+ ]
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ index: true,
+ element:
+ });
+};
+```
+
+!!!info
+The [ManagedRoutes](../reference/routing/ManagedRoutes.md) placeholder indicates where routes that are neither hoisted or nested with a [parentPath](../reference/runtime/runtime-class.md#register-nested-navigation-items) or [parentName](../reference/runtime/runtime-class.md#register-a-named-route) option will be rendered. In this example, the homepage route is considered a managed route and will be rendered under the `ManagedRoutes` placeholder.
+!!!
+
+Finally, update the bootstrapping code to [register](../reference/registration/registerLocalModules.md) the newly created local module:
+
+```tsx !#24 host/src/bootstrap.tsx
+import { createRoot } from "react-dom/client";
+import { ConsoleLogger, RuntimeContext, Runtime } from "@squide/react-router";
+import { registerRemoteModules, type RemoteDefinition } from "@squide/webpack-module-federation";
+import type { AppContext} from "@sample/shared";
+import { App } from "./App.tsx";
+import { registerHost } from "./register.tsx";
+
+// Define the remote modules.
+const Remotes: RemoteDefinition[] = [
+ { url: "http://localhost:8081", name: "remote1" }
+];
+
+// Create the shell runtime.
+const runtime = new Runtime({
+ loggers: [new ConsoleLogger()]
+});
+
+// Create an optional context.
+const context: AppContext = {
+ name: "Demo application"
+};
+
+// Register the newly created local module.
+registerLocalModules([registerHost], runtime, { context });
+
+// Register the remote module.
+registerRemoteModules(Remotes, runtime, { context });
+
+const root = createRoot(document.getElementById("root")!);
+
+root.render(
+
+
+
+);
+```
+
## Configure webpack
!!!info
@@ -354,6 +424,6 @@ To troubleshoot module registration issues, open the DevTools console. You'll fi
!!!
!!!info
-If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/sample/host).
+If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/samples/basic/host).
!!!
diff --git a/docs/getting-started/create-local-module.md b/docs/getting-started/create-local-module.md
index a19a75b7e..c0d401961 100644
--- a/docs/getting-started/create-local-module.md
+++ b/docs/getting-started/create-local-module.md
@@ -40,7 +40,7 @@ npm install @squide/core @squide/react-router react react-dom react-router-dom
+++
!!!warning
-While you can use any package manager to develop an application with Squide, it is highly recommend that you use [PNPM](https://pnpm.io/) as the following guide has been developed and tested with PNPM.
+While you can use any package manager to develop an application with Squide, it is highly recommend that you use [PNPM](https://pnpm.io/) as the guides has been developed and tested with PNPM.
!!!
## Setup the application
@@ -83,27 +83,23 @@ Finally, configure the package to be shareable by adding the `name`, `version`,
### Routes registration
-Next, register the local module routes and navigation items with [registerRoutes](/reference/runtime/runtime-class.md#register-routes) and [registerNavigationItems](/reference/runtime/runtime-class.md#register-navigation-items) functions:
+Next, register the local module routes and navigation items with [registerRoute](/reference/runtime/runtime-class.md#register-routes) and [registerNavigationItem](/reference/runtime/runtime-class.md#register-navigation-items) functions:
-```tsx !#6-11,13-18 local-module/src/register.tsx
+```tsx !#6-9,11-14 local-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import type { AppContext } from "@sample/shared";
import { Page } from "./Page.tsx";
export const register: ModuleRegisterFunction = (runtime, context) => {
- runtime.registerRoutes([
- {
- path: "/local/page",
- element:
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/local/page",
- content: "Local/Page"
- }
- ]);
+ runtime.registerRoute({
+ path: "/local/page",
+ element:
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Local/Page",
+ to: "/local/page"
+ });
}
```
@@ -222,5 +218,5 @@ To troubleshoot module registration issues, open the DevTools console. You'll fi
!!!
!!!info
-If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/sample/local-module).
+If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/samples/basic/local-module).
!!!
diff --git a/docs/getting-started/create-remote-module.md b/docs/getting-started/create-remote-module.md
index ec05e3240..7dedcd868 100644
--- a/docs/getting-started/create-remote-module.md
+++ b/docs/getting-started/create-remote-module.md
@@ -30,7 +30,7 @@ npm install @squide/core @squide/react-router @squide/webpack-module-federation
+++
!!!warning
-While you can use any package manager to develop an application with Squide, it is highly recommended that you use [PNPM](https://pnpm.io/) as the following guide has been developed and tested with PNPM.
+While you can use any package manager to develop an application with Squide, it is highly recommended that you use [PNPM](https://pnpm.io/) as the guides has been developed and tested with PNPM.
!!!
## Setup the application
@@ -60,27 +60,23 @@ Then, ensure that you are developing your module using [ESM syntax](https://deve
### Routes registration
-Next, register the remote module routes and navigation items with the [registerRoutes](/reference/runtime/runtime-class.md#register-routes) and [registerNavigationItems](/reference/runtime/runtime-class.md#register-navigation-items) functions:
+Next, register the remote module routes and navigation items with the [registerRoute](/reference/runtime/runtime-class.md#register-routes) and [registerNavigationItem](/reference/runtime/runtime-class.md#register-navigation-items) functions:
-```tsx !#6-11,13-18 remote-module/src/register.tsx
+```tsx !#6-9,11-14 remote-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import type { AppContext } from "@sample/shared";
import { Page } from "./Page.tsx";
-export const register: ModuleRegisterFunction = (runtime: Runtime, context: AppContext) => {
- runtime.registerRoutes([
- {
- path: "/remote/page",
- element:
- }
- ]);
+export const register: ModuleRegisterFunction = (runtime, context) => {
+ runtime.registerRoute({
+ path: "/remote/page",
+ element:
+ });
- runtime.registerNavigationItems([
- {
- to: "/remote/page",
- label: "Remote/Page"
- }
- ]);
+ runtime.registerNavigationItem({
+ $label: "Remote/Page",
+ to: "/remote/page"
+ });
}
```
@@ -193,6 +189,6 @@ To troubleshoot module registration issues, open the DevTools console. You'll fi
!!!
!!!info
-If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/sample/remote-module).
+If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/samples/basic/remote-module).
!!!
diff --git a/docs/getting-started/learn-the-api.md b/docs/getting-started/learn-the-api.md
index c783bd615..204692e52 100644
--- a/docs/getting-started/learn-the-api.md
+++ b/docs/getting-started/learn-the-api.md
@@ -48,7 +48,7 @@ const logger = useLogger();
logger.debug("Hello", { world: "!" });
```
-The logger is also available from the [Runtime](/reference/runtime/runtime-class.md) instance.
+The logger is also available from the [Runtime](/reference/runtime/runtime-class.md#use-the-logger) instance.
## Messaging
@@ -79,13 +79,13 @@ dispatch("foo", "bar");
You can use the event bus to enable various communication scenarios, such as notifying components of state changes, broadcasting messages across modules, or triggering actions based on specific events.
-The event bus is also available from the [Runtime](/reference/runtime/runtime-class.md) instance.
+The event bus is also available from the [Runtime](/reference/runtime/runtime-class.md#use-the-event-bus) instance.
## Session
Most of our applications (if not all) will eventually require the user to authenticate. To facilitate this process, the Squide [Runtime](/reference/runtime/runtime-class.md) class accepts a [sessionAccessor](/reference/fakes/LocalStorageSessionManager.md#integrate-with-a-runtime-instance) function. Once the shell registration flow is completed, the function will be made accessible to every module of the application.
-First, let's define a `sessionAccessor` function:
+First, define a `sessionAccessor` function:
```ts host/src/session.ts
import type { SessionAccessorFunction } from "@squide/react-router";
@@ -131,33 +131,101 @@ const isAuthenticated = useIsAuthenticated();
The session is also available from the [Runtime](/reference/runtime/runtime-class.md) instance.
-## Services
+## Plugins
-While Squide provides a range of built-in functionalities, by no mean these alone can support the needs of every mature application. Therefore, the shell [Runtime](/reference/runtime/runtime-class.md) allows the addition of custom services.
+To keep Squide lightweight, not all functionalities should be integrated as a core functionality. However, to accommodate a broad range of technologies, a [plugin system](../reference/plugins/plugin.md) has been implemented to fill the gap.
-First, make the service available to every part of the application by passing a service instance to the `Runtime` instance:
+Plugins can be registered at bootstrapping with the [Runtime](../reference/runtime/runtime-class.md) instance:
```ts host/src/boostrap.tsx
import { Runtime } from "@squide/react-router";
-import { UserService } from "@sample/shared";
+import { MyPlugin } from "@sample/my-plugin";
const runtime = new Runtime({
- services: {
- "user-service": new UserService()
- }
+ plugins: [new MyPlugin()]
});
```
-Then, access the service instance from anywhere with the [useService](/reference/runtime/useService.md) hook:
+Then, the plugins can be accessed anywhere from the `Runtime` instance:
```ts
-import { useService } from "@squide/react-router";
-import { type UserService } from "@sample/shared";
+import { MyPlugin } from "@sample/my-plugin";
-const service = useService("user-service") as UserService;
+const myPlugin = runtime.getPlugin(MyPlugin.name) as MyPlugin;
```
-The services are also available from the [Runtime](/reference/runtime/runtime-class.md) instance.
+## Mock Service Worker
+
+We recommend to mock the API endpoints with [Mock Service Worker](https://mswjs.io/) (MSW) to faciliate the development and encourage an [Contract Design First](https://devblogs.microsoft.com/ise/2023/05/08/design-api-first-with-typespec/) approach.
+
+To help with that, a `@squide/msw` package is available.
+
+First, install the plugin, then [register the plugin](../reference/msw/MswPlugin.md#register-the-plugin) at bootstrap:
+
+```ts host/src/boostrap.tsx
+import { Runtime } from "@squide/react-router";
+import { MswPlugin } from "@squide/msw";
+
+const runtime = new Runtime({
+ plugins: [new MswPlugin()]
+});
+```
+
+Then, [register the modules MSW request handlers](../reference/msw/MswPlugin.md#register-request-handlers) at registration:
+
+```ts !#12 remote-module/src/register.tsx
+import { getMswPlugin } from "@squide/msw";
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+
+export const register: ModuleRegisterFunction = async runtime => {
+ if (process.env.USE_MSW) {
+ const mswPlugin = getMswPlugin(runtime);
+
+ // Files including an import to the "msw" package are included dynamically to prevent adding
+ // MSW stuff to the bundled when it's not used.
+ const requestHandlers = (await import("../mocks/handlers.ts")).requestHandlers;
+
+ mswPlugin.registerRequestHandlers(requestHandlers);
+ }
+}
+```
+
+!!!info
+Don't forget to mark the registration function as `async` since there's a dynamic import.
+!!!
+
+Then, [retrieve the modules MSW request handlers](../reference/msw/MswPlugin.md#retrieve-the-request-handlers) in the host application and start MSW:
+
+```ts !#9,12
+import { registerRemoteModules } from "@squide/webpack-module-federation";
+import { setMswAsStarted } from "@squide/msw";
+
+registerRemoteModules(Remotes, runtime).then(() => {
+ if (process.env.USE_MSW) {
+ // Files including an import to the "msw" package are included dynamically to prevent adding
+ // MSW stuff to the bundled when it's not used.
+ import("../mocks/browser.ts").then(({ startMsw }) => {
+ // Will start MSW with the request handlers provided by every module.
+ startMsw(mswPlugin.requestHandlers);
+
+ // Indicate to resources that are dependent on MSW that the service has been started.
+ setMswAsStarted();
+ });
+ }
+});
+```
+
+Finally, make sure that the [application rendering is delayed](../reference/msw/useIsMswReady.md) until MSW is started:
+
+```ts !#3 host/src/App.tsx
+import { useIsMswStarted } from "@squide/msw";
+
+const isMswReady = useIsMswStarted(process.env.USE_MSW);
+
+if (!isMswReady) {
+ return Loading...
+}
+```
## Fakes
diff --git a/docs/guides/add-authentication.md b/docs/guides/add-authentication.md
index 4c24f1a87..60a5b9ab9 100644
--- a/docs/guides/add-authentication.md
+++ b/docs/guides/add-authentication.md
@@ -4,26 +4,37 @@ order: 80
# Add authentication
-Most of our applications (if not all) will eventually require the user to authenticate. To facilitate this process, the Squide [Runtime](/reference/runtime/runtime-class.md) class accepts a [sessionAccessor](/reference/fakes/LocalStorageSessionManager.md#integrate-with-a-runtime-instance) function. Once the shell registration flow is completed, the function will be made accessible to every module of the application.
+Most of our applications (if not all) will eventually requires the user to authenticate. To facilitate this process, the Squide [Runtime](/reference/runtime/runtime-class.md) class accepts a [sessionAccessor](/reference/fakes/LocalStorageSessionManager.md#integrate-with-a-runtime-instance) function. Once the application registration flow is completed, the function will be made accessible to every module of the application.
When combined with a [React Router](https://reactrouter.com/en/main) authentication boundary and a login page, the shared `sessionAccessor` function is of great help to manage authentication concerns.
## Create a session accessor function
-Define a `sessionAccessor` function wrapping a `LocalStorageSessionManager` instance:
+First, create a shared type for the session:
+
+```ts shared/src/session.ts
+export interface Session {
+ user: {
+ name: string;
+ };
+}
+```
+
+Then, define a `sessionAccessor` function wrapping a `LocalStorageSessionManager` instance:
```ts host/src/session.ts
import type { SessionAccessorFunction } from "@squide/react-router";
import { LocalStorageSessionManager } from "@squide/fakes";
+import type { Session } from "@sample/shared";
export const sessionManager = new LocalStorageSessionManager();
-const sessionAccessor: SessionAccessorFunction = () => {
+export const sessionAccessor: SessionAccessorFunction = () => {
return sessionManager.getSession();
};
```
-Then, create the [Runtime](/reference/runtime/runtime-class.md) instance with the new `sessionAccessor` function:
+Finally, create the [Runtime](/reference/runtime/runtime-class.md) instance with the new `sessionAccessor` function:
```ts #5 host/src/boostrap.tsx
import { Runtime } from "@squide/react-router";
@@ -234,84 +245,75 @@ export function RootLayout() {
## Setup the routes
-Assemble everything with React Router [nested routes](https://reactrouter.com/en/main/start/tutorial#nested-routes):
+Assemble everything with React Router [nested routes](https://reactrouter.com/en/main/start/tutorial#nested-routes) and a [register](../reference/registration/registerLocalModules.md) function:
-```tsx !#29-30,33-34,38,41 host/src/App.tsx
-import { lazy, useMemo } from "react";
-import { RouterProvider, createBrowserRouter } from "react-router-dom";
-import { useRoutes } from "@squide/react-router";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
-import { AuthenticationBoundary } from "./AuthenticationBoundary.tsx";
+```tsx !#17,22,25,46-51,55-60 host/src/register.tsx
+import { ManagedRoutes, type ModuleRegisterFunction, type Runtime } from "@squide/react-router";
+import { RootLayout } from "./Rootlayout.tsx";
import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
-import { RootLayout } from "./RootLayout.tsx";
-import { AuthenticatedLayout } from "./AuthenticatedLayout.tsx";
+import { AuthenticationBoundary } from "./AuthenticationBoundary.tsx";
import { ModuleErrorBoundary } from "./ModuleErrorBoundary.tsx";
-import { Home } from "./Home.tsx";
-import { Login } from "./Login.tsx";
-import { Logout } from "./Logout.tsx";
-
-export function App() {
- const isReady = useAreModulesReady();
-
- const routes = useRoutes();
-
- const router = useMemo(() => {
- return createBrowserRouter({
- element: ,
- children: [
- {
- errorElement: ,
- children: [
- {
- // The login and logout page are declared before the authentication boundary,
- // therefore they are public page.
- path: "/login",
- element:
- },
- {
- path: "/logout",
- element:
- },
- {
- // Every page beyond the authenticated boundary are protected.
- element: ,
- children: [
- {
- element: ,
- children: [
- {
- // By having the error boundary under the authenticated layout, modules unmanaged errors
- // will be displayed inside the layout rather than replacing the whole page.
- errorElement: ,
- children: [
- {
- index: true,
- element:
- },
- ...routes
- ]
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- });
- }, [routes]);
-
- if (!isReady) {
- return Loading...
;
- }
-
- return (
- Loading...}
- />
- );
-}
+import { LoginPage } from "./LoginPage.tsx";
+import { LogoutPage } from "./LogoutPage.tsx";
+import { HomePage } from "./Homepage.tsx";
+
+export const registerHost: ModuleRegisterFunction = runtime => {
+ runtime.registerRoute({
+ element: ,
+ children: [
+ {
+ // The root error boundary is a named route to be able to nest
+ // the loging / logout page under it with the "parentName" optionΓ©
+ $name: "root-error-boundary",
+ errorElement: ,
+ children: [
+ {
+ // Every page beyond the authenticated boundary are protected.
+ element: ,
+ children: [
+ {
+ element: ,
+ children: [
+ {
+ // By having the error boundary under the authenticated layout, modules unmanaged errors
+ // will be displayed inside the layout rather than replacing the whole page.
+ errorElement: ,
+ children: [
+ ManagedRoutes
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ });
+
+ // The login page is nested under the root error boundary to be defined before the
+ // authentication boundary to be publicly accessible.
+ runtime.registerRoute({
+ path: "/login",
+ element:
+ }, {
+ parentName: "root-error-boundary"
+ });
+
+ // The logout page is nested under the root error boundary to be defined before the
+ // authentication boundary to be publicly accessible.
+ runtime.registerRoute({
+ path: "/logout",
+ element:
+ }, {
+ parentName: "root-error-boundary"
+ });
+
+ runtime.registerRoute({
+ index: true,
+ element:
+ });
+});
```
## Try it :rocket:
@@ -319,7 +321,7 @@ export function App() {
Start the application and attempt navigating to the root page (`/`). You will be redirected to the `/login` page. Login with `"temp"` / `"temp"`, you will be redirected to the root page.
!!!info
-If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/sample/shell).
+If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/samples/basic/shell).
!!!
diff --git a/docs/guides/develop-a-module-in-isolation.md b/docs/guides/develop-a-module-in-isolation.md
index 171e52fbc..9200c13ee 100644
--- a/docs/guides/develop-a-module-in-isolation.md
+++ b/docs/guides/develop-a-module-in-isolation.md
@@ -16,7 +16,8 @@ host
ββββββββββ src
ββββββββββββ RootLayout.tsx
ββββββββββββ RootErrorBoundary.tsx
-ββββββββββββ useAppRouter.ts
+ββββββββββββ AppRouter.ts
+ββββββββββββ register.tsx
ββββββββββββ index.ts
ββββββββββ package.json
ββββββββββ tsup.dev.ts
@@ -46,44 +47,56 @@ First, create a new package (we'll refer to ours as `shell`) and add the followi
Then, install the package dependencies and configure the new package with [tsup](https://gsoft-inc.github.io/wl-web-configs/tsup/).
-Finally, create a `useAppRouter` hook in the shell package. Its purpose is to provide a **reusable router configuration** that can be utilized by both the host application and the isolated modules. By using this hook, modules developed in isolation can utilize the **same application shell and routing configuration** as the host application.
+Then, create a `AppRouter` component in the shell package to provide a **reusable router configuration** that can be utilized by both the host application and the isolated modules.
-```tsx shell/src/useAppRouter.tsx
-import { useMemo, useState } from "react";
-import { createBrowserRouter } from "react-router-dom";
-import { Route, useRoutes } from "@squide/react-router";
-import { RootErrorBoundary } from "./RootErrorBoundary";
-import { RootLayout } from "./RootLayout";
+```tsx shell/src/AppRouter.tsx
+import { useRoutes } from "@squide/react-router";
+import { useAreModulesReady } from "@squide/webpack-module-federation";
+import { useMemo } from "react";
+import { RouterProvider, createBrowserRouter } from "react-router-dom";
+
+export function AppRouter() {
+ const routes = useRoutes();
+
+ // Re-render the app once all the remotes are registered, otherwise the remotes routes won't be added to the router.
+ const areModulesReady = useAreModulesReady();
+
+ const router = useMemo(() => {
+ return createBrowserRouter(routes);
+ }, [routes]);
+
+ if (!areModulesReady) {
+ return Loading...
;
+ }
-export interface UseAppRouterOptions {
- rootRoutes?: Route[];
+ return (
+
+ );
}
+```
-export function useAppRouter({ rootRoutes = [] }: UseAppRouterOptions = {}) {
- // Reuse the same array reference through re-renders.
- const [memoizedRootRoutes] = useState(rootRoutes);
+Finally, create a local module to register the **application shell** that will also be utilized by the host application and the isolated modules:
- const routes = useRoutes();
+```tsx shell/src/register.tsx
+import { ManagedRoutes, type ModuleRegisterFunction, type Runtime } from "@squide/react-router";
+import { RootLayout } from "./RootLayout.tsx";
+import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
- const router = useMemo(() => {
- return createBrowserRouter([
+export const registerShell: ModuleRegisterFunction = runtime => {
+ runtime.registerRoute({
+ element: ,
+ children: [
{
- element: ,
+ errorElement: ,
children: [
- {
- errorElement: ,
- children: [
- ...routes
- ]
- }
+ ManagedRoutes
]
- },
- ...memoizedRootRoutes
- ]);
- }, [routes, memoizedRootRoutes]);
-
- return router;
-}
+ }
+ ]
+ }, {
+ hoist: true
+ });
+};
```
!!!info
@@ -102,37 +115,51 @@ Now, let's revisit the host application by first adding a dependency to the new
}
```
-Then, incorporate the newly introduced `useAppRouter` hook:
+Then, incorporate the newly introduced `AppRouter` component:
-```tsx !#9-16 host/src/App.tsx
-import { RouterProvider } from "react-router-dom";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
-import { useAppRouter } from "@sample/shell";
-import { Home } from "./Home.tsx";
+```tsx host/src/App.tsx
+import { AppRouter } from "@sample/shell";
export function App() {
- const isReady = useAreModulesReady();
+ return
+}
+```
- const router = useAppRouter({
- rootRoutes: [
- {
- index: true,
- element:
- }
- ]
- });
+And the `registerShell` function to setup the `RootLayout`, the `RootErrorBoundary` and any other shell assets:
- if (!isReady) {
- return Loading...
;
- }
+```tsx !#22 host/src/bootstrap.tsx
+import { createRoot } from "react-dom/client";
+import { ConsoleLogger, RuntimeContext, Runtime } from "@squide/react-router";
+import { registerRemoteModules, type RemoteDefinition } from "@squide/webpack-module-federation";
+import type { AppContext} from "@sample/shared";
+import { App } from "./App.tsx";
+import { registerHost } from "./register.tsx";
+import { registerShell } from "@sample/shell";
- return (
- Loading...}
- />
- );
-}
+const Remotes: RemoteDefinition[] = [
+ { url: "http://localhost:8081", name: "remote1" }
+];
+
+const runtime = new Runtime({
+ loggers: [new ConsoleLogger()]
+});
+
+const context: AppContext = {
+ name: "Demo application"
+};
+
+// Register the shell module.
+registerLocalModules([registerShell, registerHost], runtime, { context });
+
+registerRemoteModules(Remotes, runtime, { context });
+
+const root = createRoot(document.getElementById("root")!);
+
+root.render(
+
+
+
+);
```
## Setup a remote module
@@ -151,14 +178,16 @@ To begin, let's start by adding a dependency to the `@sample/shell` package:
Then, create the following files in the remote module application:
-``` !#2-3,7-9
+``` !#2-3,5-7,10-11
remote-module
βββ public
βββββ index.html
βββ src
+βββββββ dev
+βββββββββββ DevHome.tsx
+βββββββββββ register.tsx
βββββββ register.tsx
βββββββ Page.tsx
-βββββββ DevHome.tsx
βββββββ index.tsx
βββββββ App.tsx
βββ webpack.dev.js
@@ -167,14 +196,15 @@ remote-module
### index.tsx
-The `index.tsx` file is similar to the `bootstrap.tsx` file of an host application but, tailored for an isolated module. The key distinction is that, since the project is set up for local development, the module is registered with the [registerLocalModules](/reference/registration/registerLocalModules.md) function instead of the [registerRemoteModules](/reference/registration/registerRemoteModules.md) function:
+The `index.tsx` file is similar to the `bootstrap.tsx` file of an host application but, tailored for an isolated module. The key distinctions are that, since the project is set up for isolated development, the module is registered with the [registerLocalModules](/reference/registration/registerLocalModules.md) function instead of the [registerRemoteModules](/reference/registration/registerRemoteModules.md) function, and a new `registerDev` function is introduced to register the development homepage (which will be covered in an upcoming section):
-```tsx !#9-11,15 remote-module/src/index.tsx
-import { Suspense } from "react";
+```tsx !#10-12,16 remote-module/src/index.tsx
import { createRoot } from "react-dom/client";
import { ConsoleLogger, RuntimeContext, Runtime, registerLocalModules } from "@squide/react-router";
import { App } from "./App.tsx";
-import { register } from "./register.tsx";
+import { register as registerModule } from "./register.tsx";
+import { registerDev } from "./dev/register.tsx";
+import { registerShell } from "@sample/shell";
// Create the shell runtime.
// Services, loggers and sessionAccessor could be reuse through a shared packages or faked when in isolation.
@@ -184,44 +214,26 @@ const runtime = new Runtime({
// Registering the remote module as a static module because the "register" function
// is local when developing in isolation.
-registerLocalModules([register], runtime);
+registerLocalModules([registerModule, registerDev, registerShell], runtime);
const root = createRoot(document.getElementById("root")!);
root.render(
- Loading...}>
-
-
+
);
```
### App.tsx
-The `App.tsx` file uses the newly created `useAppRouter` hook to setup [React Router](https://reactrouter.com/) with the ``, the `` and the other shell assets:
+The `App.tsx` file uses the newly created `AppRouter` component to setup [React Router](https://reactrouter.com/):
-```tsx !#6-13 remote-module/src/App.tsx
-import { RouterProvider } from "react-router-dom";
-import { useAppRouter } from "@sample/shell";
-import { DevHome } from "./DevHome.tsx";
+```tsx remote-module/src/App.tsx
+import { AppRouter } from "@sample/shell";
export function App() {
- const router = useAppRouter({
- rootRoutes: [
- {
- index: true,
- element:
- }
- ]
- });
-
- return (
- Loading...}
- />
- );
+ return ;
}
```
@@ -229,7 +241,7 @@ export function App() {
The `DevHome` component purpose is strictly to serve as an `index` page when developing the remote module in isolation.
-```tsx remote-module/src/DevHome.tsx
+```tsx remote-module/src/dev/DevHome.tsx
function DevHome() {
return (
@@ -240,18 +252,32 @@ function DevHome() {
}
```
+To register the development homepage, let's create a new local module specifically for registering what is needed to develop the module in isolation:
+
+```tsx remote-module/src/dev/register.tsx
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { DevHome } from "./DevHome.tsx";
+
+export const registerDev: ModuleRegisterFunction
= runtime => {
+ runtime.registerRoute({
+ index: true,
+ element:
+ });
+}
+```
+
### Add a new CLI script
-Next, add a new `dev-local` script to the `package.json` file to start the local development server in **"isolation"**:
+Next, add a new `dev-isolated` script to the `package.json` file to start the local development server in **"isolation"**:
```json !#3 remote-module/package.json
{
"dev": "webpack serve --config webpack.dev.js",
- "dev-local": "cross-env LOCAL=true webpack serve --config webpack.dev.js",
+ "dev-isolated": "cross-env ISOLATED=true webpack serve --config webpack.dev.js",
}
```
-The `dev-local` script is similar to the `dev` script but introduces a `LOCAL` environment variable. This new environment variable will be utilized by the `webpack.dev.js` file to conditionally setup the development server for **local** development in **isolation** or to be consumed by a host application through the `/remoteEntry.js` entry point:
+The `dev-isolated` script is similar to the `dev` script but introduces a `ISOLATED` environment variable. This new environment variable will be utilized by the `webpack.dev.js` file to conditionally setup the development server for development in **isolation** or to be consumed by a host application through the `/remoteEntry.js` entry point:
### Configure webpack
@@ -280,7 +306,7 @@ extends @workleap/browserslist-config
#### `defineDevConfig`
-To configure webpack, open the `webpack.dev.js` file and update the configuration to incorporate the `LOCAL` environment variable and the [defineDevConfig](https://gsoft-inc.github.io/wl-web-configs/webpack/configure-dev/) function:
+To configure webpack, open the `webpack.dev.js` file and update the configuration to incorporate the `ISOLATED` environment variable and the [defineDevConfig](https://gsoft-inc.github.io/wl-web-configs/webpack/configure-dev/) function:
```js !#9,12 remote-module/webpack.dev.js
// @ts-check
@@ -291,7 +317,7 @@ import { swcConfig } from "./swc.dev.js";
let config;
-if (!process.env.LOCAL) {
+if (!process.env.ISOLATED) {
config = defineDevRemoteModuleConfig(swcConfig, "remote1", 8081);
} else {
config = defineDevConfig(swcConfig);
@@ -302,7 +328,7 @@ export default config;
### Try it :rocket:
-Start the remote module in isolation by running the `dev-local` script. The application shell should wrap the pages of the module and the default page should be `DevHome`.
+Start the remote module in isolation by running the `dev-isolated` script. The application shell should wrap the pages of the module and the default page should be `DevHome`.
## Setup a local module
@@ -324,16 +350,22 @@ npm install -D @workleap/webpack-configs @workleap/swc-configs @workleap/browser
```
+++
+!!!warning
+While you can use any package manager to develop an application with Squide, it is highly recommended that you use [PNPM](https://pnpm.io/) as the guides has been developed and tested with PNPM.
+!!!
+
Then, create the following files in the local module application:
-``` !#2-3,7-12
+``` !#2-3,5-7,10-11
local-module
βββ public
βββββββ index.html
βββ src
+βββββββ dev
+βββββββββββ DevHome.tsx
+βββββββββββ register.tsx
βββββββ register.tsx
βββββββ Page.tsx
-βββββββ DevHome.tsx
βββββββ index.tsx
βββββββ App.tsx
βββ .browserslistrc
@@ -350,9 +382,9 @@ This file is similar to the `index.tsx` file of the [remote module](#indextsx).
This file is similar to the `App.tsx` file of the [remote module](#apptsx).
-### DevHome.tsx
+### DevHome.tsx & registerDev
-This file is similar to the `DevHome.tsx` file of the [remote module](#devhometsx).
+These files are similar to the `dev/DevHome.tsx` and `dev/register.tsx` files of the [remote module](#devhometsx).
### Configure webpack
@@ -404,18 +436,18 @@ export default defineDevConfig(swcConfig);
### Add a new CLI script
-Next, add a new `dev-local` script to the `package.json` file to start the local development server:
+Next, add a new `dev-isolated` script to the `package.json` file to start the local development server:
```json local-module/package.json
{
- "dev-local": "webpack serve --config webpack.config.js"
+ "dev-isolated": "webpack serve --config webpack.config.js"
}
```
### Try it :rocket:
-Start the remote module in isolation by running the `dev-local` script. The application shell should wrap the pages of the module and the default page should be `DevHome`.
+Start the remote module in isolation by running the `dev-isolated` script. The application shell should wrap the pages of the module and the default page should be `DevHome`.
!!!info
-If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/sample).
+If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/samples/basic).
!!!
diff --git a/docs/guides/federated-tabs.md b/docs/guides/federated-tabs.md
index 549ee16f5..5dd030779 100644
--- a/docs/guides/federated-tabs.md
+++ b/docs/guides/federated-tabs.md
@@ -24,7 +24,7 @@ To construct this page while adhering to Squide constraint of exclusively permit
import { Suspense } from "react";
import { Link, Outlet } from "react-router-dom";
-export default function FederatedTabsLayout() {
+export function FederatedTabsLayout() {
return (
Every tab is registered by a different module.
@@ -45,27 +45,23 @@ export default function FederatedTabsLayout() {
In the previous code sample, the `FederatedTabsLayout` is similar to the `RootLayout` introduced in previous guides. However, the key distinction is that this layout is nested under the `/federated-tabs` URL segment. By nesting the layout under a specific path, it will only render when the user navigates to one of the federated tab pages (e.g. `/federated-tabs/tab-1`, `/federated-tabs/tab-2`, `/federated-tabs/tab-3`).
-To register the newly created layout as a nested layout, use the [registerRemoteModules](../reference/registration/registerRemoteModules.md) function:
+To register the newly created layout as a nested layout, use the [registerRoute](../reference/runtime/runtime-class.md#register-routes) function:
-```tsx !#8-9 remote-module-3/src/register.tsx
+```tsx !#7-8 remote-module-3/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { FederatedTabsLayout } from "./FederatedTabsLayout.tsx";
export const register: ModuleRegisterFunction
= runtime => {
- runtime.registerRoutes([
- {
- // Register the layout as a nested layout under the "/federated-tabs" URL segment.
- path: "/federated-tabs",
- element:
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/federated-tabs",
- label: "Federated tabs"
- }
- ]);
+ runtime.registerRoute({
+ // Register the layout as a nested layout under the "/federated-tabs" URL segment.
+ path: "/federated-tabs",
+ element:
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Federated tabs",
+ to: "/federated-tabs"
+ });
}
```
@@ -75,20 +71,20 @@ As a bonus, each individual tab will have its own dedicated URL! :partying_face:
## Create the tab routes
-Next, let's add the actual tab pages to the modules. To do so, we'll use the [layoutPath](../reference/runtime/runtime-class.md#register-routes-under-a-specific-nested-layout-route) option of the [registerRoutes](../reference/runtime/runtime-class.md#register-routes) function to register the routes under the `FederatedTabsLayout`:
+Next, let's add the actual tab pages to the modules. To do so, we'll use the [parentPath](../reference/runtime/runtime-class.md#register-nested-routes-under-an-existing-route) option of the [registerRoute](../reference/runtime/runtime-class.md#register-routes) function to register the routes under the `FederatedTabsLayout`:
-```tsx !#8,11 remote-module-1/src/register.tsx
+```tsx !#7,10 remote-module-1/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { Tab1 } from "./Tab1.tsx";
export const register: ModuleRegisterFunction = (runtime: Runtime) => {
- runtime.registerRoutes([
- {
- // Using "index: true" instead of a path because this is the default active tab.
- index: true
- element:
- }
- ], { layoutPath: "/federated-tabs" });
+ runtime.registerRoute({
+ // Using "index: true" instead of a path because this is the default active tab.
+ index: true
+ element:
+ }, {
+ parentPath: "/federated-tabs"
+ });
}
```
@@ -100,18 +96,18 @@ export function Tab1() {
}
```
-```tsx !#8,11 remote-module-2/src/register.tsx
+```tsx !#7,10 remote-module-2/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { Tab2 } from "./Tab2.tsx";
export const register: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- // The first part of the "path" must be the same as the nested layout path (FederatedTabsLayout).
- path: "/federated-tabs/tab-2"
- element:
- }
- ], { layoutPath: "/federated-tabs" });
+ runtime.registerRoute({
+ // The first part of the "path" must be the same as the nested layout path (FederatedTabsLayout).
+ path: "/federated-tabs/tab-2"
+ element:
+ }, {
+ parentPath: "/federated-tabs"
+ });
}
```
@@ -123,18 +119,18 @@ export function Tab2() {
}
```
-```tsx !#8,11 local-module/src/register.tsx
+```tsx !#7,10 local-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { Tab3 } from "./Tab3.tsx";
export const register: ModuleRegisterFunction = (runtime: Runtime) => {
- runtime.registerRoutes([
- {
- // The first part of the "path" must be the same as the nested layout path (FederatedTabsLayout).
- path: "/federated-tabs/tab-3"
- element:
- }
- ], { layoutPath: "/federated-tabs" });
+ runtime.registerRoute({
+ // The first part of the "path" must be the same as the nested layout path (FederatedTabsLayout).
+ path: "/federated-tabs/tab-3"
+ element:
+ }, {
+ parentPath: "/federated-tabs"
+ });
}
```
@@ -152,79 +148,79 @@ Now that the tabs have been registered, ensure that all four modules (including
Althought it's functional, there are still a few configurations needed since the modules are currently coupled by hardcoded URLs within the `FederatedTabsLayout`.
-To decouple the navigation items, similar to what is done for regular federated pages, we'll utilize the [registerNavigationItems](../reference/runtime/runtime-class.md#register-navigation-items) function. In this case, we'll also use the [menuId](../reference/runtime/runtime-class.md#register-navigation-items-for-a-specific-menu) option. Defining the `menuId` option will enable the `FederatedTabsLayout` to retrieve navigation items exclusively for the federated tab component.
+To decouple the navigation items, similar to what is done for regular federated pages, we'll utilize the [registerNavigationItem](../reference/runtime/runtime-class.md#register-navigation-items) function. In this case, we'll also use the [menuId](../reference/runtime/runtime-class.md#register-navigation-items-for-a-specific-menu) option. Defining the `menuId` option will enable the `FederatedTabsLayout` to retrieve navigation items exclusively for the federated tab component.
First, let's register the navigation items with the `menuId` option:
-```tsx !#20 remote-module-1/src/register.tsx
+```tsx !#19 remote-module-1/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { Tab1 } from "./Tab1.tsx";
export const register: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- // Using "index: true" instead of a path because this is the default active tab.
- index: true
- element:
- }
- ], { layoutPath: "/federated-tabs" });
-
- runtime.registerNavigationItems([
- {
- to: "/federated-tabs",
- label: "Tab 1"
- }
- // The menu id could be anything, in this example we are using the same path as the nested layout
- // path for convenience.
- ], { menuId: "/federated-tabs" });
+ runtime.registerRoute({
+ // Using "index: true" instead of a path because this is the default active tab.
+ index: true
+ element:
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Tab 1",
+ to: "/federated-tabs"
+ }, {
+ // The menu id could be anything, in this example we are using the same path as the nested layout
+ // path for convenience.
+ menuId: "/federated-tabs"
+ });
}
```
-```tsx !#20 remote-module-2/src/register.tsx
+```tsx !#19 remote-module-2/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { Tab2 } from "./Tab2.tsx";
export const register: ModuleRegisterFunction = (runtime: Runtime) => {
- runtime.registerRoutes([
- {
- // The first part of the "path" must be the same as the nested layout path (FederatedTabsLayout).
- path: "/federated-tabs/tab-2"
- element:
- }
- ], { layoutPath: "/federated-tabs" });
-
- runtime.registerNavigationItems([
- {
- to: "/federated-tabs/tab-2",
- label: "Tab 2"
- }
- // The menu id could be anything, in this example we are using the same path as the nested layout
- // path for convenience.
- ], { menuId: "/federated-tabs" });
+ runtime.registerRoute({
+ // The first part of the "path" must be the same as the nested layout path (FederatedTabsLayout).
+ path: "/federated-tabs/tab-2"
+ element:
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Tab 2",
+ to: "/federated-tabs/tab-2"
+ }, {
+ // The menu id could be anything, in this example we are using the same path as the nested layout
+ // path for convenience.
+ menuId: "/federated-tabs"
+ });
}
```
-```tsx !#20 local-module/src/register.tsx
+```tsx !#19 local-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { Tab3 } from "./Tab3.tsx";
export const register: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- // The first part of the "path" must be the same as the nested layout path (FederatedTabsLayout).
- path: "/federated-tabs/tab-3"
- element:
- }
- ], { layoutPath: "/federated-tabs" });
-
- runtime.registerNavigationItems([
- {
- to: "/federated-tabs/tab-3",
- label: "Tab 3"
- }
- // The menu id could be anything, in this example we are using the same path as the nested layout
- // path for convenience.
- ], { menuId: "/federated-tabs" });
+ runtime.registerRoute({
+ // The first part of the "path" must be the same as the nested layout path (FederatedTabsLayout).
+ path: "/federated-tabs/tab-3"
+ element:
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Tab 3",
+ to: "/federated-tabs/tab-3"
+ }, {
+ // The menu id could be anything, in this example we are using the same path as the nested layout
+ // path for convenience.
+ menuId: "/federated-tabs"
+ });
}
```
@@ -261,7 +257,7 @@ const renderSection: RenderSectionFunction = elements => {
);
};
-export default function FederatedTabsLayout() {
+export function FederatedTabsLayout() {
const navigationItems = useNavigationItems("/federated-tabs");
const renderedTabs = useRenderedNavigationItems(navigationItems, renderItem, renderSection);
@@ -283,28 +279,28 @@ export default function FederatedTabsLayout() {
Similarly to how the display order of regular navigation items can be configured, a federated tab position can be affected with the [priority](http://localhost:5000/wl-squide/reference/runtime/runtime-class/#sort-registered-navigation-items) property.
-To force `Tab 3` to be positioned first:
+To force `Tab 3` to be positioned first, we'll give him a priority of `999`:
-```tsx !#17 local-module/src/register.tsx
+```tsx !#16 local-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { Tab3 } from "./Tab3.tsx";
export const register: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- path: "/federated-tabs/tab-3"
- element:
- }
- ], { layoutPath: "/federated-tabs" });
-
- runtime.registerNavigationItems([
- {
- to: "/federated-tabs/tab-3",
- label: "Tab 3",
- // Highest priority goes first.
- priority: 999
- }
- ], { menuId: "/federated-tabs" });
+ runtime.registerRoute({
+ path: "/federated-tabs/tab-3"
+ element:
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Tab 3",
+ // Highest priority goes first.
+ $priority: 999,
+ to: "/federated-tabs/tab-3"
+ }, {
+ menuId: "/federated-tabs"
+ });
}
```
diff --git a/docs/guides/isolate-module-failures.md b/docs/guides/isolate-module-failures.md
index 5b69c32ea..3b0738d9f 100644
--- a/docs/guides/isolate-module-failures.md
+++ b/docs/guides/isolate-module-failures.md
@@ -14,7 +14,7 @@ Nevertheless, an application can get very close to iframes failure isolation by
In the following code sample, a `RootErrorBoundary` is declared below the `RootLayout` but above the routes of the module. By doing so, if a module encounters an unhandled error, the nested error boundary will only replace the section rendered by the `Outlet` component within the `RootLayout` rather than the entire page:
-```tsx !#16,20 host/src/App.tsx
+```tsx host/src/App.tsx
import { useMemo } from "react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { useAreModulesReady } from "@squide/webpack-module-federation";
@@ -23,35 +23,20 @@ import { RootLayout } from "./RootLayout.tsx";
import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
export function App() {
- const isReady = useAreModulesReady();
+ const areModulesReady = useAreModulesReady();
const routes = useRoutes();
const router = useMemo(() => {
- return createBrowserRouter({
- // Default layout.
- element: ,
- children: [
- {
- // Default error boundary.
- errorElement: ,
- children: [
- ...routes
- ]
- }
- ]
- });
+ return createBrowserRouter(routes);
}, [routes]);
- if (!isReady) {
+ if (!areModulesReady) {
return Loading...
;
}
return (
- Loading... }
- />
+
);
}
```
@@ -79,10 +64,34 @@ export function RootLayout() {
}
```
+```tsx !#8,12 host/src/register.tsx
+import { ManagedRoutes, type ModuleRegisterFunction, type Runtime } from "@squide/react-router";
+import { RootLayout } from "./RootLayout.tsx";
+import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
+
+export const registerHost: ModuleRegisterFunction = runtime => {
+ runtime.registerRoute({
+ // Default layout.
+ element: ,
+ children: [
+ {
+ // Default error boundary.
+ errorElement: ,
+ children: [
+ ManagedRoutes
+ ]
+ }
+ ]
+ }, {
+ hoist: true
+ });
+};
+```
+
By implementing this mechanism, the level of failure isolation achieved is **comparable** to that of an **iframes** or **subdomains** implementation. With this mechanism, failure isolation **is as good as** with an **iframes** or **subdomains** implementation.
!!!warning
-If your application is [hoisting pages](/reference/routing/useHoistedRoutes.md), it's important to note that they will be rendered outside of the host application's root error boundary. To prevent breaking the entire application when an hoisted page encounters unhandled errors, it is highly recommended to declare a React Router's `errorElement` property for each hoisted page.
+If your application is [hoisting pages](../reference/runtime/runtime-class.md#register-an-hoisted-route), it's important to note that they will be rendered outside of the host application's root error boundary. To prevent breaking the entire application when an hoisted page encounters unhandled errors, it is highly recommended to declare a React Router's `errorElement` property for each hoisted page.
!!!
## Try it :rocket:
@@ -90,5 +99,5 @@ If your application is [hoisting pages](/reference/routing/useHoistedRoutes.md),
Start the application in a development environment using the `dev` script. Update any of your application routes that is rendered under the newly created error boundary (e.g. that is not hoisted) and throw an `Error`. The error should be handled by the error boundary instead of breaking the whole application.
!!!info
-If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/sample/shell).
+If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/samples/basic/shell).
!!!
diff --git a/docs/guides/override-a-react-context.md b/docs/guides/override-a-react-context.md
index 209c8ac41..37205678d 100644
--- a/docs/guides/override-a-react-context.md
+++ b/docs/guides/override-a-react-context.md
@@ -9,43 +9,28 @@ In a federated application using [Module Federation](https://webpack.js.org/conc
Let's take a simple example using a `BackgroundColorContext`:
-```tsx !#16-21 host/src/App.tsx
-import { useAppRouter } from "@sample/shell";
+```tsx !#6,8 host/src/App.tsx
+import { AppRouter } from "@sample/shell";
import { BackgroundColorContext } from "@sample/shared";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
-import { RouterProvider } from "react-router-dom";
export function App() {
- const isReady = useAreModulesReady();
-
- const router = useAppRouter(sessionManager);
-
- if (!isReady) {
- return Loading...
;
- }
-
return (
- Loading... }
- />
+
);
}
```
-```tsx !#8 remote-module/src/register.tsx
+```tsx !#7 remote-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { ColoredPage } from "./ColoredPage.tsx";
export const register: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- path: "/colored-page",
- element:
- }
- ]);
+ runtime.registerRoute({
+ path: "/colored-page",
+ element:
+ });
}
```
@@ -69,22 +54,20 @@ In the previous code samples, the host application provides a value for the `Bac
Now, suppose the requirements change, and one remote module's pages need to have a `red` background. The context can be overriden for the remote module by declaring a new provider directly in the routes registration:
-```tsx !#10-12 remote-module/src/register.tsx
+```tsx !#9,11 remote-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { BackgroundColorContext } from "@sample/shared";
import { ColoredPage } from "./ColoredPage.tsx";
export const register: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- path: "/colored-page",
- element: (
-
-
-
- )
- }
- ]);
+ runtime.registerRoute({
+ path: "/colored-page",
+ element: (
+
+
+
+ )
+ });
}
```
@@ -92,7 +75,7 @@ export const register: ModuleRegisterFunction = runtime => {
Since there are multiple routes to setup with the new provider, an utility function can be extracted:
-```tsx !#6-12,18 remote-module/src/register.tsx
+```tsx !#6-12,17 remote-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { BackgroundColorContext } from "@sample/shared";
import { ColoredPage } from "./ColoredPage.tsx";
@@ -107,12 +90,10 @@ function withRedBackground(page: ReactElement) {
}
export const register: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- path: "/colored-page",
- element: withRedBackground( )
- }
- ]);
+ runtime.registerRoute({
+ path: "/colored-page",
+ element: withRedBackground( )
+ });
}
```
@@ -120,27 +101,14 @@ export const register: ModuleRegisterFunction = runtime => {
Let's consider a more specific use case where the host application declares a `ThemeContext` from Workleap's new design system, Hopper:
-```tsx !#16-21 host/src/App.tsx
-import { useAppRouter } from "@sample/shell";
+```tsx !#6,8 host/src/App.tsx
+import { AppRouter } from "@sample/shell";
import { ThemeContext } from "@hopper/components";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
-import { RouterProvider } from "react-router-dom";
export function App() {
- const isReady = useAreModulesReady();
-
- const router = useAppRouter(sessionManager);
-
- if (!isReady) {
- return Loading...
;
- }
-
return (
- Loading...}
- />
+
);
}
@@ -169,27 +137,25 @@ To update the host application without breaking the remote modules, the recommen
As `@hopper/components` expose the `ThemeContext`, the context must be re-declared in each remote module until every part of the federated application has been updated to the latest version of Hopper:
-```tsx !#6-12,18 remote-module/src/register.tsx
+```tsx !#6-12,17 remote-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import { ThemeContext } from "@hopper/components";
import { Page } from "./Page.tsx";
-import type { ReactElement } from "react";
+import type { ReactNode } from "react";
-function withHopperTheme(page: ReactElement) {
+function Providers({ children }: { children: ReactNode }) {
return (
- {page}
+ {children}
)
}
export const register: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- path: "/page",
- element: withHopperTheme( )
- }
- ]);
+ runtime.registerRoute({
+ path: "/page",
+ element:
+ });
}
```
diff --git a/docs/guides/override-the-host-layout.md b/docs/guides/override-the-host-layout.md
index aa47e091f..5aa1accbe 100644
--- a/docs/guides/override-the-host-layout.md
+++ b/docs/guides/override-the-host-layout.md
@@ -8,56 +8,40 @@ order: 100
In many applications, multiple pages often share a **common layout** that includes elements such as a navigation bar, a user profile menu, and a main content section. In a [React Router](https://reactrouter.com/en/main) application, this shared layout is commonly referred to as a `RootLayout`:
-
-```tsx !#16,21,24,30,36 host/src/App.tsx
-import { useMemo } from "react";
-import { createBrowserRouter, RouterProvider } from "react-router-dom";
-import { useRoutes } from "@squide/react-router";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
+```tsx !#10,13,17,19 host/src/register.tsx
+import { ManagedRoutes, type ModuleRegisterFunction, type Runtime } from "@squide/react-router";
+import { HomePage } from "./HomePage.tsx";
+import { AuthenticationBoundary } from "./AuthenticationBoundary.tsx";
import { RootLayout } from "./RootLayout.tsx";
import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
-import { AuthenticationBoundary } from "./AuthenticationBoundary.tsx";
-import { Home } from "./Home.tsx";
-export function App() {
- const isReady = useAreModulesReady();
-
- const routes = useRoutes();
-
- const router = useMemo(() => {
- return createBrowserRouter({
- // Pathless route to declare an authentication boundary.
- element: ,
+export const registerHost: ModuleRegisterFunction = runtime => {
+ runtime.registerRoute({
+ // Pathless route to declare an authentication boundary.
+ element: ,
+ children: [
+ // Pathless route to declare the root layout.
+ element: ,
children: [
- // Pathless route to declare the root layout.
- element: ,
- children: [
- {
- errorElement: ,
- children: [
- {
- index: "true",
- element:
- },
- ...routes
- ]
- }
- ]
+ {
+ // Pathless route to declare a root error boundary.
+ errorElement: ,
+ children: [
+ ManagedRoutes
+ ]
+ }
]
- });
- }, [routes]);
-
- if (!isReady) {
- return Loading...
;
- }
-
- return (
- Loading...}
- />
- );
-}
+ ]
+ }, {
+ // We will talk about this in the next section of this guide.
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ index: true,
+ element:
+ });
+};
```
```tsx host/src/RootLayout.tsx
@@ -87,9 +71,9 @@ export function RootLayout() {
}
```
-In the previous code sample, the `RootLayout` serves as the default layout for the home page as well as for every page (route) registered by a module.
+In the previous code sample, the `RootLayout` serves as the default layout for the homepage as well as for every page (route) registered by a module that are not nested with either the [parentPath](../reference/runtime/runtime-class.md#register-nested-routes-under-an-existing-route) or the [parentName](../reference/runtime/runtime-class.md#register-a-named-route) option.
-For most pages, this is the behavior expected by the author. However, for pages such as a login page, the default `RootLayout` isn't suitable because the page is not bound to a user session (the user is not even authenticated yet).
+For most pages, this is the behavior expected by the author. However, for pages such as a login, the default `RootLayout` isn't suitable because the page is not bound to a user session (the user is not even authenticated yet).
To accomodate pages that require a different layout, a mechanism is needed to move their route declaration at the root of the React Router [router instance](https://reactrouter.com/en/main/routers/create-browser-router), before the `RootLayout` is declared.
@@ -98,112 +82,56 @@ root
βββ Login page <---------------- Raise the page here
βββββ Authentication boundary
βββββββββ Root layout
-ββββββββββββ Home page
+ββββββββββββ Homepage
```
-## Hoist the module pages
+## Hoist a module pages
Package managers supporting workspaces such as Yarn and NPM call this mechanism "hoisting", which means "raise (something) by means of ropes and pulleys". This is exactly what we are trying to achieve here.
-Squide has a built-in [useHoistedRoutes](/reference/routing/useHoistedRoutes.md) hook capable of raising module routes marked as `hoist` at the root of the routes array, before the `RootLayout` declaration. Thus, an hoisted page will not be wrapped by the `RootLayout` and will have full control over its rendering.
+Squide has a built-in [hoist](../reference/runtime/runtime-class.md#register-an-hoisted-route) functionality capable of raising module routes marked as `hoist` at the root of the routes array, before the `RootLayout` declaration. Thus, an hoisted page will not be wrapped by the `RootLayout` (or the `AuthenticationBoundary`) and will have full control over its rendering.
-To hoist module pages, first transform the module routes with the `useHoistedRoutes` hook before creating the router instance:
+To hoist module pages, simple add the [hoist](../reference/runtime/runtime-class.md#register-an-hoisted-route) option to the route options at registration and optionally use a new layout:
-```tsx #15-34,38,42 host/src/App.tsx
-import { useMemo } from "react";
-import { createBrowserRouter, RouterProvider } from "react-router-dom";
-import { useRoutes, useHoistedRoutes, type Route } from "@squide/react-router";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
-import { RootLayout } from "./RootLayout.tsx";
-import { AuthenticationBoundary } from "./AuthenticationBoundary.tsx";
-import { Home } from "./Home.tsx";
-
-export function App() {
- const isReady = useAreModulesReady();
-
- const routes = useRoutes();
+```tsx !#9,12,22 local-module/src/register.tsx
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { LocalLayout } from "./LocalLayout.tsx";
+import { LocalErrorBoundary } from "./LocalErrorBoundary.tsx";
+import { LoginPage } from "./LoginPage.tsx";
- // Non hoisted routes will still be bound to the root layout.
- const wrapManagedRoutes = useCallback((managedRoutes: Route[]) => {
- return {
- element: ,
- children: [
- element: ,
+export function register: ModuleRegisterFunction(runtime) {
+ runtime.registerRoute({
+ path: "/login",
+ element: ,
+ children: [
+ {
+ errorElement: ,
children: [
{
- errorElement: ,
- children: [
- {
- index: "true",
- element:
- },
- ...routes
- ]
+ index: true,
+ element:
}
]
- ]
- };
- }, []);
-
- // Allow hoisted routes hoisted by modules to be rendered at the root of the router rather than
- // under the root layout.
- const hoistedRoutes = useHoistedRoutes(routes, wrapManagedRoutes);
-
- const router = useMemo(() => {
- return createBrowserRouter(hoistedRoutes);
- }, [hoistedRoutes]);
-
- if (!isReady) {
- return Loading...
;
- }
-
- return (
- Loading...}
- />
- );
+ }
+ ]
+ }, {
+ hoist: true
+ });
}
```
-Then, mark the pages as hoisted and optionally use a new layout:
-
-```tsx #12-13,16,19-20 local-module/src/register.tsx
-import { lazy } from "react";
-import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
-
-const LocalLayout = lazy(() => import("./LocalLayout.tsx"));
-const LocalErrorBoundary = lazy(() => import("./LocalErrorBoundary.tsx"));
-const Login = lazy(() => import("./Login.tsx"));
-
-export function register: ModuleRegisterFunction(runtime) {
- runtime.registerRoutes([
- {
- path: "/login",
- hoist: true,
- element: ,
- children: [
- {
- errorElement: ,
- children: [
- {
- index: true,
- element:
- }
- ]
- }
- ]
- }
- ]);
-}
-```
+!!!warning
+By declaring a page as hoisted, other parts of the application will not be isolated anymore from this page's failures as the page will be rendered outside of the host application's root error boundary. To **avoid breaking the entire application** when an hoisted page encounters unhandled errors, it is highly recommended to declare a React Router's [errorElement](https://reactrouter.com/en/main/route/error-element) property for each hoisted page.
+!!!
-[!ref text="For additional options, go to the `useHoistedRoutes` hook reference page"](/reference/routing/useHoistedRoutes.md)
+!!!warning
+By declaring a page as hoisted, the page will be rendered at the root of the router, therefore, most certainly outside the authenticated boundary of the application. If the hoisted page requires an authentication, make sure to **wrap the page with an authentication boundary** or to handle the authentication within the page.
+!!!
## Try it :rocket:
Start the application in a development environment using the `dev` script and navigate to the `/login` page. The page should be displayed even if you are not authenticated.
!!!info
-If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/sample/shell).
+If you are having issues with this guide, have a look at a working example on [GitHub](https://github.com/gsoft-inc/wl-squide/tree/main/samples/basic/shell).
!!!
diff --git a/docs/reference/default.md b/docs/reference/default.md
index 25db4f803..0b74801d3 100644
--- a/docs/reference/default.md
+++ b/docs/reference/default.md
@@ -20,8 +20,6 @@ expanded: true
- [useRoutes](runtime/useRoutes.md)
- [useNavigationItems](runtime/useNavigationItems.md)
- [useLogger](runtime/useLogger.md)
-- [useService](runtime/useService.md)
-- [useServices](runtime/useServices.md)
- [useSession](runtime/useSession.md)
### Registration
@@ -33,8 +31,10 @@ expanded: true
### Routing
-- [useHoistedRoutes](routing/useHoistedRoutes.md)
+- [ManagedRoutes](routing/ManagedRoutes.md)
- [useRenderedNavigationItems](routing/useRenderedNavigationItems.md)
+- [useRouteMatch](routing/useRouteMatch.md)
+- [useIsRouteMatchProtected](routing/useIsRouteMatchProtected.md)
### Logging
@@ -51,13 +51,24 @@ expanded: true
- [useIsAuthenticated](session/useIsAuthenticated.md)
-### Webpack
+### Plugins
+
+- [Plugin](plugins/plugin.md)
+
+### webpack
- [defineDevHostConfig](webpack/defineDevHostConfig.md)
- [defineDevRemoteModuleConfig](webpack/defineDevRemoteModuleConfig.md)
- [defineBuildHostConfig](webpack/defineBuildHostConfig.md)
- [defineBuildRemoteModuleConfig](webpack/defineBuildRemoteModuleConfig.md)
+### Mock Service Worker
+
+- [MswPlugin](msw/MswPlugin.md)
+- [getMswPlugin](msw/getMswPlugin.md)
+- [useIsMswReady](msw/useIsMswReady.md)
+- [setMswAsStarted](msw/setMswAsStarted.md)
+
## Fakes
Squide offers a collection of fake implementations to facilitate the development of modules in isolation from the other parts of the application.
diff --git a/docs/reference/fakes/index.yaml b/docs/reference/fakes/index.yaml
index abb084c44..ebcd7d934 100644
--- a/docs/reference/fakes/index.yaml
+++ b/docs/reference/fakes/index.yaml
@@ -1 +1 @@
-order: 30
+order: -10
diff --git a/docs/reference/logging/Logger.md b/docs/reference/logging/Logger.md
index 5a503521d..c1473975c 100644
--- a/docs/reference/logging/Logger.md
+++ b/docs/reference/logging/Logger.md
@@ -1,18 +1,15 @@
----
-toc:
- depth: 2-3
----
-
# Logger
-A basic logger interface.
+An abstract base class to define a logger.
## Usage
+### Define a custom logger
+
```ts
import { Logger } from "@squide/react-router";
-class CustomLogger: Logger {
+export class CustomLogger: Logger {
debug(log) { ... }
information(log) { ... }
warning(log) { ... }
diff --git a/docs/reference/msw/MswPlugin.md b/docs/reference/msw/MswPlugin.md
new file mode 100644
index 000000000..2166e5234
--- /dev/null
+++ b/docs/reference/msw/MswPlugin.md
@@ -0,0 +1,63 @@
+---
+order: 100
+toc:
+ depth: 2-3
+---
+
+# MswPlugin
+
+A plugin to faciliate the integration of [Mock Service Worker](https://mswjs.io/) (MSW) in a federated application.
+
+> MSW doesn't support having multiple remote modules starting their own service worker as MSW request handlers must be registered to a **service worker that is on the same host as the originator of an HTTP request** (which would always be the host application for a federated application). To circumvent this limitation, `@squide/msw` offers a shared registry to modules, allowing them to register their request handlers in a way that makes them available to the host application. The host application can then retrieve the request handlers registered by the modules and register them to it's own MSW.
+
+## Reference
+
+```ts
+const mswPlugin = new MswPlugin();
+```
+
+### Parameters
+
+None
+
+## Usage
+
+!!!info
+Do not include MSW in production code. To address this, we recommend conditionally importing the code using the [msw](https://www.npmjs.com/package/msw) package based on an environment variable.
+!!!
+
+### Register the plugin
+
+```ts !#7
+import { MswPlugin } from "@squide/msw";
+import { Runtime } from "@squide/react-router";
+
+const mswPlugin = new MswPlugin();
+
+const runtime = new Runtime({
+ plugins: [mswPlugin]
+});
+```
+
+### Register request handlers
+
+```ts !#10
+import { getMswPlugin } from "@squide/msw";
+
+if (process.env.USE_MSW) {
+ const mswPlugin = getMswPlugin(runtime);
+
+ // Files including an import to the "msw" package are included dynamically to prevent adding
+ // MSW stuff to the bundled when it's not used.
+ const requestHandlers = (await import("../mocks/handlers.ts")).requestHandlers;
+
+ mswPlugin.registerRequestHandlers(requestHandlers);
+}
+```
+
+### Retrieve the request handlers
+
+```ts
+const handlers = mswPlugin.requestHandlers;
+```
+
diff --git a/docs/reference/msw/getMswPlugin.md b/docs/reference/msw/getMswPlugin.md
new file mode 100644
index 000000000..bc889855c
--- /dev/null
+++ b/docs/reference/msw/getMswPlugin.md
@@ -0,0 +1,30 @@
+---
+toc:
+ depth: 2-3
+---
+
+# getMswPlugin
+
+Return an instance of the [MswPlugin](./MswPlugin.md) from the list of plugins registered in the [Runtime](../runtime/runtime-class.md) instance.
+
+## Reference
+
+```ts
+const plugin = getMswPlugin(runtime)
+```
+
+### Parameters
+
+- `runtime`: A runtime instance.
+
+### Returns
+
+An `MswPlugin` instance if the plugin has been registered, otherwise an `Error` is thrown.
+
+## Usage
+
+```ts
+import { getMswPlugin } from "@squide/msw";
+
+const plugin = getMswPlugin(runtime);
+```
diff --git a/docs/reference/msw/index.yaml b/docs/reference/msw/index.yaml
new file mode 100644
index 000000000..c4fd78ca1
--- /dev/null
+++ b/docs/reference/msw/index.yaml
@@ -0,0 +1,2 @@
+order: 0
+label: "Mock Service Worker"
diff --git a/docs/reference/msw/setMswAsStarted.md b/docs/reference/msw/setMswAsStarted.md
new file mode 100644
index 000000000..6b45178a1
--- /dev/null
+++ b/docs/reference/msw/setMswAsStarted.md
@@ -0,0 +1,27 @@
+# setMswAsStarted
+
+Indicates to the [useIsMswStarted](./useIsMswReady.md) hook that [Mock Service Worker](https://mswjs.io/) (MSW) is started and the application can safely be rendered.
+
+## Reference
+
+```ts
+setMswAsStarted()
+```
+
+### Parameters
+
+None
+
+### Returns
+
+Nothing
+
+## Usage
+
+```ts
+import { setMswAsStarted } from "@squide/msw";
+
+setMswAsStarted();
+```
+
+[!ref Also take a look at the `useIsMswReady` hook](./useIsMswReady.md)
diff --git a/docs/reference/msw/useIsMswReady.md b/docs/reference/msw/useIsMswReady.md
new file mode 100644
index 000000000..984de7695
--- /dev/null
+++ b/docs/reference/msw/useIsMswReady.md
@@ -0,0 +1,29 @@
+# useIsMswReady
+
+Force the application to re-render once [Mock Service Worker](https://mswjs.io/) (MSW) is started. Without this hook, the page is rendered before all the request handlers are registered to MSW which could results in 404 errors.
+
+## Reference
+
+```ts
+const isMswReady = useIsMswReady(enabled, { interval })
+```
+
+### Parameters
+
+- `enabled`: Whether or not MSW is currently enabled for the application. This is especially useful to ensure the application is not waiting for MSW when in production.
+- `options`: An optional object literal of options:
+ - `interval`: The interval in milliseconds at which the hook is validating if MSW is started.
+
+### Returns
+
+A boolean indicating if MSW is started.
+
+## Usage
+
+```ts
+import { useIsMswStarted } from "@squide/msw";
+
+const isMswStarted = useIsMswStarted(process.env.USE_MSW);
+```
+
+[!ref Also take a look at the `setIsMswAsStarted` function](./setMswAsStarted.md)
diff --git a/docs/reference/packages.md b/docs/reference/packages.md
index dcc53c44e..c8bddba83 100644
--- a/docs/reference/packages.md
+++ b/docs/reference/packages.md
@@ -19,4 +19,5 @@ order: 200
| :icon-mark-github: [@squide/core](https://github.com/gsoft-inc/wl-squide/tree/main/packages/core) | Core functionalities of Squide. | [![npm version](https://img.shields.io/npm/v/@squide/core)](https://www.npmjs.com/package/@squide/core) |
| :icon-mark-github: [@squide/react-router](https://github.com/gsoft-inc/wl-squide/tree/main/packages/react-router) | Specific implementation of the core functionalities to support [React Router](https://reactrouter.com/en/main). | [![npm version](https://img.shields.io/npm/v/@squide/react-router)](https://www.npmjs.com/package/@squide/react-router) |
| :icon-mark-github: [@squide/webpack-module-federation](https://github.com/gsoft-inc/wl-squide/tree/main/packages/webpack-module-federation) | Add support for [Module Federation](https://webpack.js.org/concepts/module-federation/). | [![npm version](https://img.shields.io/npm/v/@squide/webpack-module-federation)](https://www.npmjs.com/package/@squide/webpack-module-federation) |
+| :icon-mark-github: [@squide/msw](https://github.com/gsoft-inc/wl-squide/tree/main/packages/msw) | Add support for [MSW](https://mswjs.io/). | [![npm version](https://img.shields.io/npm/v/@squide/msw)](https://www.npmjs.com/package/@squide/msw) |
| :icon-mark-github: [@squide/fakes](https://github.com/gsoft-inc/wl-squide/tree/main/packages/fakes) | A collection of fake implementations to facilitate the development of federated modules. | [![npm version](https://img.shields.io/npm/v/@squide/fakes)](https://www.npmjs.com/package/@squide/fakes) |
diff --git a/docs/reference/plugins/index.yaml b/docs/reference/plugins/index.yaml
new file mode 100644
index 000000000..8149a5c67
--- /dev/null
+++ b/docs/reference/plugins/index.yaml
@@ -0,0 +1,2 @@
+order: 20
+label: "Plugins"
diff --git a/docs/reference/plugins/plugin.md b/docs/reference/plugins/plugin.md
new file mode 100644
index 000000000..748f232c0
--- /dev/null
+++ b/docs/reference/plugins/plugin.md
@@ -0,0 +1,80 @@
+---
+toc:
+ depth: 2-3
+---
+
+# Plugin
+
+An abstract base class to define a plugin.
+
+## Usage
+
+### Define a plugin
+
+```ts !#4 shared/src/mswPlugin.ts
+import { Plugin } from "@squide/react-router";
+import type { RestHandler } from "msw";
+
+export class MswPlugin extends Plugin {
+ constructor() {
+ super(MswPlugin.name);
+ }
+
+ registerRequestHandlers(handlers: RestHandler[]) {
+ ...
+ }
+}
+```
+
+### Register a plugin
+
+```ts !#5
+import { Runtime } from "@squide/react-router";
+import { MswPlugin } from "@squide/msw";
+
+const runtime = new Runtime({
+ plugins: [new MswPlugin()]
+});
+```
+
+### Retrieve a plugin from a runtime instance
+
+```ts !#4
+import { MswPlugin } from "@sample/shared";
+import { requetHandlers } from "../mocks/handlers.ts";
+
+const mswPlugin = runtime.getPlugin(MswPlugin.name) as MswPlugin;
+
+mswPlugin.registerRequestHandlers(requetHandlers);
+```
+
+### Retrieve a plugin with a custom function
+
+We recommend pairing a plugin definition with a custom function to retrieve the plugin from a runtime instance.
+
+```ts !#14-16 shared/src/mswPlugin.ts
+import { Plugin, type Runtime } from "@squide/react-router";
+import type { RestHandler } from "msw";
+
+export class MswPlugin extends Plugin {
+ constructor() {
+ super(MswPlugin.name);
+ }
+
+ registerRequestHandlers(handlers: RestHandler[]) {
+ ...
+ }
+}
+
+export function getMswPlugin(runtime: Runtime) {
+ return runtime.getPlugin(MswPlugin.name);
+}
+```
+
+```ts
+import { getMswPlugin } from "@sample/shared";
+
+const mswPlugin = getMswPlugin(runtime);
+```
+
+Retrieving a plugin with a custom function doesn't require the consumer to remember the plugin name, and has the upside of inferring the typings.
diff --git a/docs/reference/registration/registerLocalModules.md b/docs/reference/registration/registerLocalModules.md
index b2a838bc4..079131342 100644
--- a/docs/reference/registration/registerLocalModules.md
+++ b/docs/reference/registration/registerLocalModules.md
@@ -24,10 +24,15 @@ registerLocalModules(registerFunctions: [], runtime, options?: { context? })
### Returns
-Nothing
+A `Promise` object with an array of `LocalModuleRegistrationError` if any error happens during the registration.
+
+- `LocalModuleRegistrationError`:
+ - `error`: The original error object.
## Usage
+### Register a local module
+
```tsx !#11 host/src/bootstrap.tsx
import { registerLocalModules, Runtime } from "@squide/react-router";
import { register } from "@sample/local-module";
@@ -42,26 +47,40 @@ const context: AppContext = {
registerLocalModules([register], runtime, { context });
```
-```tsx !#7-21 local-module/src/register.tsx
-import { lazy } from "react";
+```tsx !#5-15 local-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import type { AppContext } from "@sample/shared";
-
-const About = lazy(() => import("./About.tsx"));
+import { About } from "./About.tsx";
export function register: ModuleRegisterFunction(runtime, context) {
- runtime.registerRoutes([
- {
- path: "/about",
- element:
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/about",
- label: "About"
- }
- ]);
+ runtime.registerRoute({
+ path: "/about",
+ element:
+ });
+
+ runtime.registerNavigationItem({
+ $label: "About",
+ to: "/about"
+ });
}
```
+
+### Handle the registration errors
+
+```tsx !#11-15 host/src/bootstrap.tsx
+import { registerLocalModules, Runtime } from "@squide/react-router";
+import { register } from "@sample/local-module";
+import type { AppContext } from "@sample/shared";
+
+const runtime = new Runtime();
+
+const context: AppContext = {
+ name: "Test app"
+};
+
+registerLocalModules([register], runtime, { context }).then(errors => {
+ errors.forEach(x => {
+ console.log(x);
+ });
+});
+```
diff --git a/docs/reference/registration/registerRemoteModules.md b/docs/reference/registration/registerRemoteModules.md
index c337d11ff..35b3848a8 100644
--- a/docs/reference/registration/registerRemoteModules.md
+++ b/docs/reference/registration/registerRemoteModules.md
@@ -24,9 +24,9 @@ registerRemoteModules(remotes: [], runtime, options?: { context? })
### Returns
-A `Promise` object with an array of `RegistrationError` if any happens during the registration.
+A `Promise` object with an array of `RemoteModuleRegistrationError` if any error happens during the registration.
-- `RegistrationError`:
+- `RemoteModuleRegistrationError`:
- `url`: The URL of the module federation remote that failed to load.
- `containerName`: The name of the [dynamic container](https://webpack.js.org/concepts/module-federation/#dynamic-remote-containers) that Squide attempted to recover.
- `moduleName`: The name of the [module](#name) that Squide attempted to recover.
@@ -34,6 +34,8 @@ A `Promise` object with an array of `RegistrationError` if any happens during th
## Usage
+### Register a remote module
+
```tsx !#11-13,15 host/src/bootstrap.tsx
import { Runtime } from "@squide/react-router";
import { registerRemoteModules, type RemoteDefinition } from "@squide/webpack-module-federation";
@@ -52,35 +54,53 @@ const Remotes: RemoteDefinition = [
registerRemoteModules(Remotes, runtime, { context });
```
-```tsx !#7-21 remote-module/src/register.tsx
-import { lazy } from "react";
+```tsx !#5-15 remote-module/src/register.tsx
import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
import type { AppContext } from "@sample/shared";
-
-const About = lazy(() => import("./About.tsx"));
+import { About } from "./About.tsx";
export function register: ModuleRegisterFunction(runtime, context) {
- runtime.registerRoutes([
- {
- path: "/about",
- element:
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/about",
- label: "About"
- }
- ]);
+ runtime.registerRoute({
+ path: "/about",
+ element:
+ });
+
+ runtime.registerNavigationItem({
+ $label: "About",
+ to: "/about"
+ });
}
```
+### Handle the registration errors
+
+```tsx !#15-19 host/src/bootstrap.tsx
+import { Runtime } from "@squide/react-router";
+import { registerRemoteModules, type RemoteDefinition } from "@squide/webpack-module-federation";
+import type { AppContext } from "@sample/shared";
+
+const runtime = new Runtime();
+
+const context: AppContext = {
+ name: "Test app"
+};
+
+const Remotes: RemoteDefinition = [
+ { name: "remote1", url: "http://localhost:8081" }
+];
+
+registerRemoteModules(Remotes, runtime, { context }).then(errors => {
+ errors.forEach(x => {
+ console.log(x);
+ });
+});
+```
+
## Remote definition
To ease the configuration of remote modules, make sure that you first import the `RemoteDefinition` type and assign it to your remote definitions array declaration.
-```ts !#3
+```ts !#3 host/src/bootstrap.tsx
import type { RemoteDefinition } from "@squide/webpack-module-federation";
const Remotes: RemoteDefinition = [
diff --git a/docs/reference/registration/useAreModulesReady.md b/docs/reference/registration/useAreModulesReady.md
index 88b838039..5f2efba4f 100644
--- a/docs/reference/registration/useAreModulesReady.md
+++ b/docs/reference/registration/useAreModulesReady.md
@@ -10,7 +10,7 @@ Force the application to re-render once all the modules are registered. Without
## Reference
```ts
-const isReady = useAreModulesReady(options?: { interval? })
+const areModulesReady = useAreModulesReady(options?: { interval? })
```
### Parameters
@@ -57,7 +57,7 @@ export function App() {
// Re-render the application once all the modules are registered.
// Otherwise, the remotes routes won't be added to the router as the router will be
// rendered before the remote modules registered their routes.
- const isReady = useAreModulesReady();
+ const areModulesReady = useAreModulesReady();
const routes = useRoutes();
@@ -65,7 +65,7 @@ export function App() {
return createBrowserRouter(routes);
}, [routes]);
- if (!isReady) {
+ if (!areModulesReady) {
return Loading...
;
}
diff --git a/docs/reference/routing/ManagedRoutes.md b/docs/reference/routing/ManagedRoutes.md
new file mode 100644
index 000000000..997e4ef44
--- /dev/null
+++ b/docs/reference/routing/ManagedRoutes.md
@@ -0,0 +1,59 @@
+---
+toc:
+ depth: 2-3
+---
+
+# ManagedRoutes
+
+A placeholder indicating where in the routing tree should the managed routes be rendered. The `ManagedRoutes` placeholder concept is similar to React Router's [outlet](https://reactrouter.com/en/main/components/outlet), it's a pipeline to inject routes at a predetermined location.
+
+> A managed route is a route that is neither [hoisted](../runtime/runtime-class.md#register-an-hoisted-route) or nested with a [parentPath](../runtime/runtime-class.md#register-nested-routes-under-an-existing-route) or [parentName](../runtime/runtime-class.md#register-a-named-route) option.
+
+## Reference
+
+```tsx
+runtime.registerRoute({
+ children: [
+ ManagedRoutes
+ ]
+}, { hoist: true });
+```
+
+### Parameters
+
+None
+
+## Usage
+
+The registration of the route including the `ManagedRoutes` placeholder must be [hoisted](../runtime/runtime-class.md#register-an-hoisted-route), otherwise there will be an infinite loop as the placeholder will render in the placeholder.
+
+```tsx !#20,27 shell/src/register.tsx
+import { ManagedRoutes } from "@squide/react-router";
+import { RootLayout } from "./RootLayout.tsx";
+import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
+import { AuthenticatedLayout } from "./AuthenticatedLayout.tsx";
+
+runtime.registerRoute({
+ // Pathless route to declare a root layout.
+ $visibility: "public",
+ element: ,
+ children: [
+ {
+ // Pathless route to declare a root error boundary.
+ $visibility: "public",
+ errorElement: ,
+ children: [
+ {
+ // Pathless route to declare an authenticated layout.
+ element:
+ children: [
+ ManagedRoutes
+ ]
+ }
+ ]
+ }
+ ]
+}, {
+ hoist: true
+});
+```
diff --git a/docs/reference/routing/useHoistedRoutes.md b/docs/reference/routing/useHoistedRoutes.md
deleted file mode 100644
index d1348e356..000000000
--- a/docs/reference/routing/useHoistedRoutes.md
+++ /dev/null
@@ -1,328 +0,0 @@
----
-toc:
- depth: 2-3
----
-
-# useHoistedRoutes
-
-Allow modules to register pages outside of the host application's elements boundary. Unlike a regular page, an hoisted page is added at the root of the router, meaning before the host application root layout, root error boundary and even root authentication boundary. Thus, an hoisted page has full control over its rendering.
-
-!!!warning
-By declaring a page as hoisted, other parts of the application will not be isolated anymore from this page's failures as the page will be rendered outside of the host application's root error boundary. To avoid breaking the entire application when an hoisted page encounters unhandled errors, it is highly recommended to declare a React Router's [errorElement](https://reactrouter.com/en/main/route/error-element) property for each hoisted page.
-!!!
-
-## Reference
-
-```ts
-const hoistedRoutes = useHoistedRoutes(routes: [], wrapManagedRoutes: () => {}, options?: { allowedPaths?: [] })
-```
-
-### Parameters
-
-- `routes`: An array of `Route` to process.
-- `wrapManagedRoutes`: A function nesting the managed routes under React elements such as a layout, an error boundary or an authentication boundary.
-- `options`: An optional object literal of options:
- - `allowedPaths`: An optional array of exclusive route paths available for hosting.
-
-### Returns
-
-An array of `Route`.
-
-## Usage
-
-### Hoist a module page
-
-```tsx !#13-27,31,35 host/src/App.tsx
-import { useCallback, useMemo } from "react";
-import { createBrowserRouter, RouterProvider } from "react-router-dom";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
-import { useRoutes, useHoistedRoutes, type Route } from "@squide/react-router";
-import { RootLayout } from "./RootLayout.tsx";
-import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
-
-export function App() {
- const isReady = useAreModulesReady();
-
- const routes = useRoutes();
-
- const wrapManagedRoutes = useCallback((managedRoutes: Route[]) => {
- return {
- // Default layout.
- element: ,
- children: [
- {
- // Default error boundary.
- errorElement: ,
- children: [
- ...managedRoutes
- ]
- }
- ]
- };
- }, []);
-
- // Allow hoisted routes to be rendered at the root of the router rather than
- // under the default layout and error boundary.
- const hoistedRoutes = useHoistedRoutes(routes, wrapManagedRoutes);
-
- const router = useMemo(() => {
- return createBrowserRouter(hoistedRoutes);
- }, [hoistedRoutes]);
-
- if (!isReady) {
- return Loading...
;
- }
-
- return (
- Loading...}
- />
- );
-}
-```
-
-```tsx !#11-12 remote-module/src/register.tsx
-import { lazy } from "react";
-import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
-
-const RemoteErrorBoundary = lazy(() => import("./RemoteErrorBoundary.tsx"));
-const About = lazy(() => import("./About.tsx"));
-
-export function register: ModuleRegisterFunction(runtime) {
- runtime.registerRoutes([
- {
- path: "/about",
- element: ,
- errorElement:
- hoist: true
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/about",
- label: "About"
- }
- ]);
-}
-```
-
-### Register a module page with a different layout
-
-!!!info
-For a detailed walkthrough, read the guide on [how to override the host layout](/guides/override-the-host-layout.md).
-!!!
-
-```tsx !#15,18 host/src/App.tsx
-import { useCallback, useMemo } from "react";
-import { createBrowserRouter, RouterProvider } from "react-router-dom";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
-import { useRoutes, useHoistedRoutes, type Route } from "@squide/react-router";
-import { RootLayout } from "./RootLayout.tsx";
-import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
-
-export function App() {
- const isReady = useAreModulesReady();
-
- const routes = useRoutes();
-
- const wrapManagedRoutes = useCallback((managedRoutes: Route[]) => {
- return {
- element: ,
- children: [
- {
- errorElement: ,
- children: [
- ...managedRoutes
- ]
- }
- ]
- };
- }, []);
-
- const hoistedRoutes = useHoistedRoutes(routes, wrapManagedRoutes);
-
- const router = useMemo(() => {
- return createBrowserRouter(hoistedRoutes);
- }, [hoistedRoutes]);
-
- if (!isReady) {
- return Loading...
;
- }
-
- return (
- Loading...}
- />
- );
-}
-```
-
-```tsx !#12,15,18,21-22 remote-module/src/register.tsx
-import { lazy } from "react";
-import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
-
-const RemoteLayout = lazy(() => import("./RemoteLayout.tsx"));
-const RemoteErrorBoundary = lazy(() => import("./RemoteErrorBoundary.tsx"));
-const About = lazy(() => import("./About.tsx"));
-
-export function register: ModuleRegisterFunction(runtime) {
- runtime.registerRoutes([
- {
- path: "/about",
- hoist: true,
- // Will render the "About" page inside the "RemoteLayout" rather than the "RootLayout".
- // For more information about React Router's nested routes, view https://reactrouter.com/en/main/start/tutorial#nested-routes.
- element: ,
- children: [
- {
- errorElement: ,
- children: [
- {
- index: true,
- element:
- }
- ]
- }
- ]
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/about",
- label: "About"
- }
- ]);
-}
-```
-
-### Register a public page
-
-```tsx #17 host/src/App.tsx
-import { useCallback, useMemo } from "react";
-import { createBrowserRouter, RouterProvider } from "react-router-dom";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
-import { useRoutes, useHoistedRoutes, type Route } from "@squide/react-router";
-import { AuthenticationBoundary } from "./AuthenticationBoundary.tsx";
-import { RootLayout } from "./RootLayout.tsx";
-import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
-
-export function App() {
- const isReady = useAreModulesReady();
-
- const routes = useRoutes();
-
- const wrapManagedRoutes = useCallback((managedRoutes: Route[]) => {
- return {
- // Every pages under the authentication boundary requires authentication.
- element: ,
- children: [
- {
- element: ,
- children: [
- {
- errorElement: ,
- children: [
- ...managedRoutes
- ]
- }
- ]
- }
- ]
- };
- }, []);
-
- const hoistedRoutes = useHoistedRoutes(routes, wrapManagedRoutes);
-
- const router = useMemo(() => {
- return createBrowserRouter(hoistedRoutes);
- }, [hoistedRoutes]);
-
- if (!isReady) {
- return Loading...
;
- }
-
- return (
- Loading...}
- />
- );
-}
-```
-
-```tsx !#11-12,15 remote-module/src/register.tsx
-import { lazy } from "react";
-import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
-
-const RemoteErrorBoundary = lazy(() => import("./RemoteErrorBoundary.tsx"));
-const Login = lazy(() => import("./Login.tsx"));
-
-export function register: ModuleRegisterFunction(runtime) {
- runtime.registerRoutes([
- {
- path: "/login",
- element: ,
- errorElement: ,
- // By hoisting the "Login" page, it will now be rendered outside of the default
- // authenticated boundary and will therefore be public.
- hoist: true
- }
- ]);
-}
-```
-
-### Allowing an exclusive set of routes to be hoisted
-
-```tsx !#26-29 host/src/App.tsx
-import { useCallback, useMemo } from "react";
-import { createBrowserRouter, RouterProvider } from "react-router-dom";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
-import { useRoutes, useHoistedRoutes, type Route } from "@squide/react-router";
-import { RootLayout } from "./RootLayout.tsx";
-import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
-
-export function App() {
- const isReady = useAreModulesReady();
-
- const routes = useRoutes();
-
- const wrapManagedRoutes = useCallback((managedRoutes: Route[]) => {
- return {
- element: ,
- errorElement: ,
- children: [
- ...managedRoutes
- ]
- };
- }, []);
-
- const hoistedRoutes = useHoistedRoutes(routes, wrapManagedRoutes, {
- // Only the following route paths can be hoisted by modules.
- // When a page not included in the allowed paths is hoisted, an Error is thrown at rendering.
- allowedPaths: [
- "/about",
- "/another-page"
- ]
- });
-
- const router = useMemo(() => {
- return createBrowserRouter(hoistedRoutes);
- }, [hoistedRoutes]);
-
- if (!isReady) {
- return Loading...
;
- }
-
- return (
- Loading...}
- />
- );
-}
-```
-
diff --git a/docs/reference/routing/useIsRouteMatchProtected.md b/docs/reference/routing/useIsRouteMatchProtected.md
new file mode 100644
index 000000000..e06d537e4
--- /dev/null
+++ b/docs/reference/routing/useIsRouteMatchProtected.md
@@ -0,0 +1,42 @@
+---
+toc:
+ depth: 2-3
+---
+
+# useIsRouteMatchProtected
+
+Execute [React Router's matching algorithm](https://reactrouter.com/en/main/utils/match-routes) against the registered routes and a given `location` to determine if any route match the location and whether or not that matching route is protected.
+
+## Reference
+
+```ts
+const isProtected = useIsRouteMatchProtected(locationArg)
+```
+
+### Parameters
+
+- `locationArg`: The location to match the route paths against.
+
+### Returns
+
+A `boolean` value indicating whether or not the matching route is protected. If no route match the given location, an `Error` is thrown.
+
+## Usage
+
+### Using `useLocation`
+
+```ts
+import { useLocation } from "react-router-dom";
+import { useIsRouteMatchProtected } from "@squide/react-router";
+
+const location = useLocation();
+const isActiveRouteProtected = useIsRouteMatchProtected(location);
+```
+
+### Using `window.location`
+
+```ts
+import { useIsRouteMatchProtected } from "@squide/react-router";
+
+const isActiveRouteProtected = useIsRouteMatchProtected(window.location);
+```
diff --git a/docs/reference/routing/useRenderedNavigationItems.md b/docs/reference/routing/useRenderedNavigationItems.md
index e6ddb7fae..0d15fd5ae 100644
--- a/docs/reference/routing/useRenderedNavigationItems.md
+++ b/docs/reference/routing/useRenderedNavigationItems.md
@@ -79,7 +79,7 @@ const renderSection: RenderSectionFunction = (elements, index, level) => {
);
};
-export default function RootLayout() {
+export function RootLayout() {
const navigationItems = useNavigationItems();
const navigationElements = useRenderedNavigationItems(navigationItems, renderItem, renderSection);
diff --git a/docs/reference/routing/useRouteMatch.md b/docs/reference/routing/useRouteMatch.md
new file mode 100644
index 000000000..92ed5b6b6
--- /dev/null
+++ b/docs/reference/routing/useRouteMatch.md
@@ -0,0 +1,42 @@
+---
+toc:
+ depth: 2-3
+---
+
+# useRouteMatch
+
+Execute [React Router's matching algorithm](https://reactrouter.com/en/main/utils/match-routes) against the registered routes and a given `location` to determine if any route match the location.
+
+## Reference
+
+```ts
+const match = useRouteMatch(locationArg)
+```
+
+### Parameters
+
+- `locationArg`: The location to match the route paths against.
+
+### Returns
+
+A `Route` object if there's a matching route, otherwise an `Error` is thrown.
+
+## Usage
+
+### Using `useLocation`
+
+```ts
+import { useLocation } from "react-router-dom";
+import { useRouteMatch } from "@squide/react-router";
+
+const location = useLocation();
+const activeRoute = useRouteMatch(location);
+```
+
+### Using `window.location`
+
+```ts
+import { useRouteMatch } from "@squide/react-router";
+
+const activeRoute = useRouteMatch(window.location);
+```
diff --git a/docs/reference/runtime/runtime-class.md b/docs/reference/runtime/runtime-class.md
index 4d8b68d8a..c23787c58 100644
--- a/docs/reference/runtime/runtime-class.md
+++ b/docs/reference/runtime/runtime-class.md
@@ -11,7 +11,7 @@ A runtime instance give modules access to functionalities such as routing, navig
## Reference
```ts
-const runtime = new Runtime(options?: { loggers?: [], services?: {}, sessionAccessor?: () => {} })
+const runtime = new Runtime(options?: { loggers?: [], plugins?: [], sessionAccessor?: () => {} })
```
### Parameters
@@ -19,7 +19,7 @@ const runtime = new Runtime(options?: { loggers?: [], services?: {}, sessionAcce
- `options`: An optional object literal of options:
- `mode`: An optional mode to optimize Squide for `production`. Values are `"development"` (default) and `"production"`.
- `loggers`: An optional array of `Logger` instances.
- - `services`: An optional string-keyed object literal of custom service instances.
+ - `plugins`: An optional array of custom plugin instances.
- `sessionAccessor`: An optional function returning the current session.
## Usage
@@ -29,15 +29,14 @@ const runtime = new Runtime(options?: { loggers?: [], services?: {}, sessionAcce
```ts
import { ConsoleLogger, Runtime } from "@squide/react-router";
import { LocalStorageSessionManager } from "@squide/fakes";
-import { UserService, type UserService, type AppSession } from "@sample/shared";
+import { MswPlugin } from "@squide/msw";
+import { type AppSession } from "@sample/shared";
const sessionManager = new LocalStorageSessionManager();
const runtime = new Runtime({
loggers: [new ConsoleLogger()],
- services: {
- "user-service": new UserService()
- },
+ plugins: [new MswPlugin()],
sessionAccessor: () => {
return sessionManager.getSession();
};
@@ -56,104 +55,192 @@ const runtime = new Runtime({
### Register routes
-A Squide route accept any properties of a React Router [Route](https://reactrouter.com/en/main/components/route) component with the addition of an `hoist` property.
+```ts
+runtime.registerRoute(route, options?: {})
+```
-```tsx
-import { lazy } from "react";
+- `route`: accept any properties of a React Router [Route](https://reactrouter.com/en/main/components/route) component with the addition of:
+ - `$name`: An optional name for the route.
+ - `$visibility`: An optional visibility indicator for the route. Accepted values are `"public"` or `"protected"`.
+- `options`: An optional object literal of options:
+ - `hoist`: An optional boolean value to register the route at the root of the router. The default value is `false`.
+ - `parentPath`: An optional path of a parent route to register this new route under.
+ - `parentName`: An optional name of a parent route to register this new route under.
-const Page = lazy(() => import("./Page.tsx"));
+```tsx
+import { Page } from "./Page.tsx"
// Register a new route from a local or remote module.
-runtime.registerRoutes([
- {
- path: "/page-1",
- element:
- }
-]);
+runtime.registerRoute({
+ path: "/page-1",
+ element:
+});
```
-### Register an hoisted page
+### Register an hoisted route
-Unlike a regular page, a hoisted page is added at the root of the router, outside of the boundaries of the host application's root layout. This means that a hoisted page has full control over its rendering.
+Unlike a regular page, a hoisted page is added at the root of the router, outside of the host application's root layout, root error boundary and even root authentication boundary. This means that a hoisted page has full control over its rendering. To mark a route as hoisted, provide an `hoist` property to the route options.
-```tsx !#9
-import { lazy } from "react";
+```tsx !#7
+import { Page } from "./Page.tsx";
-const Page = lazy(() => import("./Page.tsx"));
-
-runtime.registerRoutes([
- {
- path: "/page-1",
- element: ,
- hoist: true
- }
-]);
+runtime.registerRoute({
+ path: "/page-1",
+ element:
+}, {
+ hoist: true
+});
```
-[!ref text="Setup the host application to accept hoisted routes"](/reference/routing/useHoistedRoutes.md)
+!!!warning
+By declaring a page as hoisted, other parts of the application will not be isolated anymore from this page's failures as the page will be rendered outside of the host application's root error boundary. To **avoid breaking the entire application** when an hoisted page encounters unhandled errors, it is highly recommended to declare a React Router's [errorElement](https://reactrouter.com/en/main/route/error-element) property for each hoisted page.
+!!!
-### Register routes under a specific nested layout route
+!!!warning
+By declaring a page as hoisted, the page will be rendered at the root of the router, therefore, most certainly outside the authenticated boundary of the application. If the hoisted page requires an authentication, make sure to **wrap the page with an authentication boundary** or to handle the authentication within the page.
+!!!
-React router [nested routes](https://reactrouter.com/en/main/start/tutorial#nested-routes) enable applications to render nested layouts at various points within the router tree. This is quite helpful for federated applications as it enables composable and decoupled UI.
+### Register a route with a different layout
-To fully harness the power of nested routes, the `registerRoutes` function allows a route to be registered **under any** previously registered **nested layout route**, even if that route was registered by another module.
+!!!info
+For a detailed walkthrough, read the guide on [how to override the host layout](/guides/override-the-host-layout.md).
+!!!
-When registering a new route with the `registerRoutes` function, to render the route under a specific nested layout route, specify a `layoutPath` property that matches the nested layout route's `path` property. The only requirement is that the **nested layout route** must be registered with `registerRoutes`.
+```tsx !#9,12,22
+import { Page } from "./Page.tsx";
+import { RemoteLayout } from "./RemoteLayout.tsx";
+import { RemoteErrorBoundary } from "./RemoteErrorBoundary.tsx";
+
+runtime.registerRoute({
+ path: "/page-1",
+ // Will render the page inside the "RemoteLayout" rather than the "RootLayout".
+ // For more information about React Router's nested routes, view https://reactrouter.com/en/main/start/tutorial#nested-routes.
+ element: ,
+ children: [
+ {
+ errorElement: ,
+ children: [
+ {
+ index: true,
+ element:
+ }
+ ]
+ }
+ ]
+}, {
+ hoist: true
+});
+```
-```tsx !#10
-import { lazy } from "react";
+### Register a public route
+
+When registering a route, a hint can be provided, indicating if the route is intended to be displayed as a `public` or `protected` route. This is especially useful when dealing with code that conditionally fetch data for protected routes (e.g. a session). Don't forget to mark the route as hoisted with the `host` option if the route is nested under an authentication boundary.
+
+```tsx !#4,8
+import { Page } from "./Page.tsx";
+
+runtime.registerRoute({
+ $visibility: "public"
+ path: "/page-1",
+ element:
+}, {
+ hoist: true
+});
+```
-const Page = lazy(() => import("./Page.tsx"));
+A nested route can also have a visibility hint:
-runtime.registerRoutes([
- {
- path: "/layout/page-1",
- element:
- }
-], { layoutPath: "/layout" }); // Register the page under the "/layout" nested layout.
+```tsx !#10
+import { Layout } from "./Layout.tsx";
+import { Page } from "./Page.tsx";
+
+runtime.registerRoute({
+ $visibility: "public"
+ path: "/layout",
+ element: ,
+ children: [
+ {
+ $visibility: "public",
+ path: "/page-1",
+ element: ,
+ }
+ ]
+}, {
+ hoist: true
+});
```
!!!info
-Likewise any other React Router routes, the `path` property of a page rendered under a nested layout must be an absolute path. For example, if a nested layout `path` is `/layout`, the `path` property of a page rendered under that layout route and responding to the `/page-1` url, should be `/layout/page-1`.
+When no visibility hint is provided, a route is considered `protected`.
!!!
-#### Index routes
+### Register a named route
+
+The `registerRoute` function accepts a `parentName` property, allowing a route to be [nested under an existing parent route](#register-nested-routes-under-an-existing-route). When searching for the parent route matching the `parentName` property, the `parentName` will be matched against the `$name` property of every route.
+
+> A `$name` property should only be defined for routes that doesn't have a path like an error boundary or an authentication boundary.
+
+```tsx !#4
+import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
+
+runtime.registerRoute({
+ $name: "error-boundary",
+ element:
+});
+```
+
+A nested route can also be named:
-Although nested layout routes that serve as indexes (e.g. `{ index: true, element: }`) are not very common, Squide still supports this scenario. To register a route **under an index route**, set the `layoutPath` property as the concatenation of the index route's parent path and `/$index$`.
+```tsx !#8
+import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
+import { RootLayout } from "./RootLayout.tsx";
-```tsx !#8,12 host/src/register.tsx
-import { lazy } from "react";
+runtime.registerRoute({
+ $name: "error-boundary",
+ element: ,
+ children: [
+ $name: "root-layout",
+ element:
+ ]
+});
+```
+
+### Register nested routes under an existing route
+
+React router [nested routes](https://reactrouter.com/en/main/start/tutorial#nested-routes) enable applications to render nested layouts at various points within the router tree. This is quite helpful for federated applications as it enables composable and decoupled UI.
-const Page = lazy(() => import("./Page.tsx"));
-const Layout = lazy(() => import("./Layout.tsx"));
+To fully harness the power of nested routes, the `registerRoute` function allows a route to be registered **under any** previously **registered route**, even if that route was registered by another module. The only requirement is that the **parent route** must have been registered with the `registerRoute` function.
-runtime.registerRoutes([
- {
- path: "/page-1",
- element: ,
- children: [
- {
- index: true,
- element:
- }
- ]
- }
-]);
+When registering a new route with the `registerRoute` function, to render the route under a parent route, specify a `parentPath` property that matches the parent route's `path` property:
+
+```tsx !#7
+import { Page } from "./Page.tsx";
+
+runtime.registerRoute({
+ path: "/layout/page-1",
+ element:
+}, {
+ parentPath: "/layout" // Register the page under an existing route having "/layout" as its "path".
+});
```
-```tsx !#10 remote-module/src/register.tsx
-import { lazy } from "react";
+Or a `parentName` property that matches the parent route's `name` property:
-const Page = lazy(() => import("./Page.tsx"));
+```tsx !#7
+import { Page } from "./Page.tsx";
-runtime.registerRoutes([
- {
- path: "/page-1/page-2",
- element:
- }
-], { layoutPath: "/page-1/$index$" }); // Using $index$ to match "index: true"
+runtime.registerRoute({
+ path: "/page-1",
+ element:
+}, {
+ parentName: "error-boundary" // Register the page under an existing route having "error-boundary" as its "name".
+});
```
+!!!info
+Likewise any other React Router routes, the `path` property of a page rendered under an existing parent route must be an absolute path. For example, if a parent route `path` is `/layout`, the `path` property of a page rendered under that parent route and responding to the `/page-1` url, should be `/layout/page-1`.
+!!!
+
### Retrieve routes
A federated application routes are accessible from a `Runtime` instance, but keep in mind that the preferred way to retrieve the routes is with the [useRoutes](./useRoutes) hook.
@@ -164,26 +251,32 @@ const routes = runtime.routes;
### Register navigation items
+```ts
+runtime.registerNavigationItem(item, options?: {})
+```
+
+- `item`: `NavigationSection | NavigationLink`.
+- `options`: An optional object literal of options:
+ - `menuId`: An optional menu id to associate the item with.
+
A Squide navigation item can either be a `NavigationLink` or a `NavigationSection`. Both types can be intertwined to create a multi-level menu hierarchy. A `NavigationSection` item is used to setup a new level while a `NavigationLink` define a link.
- `NavigationSection` accept the following properties:
- - `label`: The section text.
+ - `$label`: The section text.
+ - `$priority`: An order priority affecting the position of the item in the menu (higher first)
+ - `$addiltionalProps`: Additional properties to be forwarded to the section renderer.
- `children`: The section content.
- - `priority`: An order priority affecting the position of the item in the menu (higher first)
- - `addiltionalProps`: Additional properties to be forwarded to the section renderer.
- `NavigationLink` accept any properties of a React Router [Link](https://reactrouter.com/en/main/components/link) component with the addition of:
- - `label`: The link text.
- - `priority`: An order priority affecting the position of the item in the menu (higher first)
- - `additionalProps`: Additional properties to be forwarded to the link renderer.
+ - `$label`: The link text.
+ - `$priority`: An order priority affecting the position of the item in the menu (higher first)
+ - `$additionalProps`: Additional properties to be forwarded to the link renderer.
```ts
// Register a new navigation item from a local or remote module.
-runtime.registerNavigationItems([
- {
- to: "/page-1",
- label: "Page 1"
- }
-]);
+runtime.registerNavigationItem({
+ $label: "Page 1",
+ to: "/page-1"
+});
```
[!ref text="Setup the host application to render navigation items"](/reference/routing/useRenderedNavigationItems.md)
@@ -198,125 +291,114 @@ runtime.registerNavigationItems([
// ------- Nested Nested Link
// --- Nested Link
// Link
-runtime.registerNavigationItems([
- {
- label: "Section",
- children: [
- {
- label: "Nested Section",
- children: [
- {
- to: "#",
- label: "Nested Nested Link",
- }
- ]
- },
- {
- to: "#",
- label: "Nested Link"
- }
- ]
- },
- {
- to: "#",
- label: "Link"
- }
-]);
+runtime.registerNavigationItem({
+ $label: "Section",
+ children: [
+ {
+ label: "Nested Section",
+ children: [
+ {
+ $label: "Nested Nested Link",
+ to: "#"
+ }
+ ]
+ },
+ {
+ $label: "Nested Link",
+ to: "#"
+ }
+ ]
+},
+{
+ $label: "Link",
+ to: "#"
+});
```
### Sort registered navigation items
-A `priority` property can be added to a navigation item to affect it's position in the menu. The sorting algorithm is as follow:
+A `$priority` property can be added to a navigation item to affect it's position in the menu. The sorting algorithm is as follow:
- By default a navigation item have a priority of `0`.
- If no navigation item have a priority, the items are positioned according to their registration order.
- If an item have a priority `> 0`, the item will be positioned before any other items with a lower priority (or without an explicit priority value).
- If an item have a priority `< 0`, the item will be positioned after any other items with a higher priority (or without an explicit priority value).
-```ts !#5,12
-runtime.registerNavigationItems([
- {
- to: "/about",
- label: "About",
- priority: 10
- },
- {
- to: "/home",
- label: "Home",
- // Because the "Home" navigation item has an higher priority, it will be rendered
- // before the "About" navigation item.
- priority: 100
- }
-]);
+```ts !#3,11
+runtime.registerNavigationItem({
+ $label: "About",
+ $priority: 10,
+ to: "/about"
+});
+
+runtime.registerNavigationItem({
+ $label: "Home",
+ // Because the "Home" navigation item has an higher priority, it will be rendered
+ // before the "About" navigation item.
+ $priority: 100,
+ to: "/home"
+});
```
### Use a React element as navigation item label
-```tsx !#6-9
+```tsx !#4-7
import { QuestionMarkIcon } from "@sample/icons";
-runtime.registerNavigationItems([
- {
- to: "/about",
- label: (
-
- About
- )
- }
-]);
+runtime.registerNavigationItem({
+ $label: (
+
+ About
+ ),
+ to: "/about"
+});
```
### Style a navigation item
-```ts !#5-7
-runtime.registerNavigationItems([
- {
- to: "/about",
- label: "About",
- style: {
- backgroundColor: "#000"
- }
- }
-]);
+```ts !#3-5
+runtime.registerNavigationItem({
+ $label: "About",
+ style: {
+ backgroundColor: "#000"
+ },
+ to: "/about"
+});
```
### Open a navigation link in a new tab
-```ts !#5
-runtime.registerNavigationItems([
- {
- to: "/about",
- label: "About",
- target: "_blank"
- }
-]);
+```ts !#3
+runtime.registerNavigationItem({
+ $label: "About",
+ target: "_blank",
+ to: "/about"
+});
```
### Render additional props on a navigation item
-```ts !#5-7
-runtime.registerNavigationItems([
- {
- to: "/about",
- label: "About",
- additionalProps: {
+```ts !#3-5
+runtime.registerNavigationItem({
+ $label: "About",
+ $additionalProps: {
highlight: true
- }
- }
-]);
+ },
+ to: "/about"
+ });
```
### Register navigation items for a specific menu
-By default, every navigation item registered with the `registerNavigationItems` function is registered as part of the `root` navigation menu. To register a navigation item for a different navigation menu, specify a `menuId` property when registering the items.
+By default, every navigation item registered with the `registerNavigationItem` function is registered as part of the `root` navigation menu. To register a navigation item for a different navigation menu, specify a `menuId` property when registering the items.
-```tsx !#6
-runtime.registerNavigationItems([
- {
- to: "/layout/page-1",
- label: "Page 1"
- }
-], { menuId: "my-custom-layout" });
+```tsx !#5
+runtime.registerNavigationItem({
+ $label: "Page 1",
+ to: "/layout/page-1"
+}, {
+ menuId: "my-custom-layout"
+});
```
### Retrieve navigation items
@@ -353,13 +435,15 @@ runtime.eventBus.addListener("write-to-host", () => {});
runtime.eventBus.dispatch("write-to-host", "Hello host!");
```
-### Retrieve a service
+### Retrieve a plugin
```ts
-// If the service isn't registered, undefined will be returned.
-const service = runtime.getService("user-service") as UserService;
+// If the plugin isn't registered, an exception will be thrown.
+const plugin = runtime.getPlugin(MswPlugin.name) as MswPlugin;
```
+[!ref Learn more about plugins](../plugins/plugin.md)
+
### Retrieve the current session
```ts
diff --git a/docs/reference/runtime/useRuntime.md b/docs/reference/runtime/useRuntime.md
index 5efef17f9..c18df5ee0 100644
--- a/docs/reference/runtime/useRuntime.md
+++ b/docs/reference/runtime/useRuntime.md
@@ -9,7 +9,7 @@ toc:
Retrive a shared `Runtime` instance.
!!!info
-When possible, prefer [useRoutes](useRoutes.md), [useNavigationItems](useNavigationItems.md), [useLogger](useLogger.md), [useServices](useServices.md), [useService](useService.md) to `useRuntime`.
+When possible, prefer [useRoutes](useRoutes.md), [useNavigationItems](useNavigationItems.md), [useLogger](useLogger.md) to `useRuntime`.
!!!
## Reference
diff --git a/docs/reference/runtime/useService.md b/docs/reference/runtime/useService.md
deleted file mode 100644
index 11dc9976f..000000000
--- a/docs/reference/runtime/useService.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-toc:
- depth: 2-3
----
-
-# useService
-
-Retrieve a custom service from the `Runtime` instance provided by `RuntimeContext`.
-
-## Reference
-
-```ts
-const service = useService(name)
-```
-
-### Parameters
-
-- `name`: A custom service instance name.
-
-### Returns
-
-A service instance or undefined if the specified service name doesn't match any registered instance.
-
-## Usage
-
-```ts
-import { useService } from "@squide/react-router";
-import type { UserService } from "@sample/shared";
-
-const userService = useService("use-service") as UserService;
-
-const users = userService.fetchAll();
-```
diff --git a/docs/reference/runtime/useServices.md b/docs/reference/runtime/useServices.md
deleted file mode 100644
index c0d1fee38..000000000
--- a/docs/reference/runtime/useServices.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-toc:
- depth: 2-3
----
-
-# useServices
-
-Retrieve a string-keyed object literal of custom service instances from the `Runtime` instance provided by `RuntimeContext`.
-
-## Reference
-
-```ts
-const services = useServices()
-```
-
-### Parameters
-
-None
-
-### Returns
-
-A string-keyed object literal of custom service instances.
-
-## Usage
-
-```ts
-import { useServices } from "@squide/react-router";
-
-const services = useServices();
-```
diff --git a/docs/reference/webpack/index.yaml b/docs/reference/webpack/index.yaml
index b96ddaf94..a58cd4fa2 100644
--- a/docs/reference/webpack/index.yaml
+++ b/docs/reference/webpack/index.yaml
@@ -1,2 +1,2 @@
-order: 30
+order: 10
label: "webpack"
diff --git a/docs/samples.md b/docs/samples.md
index a045fed6c..9a5b16394 100644
--- a/docs/samples.md
+++ b/docs/samples.md
@@ -3,12 +3,18 @@ order: 50
icon: command-palette
---
-## Squide sandbox
-
-- :icon-mark-github: [Host application](https://github.com/gsoft-inc/wl-squide/tree/main/sample/host)
-- :icon-mark-github: [Remote module](https://github.com/gsoft-inc/wl-squide/tree/main/sample/remote-module)
-- :icon-mark-github: [Another remote module](https://github.com/gsoft-inc/wl-squide/tree/main/sample/another-remote-module)
-- :icon-mark-github: [Local module](https://github.com/gsoft-inc/wl-squide/tree/main/sample/local-module)
-- :icon-mark-github: [Shared application shell](https://github.com/gsoft-inc/wl-squide/tree/main/sample/shell)
-- :icon-mark-github: [Shared library](https://github.com/gsoft-inc/wl-squide/tree/main/sample/shared)
-- :icon-cloud: [Live sample](https://squide-host.netlify.app/)
+## Squide "basic" sample
+
+- :icon-mark-github: [Host application](https://github.com/gsoft-inc/wl-squide/tree/main/sample/basic/host)
+- :icon-mark-github: [Remote module](https://github.com/gsoft-inc/wl-squide/tree/main/sample/basic/remote-module)
+- :icon-mark-github: [Another remote module](https://github.com/gsoft-inc/wl-squide/tree/main/sample/basic/another-remote-module)
+- :icon-mark-github: [Local module](https://github.com/gsoft-inc/wl-squide/tree/main/sample/basic/local-module)
+- :icon-mark-github: [Shared application shell](https://github.com/gsoft-inc/wl-squide/tree/main/sample/basic/shell)
+- :icon-mark-github: [Shared library](https://github.com/gsoft-inc/wl-squide/tree/main/sample/basic/shared)
+- :icon-cloud: [Live sample](https://squide-basic-host.netlify.app/)
+
+## Squide sample with "endpoints"
+
+- :icon-mark-github: [Host application](https://github.com/gsoft-inc/wl-squide/tree/main/sample/endpoints/host)
+- :icon-mark-github: [Remote module](https://github.com/gsoft-inc/wl-squide/tree/main/sample/endpoints/remote-module)
+- :icon-cloud: [Live sample](https://squide-endpoints-host.netlify.app/)
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index f5eb7c68e..aad0c9899 100644
--- a/docs/troubleshooting.md
+++ b/docs/troubleshooting.md
@@ -19,4 +19,4 @@ To resolve this issue:
If the issue persists, update your host application and remote module's webpack build configuration with the `optimize: false` option. Afterward, build the bundles and serve them. Open a web browser, access the DevTools, switch to the Network tab (ensure that JS files are listed), navigate to the application's homepage, and inspect the downloaded bundle files. The problematic React context definition should appear only once; otherwise, you may have multiple instances of the React context.
-For additional information on shared dependency versioning, please refer to: https://github.com/patricklafrance/wmf-versioning.
+For additional information on shared dependency versioning, please refer to the [add a shared dependency guide](./guides/add-a-shared-dependency.md) and https://github.com/patricklafrance/wmf-versioning.
diff --git a/package.json b/package.json
index 8d7c1edd6..ee7e4ee31 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
},
"scripts": {
"postinstall": "pnpm -r --parallel --include-workspace-root exec pnpm dlx rimraf node_modules/.cache && pnpm temporary-script-until-build-order-topology-is-fixed",
- "temporary-script-until-build-order-topology-is-fixed": "pnpm build",
+ "temporary-script-until-build-order-topology-is-fixed": "pnpm build && pnpm build-basic && pnpm build-endpoints",
"dev": "pnpm --filter \"./packages/*\" -r --parallel dev",
"build": "pnpm --filter \"./packages/*\" -r --parallel build",
"test": "jest",
@@ -22,13 +22,19 @@
"clean": "pnpm -r --parallel --include-workspace-root exec pnpm dlx rimraf dist node_modules/.cache",
"reset": "pnpm clean && pnpm reset:modules",
"reset:modules": "pnpm -r --parallel --include-workspace-root exec pnpm dlx rimraf node_modules pnpm-lock.yaml",
- "dev-sample": "pnpm --filter \"./sample/*\" -r --parallel dev",
- "build-sample": "pnpm --filter \"./sample/*\" -r --parallel build",
- "serve-sample": "pnpm --filter \"./sample/*\" -r --parallel serve-build",
- "deploy-sample": "cross-env NETLIFY=true pnpm build-sample && pnpm run deploy-sample:host && pnpm run deploy-sample:remote-module && pnpm run deploy-sample:another-remote-module",
- "deploy-sample:host": "netlify deploy --dir=sample/host/dist --site=ae684cea-e6b1-4293-95d6-fc82462654c8 --prod",
- "deploy-sample:remote-module": "netlify deploy --dir=sample/remote-module/dist --site=43234f6e-a884-410e-9b4d-f290459f841f --prod",
- "deploy-sample:another-remote-module": "netlify deploy --dir=sample/another-remote-module/dist --site=2673b626-74aa-4c03-8a8f-8c794e90fd07 --prod",
+ "dev-basic": "pnpm --filter \"./samples/basic/*\" -r --parallel dev",
+ "build-basic": "pnpm --filter \"./samples/basic/*\" -r --parallel build",
+ "serve-basic": "pnpm --filter \"./samples/basic/*\" -r --parallel serve-build",
+ "deploy-basic": "cross-env NETLIFY=true pnpm build-basic && pnpm run deploy-basic:host && pnpm run deploy-basic:remote-module && pnpm run deploy-basic:another-remote-module",
+ "deploy-basic:host": "netlify deploy --dir=samples/basic/host/dist --site=ae684cea-e6b1-4293-95d6-fc82462654c8 --prod",
+ "deploy-basic:remote-module": "netlify deploy --dir=samples/basic/remote-module/dist --site=43234f6e-a884-410e-9b4d-f290459f841f --prod",
+ "deploy-basic:another-remote-module": "netlify deploy --dir=samples/basic/another-remote-module/dist --site=2673b626-74aa-4c03-8a8f-8c794e90fd07 --prod",
+ "dev-endpoints": "pnpm --filter \"./samples/endpoints/*\" -r --parallel dev",
+ "build-endpoints": "pnpm --filter \"./samples/endpoints/*\" -r --parallel build",
+ "serve-endpoints": "pnpm --filter \"./samples/endpoints/*\" -r --parallel serve-build",
+ "deploy-endpoints": "cross-env NETLIFY=true pnpm build-endpoints && pnpm run deploy-endpoints:host && pnpm run deploy-endpoints:remote-module",
+ "deploy-endpoints:host": "netlify deploy --dir=samples/endpoints/host/dist --site=4bde6b8b-cea6-487f-913b-acec9332eb2f --prod",
+ "deploy-endpoints:remote-module": "netlify deploy --dir=samples/endpoints/remote-module/dist --site=a3f091c3-2bc9-4c50-83a0-72fc6d7fa158 --prod",
"dev-docs": "retype start",
"list-outdated-deps": "pnpm outdated -r --format list",
"update-outdated-deps": "pnpm update -r --latest"
@@ -36,13 +42,13 @@
"devDependencies": {
"@changesets/changelog-github": "0.4.8",
"@changesets/cli": "2.26.2",
- "@typescript-eslint/parser": "6.7.2",
- "@workleap/eslint-plugin": "2.1.1",
+ "@typescript-eslint/parser": "6.8.0",
+ "@workleap/eslint-plugin": "3.0.0",
"@workleap/typescript-configs": "3.0.2",
"cross-env": "7.0.3",
- "eslint": "8.49.0",
+ "eslint": "8.51.0",
"jest": "29.7.0",
- "netlify-cli": "16.4.1",
+ "netlify-cli": "16.8.0",
"retypeapp": "3.5.0",
"ts-node": "10.9.1",
"typescript": "5.2.2"
diff --git a/packages/core/package.json b/packages/core/package.json
index 296691e34..420d32714 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -35,9 +35,9 @@
"react-dom": "*"
},
"devDependencies": {
- "@types/react": "18.2.22",
- "@types/react-dom": "18.2.7",
- "@workleap/eslint-plugin": "2.1.1",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@workleap/eslint-plugin": "3.0.0",
"@workleap/tsup-configs": "3.0.1",
"@workleap/typescript-configs": "3.0.2",
"react": "18.2.0",
diff --git a/packages/core/src/federation/registerLocalModules.ts b/packages/core/src/federation/registerLocalModules.ts
index 9fc022e08..5f2879b8b 100644
--- a/packages/core/src/federation/registerLocalModules.ts
+++ b/packages/core/src/federation/registerLocalModules.ts
@@ -1,32 +1,61 @@
import type { AbstractRuntime } from "../runtime/abstractRuntime.ts";
import type { ModuleRegistrationStatus } from "./moduleRegistrationStatus.ts";
-import type { ModuleRegisterFunction } from "./registerModule.ts";
+import { registerModule, type ModuleRegisterFunction } from "./registerModule.ts";
let registrationStatus: ModuleRegistrationStatus = "none";
-// Aliasing to make the name more explicit to external modules.
-export { registrationStatus as localModulesRegistrationStatus };
+export function getLocalModulesRegistrationStatus() {
+ return registrationStatus;
+}
+
+export function resetLocalModulesRegistrationStatus() {
+ registrationStatus = "none";
+}
+
+export interface LocalModuleRegistrationError {
+ // The registration error.
+ error: unknown;
+}
export interface RegisterLocalModulesOptions {
context?: TContext;
}
-export function registerLocalModules(registerFunctions: ModuleRegisterFunction[], runtime: TRuntime, { context }: RegisterLocalModulesOptions = {}) {
+export async function registerLocalModules(registerFunctions: ModuleRegisterFunction[], runtime: TRuntime, { context }: RegisterLocalModulesOptions = {}) {
if (registrationStatus !== "none") {
- throw new Error("[squide] The \"registerLocalModules\" function can only be called once.");
+ throw new Error("[squide] [local] registerLocalModules() can only be called once.");
}
+ const errors: LocalModuleRegistrationError[] = [];
+
+ runtime.logger.information(`[squide] [local] Found ${registerFunctions.length} local module${registerFunctions.length !== 1 ? "s" : ""} to register.`);
+
registrationStatus = "in-progress";
- runtime.logger.information(`[squide] Found ${registerFunctions.length} local module${registerFunctions.length !== 1 ? "s" : ""} to register.`);
+ await Promise.allSettled(registerFunctions.map(async (x, index) => {
+ let optionalPromise;
+
+ runtime.logger.information(`[squide] [local] ${index + 1}/${registerFunctions.length} Registering local module.`);
- registerFunctions.forEach((x, index) => {
- runtime.logger.information(`[squide] ${index + 1}/${registerFunctions.length} Registering local module${registerFunctions.length !== 1 ? "s" : ""}.`);
+ try {
+ optionalPromise = registerModule(x as ModuleRegisterFunction, runtime, context);
+ } catch (error: unknown) {
+ runtime.logger.error(
+ `[squide] [local] ${index + 1}/${registerFunctions.length} An error occured while registering a local module.`,
+ error
+ );
- x(runtime, context);
+ errors.push({
+ error
+ });
+ }
- runtime.logger.information(`[squide] ${index + 1}/${registerFunctions.length} Local module${registerFunctions.length !== 1 ? "s" : ""} registration completed.`);
- });
+ runtime.logger.information(`[squide] [local] ${index + 1}/${registerFunctions.length} Local module registration completed.`);
+
+ return optionalPromise;
+ }));
registrationStatus = "ready";
+
+ return errors;
}
diff --git a/packages/core/src/federation/registerModule.ts b/packages/core/src/federation/registerModule.ts
index ef79edff5..509513efd 100644
--- a/packages/core/src/federation/registerModule.ts
+++ b/packages/core/src/federation/registerModule.ts
@@ -2,6 +2,6 @@ import type { AbstractRuntime } from "../runtime/abstractRuntime.ts";
export type ModuleRegisterFunction = (runtime: TRuntime, context?: TContext) => void;
-export function registerModule(register: ModuleRegisterFunction, runtime: AbstractRuntime, context?: unknown) {
- register(runtime, context);
+export async function registerModule(register: ModuleRegisterFunction, runtime: AbstractRuntime, context?: unknown) {
+ return register(runtime, context);
}
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 114f15a8e..9fbd49df7 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -22,3 +22,7 @@ export * from "./federation/moduleRegistrationStatus.ts";
export * from "./federation/registerLocalModules.ts";
export * from "./federation/registerModule.ts";
+export * from "./plugins/plugin.ts";
+
+export * from "./services/service.ts";
+
diff --git a/packages/core/src/plugins/plugin.ts b/packages/core/src/plugins/plugin.ts
new file mode 100644
index 000000000..c95523d7d
--- /dev/null
+++ b/packages/core/src/plugins/plugin.ts
@@ -0,0 +1,11 @@
+export abstract class Plugin {
+ protected readonly _name: string;
+
+ constructor(name: string) {
+ this._name = name;
+ }
+
+ get name() {
+ return this._name;
+ }
+}
diff --git a/packages/core/src/runtime/RuntimeContext.ts b/packages/core/src/runtime/RuntimeContext.ts
index 29e821602..c2af1810e 100644
--- a/packages/core/src/runtime/RuntimeContext.ts
+++ b/packages/core/src/runtime/RuntimeContext.ts
@@ -1,5 +1,4 @@
import { createContext, useContext } from "react";
-
import { isNil } from "../shared/assertions.ts";
import type { AbstractRuntime } from "./abstractRuntime.ts";
diff --git a/packages/core/src/runtime/abstractRuntime.ts b/packages/core/src/runtime/abstractRuntime.ts
index 3bba238d4..de597d306 100644
--- a/packages/core/src/runtime/abstractRuntime.ts
+++ b/packages/core/src/runtime/abstractRuntime.ts
@@ -1,5 +1,7 @@
import type { Logger } from "../logging/logger.ts";
import { EventBus } from "../messaging/eventBus.ts";
+import type { Plugin } from "../plugins/plugin.ts";
+import type { Service } from "../services/service.ts";
import { RuntimeLogger } from "./RuntimeLogger.ts";
export type SessionAccessorFunction = () => unknown;
@@ -9,15 +11,18 @@ export type RuntimeMode = "development" | "production";
export interface RuntimeOptions {
mode?: RuntimeMode;
loggers?: Logger[];
- services?: Record;
+ services?: Service[];
+ plugins?: Plugin[];
sessionAccessor?: SessionAccessorFunction;
}
-export interface RegisterRoutesOptions {
- layoutPath?: string;
+export interface RegisterRouteOptions {
+ hoist?: true;
+ parentPath?: string;
+ parentName?: string;
}
-export interface RegisterNavigationItemsOptions {
+export interface RegisterNavigationItemOptions {
menuId?: string;
}
@@ -27,22 +32,24 @@ export abstract class AbstractRuntime;
+ protected readonly _services: Service[];
+ protected readonly _plugins: Plugin[];
protected _sessionAccessor?: SessionAccessorFunction;
- constructor({ mode = "development", loggers, services = {}, sessionAccessor }: RuntimeOptions = {}) {
+ constructor({ mode = "development", loggers, services = [], plugins = [], sessionAccessor }: RuntimeOptions = {}) {
this._mode = mode;
+ this._plugins = plugins;
this._logger = new RuntimeLogger(loggers);
this._eventBus = new EventBus({ logger: this._logger });
this._services = services;
this._sessionAccessor = sessionAccessor;
}
- abstract registerRoutes(routes: TRoute[], options?: RegisterRoutesOptions): void;
+ abstract registerRoute(route: TRoute, options?: RegisterRouteOptions): void;
abstract get routes(): TRoute[];
- abstract registerNavigationItems(navigationItems: TNavigationItem[], options?: RegisterNavigationItemsOptions): void;
+ abstract registerNavigationItem(navigationItem: TNavigationItem, options?: RegisterNavigationItemOptions): void;
abstract getNavigationItems(menuId?: string): TNavigationItem[];
@@ -50,6 +57,20 @@ export abstract class AbstractRuntime x.name === pluginName);
+
+ if (!plugin) {
+ throw new Error(`[squide] Cannot find a plugin named "${pluginName}". Did you add an instance of the plugin to the application Runtime instance?`);
+ }
+
+ return plugin;
+ }
+
get logger() {
return this._logger;
}
@@ -63,7 +84,13 @@ export abstract class AbstractRuntime x.name === serviceName);
+
+ if (!service) {
+ throw new Error(`[squide] Cannot find a service named "${serviceName}". Did you add the service to the application Runtime instance?`);
+ }
+
+ return service;
}
getSession() {
@@ -76,6 +103,6 @@ export abstract class AbstractRuntime=18.0.0"
+ }
+}
diff --git a/packages/msw/src/index.ts b/packages/msw/src/index.ts
new file mode 100644
index 000000000..00bf92fcb
--- /dev/null
+++ b/packages/msw/src/index.ts
@@ -0,0 +1,4 @@
+export * from "./mswPlugin.ts";
+export * from "./requestHandlerRegistry.ts";
+export * from "./useIsMswReady.ts";
+
diff --git a/packages/msw/src/mswPlugin.ts b/packages/msw/src/mswPlugin.ts
new file mode 100644
index 000000000..3a5108bb1
--- /dev/null
+++ b/packages/msw/src/mswPlugin.ts
@@ -0,0 +1,23 @@
+import { Plugin, type AbstractRuntime } from "@squide/core";
+import type { RestHandler } from "msw";
+import { RequestHandlerRegistry } from "./requestHandlerRegistry.ts";
+
+export class MswPlugin extends Plugin {
+ readonly #requestHandlerRegistry = new RequestHandlerRegistry();
+
+ constructor() {
+ super(MswPlugin.name);
+ }
+
+ registerRequestHandlers(handlers: RestHandler[]) {
+ this.#requestHandlerRegistry.add(handlers);
+ }
+
+ get requestHandlers(): RestHandler[] {
+ return this.#requestHandlerRegistry.handlers;
+ }
+}
+
+export function getMswPlugin(runtime: AbstractRuntime) {
+ return runtime.getPlugin(MswPlugin.name) as MswPlugin;
+}
diff --git a/packages/msw/src/requestHandlerRegistry.ts b/packages/msw/src/requestHandlerRegistry.ts
new file mode 100644
index 000000000..a302ac27a
--- /dev/null
+++ b/packages/msw/src/requestHandlerRegistry.ts
@@ -0,0 +1,16 @@
+import type { RestHandler } from "msw";
+
+export class RequestHandlerRegistry {
+ readonly #handlers: RestHandler[] = [];
+
+ add(handlers: RestHandler[]) {
+ this.#handlers.push(...handlers);
+ }
+
+ // Must specify the return type, otherwise we get the following error:
+ // TS2742: The inferred type of 'handlers' cannot be named without a reference to X. This is likely not portable. A type annotation is necessary.
+ get handlers(): RestHandler[] {
+ return this.#handlers;
+ }
+}
+
diff --git a/packages/msw/src/useIsMswReady.ts b/packages/msw/src/useIsMswReady.ts
new file mode 100644
index 000000000..afe4a3565
--- /dev/null
+++ b/packages/msw/src/useIsMswReady.ts
@@ -0,0 +1,42 @@
+import { useLogger } from "@squide/core";
+import { useEffect, useState } from "react";
+
+let isMswStarted = false;
+
+export function setMswAsStarted() {
+ isMswStarted = true;
+}
+
+export interface UseIsMswStartedOptions {
+ // The interval is in milliseconds.
+ interval?: number;
+}
+
+export function useIsMswStarted(enabled: boolean, { interval = 10 }: UseIsMswStartedOptions = {}) {
+ const logger = useLogger();
+
+ // Using a state hook to force a rerender once MSW is started.
+ const [value, setIsStarted] = useState(!enabled);
+
+ // Perform a reload once MSW is started.
+ useEffect(() => {
+ if (enabled) {
+ const intervalId = setInterval(() => {
+ if (isMswStarted) {
+ logger.debug("[squide] %cMSW is ready%c.", "color: white; background-color: green;", "");
+
+ clearInterval(intervalId);
+ setIsStarted(true);
+ }
+ }, interval);
+
+ return () => {
+ if (intervalId) {
+ clearInterval(intervalId);
+ }
+ };
+ }
+ }, [enabled]);
+
+ return value;
+}
diff --git a/sample/shared/tsconfig.json b/packages/msw/tsconfig.json
similarity index 52%
rename from sample/shared/tsconfig.json
rename to packages/msw/tsconfig.json
index d52f7ed18..5161504c1 100644
--- a/sample/shared/tsconfig.json
+++ b/packages/msw/tsconfig.json
@@ -2,8 +2,7 @@
"extends": "@workleap/typescript-configs/library.json",
"compilerOptions": {
"paths": {
- "@squide/core": ["../../packages/core/src/index.ts"],
- "@squide/react-router": ["../../packages/react-router/src/index.ts"]
+ "@squide/core": ["../core/src/index.ts"]
}
},
"exclude": ["dist", "node_modules"]
diff --git a/sample/local-module/tsup.build.ts b/packages/msw/tsup.build.ts
similarity index 100%
rename from sample/local-module/tsup.build.ts
rename to packages/msw/tsup.build.ts
diff --git a/sample/local-module/tsup.dev.ts b/packages/msw/tsup.dev.ts
similarity index 100%
rename from sample/local-module/tsup.dev.ts
rename to packages/msw/tsup.dev.ts
diff --git a/packages/react-router/package.json b/packages/react-router/package.json
index 07ff80175..ec648b749 100644
--- a/packages/react-router/package.json
+++ b/packages/react-router/package.json
@@ -36,15 +36,15 @@
"react-router-dom": "*"
},
"devDependencies": {
- "@swc/core": "1.3.86",
- "@swc/helpers": "0.5.2",
+ "@swc/core": "1.3.93",
+ "@swc/helpers": "0.5.3",
"@swc/jest": "0.2.29",
"@testing-library/react": "14.0.0",
"@types/jest": "29.5.5",
- "@types/react": "18.2.22",
- "@types/react-dom": "18.2.7",
- "@types/react-test-renderer": "18.0.2",
- "@workleap/eslint-plugin": "2.1.1",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@types/react-test-renderer": "18.0.3",
+ "@workleap/eslint-plugin": "3.0.0",
"@workleap/swc-configs": "2.1.2",
"@workleap/tsup-configs": "3.0.1",
"@workleap/typescript-configs": "3.0.2",
@@ -52,7 +52,7 @@
"jest-environment-jsdom": "29.7.0",
"react": "18.2.0",
"react-dom": "18.2.0",
- "react-router-dom": "6.16.0",
+ "react-router-dom": "6.17.0",
"react-test-renderer": "18.2.0",
"ts-jest": "29.1.1",
"tsup": "7.2.0",
diff --git a/packages/react-router/src/index.ts b/packages/react-router/src/index.ts
index af27493ef..e88150f37 100644
--- a/packages/react-router/src/index.ts
+++ b/packages/react-router/src/index.ts
@@ -1,13 +1,11 @@
export * from "@squide/core";
-export * from "./runtime.ts";
-
-export * from "./routeRegistry.ts";
-
-export * from "./useHoistedRoutes.ts";
-export * from "./useRoutes.ts";
-
export * from "./navigationItemRegistry.ts";
+export * from "./outlets.ts";
+export * from "./routeRegistry.ts";
+export * from "./runtime.ts";
export * from "./useNavigationItems.ts";
export * from "./useRenderedNavigationItems.tsx";
+export * from "./useRouteMatch.ts";
+export * from "./useRoutes.ts";
diff --git a/packages/react-router/src/navigationItemRegistry.ts b/packages/react-router/src/navigationItemRegistry.ts
index 708fe115f..330b67b2e 100644
--- a/packages/react-router/src/navigationItemRegistry.ts
+++ b/packages/react-router/src/navigationItemRegistry.ts
@@ -3,15 +3,15 @@ import type { ReactNode } from "react";
import type { LinkProps } from "react-router-dom";
export interface NavigationLink extends Omit {
- label: ReactNode;
- additionalProps?: Record;
+ $label: ReactNode;
+ $additionalProps?: Record;
children?: never;
}
export interface NavigationSection {
- label: ReactNode;
+ $label: ReactNode;
+ $additionalProps?: Record;
children: NavigationItem[];
- additionalProps?: Record;
to?: never;
}
@@ -24,17 +24,17 @@ export function isLinkItem(item: NavigationItem): item is NavigationLink {
export type RootNavigationItem = NavigationItem & {
// Highest priority is rendered first.
- priority?: number;
+ $priority?: number;
};
export class NavigationItemRegistry {
readonly #menus: Map = new Map();
- add(menuId: string, navigationItems: RootNavigationItem[]) {
+ add(menuId: string, navigationItem: RootNavigationItem) {
// Create a new array so the navigation items array is immutable.
const items = [
...(this.#menus.get(menuId) ?? []),
- ...navigationItems
+ navigationItem
];
this.#menus.set(menuId, items);
diff --git a/packages/react-router/src/outlets.ts b/packages/react-router/src/outlets.ts
new file mode 100644
index 000000000..c6631f225
--- /dev/null
+++ b/packages/react-router/src/outlets.ts
@@ -0,0 +1,11 @@
+import type { Route } from "./routeRegistry.ts";
+
+export const ManagedRoutesOutletName = "__squide-managed-routes-outlet__";
+
+export const ManagedRoutes: Route = {
+ $name: ManagedRoutesOutletName
+};
+
+export function isManagedRoutesOutletRoute(route: Route) {
+ return route.$name === ManagedRoutesOutletName;
+}
diff --git a/packages/react-router/src/routeRegistry.ts b/packages/react-router/src/routeRegistry.ts
index cb4edbab3..9baedd18c 100644
--- a/packages/react-router/src/routeRegistry.ts
+++ b/packages/react-router/src/routeRegistry.ts
@@ -1,81 +1,179 @@
-import type { RegisterRoutesOptions } from "@squide/core";
-import type { RouteObject } from "react-router-dom";
+import type { RegisterRouteOptions } from "@squide/core";
+import type { IndexRouteObject, NonIndexRouteObject } from "react-router-dom";
+import { ManagedRoutesOutletName, isManagedRoutesOutletRoute } from "./outlets.ts";
-export type Route = RouteObject;
+export type RouteVisibility = "public" | "protected";
-export type RootRoute = Route & {
- hoist?: boolean;
-};
+export interface IndexRoute extends IndexRouteObject {
+ $name?: string;
+ $visibility?: RouteVisibility;
+}
+
+export interface NonIndexRoute extends Omit {
+ $name?: string;
+ $visibility?: RouteVisibility;
+ children?: Route[];
+}
-const IndexToken = "$index$";
+export type Route = IndexRoute | NonIndexRoute;
+
+export type RouteRegistrationStatus = "pending" | "registered";
-function normalizePath(routePath: string) {
- if (routePath !== "/" && routePath.endsWith("/")) {
+function normalizePath(routePath?: string) {
+ if (routePath && routePath !== "/" && routePath.endsWith("/")) {
return routePath.substring(0, routePath.length - 1);
}
return routePath;
}
-export function createIndexKey(route: Route, layoutPath: string) {
- if (route.index) {
- return layoutPath.endsWith("/") ? `${layoutPath}${IndexToken}` : `${layoutPath}/${IndexToken}`;
+export function createIndexKey(route: Route) {
+ if (route.path) {
+ return normalizePath(route.path);
}
- return normalizePath(route.path!);
-}
-
-export type RouteRegistrationStatus = "pending" | "registered";
+ if (route.$name) {
+ return route.$name;
+ }
-export interface AddRouteReturnType {
- registrationStatus: RouteRegistrationStatus;
- completedPendingRegistrations?: Route[];
+ return undefined;
}
+
export class RouteRegistry {
- #routes: RootRoute[];
+ #routes: Route[];
// Using an index to speed up the look up of parent routes.
- //
- readonly #routesIndex: Map = new Map();
+ //
+ readonly #routesIndex: Map = new Map();
// A collection of pending routes to registered once their layout is registered.
- //
+ //
readonly #pendingRegistrations: Map = new Map();
constructor() {
this.#routes = [];
}
- add(routes: RootRoute[] | Route[], { layoutPath }: RegisterRoutesOptions = {}) {
- if (layoutPath) {
- return this.#addNestedRoutes(routes, layoutPath);
+ #addIndex(route: Route) {
+ const key = createIndexKey(route);
+
+ if (key) {
+ if (this.#routesIndex.has(key)) {
+ throw new Error(`[squide] A route index has already been registered for the key: "${key}". Did you register two routes with the same "path" or "name" property?`);
+ }
+
+ this.#routesIndex.set(key, route);
}
- return this.#addRootRoutes(routes);
+ return key;
}
- #addRootRoutes(routes: RootRoute[]): AddRouteReturnType {
- // Add index entries to speed up the registration of future nested routes.
- routes.forEach(x => {
- const key = createIndexKey(x, "/");
+ #recursivelyAddRoutes(routes: Route[]) {
+ const newRoutes: Route[] = [];
+ const completedPendingRegistrations: Route[] = [];
+
+ routes.forEach((x: Route) => {
+ // Creates a copy of the route object and add the default properties.
+ const route = {
+ ...x,
+ $visibility: x.$visibility ?? "protected"
+ };
+
+ if (route.children) {
+ // Recursively go through the children.
+ const result = this.#recursivelyAddRoutes(route.children);
+
+ route.children = result.newRoutes;
+
+ completedPendingRegistrations.push(...result.completedPendingRegistrations);
+ }
+
+ // Add index entries to speed up the registration of future nested routes.
+ const indexKey = this.#addIndex(route);
+
+ // IMPORTANT: do not handle the pending registrations before recursively going through the children.
+ // Otherwise pending routes will be handled twice (one time as a pending registration and one time as child
+ // of the route).
+ if (indexKey) {
+ const pendingRegistrations = this.#tryRegisterPendingRoutes(indexKey);
+
+ completedPendingRegistrations.unshift(...pendingRegistrations);
+ }
- this.#routesIndex.set(key, x);
+ newRoutes.push(route);
});
- // Create a new array so the routes array is immutable.
- this.#routes = [...this.#routes, ...routes];
+ return {
+ newRoutes,
+ completedPendingRegistrations
+ };
+ }
+
+ #tryRegisterPendingRoutes(parentId: string) {
+ const pendingRegistrations = this.#pendingRegistrations.get(parentId);
+
+ if (pendingRegistrations) {
+ // Try to register the pending routes.
+ const { registrationStatus } = this.#addNestedRoutes(pendingRegistrations, parentId);
+
+ if (registrationStatus === "registered") {
+ // Remove the pending registrations.
+ this.#pendingRegistrations.delete(parentId);
+
+ return pendingRegistrations;
+ }
+ }
- let completedPendingRegistrations;
+ return [];
+ }
+
+ #validateRouteRegistrationOptions(route: Route, { hoist, parentPath, parentName }: RegisterRouteOptions = {}) {
+ if (hoist && parentPath) {
+ throw new Error(`[squide] A route cannot have the "hoist" property when a "publicPath" option is provided. Route id: "${route.path ?? route.$name ?? "(no identifier)"}".`);
+ }
+
+ if (hoist && parentName) {
+ throw new Error(`[squide] A route cannot have the "hoist" property when a "parentName" option is provided. Route id: "${route.path ?? route.$name ?? "(no identifier)"}".`);
+ }
+ }
+
+ add(route: Route, options: RegisterRouteOptions = {}) {
+ let parentName = options.parentName;
+
+ // By default, a route that is not hoisted nor nested under a known
+ // parent will be rendered under the ManagedRoutes outlet.
+ if (!options.hoist && !parentName && !isManagedRoutesOutletRoute(route)) {
+ parentName = ManagedRoutesOutletName;
+ }
- routes.forEach(x => {
- // Since the layoutPath is used as the key for pending routes and the
- // layoutPath is the same as the index key, an index key for the route must be created
- // to retrieve the route pending registrations.
- const key = createIndexKey(x, "/");
+ this.#validateRouteRegistrationOptions(route, options);
- completedPendingRegistrations = this.#tryRegisterPendingRoutes(key);
+ return this.#addRoute(route, {
+ ...options,
+ parentName
});
+ }
+
+ #addRoute(route: Route, { parentPath, parentName }: RegisterRouteOptions) {
+ if (parentPath) {
+ // The normalized path cannot be undefined because it's been provided by the consumer
+ // (e.g. it cannot be a pathless route).
+ return this.#addNestedRoutes([route], normalizePath(parentPath)!);
+ }
+
+ if (parentName) {
+ return this.#addNestedRoutes([route], parentName);
+ }
+
+ return this.#addRootRoutes([route]);
+ }
+
+ #addRootRoutes(routes: Route[]) {
+ const { newRoutes, completedPendingRegistrations } = this.#recursivelyAddRoutes(routes);
+
+ // Create a new array so the routes array is immutable.
+ this.#routes = [...this.#routes, ...newRoutes];
return {
registrationStatus: "registered",
@@ -83,74 +181,42 @@ export class RouteRegistry {
};
}
- #addNestedRoutes(routes: Route[], layoutPath: string): AddRouteReturnType {
- const indexKey = normalizePath(layoutPath);
- const layoutRoute = this.#routesIndex.get(indexKey);
+ #addNestedRoutes(routes: Route[], parentId: string) {
+ const layoutRoute = this.#routesIndex.get(parentId);
if (!layoutRoute) {
- const pendingRegistration = this.#pendingRegistrations.get(layoutPath);
+ const pendingRegistration = this.#pendingRegistrations.get(parentId);
if (pendingRegistration) {
pendingRegistration.push(...routes);
} else {
- this.#pendingRegistrations.set(layoutPath, [...routes]);
+ this.#pendingRegistrations.set(parentId, [...routes]);
}
return {
- registrationStatus: "pending"
+ registrationStatus: "pending",
+ completedPendingRegistrations: []
};
}
+ const { newRoutes, completedPendingRegistrations } = this.#recursivelyAddRoutes(routes);
+
// Register new nested routes as children of their layout route.
layoutRoute.children = [
...(layoutRoute.children ?? []),
- ...routes
+ ...newRoutes
];
- // Add index entries to speed up the registration of future nested routes.
- routes.forEach(x => {
- const key = createIndexKey(x, layoutPath);
-
- this.#routesIndex.set(key, x);
- });
-
// Create a new array since the routes array is immutable and a nested
// object has been updated.
this.#routes = [...this.#routes];
- let completedPendingRegistrations;
-
- routes.forEach(x => {
- // Since the layoutPath is used as the key for pending routes and the
- // layoutPath is the same as the index key, an index key for the route must be created
- // to retrieve the route pending registrations.
- const key = createIndexKey(x, "/");
-
- this.#tryRegisterPendingRoutes(key);
- });
-
return {
registrationStatus: "registered",
completedPendingRegistrations
};
}
- #tryRegisterPendingRoutes(layoutPath: string) {
- const pendingRegistrations = this.#pendingRegistrations.get(layoutPath);
-
- if (pendingRegistrations) {
- // Try to register the pending routes.
- this.#addNestedRoutes(pendingRegistrations, layoutPath);
-
- // Remove the pending registrations.
- this.#pendingRegistrations.delete(layoutPath);
-
- return pendingRegistrations;
- }
-
- return undefined;
- }
-
get routes() {
return this.#routes;
}
diff --git a/packages/react-router/src/runtime.ts b/packages/react-router/src/runtime.ts
index 31c0ea026..ddba04cb6 100644
--- a/packages/react-router/src/runtime.ts
+++ b/packages/react-router/src/runtime.ts
@@ -1,34 +1,38 @@
-import { AbstractRuntime, RootMenuId, type RegisterNavigationItemsOptions, type RegisterRoutesOptions } from "@squide/core";
+import { AbstractRuntime, RootMenuId, type RegisterNavigationItemOptions, type RegisterRouteOptions } from "@squide/core";
import { NavigationItemRegistry, type RootNavigationItem } from "./navigationItemRegistry.ts";
-import { RouteRegistry, type RootRoute, type Route } from "./routeRegistry.ts";
+import { ManagedRoutes } from "./outlets.ts";
+import { RouteRegistry, type Route } from "./routeRegistry.ts";
-export class Runtime extends AbstractRuntime {
+export class Runtime extends AbstractRuntime {
readonly #routeRegistry = new RouteRegistry();
readonly #navigationItemRegistry = new NavigationItemRegistry();
- registerRoutes(routes: RootRoute[] | Route[], options: RegisterRoutesOptions = {}) {
- const result = this.#routeRegistry.add(routes, options);
+ registerRoute(route: Route, options: RegisterRouteOptions = {}) {
+ const result = this.#routeRegistry.add(route, options);
if (result.registrationStatus === "registered") {
- const parentLog = options.layoutPath ? ` as children of the "${options.layoutPath}" route` : "";
+ const parentId = options.parentPath ?? options.parentName;
+ const parentLog = parentId ? ` as children of the "${parentId}" route` : "";
this._logger.debug(
- `[squide] The following route${routes.length !== 1 ? "s" : ""} has been %cregistered%c${parentLog} for a total of ${this.#routeRegistry.routes.length} route${this.#routeRegistry.routes.length !== 1 ? "s" : ""}.`, "color: white; background-color: green;", "%s",
- "Newly registered routes:", routes,
+ `[squide] The following route has been %cregistered%c${parentLog}.`, "color: white; background-color: green;", "%s",
+ "Newly registered route:", route,
"All registered routes:", this.#routeRegistry.routes
);
- if (result.completedPendingRegistrations) {
+ if (result.completedPendingRegistrations.length > 0) {
this._logger.debug(
- `[squide] The pending registration of the following route${result.completedPendingRegistrations.length !== 1 ? "s" : ""} has been %ccompleted%c.`, "color: white; background-color: #26bfa5;", "%s",
+ `[squide] The pending registration of the following route${result.completedPendingRegistrations.length !== 1 ? "s" : ""} has been %ccompleted%c.`, "color: white; background-color: green;", "%s",
"Newly registered routes:", result.completedPendingRegistrations,
"All registered routes:", this.#routeRegistry.routes
);
}
} else {
+ const parentId = options.parentPath ?? options.parentName;
+
this._logger.debug(
- `[squide] The following route${routes.length !== 1 ? "s" : ""} registration are %cpending%c until "${options.layoutPath}" is registered.`, "color: white; background-color: #007acc;", "%s",
- "Pending registration:", routes,
+ `[squide] The following route registration is %cpending%c until "${parentId}" is registered.`, "color: black; background-color: yellow;", "%s",
+ "Pending registration:", route,
"All registered routes:", this.#routeRegistry.routes
);
}
@@ -38,14 +42,14 @@ export class Runtime extends AbstractRuntime 0) {
- let message = `[squide] ${pendingRegistrations.size} layout route${pendingRegistrations.size !== 1 ? "s" : ""} were expected to be registered but ${pendingRegistrations.size !== 1 ? "are" : "is"} missing:\r\n\r\n`;
+ if (pendingRegistrations.has(ManagedRoutes.$name!)) {
+ // eslint-disable-next-line max-len
+ throw new Error("[squide] The \"ManagedRoutes\" outlet route is missing from the router configuration. The \"ManagedRoutes\" outlet route must be added as a children of an hoisted route. Did you forget to include the \"ManagedRoutes\" outlet route or hoist the parent route that includes the \"ManagedRoutes\" outlet route?");
+ }
+ let message = `[squide] ${pendingRegistrations.size} parent route${pendingRegistrations.size !== 1 ? "s" : ""} were expected to be registered but ${pendingRegistrations.size !== 0 ? "are" : "is"} missing:\r\n\r\n`;
let index = 0;
// It's easier to use for ... of with a Map object.
- for (const [layoutPath, nestedRoutes] of pendingRegistrations) {
+ for (const [parentId, nestedRoutes] of pendingRegistrations) {
index++;
- message += `${index}/${pendingRegistrations.size} Missing layout path: "${layoutPath}"\r\n`;
+ message += `${index}/${pendingRegistrations.size} Missing parent route with the following path or name: "${parentId}"\r\n`;
message += " Pending registrations:\r\n";
for (const x of nestedRoutes) {
- message += ` - "${x.index ? `${layoutPath} (index)` : x.path}"\r\n`;
+ message += ` - "${x.path ?? x.$name ?? "(no identifier)"}"\r\n`;
}
message += "\r\n";
}
- message += `If you are certain that the layout route${pendingRegistrations.size !== 1 ? "s" : ""} has been registered, make sure that the following conditions are met:\r\n`;
- message += "- The missing nested layout routes path property perfectly match the provided \"layoutPath\" (make sure that there's no leading or trailing \"/\" that differs).\r\n";
- message += "- The missing nested layout routes has been registered with the \"registerRoutes()\" function. A route cannot be registered under a nested layout route that has not be registered with the \"registerRoutes()\" function.\r\n";
- message += "- If a nested layout route is an index route, make sure that \"/$index$\" string has been appended to the \"layoutPath\".\r\n\r\n";
- message += "For more information about nested layout routes, refers to https://gsoft-inc.github.io/wl-squide/reference/runtime/runtime-class/#register-routes-under-a-specific-nested-layout-route.\r\n";
+ message += `If you are certain that the parent route${pendingRegistrations.size !== 1 ? "s" : ""} has been registered, make sure that the following conditions are met:\r\n`;
+ message += "- The missing parent routes \"path\" or \"name\" property perfectly match the provided \"parentPath\" or \"parentName\" (make sure that there's no leading or trailing \"/\" that differs).\r\n";
+ message += "- The missing parent routes has been registered with the \"registerRoute()\" function. A route cannot be registered under a parent route that has not be registered with the \"registerRoute()\" function.\r\n";
+ message += "For more information about nested routes, refers to https://gsoft-inc.github.io/wl-squide/reference/runtime/runtime-class/#register-routes-under-a-specific-nested-layout-route.";
if (this._mode === "development") {
throw new Error(message);
diff --git a/packages/react-router/src/useHoistedRoutes.ts b/packages/react-router/src/useHoistedRoutes.ts
deleted file mode 100644
index 84c593c69..000000000
--- a/packages/react-router/src/useHoistedRoutes.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { useMemo, useState } from "react";
-import type { RootRoute, Route } from "./routeRegistry.ts";
-
-import { isNil } from "@squide/core";
-
-export interface UseHoistedRoutesOptions {
- allowedPaths?: string[];
-}
-
-function getAllRoutePaths(route: Route) {
- const current = route.path;
-
- if (!isNil(route.children)) {
- const childPaths = route.children.reduce((acc: string[], x: Route) => {
- acc.push(...getAllRoutePaths(x));
-
- return acc;
- }, []);
-
- if (!isNil(current)) {
- return [current, ...childPaths];
- }
-
- return childPaths;
- }
-
- return !isNil(current) ? [current] : [];
-}
-
-export function useHoistedRoutes(routes: RootRoute[], wrapManagedRoutes: (routes: Route[]) => Route, { allowedPaths }: UseHoistedRoutesOptions = {}): Route[] {
- // Hack to reuse the same array reference through re-renders.
- const [memoizedAllowedPaths] = useState(allowedPaths);
-
- return useMemo(() => {
- const hoistedRoutes: Route[] = [];
- const managedRoutes: Route[] = [];
-
- routes.forEach(({ hoist, ...route }) => {
- if (hoist === true) {
- hoistedRoutes.push(route);
- } else {
- managedRoutes.push(route);
- }
- });
-
- if (memoizedAllowedPaths) {
- // Find hoisted routes which are not included in allowedPaths.
- hoistedRoutes.forEach(x => {
- const allRoutePaths = getAllRoutePaths(x);
- const restrictedPaths = allRoutePaths.filter(y => !memoizedAllowedPaths.includes(y));
-
- if (restrictedPaths.length > 0) {
- throw new Error(`[squide] A module is hoisting the following routes [${restrictedPaths.map(y => `"${y}"`).join(", ")}] which are not included in the provided "allowedRoutes" option: [${allowedPaths?.map(y => `"${y}"`).join(", ")}].`);
- }
- });
- }
-
- const allRoutes = [
- ...hoistedRoutes,
- ...(wrapManagedRoutes ? [wrapManagedRoutes(managedRoutes)] : managedRoutes)
- ];
-
- return allRoutes;
- }, [routes, wrapManagedRoutes, memoizedAllowedPaths]);
-}
diff --git a/packages/react-router/src/useRenderedNavigationItems.tsx b/packages/react-router/src/useRenderedNavigationItems.tsx
index c95e6f211..5927f87ac 100644
--- a/packages/react-router/src/useRenderedNavigationItems.tsx
+++ b/packages/react-router/src/useRenderedNavigationItems.tsx
@@ -1,8 +1,7 @@
-import { useMemo, type ReactNode } from "react";
-import { isLinkItem, type NavigationItem, type NavigationLink, type NavigationSection, type RootNavigationItem } from "./navigationItemRegistry.ts";
-
import { isNil } from "@squide/core";
+import { useMemo, type ReactNode } from "react";
import type { LinkProps } from "react-router-dom";
+import { isLinkItem, type NavigationItem, type NavigationLink, type NavigationSection, type RootNavigationItem } from "./navigationItemRegistry.ts";
export interface NavigationLinkRenderProps {
label: ReactNode;
@@ -26,19 +25,19 @@ export type RenderItemFunction = (item: NavigationItemRenderProps, index: number
export type RenderSectionFunction = (elements: ReactNode[], index: number, level: number) => ReactNode;
-function toLinkProps({ label, additionalProps, ...linkProps }: NavigationLink): NavigationLinkRenderProps {
+function toLinkProps({ $label, $additionalProps, ...linkProps }: NavigationLink): NavigationLinkRenderProps {
return {
- label,
+ label: $label,
linkProps,
- additionalProps: additionalProps ?? {}
+ additionalProps: $additionalProps ?? {}
};
}
-function toMenuProps({ label, additionalProps }: NavigationSection, sectionElement: ReactNode): NavigationSectionRenderProps {
+function toMenuProps({ $label, $additionalProps }: NavigationSection, sectionElement: ReactNode): NavigationSectionRenderProps {
return {
- label,
+ label: $label,
section: sectionElement,
- additionalProps: additionalProps ?? {}
+ additionalProps: $additionalProps ?? {}
};
}
@@ -70,8 +69,8 @@ export function useRenderedNavigationItems(
const sortedItems = [...navigationItems]
.sort((x, y) => {
// Default an item priority to 0 to support negative priority.
- const xp = x.priority ?? 0;
- const yp = y.priority ?? 0;
+ const xp = x.$priority ?? 0;
+ const yp = y.$priority ?? 0;
if (xp === yp) {
return 0;
@@ -81,7 +80,7 @@ export function useRenderedNavigationItems(
})
// priority is intentionally omitted.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
- .map(({ priority, ...itemProps }) => itemProps);
+ .map(({ $priority, ...itemProps }) => itemProps);
return renderItems(sortedItems, renderItem, renderSection, 0, 0);
}, [navigationItems, renderItem, renderSection]);
diff --git a/packages/react-router/src/useRouteMatch.ts b/packages/react-router/src/useRouteMatch.ts
new file mode 100644
index 000000000..609610b72
--- /dev/null
+++ b/packages/react-router/src/useRouteMatch.ts
@@ -0,0 +1,26 @@
+import { matchRoutes } from "react-router-dom";
+import { useRoutes } from "./useRoutes.ts";
+
+export function useRouteMatch(locationArg: Partial) {
+ const routes = useRoutes();
+
+ const matchingRoutes = matchRoutes(routes, locationArg) ?? [];
+
+ if (matchingRoutes.length > 0) {
+ // When a route is nested, it also returns all the parts that constituate the whole route (for example the layouts and the boundaries).
+ // We only want to know the visiblity of the actual route that has been requested, which is always the last entry.
+ return matchingRoutes[matchingRoutes.length - 1]!.route;
+ }
+
+ return undefined;
+}
+
+export function useIsRouteMatchProtected(locationArg: Partial) {
+ const activeRoute = useRouteMatch(locationArg);
+
+ if (!activeRoute) {
+ throw new Error(`[squide] There's no matching route for the location: "${locationArg.pathname}". Did you add routes to React Router without using the runtime.registerRoute() function?`);
+ }
+
+ return activeRoute.$visibility === "protected";
+}
diff --git a/packages/react-router/tests/routeRegistry.test.tsx b/packages/react-router/tests/routeRegistry.test.tsx
new file mode 100644
index 000000000..c778512d8
--- /dev/null
+++ b/packages/react-router/tests/routeRegistry.test.tsx
@@ -0,0 +1,192 @@
+import { RouteRegistry, createIndexKey } from "../src/routeRegistry.ts";
+
+describe("createIndexKey", () => {
+ test("when the route is an index route, return undefined", () => {
+ const result = createIndexKey({
+ index: true,
+ element: Hello!
+ });
+
+ expect(result).toBeUndefined();
+ });
+
+ test("when the route has a path, return the route path", () => {
+ const result1 = createIndexKey({
+ path: "/nested",
+ element: Hello!
+ });
+
+ expect(result1).toBe("/nested");
+
+ const result2 = createIndexKey({
+ path: "/parent/nested",
+ element: Hello!
+ });
+
+ expect(result2).toBe("/parent/nested");
+ });
+
+ test("when the route has a path and the path ends with a separator, strip the separator", () => {
+ const result = createIndexKey({
+ path: "/parent/nested/",
+ element: Hello!
+ });
+
+ expect(result).toBe("/parent/nested");
+ });
+
+ test("when the route has a name, return the route name", () => {
+ const result = createIndexKey({
+ $name: "foo",
+ element: Hello!
+ });
+
+ expect(result).toBe("foo");
+ });
+
+ test("when this a pathless route, return undefined", () => {
+ const result = createIndexKey({
+ element: Hello!
+ });
+
+ expect(result).toBeUndefined();
+ });
+});
+
+describe("add", () => {
+ test("when a root route is added, return the \"registered\" registration status", () => {
+ const registry = new RouteRegistry();
+
+ const result = registry.add({
+ path: "/root",
+ element: Hello
+ }, {
+ hoist: true
+ });
+
+ expect(result.registrationStatus).toBe("registered");
+ });
+
+ test("when a root route is added and complete the pending registration of nested routes, add the registered routes to the returned \"completedPendingRegistrations\" array", () => {
+ const registry = new RouteRegistry();
+
+ registry.add({
+ path: "/root/another-level-1",
+ element: Hello
+ }, {
+ parentPath: "/root"
+ });
+
+ registry.add({
+ path: "/root/another-level-2",
+ element: Hello
+ }, {
+ parentPath: "/root"
+ });
+
+ const result = registry.add({
+ path: "/root",
+ element: Hello
+ }, {
+ hoist: true
+ });
+
+ expect(result.completedPendingRegistrations![0].path).toBe("/root/another-level-1");
+ expect(result.completedPendingRegistrations![1].path).toBe("/root/another-level-2");
+ });
+
+ test("when a root route is added and do not complete any pending registration, return an empty \"completedPendingRegistrations\" array", () => {
+ const registry = new RouteRegistry();
+
+ registry.add({
+ path: "/root/another-level-1",
+ element: Hello
+ }, {
+ parentPath: "/root"
+ });
+
+ registry.add({
+ path: "/root/another-level-2",
+ element: Hello
+ }, {
+ parentPath: "/root"
+ });
+
+ const result = registry.add({
+ path: "/toto",
+ element: Hello
+ }, {
+ hoist: true
+ });
+
+ expect(result.completedPendingRegistrations!.length).toBe(0);
+ });
+
+ test("when a nested route is pending for registration, return the \"pending\" registration status", () => {
+ const registry = new RouteRegistry();
+
+ const result = registry.add({
+ path: "/root/another-level",
+ element: Hello
+ }, {
+ parentPath: "/root"
+ });
+
+ expect(result.registrationStatus).toBe("pending");
+ });
+
+ test("when a nested route is registred, return the \"registered\" registration status", () => {
+ const registry = new RouteRegistry();
+
+ registry.add({
+ path: "/root",
+ element: Hello
+ }, {
+ hoist: true
+ });
+
+ const result = registry.add({
+ path: "/root/another-level",
+ element: Hello
+ }, {
+ parentPath: "/root"
+ });
+
+ expect(result.registrationStatus).toBe("registered");
+ });
+
+ test("when a nested route is added and complete the pending registration of nested routes, add the registered routes to the returned \"completedPendingRegistrations\" array", () => {
+ const registry = new RouteRegistry();
+
+ registry.add({
+ path: "/root/another-level-1",
+ element: Hello
+ }, {
+ parentPath: "/root/another-level/yet-another-level"
+ });
+
+ registry.add({
+ path: "/root/another-level-2",
+ element: Hello
+ }, {
+ parentPath: "/root/another-level/yet-another-level"
+ });
+
+ registry.add({
+ path: "/root",
+ element: Hello
+ }, {
+ hoist: true
+ });
+
+ const result = registry.add({
+ path: "/root/another-level/yet-another-level",
+ element: Hello
+ }, {
+ parentPath: "/root"
+ });
+
+ expect(result.completedPendingRegistrations![0].path).toBe("/root/another-level-1");
+ expect(result.completedPendingRegistrations![1].path).toBe("/root/another-level-2");
+ });
+});
diff --git a/packages/react-router/tests/runtime.test.tsx b/packages/react-router/tests/runtime.test.tsx
index 0fa460270..523e97586 100644
--- a/packages/react-router/tests/runtime.test.tsx
+++ b/packages/react-router/tests/runtime.test.tsx
@@ -1,366 +1,1059 @@
-import { createIndexKey } from "../src/routeRegistry.ts";
+import { ManagedRoutes, isManagedRoutesOutletRoute } from "../src/outlets.ts";
+import type { Route } from "../src/routeRegistry.ts";
import { Runtime } from "../src/runtime.ts";
-describe("createIndexKey", () => {
- test("when the route is an index route, append \"index\" to the parent path", () => {
- const result1 = createIndexKey({
- index: true,
- element: Hello!
- }, "/");
+describe("registerRoute", () => {
+ describe("managed routes", () => {
+ function registerManagedRoutesOutlet(runtime: Runtime) {
+ runtime.registerRoute(ManagedRoutes);
+ }
- expect(result1).toBe("/$index$");
+ function getManagedRoutes(routes: Route[]): Route[] | undefined {
+ for (const route of routes) {
+ if (isManagedRoutesOutletRoute(route)) {
+ return route.children as Route[];
+ }
- const result2 = createIndexKey({
- index: true,
- element: Hello!
- }, "/parent");
+ if (route.children) {
+ const managedRoutes = getManagedRoutes(route.children);
- expect(result2).toBe("/parent/$index$");
- });
+ if (managedRoutes) {
+ return managedRoutes as Route[];
+ }
+ }
+ }
+ }
- test("when the route is not an index route, return the route path", () => {
- const result1 = createIndexKey({
- path: "/nested",
- element: Hello!
- }, "/");
+ test("when the outlet is not registered, route registrations are pending", () => {
+ const runtime = new Runtime();
- expect(result1).toBe("/nested");
+ runtime.registerRoute({
+ path: "/foo",
+ element: Hello!
+ });
- const result2 = createIndexKey({
- path: "/parent/nested",
- element: Hello!
- }, "/parent");
+ expect(runtime.routes.length).toBe(0);
+ });
- expect(result2).toBe("/parent/nested");
- });
+ test("when the outlet is registered, pending route registrations are completed", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/foo",
+ element: Hello!
+ });
+
+ expect(runtime.routes.length).toBe(0);
+
+ registerManagedRoutesOutlet(runtime);
+
+ expect(runtime.routes.length).toBe(1);
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(1);
+ expect(routes[0].path).toBe("/foo");
+ });
+
+ test("can register an index route", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ index: true,
+ element: Hello!
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(1);
+ expect(routes[0].index).toBeTruthy();
+ });
+
+ test("can register a pathless route", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ element: Hello!
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(1);
+ expect(routes[0].index).toBeUndefined();
+ expect(routes[0].path).toBeUndefined();
+ });
+
+ test("can register multiple pathless routes", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ element: Hello!
+ });
+
+ runtime.registerRoute({
+ element: How
+ });
+
+ runtime.registerRoute({
+ element: Are
+ });
+
+ runtime.registerRoute({
+ element: You?
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(4);
+ });
+
+ test("can register a deeply nested route with pathless parent routes", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ element: Hello
,
+ children: [
+ {
+ element: You!
,
+ children: [
+ {
+ path: "/deeply-nested-route",
+ element: Hello from nested!
+ }
+ ]
+ }
+ ]
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(1);
+ expect(routes[0].children![0].children![0].path).toBe("/deeply-nested-route");
+ });
+
+ test("can register a deeply nested index route with pathless parent routes", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ element: Hello
,
+ children: [
+ {
+ element: You!
,
+ children: [
+ {
+ index: true,
+ element: Hello from nested!
+ }
+ ]
+ }
+ ]
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(1);
+ expect(routes[0].children![0].children![0].index).toBeTruthy();
+ });
+
+ test("can register a root route with a \"public\" visibility", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ $visibility: "public",
+ path: "/public",
+ element: Hello!
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(1);
+ expect(routes[0].path).toBe("/public");
+ expect(routes[0].$visibility).toBe("public");
+ });
+
+ test("can register a root route with a \"protected\" visibility", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ $visibility: "protected",
+ path: "/protected",
+ element: Hello!
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(1);
+ expect(routes[0].path).toBe("/protected");
+ expect(routes[0].$visibility).toBe("protected");
+ });
+
+ test("when a root route has no visibility property, it is considered as an \"protected\" route", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ path: "/foo",
+ element: Hello!
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(1);
+ expect(routes[0].path).toBe("/foo");
+ expect(routes[0].$visibility).toBe("protected");
+ });
+
+ test("can register a nested route with a \"public\" visibility", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ path: "/layout",
+ element: Hello!
,
+ children: [
+ {
+ $visibility: "public",
+ path: "/layout/nested",
+ element: Hello!
+ }
+ ]
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes[0].children![0].path).toBe("/layout/nested");
+ expect(routes[0].children![0].$visibility).toBe("public");
+ });
+
+ test("can register a nested route with a \"protected\" visibility", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ path: "/layout",
+ element: Hello!
,
+ children: [
+ {
+ $visibility: "protected",
+ path: "/layout/nested",
+ element: Hello!
+ }
+ ]
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes[0].children![0].path).toBe("/layout/nested");
+ expect(routes[0].children![0].$visibility).toBe("protected");
+ });
+
+ test("when a nested route has no visibility property, it is considered as a \"protected\" route", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ path: "/layout",
+ element: Hello!
,
+ children: [
+ {
+ path: "/layout/nested",
+ element: Hello!
+ }
+ ]
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes[0].children![0].path).toBe("/layout/nested");
+ expect(routes[0].children![0].$visibility).toBe("protected");
+ });
+
+ test("can register a root route with a name", () => {
+ const runtime = new Runtime();
+
+ registerManagedRoutesOutlet(runtime);
+
+ runtime.registerRoute({
+ $name: "foo",
+ element: Hello!
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(1);
+ expect(routes[0].$name).toBe("foo");
+ });
+
+ test("can register a nested route with a name", () => {
+ const runtime = new Runtime();
- test("when the route is not an index route and the path ends with a separator, strip the separator", () => {
- const result = createIndexKey({
- path: "/parent/nested/",
- element: Hello!
- }, "/parent");
+ registerManagedRoutesOutlet(runtime);
- expect(result).toBe("/parent/nested");
+ runtime.registerRoute({
+ element: Hello
,
+ children: [
+ {
+ $name: "foo",
+ element: You!
+ }
+ ]
+ });
+
+ const routes = getManagedRoutes(runtime.routes)!;
+
+ expect(routes.length).toBe(1);
+ expect(routes[0].children![0].$name).toBe("foo");
+ });
});
-});
-describe("registerRoutes", () => {
- test("can register a root route", () => {
- const runtime = new Runtime();
+ describe("hoisted", () => {
+ test("can register an index route", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ index: true,
+ element: Hello!
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].index).toBeTruthy();
+ });
+
+ test("can register a pathless route", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ element: Hello!
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].index).toBeUndefined();
+ expect(runtime.routes[0].path).toBeUndefined();
+ });
+
+ test("can register multiple pathless routes", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ element: Hello!
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ element: How
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ element: Are
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ element: You?
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes.length).toBe(4);
+ });
+
+ test("can register a deeply nested route with pathless parent routes", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ element: Hello
,
+ children: [
+ {
+ element: You!
,
+ children: [
+ {
+ path: "/deeply-nested-route",
+ element: Hello from nested!
+ }
+ ]
+ }
+ ]
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].children![0].path).toBe("/deeply-nested-route");
+ });
- runtime.registerRoutes([
- {
- path: "/root",
+ test("can register a deeply nested index route with pathless parent routes", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ element: Hello
,
+ children: [
+ {
+ element: You!
,
+ children: [
+ {
+ index: true,
+ element: Hello from nested!
+ }
+ ]
+ }
+ ]
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].children![0].index).toBeTruthy();
+ });
+
+ test("can register a root route with a \"public\" visibility", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ $visibility: "public",
+ path: "/public",
+ element: Hello!
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes[0].path).toBe("/public");
+ expect(runtime.routes[0].$visibility).toBe("public");
+ });
+
+ test("can register a root route with a \"protected\" visibility", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ $visibility: "protected",
+ path: "/protected",
+ element: Hello!
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes[0].path).toBe("/protected");
+ expect(runtime.routes[0].$visibility).toBe("protected");
+ });
+
+ test("when a root route has no visibility property, it is considered as an \"protected\" route", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/foo",
+ element: Hello!
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes[0].path).toBe("/foo");
+ expect(runtime.routes[0].$visibility).toBe("protected");
+ });
+
+ test("can register a nested route with a \"public\" visibility", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/layout",
element: Hello!
,
+ children: [
+ {
+ $visibility: "public",
+ path: "/layout/nested",
+ element: Hello!
+ }
+ ]
+ }, {
hoist: true
- }
- ]);
+ });
+
+ expect(runtime.routes[0].children![0].path).toBe("/layout/nested");
+ expect(runtime.routes[0].children![0].$visibility).toBe("public");
+ });
+
+ test("can register a nested route with a \"protected\" visibility", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/layout",
+ element: Hello!
,
+ children: [
+ {
+ $visibility: "protected",
+ path: "/layout/nested",
+ element: Hello!
+ }
+ ]
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes[0].children![0].path).toBe("/layout/nested");
+ expect(runtime.routes[0].children![0].$visibility).toBe("protected");
+ });
+
+ test("when a nested route has no visibility property, it is considered as an \"protected\" route", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/layout",
+ element: Hello!
,
+ children: [
+ {
+ path: "/layout/nested",
+ element: Hello!
+ }
+ ]
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes[0].children![0].path).toBe("/layout/nested");
+ expect(runtime.routes[0].children![0].$visibility).toBe("protected");
+ });
+
+ test("can register a root route with a name", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ $name: "foo",
+ element: Hello!
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].$name).toBe("foo");
+ });
- expect(runtime.routes.length).toBe(1);
- expect(runtime.routes[0].path).toBe("/root");
+ test("can register a nested route with a name", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ element: Hello
,
+ children: [
+ {
+ $name: "foo",
+ element: You!
+ }
+ ]
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].$name).toBe("foo");
+ });
});
- test("when the layout route has already been registered, register the nested route", () => {
- const runtime = new Runtime();
+ describe("parentPath", () => {
+ test("when the parent route has already been registered, register the nested route", () => {
+ const runtime = new Runtime();
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout",
element: Hello!
- }
- ]);
+ }, {
+ hoist: true
+ });
- expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes.length).toBe(1);
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout/nested",
element: Hello!
- }
- ], { layoutPath: "/layout" });
+ }, {
+ parentPath: "/layout"
+ });
- expect(runtime.routes.length).toBe(1);
- expect(runtime.routes[0].children).toBeDefined();
- expect(runtime.routes[0].children?.length).toBe(1);
- });
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].path).toBe("/layout/nested");
+ });
- test("when the layout route has not been registered, do not register the nested route", () => {
- const runtime = new Runtime();
+ test("when the parent route has not been registered, do not register the nested route", () => {
+ const runtime = new Runtime();
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout/nested",
element: Hello!
- }
- ], { layoutPath: "/layout" });
+ }, {
+ parentPath: "/layout"
+ });
- expect(runtime.routes.length).toBe(0);
- });
+ expect(runtime.routes.length).toBe(0);
+ });
- test("when the layout route has not been registered, register the pending route once the layout route is registered", () => {
- const runtime = new Runtime();
+ test("when the parent route has not been registered, register the pending route once the parent route is registered", () => {
+ const runtime = new Runtime();
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout/nested",
element: Hello!
- }
- ], { layoutPath: "/layout" });
+ }, {
+ parentPath: "/layout"
+ });
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout/another-nested",
element: Hello!
- }
- ], { layoutPath: "/layout" });
+ }, {
+ parentPath: "/layout"
+ });
- expect(runtime.routes.length).toBe(0);
+ expect(runtime.routes.length).toBe(0);
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/foo",
element: Hello!
- }
- ]);
+ }, {
+ hoist: true
+ });
- expect(runtime.routes.length).toBe(1);
- expect(runtime.routes[0].children).toBeUndefined();
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children).toBeUndefined();
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout",
element: Hello!
- }
- ]);
+ }, {
+ hoist: true
+ });
- expect(runtime.routes.length).toBe(2);
- expect(runtime.routes[1].children).toBeDefined();
- expect(runtime.routes[1].children?.length).toBe(2);
- });
+ expect(runtime.routes.length).toBe(2);
+ expect(runtime.routes[1].children?.length).toBe(2);
+ });
- test("can register a deeply nested route", () => {
- const runtime = new Runtime();
+ test("when the parent route has not been registered, and the parent route is nested in a pending registration single block, register the pending route once the parent route is registered", () => {
+ const runtime = new Runtime();
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
+ path: "/layout/nested",
+ element: Hello!
+ }, {
+ parentPath: "/layout"
+ });
+
+ expect(runtime.routes.length).toBe(0);
+
+ runtime.registerRoute({
+ element: Hello
,
+ children: [
+ {
+ element: You!
,
+ children: [
+ {
+ path: "/layout",
+ element: Hello from nested!
+ }
+ ]
+ }
+ ]
+ }, {
+ hoist: true
+ });
+
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].path).toBeUndefined();
+ expect(runtime.routes[0].children![0].children![0].children![0].path).toBe("/layout/nested");
+ });
+
+ test("can register a route under a deeply nested layout", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
path: "/layout",
element: Hello!
- }
- ]);
+ }, {
+ hoist: true
+ });
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout/nested",
element: Hello!
- }
- ], { layoutPath: "/layout" });
+ }, {
+ parentPath: "/layout"
+ });
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout/nested/another-level",
element: Hello!
- }
- ], { layoutPath: "/layout/nested" });
+ }, {
+ parentPath: "/layout/nested"
+ });
- expect(runtime.routes.length).toBe(1);
- expect(runtime.routes[0].children![0].children).toBeDefined();
- expect(runtime.routes[0].children![0].children?.length).toBe(1);
- });
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].children![0].path).toBe("/layout/nested/another-level");
+ });
- test("when the layout path has a trailing separator but the layout route path doesn't have a trailing separator, the nested route is registered", () => {
- const runtime = new Runtime();
+ test("can register a route under a deeply nested layout that has been registered in a single block", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ element: Hello
,
+ children: [
+ {
+ element: You!
,
+ children: [
+ {
+ path: "/deeply-nested-layout",
+ element: Hello from nested!
+ }
+ ]
+ }
+ ]
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ path: "/deeply-nested-layout/another-level",
+ element: Hello!
+ }, {
+ parentPath: "/deeply-nested-layout"
+ });
- runtime.registerRoutes([
- {
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].children![0].children![0].path).toBe("/deeply-nested-layout/another-level");
+
+ runtime.registerRoute({
+ path: "/deeply-nested-layout/another-level/yet-another-level",
+ element: Hello!
+ }, {
+ parentPath: "/deeply-nested-layout/another-level"
+ });
+
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].children![0].children![0].children![0].path).toBe("/deeply-nested-layout/another-level/yet-another-level");
+ });
+
+ test("when the specified parent path has a trailing separator but the parent route path doesn't have a trailing separator, the nested route is registered", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
path: "/layout",
element: Hello!
- }
- ]);
+ }, {
+ hoist: true
+ });
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout/nested",
element: Hello!
- }
- ], { layoutPath: "/layout/" });
+ }, {
+ parentPath: "/layout/"
+ });
- expect(runtime.routes[0].children).toBeDefined();
- expect(runtime.routes[0].children!.length).toBe(1);
- });
+ expect(runtime.routes[0].children![0].path).toBe("/layout/nested");
+ });
- test("when the layout path doesn't have a trailing separator but the layout route path have a trailing separator, the nested route is registered", () => {
- const runtime = new Runtime();
+ test("when the specified parent path doesn't have a trailing separator but the parent route path have a trailing separator, the nested route is registered", () => {
+ const runtime = new Runtime();
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout/",
element: Hello!
- }
- ]);
+ }, {
+ hoist: true
+ });
- runtime.registerRoutes([
- {
+ runtime.registerRoute({
path: "/layout/nested",
element: Hello!
- }
- ], { layoutPath: "/layout" });
-
- expect(runtime.routes[0].children).toBeDefined();
- expect(runtime.routes[0].children!.length).toBe(1);
+ }, {
+ parentPath: "/layout"
+ });
+
+ expect(runtime.routes[0].children![0].path).toBe("/layout/nested");
+ });
+
+ test("when a route is hoisted, it cannot be nested under another route", () => {
+ const runtime = new Runtime();
+
+ expect(() => runtime.registerRoute({
+ element: Hello
+ }, {
+ hoist: true,
+ parentPath: "/foo"
+ })).toThrow();
+ });
});
- test("can register a nested route for an index layout route", () => {
- const runtime = new Runtime();
+ describe("parentName", () => {
+ test("when the parent route has already been registered, register the nested route", () => {
+ const runtime = new Runtime();
- runtime.registerRoutes([
- {
- path: "/layout",
+ runtime.registerRoute({
+ $name: "layout",
element: Hello!
- }
- ]);
+ }, {
+ hoist: true
+ });
- runtime.registerRoutes([
- {
- index: true,
+ expect(runtime.routes.length).toBe(1);
+
+ runtime.registerRoute({
+ path: "/layout/nested",
element: Hello!
- }
- ], { layoutPath: "/layout" });
+ }, {
+ parentName: "layout"
+ });
- runtime.registerRoutes([
- {
- path: "/layout/another-level",
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].path).toBe("/layout/nested");
+ });
+
+ test("when the parent route has not been registered, do not register the nested route", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/layout/nested",
element: Hello!
- }
- ], { layoutPath: "/layout/$index$" });
+ }, {
+ parentName: "layout"
+ });
- expect(runtime.routes[0].children![0].children).toBeDefined();
- expect(runtime.routes[0].children![0].children?.length).toBe(1);
- expect(runtime.routes[0].children![0].children![0].path).toBe("/layout/another-level");
- });
+ expect(runtime.routes.length).toBe(0);
+ });
- test("can register a nested route for the root index route", () => {
- const runtime = new Runtime();
+ test("when the parent route has not been registered, register the pending route once the parent route is registered", () => {
+ const runtime = new Runtime();
- runtime.registerRoutes([
- {
- index: true,
+ runtime.registerRoute({
+ path: "/layout/nested",
element: Hello!
- }
- ]);
+ }, {
+ parentName: "layout" });
- runtime.registerRoutes([
- {
- path: "/nested",
+ runtime.registerRoute({
+ path: "/layout/another-nested",
element: Hello!
}
- ], { layoutPath: "/$index$" });
+ , {
+ parentName: "layout"
+ });
- expect(runtime.routes[0].children).toBeDefined();
- expect(runtime.routes[0].children?.length).toBe(1);
- expect(runtime.routes[0].children![0].path).toBe("/nested");
- });
-});
+ expect(runtime.routes.length).toBe(0);
-describe("registerNavigationItems", () => {
- test("can register a root navigation link", () => {
- const runtime = new Runtime();
+ runtime.registerRoute({
+ path: "/foo",
+ element: Hello!
+ }, {
+ hoist: true
+ });
- runtime.registerNavigationItems([
- {
- to: "/root",
- label: "Root"
- }
- ]);
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children).toBeUndefined();
- expect(runtime.getNavigationItems().length).toBe(1);
- expect(runtime.getNavigationItems()[0].to).toBe("/root");
- });
+ runtime.registerRoute({
+ $name: "layout",
+ element: Hello!
+ }, {
+ hoist: true
+ });
- test("can register a root navigation section", () => {
- const runtime = new Runtime();
+ expect(runtime.routes.length).toBe(2);
+ expect(runtime.routes[1].children?.length).toBe(2);
+ });
+
+ test("when the parent route has not been registered, and the parent route is nested in a pending registration single block, register the pending route once the parent route is registered", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/layout/nested",
+ element: Hello!
+ }, {
+ parentName: "layout"
+ });
- runtime.registerNavigationItems([
- {
- label: "Section",
+ expect(runtime.routes.length).toBe(0);
+
+ runtime.registerRoute({
+ element: Hello
,
children: [
{
- to: "/child",
- label: "Child"
+ element: You!
,
+ children: [
+ {
+ $name: "layout",
+ element: Hello from nested!
+ }
+ ]
}
]
- }
- ]);
+ }, {
+ hoist: true
+ });
- expect(runtime.getNavigationItems().length).toBe(1);
- expect(runtime.getNavigationItems()[0].label).toBe("Section");
- });
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].path).toBeUndefined();
+ expect(runtime.routes[0].children![0].children![0].children![0].path).toBe("/layout/nested");
+ });
- test("can register a navigation link for a specific menu id", () => {
- const runtime = new Runtime();
+ test("can register a route under a deeply nested layout", () => {
+ const runtime = new Runtime();
- runtime.registerNavigationItems([
- {
- to: "/link",
- label: "Link"
+ runtime.registerRoute({
+ $name: "layout",
+ element: Hello!
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ $name: "layout-nested",
+ element: Hello!
}
- ], { menuId: "link-menu" });
+ , {
+ parentName: "layout"
+ });
- expect(runtime.getNavigationItems("link-menu").length).toBe(1);
- expect(runtime.getNavigationItems("link-menu")[0].to).toBe("/link");
- });
+ runtime.registerRoute({
+ path: "/layout/nested/another-level",
+ element: Hello!
+ }, {
+ parentName: "layout-nested"
+ });
- test("can register a navigation section for a specific menu id", () => {
- const runtime = new Runtime();
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].children![0].path).toBe("/layout/nested/another-level");
+ });
+
+ test("can register a route under a deeply nested layout that has been registered in a single block", () => {
+ const runtime = new Runtime();
- runtime.registerNavigationItems([
- {
- label: "Section",
+ runtime.registerRoute({
+ element: Hello
,
children: [
{
- to: "/child",
- label: "Child"
+ element: You!
,
+ children: [
+ {
+ $name: "deeply-nested-layout",
+ element: Hello from nested!
+ }
+ ]
}
]
- }
- ], { menuId: "section-menu" });
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ $name: "deeply-nested-layout/another-level",
+ element: Hello!
+ }, {
+ parentName: "deeply-nested-layout"
+ });
+
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].children![0].children![0].$name).toBe("deeply-nested-layout/another-level");
- expect(runtime.getNavigationItems("section-menu").length).toBe(1);
- expect(runtime.getNavigationItems("section-menu")[0].label).toBe("Section");
+ runtime.registerRoute({
+ path: "/deeply-nested-layout/another-level/yet-another-level",
+ element: Hello!
+ }, {
+ parentName: "deeply-nested-layout/another-level"
+ });
+
+ expect(runtime.routes.length).toBe(1);
+ expect(runtime.routes[0].children![0].children![0].children![0].children![0].path).toBe("/deeply-nested-layout/another-level/yet-another-level");
+ });
+
+ test("when a route is hoisted, it cannot be nested under another route", () => {
+ const runtime = new Runtime();
+
+ expect(() => runtime.registerRoute({
+ element: Hello
+ }, {
+ hoist: true,
+ parentName: "foo"
+ })).toThrow();
+ });
});
});
-describe("_completeRegistration", () => {
- test("when the registration is completed and there are no pending registrations, do nothing", () => {
+describe("registerNavigationItem", () => {
+ test("can register a root navigation link", () => {
const runtime = new Runtime();
- runtime.registerRoutes([
- {
- path: "/layout/nested",
- element: Hello!
- }
- ], { layoutPath: "/layout" });
+ runtime.registerNavigationItem({
+ $label: "Root",
+ to: "/root"
+ });
- runtime.registerRoutes([
- {
- path: "/layout",
- element: Hello!
- }
- ]);
+ expect(runtime.getNavigationItems()[0].to).toBe("/root");
+ });
+
+ test("can register a root navigation section", () => {
+ const runtime = new Runtime();
- expect(() => runtime._completeRegistration()).not.toThrow();
+ runtime.registerNavigationItem({
+ $label: "Section",
+ children: [
+ {
+ $label: "Child",
+ to: "/child"
+ }
+ ]
+ });
+
+ expect(runtime.getNavigationItems()[0].$label).toBe("Section");
});
- test("when the registration is completed and there are pending registrations, throw an error", () => {
+ test("can register a navigation link for a specific menu id", () => {
const runtime = new Runtime();
- runtime.registerRoutes([
- {
- path: "/layout/nested",
- element: Hello!
- }
- ], { layoutPath: "/layout" });
+ runtime.registerNavigationItem({
+ $label: "Link",
+ to: "/link"
+ }, {
+ menuId: "link-menu"
+ });
+
+ expect(runtime.getNavigationItems("link-menu")[0].to).toBe("/link");
+ });
- expect(() => runtime._completeRegistration()).toThrow();
+ test("can register a navigation section for a specific menu id", () => {
+ const runtime = new Runtime();
+
+ runtime.registerNavigationItem({
+ $label: "Section",
+ children: [
+ {
+ $label: "Child",
+ to: "/child"
+ }
+ ]
+ }, {
+ menuId: "section-menu"
+ });
+
+ expect(runtime.getNavigationItems("section-menu")[0].$label).toBe("Section");
});
});
@@ -368,39 +1061,35 @@ describe("getNavigationItems", () => {
test("when no menu id is specified, returns all the registered navigation items for the root menu", () => {
const runtime = new Runtime();
- runtime.registerNavigationItems([
- {
- to: "/item-1",
- label: "Item 1"
- },
- {
- to: "/item-2",
- label: "Item 2"
- }
- ]);
+ runtime.registerNavigationItem({
+ $label: "Item 1",
+ to: "/item-1"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 2",
+ to: "/item-2"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 3",
+ to: "/item-3"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 4",
+ to: "/item-4"
+ }, {
+ menuId: "menu-1"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 5",
+ to: "/item-5"
+ }, {
+ menuId: "menu-2"
+ });
- runtime.registerNavigationItems([
- {
- to: "/item-3",
- label: "Item 3"
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/item-4",
- label: "Item 4"
- }
- ], { menuId: "menu-1" });
-
- runtime.registerNavigationItems([
- {
- to: "/item-5",
- label: "Item 5"
- }
- ], { menuId: "menu-2" });
-
- expect(runtime.getNavigationItems().length).toBe(3);
expect(runtime.getNavigationItems()[0].to).toBe("/item-1");
expect(runtime.getNavigationItems()[1].to).toBe("/item-2");
expect(runtime.getNavigationItems()[2].to).toBe("/item-3");
@@ -409,39 +1098,127 @@ describe("getNavigationItems", () => {
test("when no menu id is specified, returns all the registered navigation items for that specific menu", () => {
const runtime = new Runtime();
- runtime.registerNavigationItems([
- {
- to: "/item-1",
- label: "Item 1"
- },
- {
- to: "/item-2",
- label: "Item 2"
- }
- ]);
+ runtime.registerNavigationItem({
+ $label: "Item 1",
+ to: "/item-1"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 2",
+ to: "/item-2"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 3",
+ to: "/item-3"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 4",
+ to: "/item-4"
+ }, {
+ menuId: "menu-1"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 5",
+ to: "/item-5"
+ }, {
+ menuId: "menu-2"
+ });
- runtime.registerNavigationItems([
- {
- to: "/item-3",
- label: "Item 3"
- }
- ]);
+ expect(runtime.getNavigationItems("menu-1")[0].to).toBe("/item-4");
+ });
+});
- runtime.registerNavigationItems([
- {
- to: "/item-4",
- label: "Item 4"
- }
- ], { menuId: "menu-1" });
+describe("_completeRegistration", () => {
+ describe("managed routes", () => {
+ test("when the outlet is missing, the error message mentions the ManagedRoutes outlet", () => {
+ const runtime = new Runtime();
+ let errorMessage;
+
+ runtime.registerRoute({
+ path: "/layout",
+ element: Hello!
+ });
- runtime.registerNavigationItems([
- {
- to: "/item-5",
- label: "Item 5"
+ try {
+ runtime._completeRegistration();
+ } catch (error: unknown) {
+ errorMessage = (error as Error).message;
}
- ], { menuId: "menu-2" });
- expect(runtime.getNavigationItems("menu-1").length).toBe(1);
- expect(runtime.getNavigationItems("menu-1")[0].to).toBe("/item-4");
+ expect(errorMessage).toContain("ManagedRoutes");
+ });
+ });
+
+ describe("parentPath", () => {
+ test("when the registration is completed and there are no pending registrations, do nothing", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/layout/nested",
+ element: Hello!
+ }, {
+ parentPath: "/layout"
+ });
+
+ runtime.registerRoute({
+ path: "/layout",
+ element: Hello!
+ }, {
+ hoist: true
+ });
+
+ expect(() => runtime._completeRegistration()).not.toThrow();
+ });
+
+ test("when the registration is completed and there are pending registrations, throw an error", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/layout/nested",
+ element: Hello!
+ }, {
+ parentPath: "/layout"
+ });
+
+ expect(() => runtime._completeRegistration()).toThrow();
+ });
+ });
+
+ describe("parentName", () => {
+ test("when the registration is completed and there are no pending registrations, do nothing", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/layout/nested",
+ element: Hello!
+ }, {
+ parentName: "layout"
+ });
+
+ runtime.registerRoute({
+ $name: "layout",
+ element: Hello!
+ }, {
+ hoist: true
+ });
+
+ expect(() => runtime._completeRegistration()).not.toThrow();
+ });
+
+ test("when the registration is completed and there are pending registrations, throw an error", () => {
+ const runtime = new Runtime();
+
+ runtime.registerRoute({
+ path: "/layout/nested",
+ element: Hello!
+ }, {
+ parentName: "layout"
+ });
+
+ expect(() => runtime._completeRegistration()).toThrow();
+ });
});
});
diff --git a/packages/react-router/tests/useHoistedRoutes.test.tsx b/packages/react-router/tests/useHoistedRoutes.test.tsx
deleted file mode 100644
index d17bfd49a..000000000
--- a/packages/react-router/tests/useHoistedRoutes.test.tsx
+++ /dev/null
@@ -1,131 +0,0 @@
-import { renderHook } from "@testing-library/react";
-import type { RootRoute, Route } from "../src/routeRegistry.ts";
-import { useHoistedRoutes, type UseHoistedRoutesOptions } from "../src/useHoistedRoutes.ts";
-
-test("hoisted routes are at the root", () => {
- const routes: RootRoute[] = [
- { path: "/foo", element: Foo
},
- { path: "/hoisted", element: Hoisted
, hoist: true }
- ];
-
- const wrapManagedRoutes = (managedRoutes: Route[]) => {
- return {
- path: "/wrapper",
- children: [
- ...managedRoutes
- ]
- };
- };
-
- const { result } = renderHook(({ routes: x, wrapManagedRoutes: y }) => useHoistedRoutes(x, y), {
- initialProps: { routes, wrapManagedRoutes }
- });
-
- expect(result.current.length).toBe(2);
- expect(result.current[0].path).toBe("/hoisted");
-});
-
-test("managed routes are wrapped", () => {
- const routes: RootRoute[] = [
- { path: "/foo", element: Foo
},
- { path: "/hoisted", element: Hoisted
, hoist: true }
- ];
-
- const wrapManagedRoutes = (managedRoutes: Route[]) => {
- return {
- path: "/wrapper",
- children: [
- ...managedRoutes
- ]
- };
- };
-
- const { result } = renderHook(({ routes: x, wrapManagedRoutes: y }) => useHoistedRoutes(x, y), {
- initialProps: {
- routes,
- wrapManagedRoutes
- }
- });
-
- expect(result.current.length).toBe(2);
- expect(result.current[1].path).toBe("/wrapper");
- // eslint-disable-next-line testing-library/no-node-access
- expect(result.current[1].children![0].path).toBe("/foo");
-});
-
-test("when a restricted route is hoisted, throw an error", () => {
- // Prevent the expected exception from printing in the console.
- const consoleMock = jest.spyOn(console, "error").mockImplementation(jest.fn());
-
- const routes: RootRoute[] = [
- { path: "/foo", element: Foo
},
- { path: "/hoisted", element: Hoisted
, hoist: true },
- { path: "/bar", element: Bar
, hoist: true }
- ];
-
- const wrapManagedRoutes = (managedRoutes: Route[]) => {
- return {
- path: "/wrapper",
- children: [
- ...managedRoutes
- ]
- };
- };
-
- expect(() => renderHook(({ routes: x, wrapManagedRoutes: y, options }) => useHoistedRoutes(x, y, options), {
- initialProps: {
- routes,
- wrapManagedRoutes,
- options: {
- allowedPaths: [
- "/hoisted"
- ]
- } satisfies UseHoistedRoutesOptions
- }
- })).toThrow(/\/bar/);
-
- consoleMock.mockRestore();
-});
-
-test("returned array is immutable", () => {
- const routes: RootRoute[] = [
- { path: "/foo", element: Foo
},
- { path: "/hoisted", element: Hoisted
, hoist: true }
- ];
-
- const wrapManagedRoutes = (managedRoutes: Route[]) => {
- return {
- path: "/wrapper",
- children: [
- ...managedRoutes
- ]
- };
- };
-
- const { result, rerender } = renderHook(({ routes: x, wrapManagedRoutes: y }) => useHoistedRoutes(x, y), {
- initialProps: {
- routes,
- wrapManagedRoutes
- }
- });
-
- const array1 = result.current;
-
- // Haven't updated the routes, the returned array should be "array1".
- rerender({
- routes,
- wrapManagedRoutes
- });
-
- const array2 = result.current;
-
- rerender({
- routes: [...routes, { path: "/bar", element: Bar
}],
- wrapManagedRoutes
- });
-
- const array3 = result.current;
-
- expect(array1).toEqual(array2);
- expect(array1).not.toEqual(array3);
-});
diff --git a/packages/react-router/tests/useNavigationItems.test.tsx b/packages/react-router/tests/useNavigationItems.test.tsx
index f01411150..1b3f56419 100644
--- a/packages/react-router/tests/useNavigationItems.test.tsx
+++ b/packages/react-router/tests/useNavigationItems.test.tsx
@@ -17,37 +17,34 @@ function renderWithRuntime(runtime: Runtime, menuId?: string) {
test("when no menu id is specified, returns all the registered navigation items for the root menu", () => {
const runtime = new Runtime();
- runtime.registerNavigationItems([
- {
- to: "/item-1",
- label: "Item 1"
- },
- {
- to: "/item-2",
- label: "Item 2"
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/item-3",
- label: "Item 3"
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/item-4",
- label: "Item 4"
- }
- ], { menuId: "menu-1" });
-
- runtime.registerNavigationItems([
- {
- to: "/item-5",
- label: "Item 5"
- }
- ], { menuId: "menu-2" });
+ runtime.registerNavigationItem({
+ $label: "Item 1",
+ to: "/item-1"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 2",
+ to: "/item-2"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 3",
+ to: "/item-3"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 4",
+ to: "/item-4"
+ }, {
+ menuId: "menu-1"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 5",
+ to: "/item-5"
+ }, {
+ menuId: "menu-2"
+ });
const { result } = renderWithRuntime(runtime);
@@ -57,37 +54,34 @@ test("when no menu id is specified, returns all the registered navigation items
test("when a menu id is specified, returns all the registered navigation items for that specific menu", () => {
const runtime = new Runtime();
- runtime.registerNavigationItems([
- {
- to: "/item-1",
- label: "Item 1"
- },
- {
- to: "/item-2",
- label: "Item 2"
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/item-3",
- label: "Item 3"
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/item-4",
- label: "Item 4"
- }
- ], { menuId: "menu-1" });
-
- runtime.registerNavigationItems([
- {
- to: "/item-5",
- label: "Item 5"
- }
- ], { menuId: "menu-2" });
+ runtime.registerNavigationItem({
+ $label: "Item 1",
+ to: "/item-1"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 2",
+ to: "/item-2"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 3",
+ to: "/item-3"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 4",
+ to: "/item-4"
+ }, {
+ menuId: "menu-1"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Item 5",
+ to: "/item-5"
+ }, {
+ menuId: "menu-2"
+ });
const { result } = renderWithRuntime(runtime, "menu-1");
@@ -97,9 +91,10 @@ test("when a menu id is specified, returns all the registered navigation items f
test("returned array is immutable", () => {
const runtime = new Runtime();
- runtime.registerNavigationItems([
- { to: "/foo", label: "Foo" }
- ]);
+ runtime.registerNavigationItem({
+ $label: "Foo",
+ to: "/foo"
+ });
const { result, rerender } = renderWithRuntime(runtime);
@@ -110,9 +105,10 @@ test("returned array is immutable", () => {
const array2 = result.current;
- runtime.registerNavigationItems([
- { to: "/bar", label: "Bar" }
- ]);
+ runtime.registerNavigationItem({
+ $label: "Bar",
+ to: "/bar"
+ });
// Added a new navigation item, the returned array should be a new instance.
rerender();
diff --git a/packages/react-router/tests/useRenderedNavigationItems.test.tsx b/packages/react-router/tests/useRenderedNavigationItems.test.tsx
index f8519fb6e..d9b5edd96 100644
--- a/packages/react-router/tests/useRenderedNavigationItems.test.tsx
+++ b/packages/react-router/tests/useRenderedNavigationItems.test.tsx
@@ -1,7 +1,7 @@
import { renderHook } from "@testing-library/react";
import { useCallback, type ReactNode } from "react";
import renderer from "react-test-renderer";
-import type { RootNavigationItem } from "../src/navigationItemRegistry.ts";
+import type { NavigationItem, RootNavigationItem } from "../src/navigationItemRegistry.ts";
import { isNavigationLink, useRenderedNavigationItems, type NavigationLinkRenderProps, type NavigationSectionRenderProps, type RenderItemFunction, type RenderSectionFunction } from "../src/useRenderedNavigationItems.tsx";
type RenderLinkItemFunction = (item: NavigationLinkRenderProps, index: number, level: number) => ReactNode;
@@ -63,22 +63,22 @@ function TestComponent({ navigationItems }: TestComponentProps) {
test("highest priority goes first", () => {
const navigationItems: RootNavigationItem[] = [
{
- to: "/foo",
- label: "Foo"
+ $label: "Foo",
+ to: "/foo"
},
{
- to: "/bar",
- label: "Bar",
- priority: 5
+ $label: "Bar",
+ $priority: 5,
+ to: "/bar"
},
{
- to: "/toto",
- label: "Toto",
- priority: 99
+ $label: "Toto",
+ $priority: 99,
+ to: "/toto"
},
{
- to: "/tutu",
- label: "Tutu"
+ $label: "Tutu",
+ to: "/tutu"
}
];
@@ -92,21 +92,21 @@ test("highest priority goes first", () => {
test("negative priority goes last", () => {
const navigationItems: RootNavigationItem[] = [
{
- to: "/foo",
- label: "Foo"
+ $label: "Foo",
+ to: "/foo"
},
{
- to: "/bar",
- label: "Bar"
+ $label: "Bar",
+ to: "/bar"
},
{
- to: "/toto",
- label: "Toto",
- priority: -1
+ $label: "Toto",
+ $priority: -1,
+ to: "/toto"
},
{
- to: "/tutu",
- label: "Tutu"
+ $label: "Tutu",
+ to: "/tutu"
}
];
@@ -120,19 +120,19 @@ test("negative priority goes last", () => {
test("support 2 section levels", () => {
const navigationItems: RootNavigationItem[] = [
{
- to: "/foo",
- label: "Foo"
+ $label: "Foo",
+ to: "/foo"
},
{
- label: "Bar",
+ $label: "Bar",
children: [
{
- to: "/toto",
- label: "Toto"
+ $label: "Toto",
+ to: "/toto"
},
{
- to: "/tutu",
- label: "Tutu"
+ $label: "Tutu",
+ to: "/tutu"
}
]
}
@@ -148,22 +148,22 @@ test("support 2 section levels", () => {
test("support 3 section levels", () => {
const navigationItems: RootNavigationItem[] = [
{
- to: "/foo",
- label: "Foo"
+ $label: "Foo",
+ to: "/foo"
},
{
- label: "Bar",
+ $label: "Bar",
children: [
{
- to: "/toto",
- label: "Toto"
+ $label: "Toto",
+ to: "/toto"
},
{
- label: "Tutu",
+ $label: "Tutu",
children: [
{
- to: "/titi",
- label: "Titi"
+ $label: "Titi",
+ to: "/titi"
}
]
}
@@ -181,15 +181,15 @@ test("support 3 section levels", () => {
test("Link item additionalProps are rendered", () => {
const navigationItems: RootNavigationItem[] = [
{
- to: "/foo",
- label: "Foo",
- additionalProps: {
+ $label: "Foo",
+ $additionalProps: {
style: { color: "red" }
- }
+ },
+ to: "/foo"
},
{
- to: "/bar",
- label: "Bar"
+ $label: "Bar",
+ to: "/bar"
}
];
@@ -203,14 +203,14 @@ test("Link item additionalProps are rendered", () => {
test("Section item additionalProps are rendered", () => {
const navigationItems: RootNavigationItem[] = [
{
- label: "Foo",
+ $label: "Foo",
children: [
{
- to: "/bar",
- label: "Bar"
+ $label: "Bar",
+ to: "/bar"
}
],
- additionalProps: {
+ $additionalProps: {
style: { color: "red" }
}
}
@@ -224,10 +224,10 @@ test("Section item additionalProps are rendered", () => {
});
test("doesn't rerender when the navigation items haven't changed", () => {
- const initialItems = [
+ const initialItems: NavigationItem[] = [
{
- to: "/foo",
- label: "Foo"
+ $label: "Foo",
+ to: "/foo"
}
];
@@ -249,10 +249,10 @@ test("doesn't rerender when the navigation items haven't changed", () => {
});
test("rerender when the navigation items change", () => {
- const initialItems = [
+ const initialItems: NavigationItem[] = [
{
- to: "/foo",
- label: "Foo"
+ $label: "Foo",
+ to: "/foo"
}
];
@@ -268,8 +268,8 @@ test("rerender when the navigation items change", () => {
rerender({
navigationItems: [
{
- to: "/bar",
- label: "Bar"
+ $label: "Bar",
+ to: "/bar"
}
]
});
diff --git a/packages/react-router/tests/useRoutes.test.tsx b/packages/react-router/tests/useRoutes.test.tsx
index 90a8b4e08..e10fc1eaa 100644
--- a/packages/react-router/tests/useRoutes.test.tsx
+++ b/packages/react-router/tests/useRoutes.test.tsx
@@ -17,10 +17,19 @@ function renderWithRuntime(runtime: Runtime, additionalProps: RenderHook
test("returns all the registered routes", () => {
const runtime = new Runtime();
- runtime.registerRoutes([
- { path: "/foo", element: Foo
},
- { path: "/bar", element: Bar
}
- ]);
+ runtime.registerRoute({
+ path: "/foo",
+ element: Foo
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ path: "/bar",
+ element: Bar
+ }, {
+ hoist: true
+ });
const { result } = renderWithRuntime(runtime);
@@ -30,9 +39,12 @@ test("returns all the registered routes", () => {
test("returned array is immutable", () => {
const runtime = new Runtime();
- runtime.registerRoutes([
- { path: "/foo", element: Foo
}
- ]);
+ runtime.registerRoute({
+ path: "/foo",
+ element: Foo
+ }, {
+ hoist: true
+ });
const { result, rerender } = renderWithRuntime(runtime);
@@ -43,9 +55,12 @@ test("returned array is immutable", () => {
const array2 = result.current;
- runtime.registerRoutes([
- { path: "/bar", element: Bar
}
- ]);
+ runtime.registerRoute({
+ path: "/bar",
+ element: Bar
+ }, {
+ hoist: true
+ });
// Added a new route, the returned array should be a new instance.
rerender();
diff --git a/packages/webpack-module-federation/jest.config.ts b/packages/webpack-module-federation/jest.config.ts
index 3bf2eaaf1..ecc6a2f7a 100644
--- a/packages/webpack-module-federation/jest.config.ts
+++ b/packages/webpack-module-federation/jest.config.ts
@@ -5,7 +5,7 @@ import { swcConfig } from "./swc.jest.ts";
import { compilerOptions } from "./tsconfig.json";
const config: Config = {
- testEnvironment: "node",
+ testEnvironment: "jsdom",
transformIgnorePatterns: [
// Must exclude @workleap/webpack-configs from the transform ignore files
// because it's an ESM only project which must be processed by SWC.
@@ -18,7 +18,7 @@ const config: Config = {
transform: {
// Must add the ".js" file extension because the files from @workleap/webpack-configs
// are ESM only and therefore must be processed by SWC.
- "^.+\\.(js|ts)$": ["@swc/jest", swcConfig as Record]
+ "^.+\\.(js|ts|tsx)$": ["@swc/jest", swcConfig as Record]
},
moduleNameMapper: {
...pathsToModuleNameMapper(compilerOptions.paths, {
diff --git a/packages/webpack-module-federation/package.json b/packages/webpack-module-federation/package.json
index fd9d1a82d..82d86b10e 100644
--- a/packages/webpack-module-federation/package.json
+++ b/packages/webpack-module-federation/package.json
@@ -43,25 +43,27 @@
"webpack": ">=5.0.0"
},
"devDependencies": {
- "@swc/core": "1.3.86",
- "@swc/helpers": "0.5.2",
+ "@swc/core": "1.3.93",
+ "@swc/helpers": "0.5.3",
"@swc/jest": "0.2.29",
+ "@testing-library/react": "14.0.0",
"@types/jest": "29.5.5",
- "@types/node": "20.6.3",
- "@types/react": "18.2.22",
- "@types/react-dom": "18.2.7",
- "@workleap/eslint-plugin": "2.1.1",
+ "@types/node": "20.8.6",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@workleap/eslint-plugin": "3.0.0",
"@workleap/swc-configs": "2.1.2",
"@workleap/tsup-configs": "3.0.1",
"@workleap/typescript-configs": "3.0.2",
- "@workleap/webpack-configs": "1.0.8",
+ "@workleap/webpack-configs": "1.1.0",
"jest": "29.7.0",
+ "jest-environment-jsdom": "29.7.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"ts-jest": "29.1.1",
"tsup": "7.2.0",
"typescript": "5.2.2",
- "webpack": "5.88.2"
+ "webpack": "5.89.0"
},
"dependencies": {
"@squide/core": "workspace:*",
diff --git a/packages/webpack-module-federation/src/defineConfig.ts b/packages/webpack-module-federation/src/defineConfig.ts
index ab2e14ecd..8f70546d5 100644
--- a/packages/webpack-module-federation/src/defineConfig.ts
+++ b/packages/webpack-module-federation/src/defineConfig.ts
@@ -60,6 +60,18 @@ export interface DefineHostModuleFederationPluginOptions extends ModuleFederatio
router?: Router;
}
+const forceNamedChunkIdsTransformer: WebpackConfigTransformer = (config: WebpackConfig) => {
+ config.optimization = {
+ ...(config.optimization ?? {}),
+ // Without named chunk ids, there are some Webpack features that do not work
+ // when used with Module Federation. One of these feature is using a dynamic import in
+ // a remote module.
+ chunkIds: "named"
+ };
+
+ return config;
+};
+
//////////////////////////// Host /////////////////////////////
// The function return type is mandatory, otherwise we got an error TS4058.
@@ -134,6 +146,7 @@ export function defineBuildHostConfig(swcConfig: SwcConfig, applicationName: str
cache = false,
plugins = [],
htmlWebpackPluginOptions,
+ transformers = [],
router,
sharedDependencies,
moduleFederationPluginOptions = defineHostModuleFederationPluginOptions(applicationName, { router, shared: sharedDependencies }),
@@ -149,6 +162,10 @@ export function defineBuildHostConfig(swcConfig: SwcConfig, applicationName: str
...plugins,
new webpack.container.ModuleFederationPlugin(moduleFederationPluginOptions)
],
+ transformers: [
+ forceNamedChunkIdsTransformer,
+ ...transformers
+ ],
...webpackOptions
});
}
@@ -204,7 +221,7 @@ const devRemoteModuleTransformer: WebpackConfigTransformer = (config: WebpackCon
return config;
};
-export interface DefineDevRemoteModuleConfigOptions extends Omit {
+export interface DefineDevRemoteModuleConfigOptions extends Omit {
router?: Router;
sharedDependencies?: ModuleFederationPluginOptions["shared"];
moduleFederationPluginOptions?: ModuleFederationPluginOptions;
@@ -230,6 +247,9 @@ export function defineDevRemoteModuleConfig(swcConfig: SwcConfig, applicationNam
cache,
fastRefresh: false,
htmlWebpackPlugin,
+ // Disable the error overlay by default for remotes as otherwise every remote module's error overlay will be
+ // stack on top of the host application's error overlay.
+ overlay: false,
plugins: [
...plugins,
new webpack.container.ModuleFederationPlugin(moduleFederationPluginOptions)
@@ -255,6 +275,7 @@ export function defineBuildRemoteModuleConfig(swcConfig: SwcConfig, applicationN
cache = false,
plugins = [],
htmlWebpackPlugin = false,
+ transformers = [],
router,
sharedDependencies,
moduleFederationPluginOptions = defineRemoteModuleFederationPluginOptions(applicationName, { router, shared: sharedDependencies }),
@@ -270,6 +291,10 @@ export function defineBuildRemoteModuleConfig(swcConfig: SwcConfig, applicationN
...plugins,
new webpack.container.ModuleFederationPlugin(moduleFederationPluginOptions)
],
+ transformers: [
+ forceNamedChunkIdsTransformer,
+ ...transformers
+ ],
...webpackOptions
});
}
diff --git a/packages/webpack-module-federation/src/registerRemoteModules.ts b/packages/webpack-module-federation/src/registerRemoteModules.ts
index b374b8863..a3e9deff1 100644
--- a/packages/webpack-module-federation/src/registerRemoteModules.ts
+++ b/packages/webpack-module-federation/src/registerRemoteModules.ts
@@ -4,17 +4,23 @@ import { RemoteEntryPoint, RemoteModuleName, type RemoteDefinition } from "./rem
let registrationStatus: ModuleRegistrationStatus = "none";
-// Aliasing to make the name more explicit to external modules.
-export { registrationStatus as remoteModulesRegistrationStatus };
+export function getRemoteModulesRegistrationStatus() {
+ return registrationStatus;
+}
+
+// Strictly for testing purpose.
+export function resetRemoteModulesRegistrationStatus() {
+ registrationStatus = "none";
+}
-export interface RegistrationError {
- // The remote base URL
+export interface RemoteModuleRegistrationError {
+ // The remote base URL.
url: string;
- // The remote container name
+ // The remote container name.
containerName: string;
- // The remote resource module name
+ // The remote resource module name.
moduleName: string;
- // The registration error
+ // The registration error.
error: unknown;
}
@@ -24,12 +30,12 @@ export interface RegisterRemoteModulesOptions {
export async function registerRemoteModules(remotes: RemoteDefinition[], runtime: AbstractRuntime, { context }: RegisterRemoteModulesOptions = {}) {
if (registrationStatus !== "none") {
- throw new Error("[squide] The \"registerRemoteModules\" function can only be called once.");
+ throw new Error("[squide] [remote] registerRemoteModules() can only be called once.");
}
- const errors: RegistrationError[] = [];
+ const errors: RemoteModuleRegistrationError[] = [];
- runtime.logger.information(`[squide] Found ${remotes.length} remote module${remotes.length !== 1 ? "s" : ""} to register.`);
+ runtime.logger.information(`[squide] [remote] Found ${remotes.length} remote module${remotes.length !== 1 ? "s" : ""} to register.`);
registrationStatus = "in-progress";
@@ -42,22 +48,22 @@ export async function registerRemoteModules(remotes: RemoteDefinition[], runtime
// Is included in the try/catch becase the URL could be invalid and cause an error.
remoteUrl = new URL(RemoteEntryPoint, x.url).toString();
- runtime.logger.information(`[squide] ${index + 1}/${remotes.length} Loading module "${RemoteModuleName}" from container "${containerName}" of remote "${remoteUrl}".`);
+ runtime.logger.information(`[squide] [remote] ${index + 1}/${remotes.length} Loading module "${RemoteModuleName}" from container "${containerName}" of remote "${remoteUrl}".`);
const module = await loadRemote(remoteUrl, containerName, RemoteModuleName);
if (isNil(module.register)) {
- throw new Error(`[squide] A "register" function is not available for module "${RemoteModuleName}" of container "${containerName}" from remote "${remoteUrl}". Make sure your remote "./register.js" file export a function named "register".`);
+ throw new Error(`[squide] [remote] A "register" function is not available for module "${RemoteModuleName}" of container "${containerName}" from remote "${remoteUrl}". Make sure your remote "./register.js" file export a function named "register".`);
}
- runtime.logger.information(`[squide] ${index + 1}/${remotes.length} Registering module "${RemoteModuleName}" from container "${containerName}" of remote "${remoteUrl}".`);
+ runtime.logger.information(`[squide] [remote] ${index + 1}/${remotes.length} Registering module "${RemoteModuleName}" from container "${containerName}" of remote "${remoteUrl}".`);
- registerModule(module.register, runtime, context);
+ await registerModule(module.register, runtime, context);
- runtime.logger.information(`[squide] ${index + 1}/${remotes.length} Container "${containerName}" of remote "${remoteUrl}" registration completed.`);
+ runtime.logger.information(`[squide] [remote] ${index + 1}/${remotes.length} Container "${containerName}" of remote "${remoteUrl}" registration completed.`);
} catch (error: unknown) {
runtime.logger.error(
- `[squide] ${index + 1}/${remotes.length} An error occured while registering module "${RemoteModuleName}" from container "${containerName}" of remote "${remoteUrl}".`,
+ `[squide] [remote] ${index + 1}/${remotes.length} An error occured while registering module "${RemoteModuleName}" from container "${containerName}" of remote "${remoteUrl}".`,
error
);
diff --git a/packages/webpack-module-federation/src/useAreModulesReady.ts b/packages/webpack-module-federation/src/useAreModulesReady.ts
index dcca7c578..41b73f936 100644
--- a/packages/webpack-module-federation/src/useAreModulesReady.ts
+++ b/packages/webpack-module-federation/src/useAreModulesReady.ts
@@ -1,35 +1,35 @@
import { useEffect, useState } from "react";
-import { localModulesRegistrationStatus, useRuntime } from "@squide/core";
-import { remoteModulesRegistrationStatus } from "./registerRemoteModules.ts";
+import { getLocalModulesRegistrationStatus, useRuntime } from "@squide/core";
+import { getRemoteModulesRegistrationStatus } from "./registerRemoteModules.ts";
export interface UseAreModulesReadyOptions {
// The interval is in milliseconds.
interval?: number;
}
-function isReady() {
+function areModulesReady() {
// Validating for "in-progress" instead of "ready" for the local module because "registerLocalModules"
// could never be called.
- return localModulesRegistrationStatus !== "in-progress" && remoteModulesRegistrationStatus === "ready";
+ return getLocalModulesRegistrationStatus() !== "in-progress" && getRemoteModulesRegistrationStatus() !== "in-progress";
}
export function useAreModulesReady({ interval = 10 }: UseAreModulesReadyOptions = {}) {
const runtime = useRuntime();
// Using a state hook to force a rerender once ready.
- const [, setIsReady] = useState(false);
+ const [value, setAreModulesReady] = useState(false);
// Perform a reload once the modules are registered.
useEffect(() => {
const intervalId = setInterval(() => {
- if (isReady()) {
+ if (areModulesReady()) {
// Must clear interval before calling "_completeRegistration" in case there's an error.
clearInterval(intervalId);
runtime._completeRegistration();
- setIsReady(true);
+ setAreModulesReady(true);
}
}, interval);
@@ -40,5 +40,5 @@ export function useAreModulesReady({ interval = 10 }: UseAreModulesReadyOptions
};
}, []);
- return isReady();
+ return value;
}
diff --git a/packages/webpack-module-federation/swc.jest.ts b/packages/webpack-module-federation/swc.jest.ts
index 2e6bdb4ce..dc009c5ef 100644
--- a/packages/webpack-module-federation/swc.jest.ts
+++ b/packages/webpack-module-federation/swc.jest.ts
@@ -1,3 +1,5 @@
import { defineJestConfig } from "@workleap/swc-configs";
-export const swcConfig = defineJestConfig();
+export const swcConfig = defineJestConfig({
+ react: true
+});
diff --git a/packages/webpack-module-federation/tests/defineConfig.test.ts b/packages/webpack-module-federation/tests/defineConfig.test.ts
index b2d7b1e5e..dab9c5e85 100644
--- a/packages/webpack-module-federation/tests/defineConfig.test.ts
+++ b/packages/webpack-module-federation/tests/defineConfig.test.ts
@@ -119,6 +119,18 @@ describe("defineDevHostConfig", () => {
expect(result).toBeDefined();
});
+
+ test("when configuration transformers are provided, the transformers are applied to the configuration", () => {
+ const result = defineDevHostConfig(SwcConfig, "host", 8080, {
+ transformers: [(config: WebpackConfig) => {
+ config.entry = "updated by the dummy transformer";
+
+ return config;
+ }]
+ });
+
+ expect(result.entry).toBe("updated by the dummy transformer");
+ });
});
@@ -215,6 +227,18 @@ describe("defineBuildHostConfig", () => {
expect(result).toBeDefined();
});
+
+ test("when configuration transformers are provided, the transformers are applied to the configuration", () => {
+ const result = defineBuildHostConfig(SwcConfig, "host", "http://localhost:8080/", {
+ transformers: [(config: WebpackConfig) => {
+ config.entry = "updated by the dummy transformer";
+
+ return config;
+ }]
+ });
+
+ expect(result.entry).toBe("updated by the dummy transformer");
+ });
});
@@ -439,6 +463,20 @@ describe("defineBuildRemoteModuleConfig", () => {
expect(result).toBeDefined();
});
+
+ test("when configuration transformers are provided, the transformers are applied to the configuration", () => {
+ const dummyTransformer = (config: WebpackConfig) => {
+ config.entry = "updated by the dummy transformer";
+
+ return config;
+ };
+
+ const result = defineBuildRemoteModuleConfig(SwcConfig, "remote1", "http://localhost:8081/", {
+ transformers: [dummyTransformer]
+ });
+
+ expect(result.entry).toBe("updated by the dummy transformer");
+ });
});
describe("defineHostModuleFederationPluginOptions", () => {
diff --git a/packages/webpack-module-federation/tests/useAreModulesReady.test.tsx b/packages/webpack-module-federation/tests/useAreModulesReady.test.tsx
new file mode 100644
index 000000000..c59198625
--- /dev/null
+++ b/packages/webpack-module-federation/tests/useAreModulesReady.test.tsx
@@ -0,0 +1,197 @@
+import { AbstractRuntime, RuntimeContext, registerLocalModules, resetLocalModulesRegistrationStatus } from "@squide/core";
+import { act, renderHook } from "@testing-library/react";
+import type { ReactNode } from "react";
+import { loadRemote } from "../src/loadRemote.ts";
+import { registerRemoteModules, resetRemoteModulesRegistrationStatus } from "../src/registerRemoteModules.ts";
+import { useAreModulesReady } from "../src/useAreModulesReady.ts";
+
+// The mock implementation is defined directly in the tests.
+jest.mock("../src/loadRemote.ts");
+
+// The interval at which the hook will perform a check to determine if the modules are ready.
+const CheckInterval = 10;
+
+class DummyRuntime extends AbstractRuntime {
+ registerRoute() {
+ throw new Error("Method not implemented.");
+ }
+
+ get routes() {
+ return [];
+ }
+
+ registerNavigationItem() {
+ throw new Error("Method not implemented.");
+ }
+
+ getNavigationItems() {
+ return [];
+ }
+}
+
+function renderWithRuntime(runtime: AbstractRuntime) {
+ return renderHook(() => useAreModulesReady({ interval: CheckInterval }), {
+ wrapper: ({ children }: { children?: ReactNode }) => (
+
+ {children}
+
+ )
+ });
+}
+
+beforeEach(() => {
+ // Since the module registration status variables are singletons,
+ // they are not reseted between the tests.
+ resetLocalModulesRegistrationStatus();
+ resetRemoteModulesRegistrationStatus();
+
+ // Typing a mocked imported function is too complicated.
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ if (loadRemote.mockClear) {
+ // Typing a mocked imported function is too complicated.
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ loadRemote.mockClear();
+ }
+
+ jest.useFakeTimers();
+});
+
+afterEach(() => {
+ jest.useRealTimers();
+});
+
+test("when only local modules are registered, return true when all the local modules are registered", async () => {
+ const runtime = new DummyRuntime();
+
+ await registerLocalModules([
+ () => {},
+ () => {},
+ () => {}
+ ], runtime);
+
+ const { result } = renderWithRuntime(runtime);
+
+ expect(result.current).toBeFalsy();
+
+ // To justify the usage of act, refer to: https://github.com/testing-library/react-hooks-testing-library/issues/241
+ act(() => {
+ jest.advanceTimersByTime(CheckInterval + 1);
+ });
+
+ expect(result.current).toBeTruthy();
+});
+
+test("when only remote modules are registered, return true when all the remote modules are registered", async () => {
+ // Typing a mocked imported function is too complicated.
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ loadRemote.mockResolvedValue({
+ register: jest.fn()
+ });
+
+ const runtime = new DummyRuntime();
+
+ await registerRemoteModules([
+ { name: "Dummy-1", url: "http://anything1.com" },
+ { name: "Dummy-2", url: "http://anything2.com" },
+ { name: "Dummy-3", url: "http://anything3.com" }
+ ], runtime);
+
+ const { result } = renderWithRuntime(runtime);
+
+ expect(result.current).toBeFalsy();
+
+ // To justify the usage of act, refer to: https://github.com/testing-library/react-hooks-testing-library/issues/241
+ act(() => {
+ jest.advanceTimersByTime(CheckInterval + 1);
+ });
+
+ expect(result.current).toBeTruthy();
+});
+
+test("when local and remote modules are registered, return true when all the remote modules are registered", async () => {
+ // Typing a mocked imported function is too complicated.
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ loadRemote.mockResolvedValue({
+ register: jest.fn()
+ });
+
+ const runtime = new DummyRuntime();
+
+ await registerLocalModules([
+ () => {},
+ () => {},
+ () => {}
+ ], runtime);
+
+ await registerRemoteModules([
+ { name: "Dummy-1", url: "http://anything1.com" },
+ { name: "Dummy-2", url: "http://anything2.com" },
+ { name: "Dummy-3", url: "http://anything3.com" }
+ ], runtime);
+
+ const { result } = renderWithRuntime(runtime);
+
+ expect(result.current).toBeFalsy();
+
+ // To justify the usage of act, refer to: https://github.com/testing-library/react-hooks-testing-library/issues/241
+ act(() => {
+ jest.advanceTimersByTime(CheckInterval + 1);
+ });
+
+ expect(result.current).toBeTruthy();
+});
+
+test("when a local module registration fail, return true when all the other modules are registered", async () => {
+ const runtime = new DummyRuntime();
+
+ await registerLocalModules([
+ () => {},
+ () => { throw new Error("Registration failed!"); },
+ () => {}
+ ], runtime);
+
+ const { result } = renderWithRuntime(runtime);
+
+ expect(result.current).toBeFalsy();
+
+ // To justify the usage of act, refer to: https://github.com/testing-library/react-hooks-testing-library/issues/241
+ act(() => {
+ jest.advanceTimersByTime(CheckInterval + 1);
+ });
+
+ expect(result.current).toBeTruthy();
+});
+
+test("when a remote module registration fail, return true when all the other modules are registered", async () => {
+ const resolvedValue = {
+ register: jest.fn()
+ };
+
+ // Typing a mocked imported function is too complicated.
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ loadRemote.mockResolvedValueOnce(resolvedValue).mockResolvedValueOnce(resolvedValue).mockRejectedValueOnce(null);
+
+ const runtime = new DummyRuntime();
+
+ await registerRemoteModules([
+ { name: "Dummy-1", url: "http://anything1.com" },
+ { name: "Dummy-2", url: "http://anything2.com" },
+ { name: "Dummy-3", url: "http://anything3.com" }
+ ], runtime);
+
+ const { result } = renderWithRuntime(runtime);
+
+ expect(result.current).toBeFalsy();
+
+ // To justify the usage of act, refer to: https://github.com/testing-library/react-hooks-testing-library/issues/241
+ act(() => {
+ jest.advanceTimersByTime(CheckInterval + 1);
+ });
+
+ expect(result.current).toBeTruthy();
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d838817f5..554b7bcdb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15,11 +15,11 @@ importers:
specifier: 2.26.2
version: 2.26.2
'@typescript-eslint/parser':
- specifier: 6.7.2
- version: 6.7.2(eslint@8.49.0)(typescript@5.2.2)
+ specifier: 6.8.0
+ version: 6.8.0(eslint@8.51.0)(typescript@5.2.2)
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/typescript-configs':
specifier: 3.0.2
version: 3.0.2(typescript@5.2.2)
@@ -27,20 +27,20 @@ importers:
specifier: 7.0.3
version: 7.0.3
eslint:
- specifier: 8.49.0
- version: 8.49.0
+ specifier: 8.51.0
+ version: 8.51.0
jest:
specifier: 29.7.0
- version: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ version: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
netlify-cli:
- specifier: 16.4.1
- version: 16.4.1(@types/node@20.6.3)
+ specifier: 16.8.0
+ version: 16.8.0(@types/node@20.8.6)
retypeapp:
specifier: 3.5.0
version: 3.5.0
ts-node:
specifier: 10.9.1
- version: 10.9.1(@types/node@20.6.3)(typescript@5.2.2)
+ version: 10.9.1(@types/node@20.8.6)(typescript@5.2.2)
typescript:
specifier: 5.2.2
version: 5.2.2
@@ -52,14 +52,14 @@ importers:
version: 5.0.1
devDependencies:
'@types/react':
- specifier: 18.2.22
- version: 18.2.22
+ specifier: 18.2.28
+ version: 18.2.28
'@types/react-dom':
- specifier: 18.2.7
- version: 18.2.7
+ specifier: 18.2.13
+ version: 18.2.13
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/tsup-configs':
specifier: 3.0.1
version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
@@ -74,7 +74,7 @@ importers:
version: 18.2.0(react@18.2.0)
tsup:
specifier: 7.2.0
- version: 7.2.0(@swc/core@1.3.86)(postcss@8.4.30)(ts-node@10.9.1)(typescript@5.2.2)
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
typescript:
specifier: 5.2.2
version: 5.2.2
@@ -89,8 +89,8 @@ importers:
specifier: 29.5.5
version: 29.5.5
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/tsup-configs':
specifier: 3.0.1
version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
@@ -99,10 +99,53 @@ importers:
version: 3.0.2(typescript@5.2.2)
jest:
specifier: 29.7.0
- version: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ version: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
tsup:
specifier: 7.2.0
- version: 7.2.0(@swc/core@1.3.86)(postcss@8.4.30)(ts-node@10.9.1)(typescript@5.2.2)
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
+ typescript:
+ specifier: 5.2.2
+ version: 5.2.2
+
+ packages/msw:
+ dependencies:
+ '@squide/core':
+ specifier: workspace:*
+ version: link:../core
+ devDependencies:
+ '@types/jest':
+ specifier: 29.5.5
+ version: 29.5.5
+ '@types/react':
+ specifier: 18.2.28
+ version: 18.2.28
+ '@types/react-dom':
+ specifier: 18.2.13
+ version: 18.2.13
+ '@workleap/eslint-plugin':
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
+ '@workleap/tsup-configs':
+ specifier: 3.0.1
+ version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
+ '@workleap/typescript-configs':
+ specifier: 3.0.2
+ version: 3.0.2(typescript@5.2.2)
+ jest:
+ specifier: 29.7.0
+ version: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
+ msw:
+ specifier: 1.3.2
+ version: 1.3.2(typescript@5.2.2)
+ react:
+ specifier: 18.2.0
+ version: 18.2.0
+ react-dom:
+ specifier: 18.2.0
+ version: 18.2.0(react@18.2.0)
+ tsup:
+ specifier: 7.2.0
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
typescript:
specifier: 5.2.2
version: 5.2.2
@@ -114,14 +157,14 @@ importers:
version: link:../core
devDependencies:
'@swc/core':
- specifier: 1.3.86
- version: 1.3.86(@swc/helpers@0.5.2)
+ specifier: 1.3.93
+ version: 1.3.93(@swc/helpers@0.5.3)
'@swc/helpers':
- specifier: 0.5.2
- version: 0.5.2
+ specifier: 0.5.3
+ version: 0.5.3
'@swc/jest':
specifier: 0.2.29
- version: 0.2.29(@swc/core@1.3.86)
+ version: 0.2.29(@swc/core@1.3.93)
'@testing-library/react':
specifier: 14.0.0
version: 14.0.0(react-dom@18.2.0)(react@18.2.0)
@@ -129,20 +172,20 @@ importers:
specifier: 29.5.5
version: 29.5.5
'@types/react':
- specifier: 18.2.22
- version: 18.2.22
+ specifier: 18.2.28
+ version: 18.2.28
'@types/react-dom':
- specifier: 18.2.7
- version: 18.2.7
+ specifier: 18.2.13
+ version: 18.2.13
'@types/react-test-renderer':
- specifier: 18.0.2
- version: 18.0.2
+ specifier: 18.0.3
+ version: 18.0.3
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/swc-configs':
specifier: 2.1.2
- version: 2.1.2(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@swc/jest@0.2.29)(browserslist@4.21.10)
+ version: 2.1.2(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@swc/jest@0.2.29)(browserslist@4.22.1)
'@workleap/tsup-configs':
specifier: 3.0.1
version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
@@ -151,7 +194,7 @@ importers:
version: 3.0.2(typescript@5.2.2)
jest:
specifier: 29.7.0
- version: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ version: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
jest-environment-jsdom:
specifier: 29.7.0
version: 29.7.0
@@ -162,17 +205,17 @@ importers:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
react-router-dom:
- specifier: 6.16.0
- version: 6.16.0(react-dom@18.2.0)(react@18.2.0)
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
react-test-renderer:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
ts-jest:
specifier: 29.1.1
- version: 29.1.1(@babel/core@7.22.20)(esbuild@0.18.20)(jest@29.7.0)(typescript@5.2.2)
+ version: 29.1.1(@babel/core@7.23.2)(esbuild@0.18.20)(jest@29.7.0)(typescript@5.2.2)
tsup:
specifier: 7.2.0
- version: 7.2.0(@swc/core@1.3.86)(postcss@8.4.30)(ts-node@10.9.1)(typescript@5.2.2)
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
typescript:
specifier: 5.2.2
version: 5.2.2
@@ -187,35 +230,38 @@ importers:
version: 4.3.1
html-webpack-plugin:
specifier: 5.5.3
- version: 5.5.3(webpack@5.88.2)
+ version: 5.5.3(webpack@5.89.0)
devDependencies:
'@swc/core':
- specifier: 1.3.86
- version: 1.3.86(@swc/helpers@0.5.2)
+ specifier: 1.3.93
+ version: 1.3.93(@swc/helpers@0.5.3)
'@swc/helpers':
- specifier: 0.5.2
- version: 0.5.2
+ specifier: 0.5.3
+ version: 0.5.3
'@swc/jest':
specifier: 0.2.29
- version: 0.2.29(@swc/core@1.3.86)
+ version: 0.2.29(@swc/core@1.3.93)
+ '@testing-library/react':
+ specifier: 14.0.0
+ version: 14.0.0(react-dom@18.2.0)(react@18.2.0)
'@types/jest':
specifier: 29.5.5
version: 29.5.5
'@types/node':
- specifier: 20.6.3
- version: 20.6.3
+ specifier: 20.8.6
+ version: 20.8.6
'@types/react':
- specifier: 18.2.22
- version: 18.2.22
+ specifier: 18.2.28
+ version: 18.2.28
'@types/react-dom':
- specifier: 18.2.7
- version: 18.2.7
+ specifier: 18.2.13
+ version: 18.2.13
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/swc-configs':
specifier: 2.1.2
- version: 2.1.2(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@swc/jest@0.2.29)(browserslist@4.21.10)
+ version: 2.1.2(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@swc/jest@0.2.29)(browserslist@4.22.1)
'@workleap/tsup-configs':
specifier: 3.0.1
version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
@@ -223,11 +269,14 @@ importers:
specifier: 3.0.2
version: 3.0.2(typescript@5.2.2)
'@workleap/webpack-configs':
- specifier: 1.0.8
- version: 1.0.8(@swc/core@1.3.86)(@swc/helpers@0.5.2)(browserslist@4.21.10)(esbuild@0.18.20)(postcss@8.4.30)(react-refresh@0.14.0)(typescript@5.2.2)(webpack@5.88.2)
+ specifier: 1.1.0
+ version: 1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(browserslist@4.22.1)(esbuild@0.18.20)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack@5.89.0)
jest:
specifier: 29.7.0
- version: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ version: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
+ jest-environment-jsdom:
+ specifier: 29.7.0
+ version: 29.7.0
react:
specifier: 18.2.0
version: 18.2.0
@@ -236,34 +285,34 @@ importers:
version: 18.2.0(react@18.2.0)
ts-jest:
specifier: 29.1.1
- version: 29.1.1(@babel/core@7.22.20)(esbuild@0.18.20)(jest@29.7.0)(typescript@5.2.2)
+ version: 29.1.1(@babel/core@7.23.2)(esbuild@0.18.20)(jest@29.7.0)(typescript@5.2.2)
tsup:
specifier: 7.2.0
- version: 7.2.0(@swc/core@1.3.86)(postcss@8.4.30)(ts-node@10.9.1)(typescript@5.2.2)
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
typescript:
specifier: 5.2.2
version: 5.2.2
webpack:
- specifier: 5.88.2
- version: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ specifier: 5.89.0
+ version: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
- sample/another-remote-module:
+ samples/basic/another-remote-module:
dependencies:
- '@sample/shared':
+ '@basic/shared':
specifier: workspace:*
version: link:../shared
- '@sample/shell':
+ '@basic/shell':
specifier: workspace:*
version: link:../shell
'@squide/fakes':
specifier: workspace:*
- version: link:../../packages/fakes
+ version: link:../../../packages/fakes
'@squide/react-router':
specifier: workspace:*
- version: link:../../packages/react-router
+ version: link:../../../packages/react-router
'@squide/webpack-module-federation':
specifier: workspace:*
- version: link:../../packages/webpack-module-federation
+ version: link:../../../packages/webpack-module-federation
react:
specifier: 18.2.0
version: 18.2.0
@@ -271,81 +320,248 @@ importers:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
react-router-dom:
- specifier: 6.16.0
- version: 6.16.0(react-dom@18.2.0)(react@18.2.0)
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
devDependencies:
'@swc/core':
- specifier: 1.3.86
- version: 1.3.86(@swc/helpers@0.5.2)
+ specifier: 1.3.93
+ version: 1.3.93(@swc/helpers@0.5.3)
'@swc/helpers':
- specifier: 0.5.2
- version: 0.5.2
+ specifier: 0.5.3
+ version: 0.5.3
'@types/react':
- specifier: 18.2.22
- version: 18.2.22
+ specifier: 18.2.28
+ version: 18.2.28
'@types/react-dom':
- specifier: 18.2.7
- version: 18.2.7
+ specifier: 18.2.13
+ version: 18.2.13
'@types/webpack':
- specifier: 5.28.2
- version: 5.28.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
+ specifier: 5.28.3
+ version: 5.28.3(@swc/core@1.3.93)(webpack-cli@5.1.4)
'@workleap/browserslist-config':
specifier: 2.0.0
version: 2.0.0
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/swc-configs':
specifier: 2.1.2
- version: 2.1.2(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@swc/jest@0.2.29)(browserslist@4.21.10)
+ version: 2.1.2(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@swc/jest@0.2.29)(browserslist@4.22.1)
'@workleap/typescript-configs':
specifier: 3.0.2
version: 3.0.2(typescript@5.2.2)
'@workleap/webpack-configs':
- specifier: 1.0.8
- version: 1.0.8(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@types/webpack@5.28.2)(browserslist@4.21.10)(postcss@8.4.30)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ specifier: 1.1.0
+ version: 1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@types/webpack@5.28.3)(browserslist@4.22.1)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.89.0)
browserslist:
- specifier: 4.21.10
- version: 4.21.10
+ specifier: 4.22.1
+ version: 4.22.1
cross-env:
specifier: 7.0.3
version: 7.0.3
http-server:
specifier: 14.1.1
version: 14.1.1
+ nodemon:
+ specifier: 3.0.1
+ version: 3.0.1
typescript:
specifier: 5.2.2
version: 5.2.2
webpack:
- specifier: 5.88.2
- version: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
+ specifier: 5.89.0
+ version: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
webpack-cli:
specifier: 5.1.4
- version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
webpack-dev-server:
specifier: 4.15.1
- version: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2)
+ version: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
- sample/host:
+ samples/basic/host:
dependencies:
- '@sample/local-module':
+ '@basic/local-module':
specifier: workspace:*
version: link:../local-module
- '@sample/shared':
+ '@basic/shared':
+ specifier: workspace:*
+ version: link:../shared
+ '@basic/shell':
+ specifier: workspace:*
+ version: link:../shell
+ '@squide/react-router':
+ specifier: workspace:*
+ version: link:../../../packages/react-router
+ '@squide/webpack-module-federation':
+ specifier: workspace:*
+ version: link:../../../packages/webpack-module-federation
+ react:
+ specifier: 18.2.0
+ version: 18.2.0
+ react-dom:
+ specifier: 18.2.0
+ version: 18.2.0(react@18.2.0)
+ react-router-dom:
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
+ devDependencies:
+ '@squide/fakes':
+ specifier: workspace:*
+ version: link:../../../packages/fakes
+ '@swc/core':
+ specifier: 1.3.93
+ version: 1.3.93(@swc/helpers@0.5.3)
+ '@swc/helpers':
+ specifier: 0.5.3
+ version: 0.5.3
+ '@types/react':
+ specifier: 18.2.28
+ version: 18.2.28
+ '@types/react-dom':
+ specifier: 18.2.13
+ version: 18.2.13
+ '@types/webpack':
+ specifier: 5.28.3
+ version: 5.28.3(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ '@workleap/browserslist-config':
+ specifier: 2.0.0
+ version: 2.0.0
+ '@workleap/eslint-plugin':
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
+ '@workleap/swc-configs':
+ specifier: 2.1.2
+ version: 2.1.2(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@swc/jest@0.2.29)(browserslist@4.22.1)
+ '@workleap/typescript-configs':
+ specifier: 3.0.2
+ version: 3.0.2(typescript@5.2.2)
+ '@workleap/webpack-configs':
+ specifier: 1.1.0
+ version: 1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@types/webpack@5.28.3)(browserslist@4.22.1)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.89.0)
+ browserslist:
+ specifier: 4.22.1
+ version: 4.22.1
+ copyfiles:
+ specifier: 2.4.1
+ version: 2.4.1
+ http-server:
+ specifier: 14.1.1
+ version: 14.1.1
+ nodemon:
+ specifier: 3.0.1
+ version: 3.0.1
+ typescript:
+ specifier: 5.2.2
+ version: 5.2.2
+ webpack:
+ specifier: 5.89.0
+ version: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ webpack-cli:
+ specifier: 5.1.4
+ version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
+ webpack-dev-server:
+ specifier: 4.15.1
+ version: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
+
+ samples/basic/local-module:
+ dependencies:
+ '@basic/shared':
specifier: workspace:*
version: link:../shared
- '@sample/shell':
+ '@basic/shell':
specifier: workspace:*
version: link:../shell
'@squide/fakes':
specifier: workspace:*
- version: link:../../packages/fakes
+ version: link:../../../packages/fakes
'@squide/react-router':
specifier: workspace:*
- version: link:../../packages/react-router
+ version: link:../../../packages/react-router
+ react:
+ specifier: 18.2.0
+ version: 18.2.0
+ react-dom:
+ specifier: 18.2.0
+ version: 18.2.0(react@18.2.0)
+ react-router-dom:
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
+ devDependencies:
+ '@swc/core':
+ specifier: 1.3.93
+ version: 1.3.93(@swc/helpers@0.5.3)
+ '@swc/helpers':
+ specifier: 0.5.3
+ version: 0.5.3
+ '@types/react':
+ specifier: 18.2.28
+ version: 18.2.28
+ '@types/react-dom':
+ specifier: 18.2.13
+ version: 18.2.13
+ '@types/webpack':
+ specifier: 5.28.3
+ version: 5.28.3(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ '@workleap/browserslist-config':
+ specifier: 2.0.0
+ version: 2.0.0
+ '@workleap/eslint-plugin':
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
+ '@workleap/swc-configs':
+ specifier: 2.1.2
+ version: 2.1.2(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@swc/jest@0.2.29)(browserslist@4.22.1)
+ '@workleap/tsup-configs':
+ specifier: 3.0.1
+ version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
+ '@workleap/typescript-configs':
+ specifier: 3.0.2
+ version: 3.0.2(typescript@5.2.2)
+ '@workleap/webpack-configs':
+ specifier: 1.1.0
+ version: 1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@types/webpack@5.28.3)(browserslist@4.22.1)(esbuild@0.18.20)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.89.0)
+ browserslist:
+ specifier: 4.22.1
+ version: 4.22.1
+ cross-env:
+ specifier: 7.0.3
+ version: 7.0.3
+ nodemon:
+ specifier: 3.0.1
+ version: 3.0.1
+ tsup:
+ specifier: 7.2.0
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
+ typescript:
+ specifier: 5.2.2
+ version: 5.2.2
+ webpack:
+ specifier: 5.89.0
+ version: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ webpack-cli:
+ specifier: 5.1.4
+ version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
+ webpack-dev-server:
+ specifier: 4.15.1
+ version: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
+
+ samples/basic/remote-module:
+ dependencies:
+ '@basic/shared':
+ specifier: workspace:*
+ version: link:../shared
+ '@basic/shell':
+ specifier: workspace:*
+ version: link:../shell
+ '@squide/fakes':
+ specifier: workspace:*
+ version: link:../../../packages/fakes
+ '@squide/react-router':
+ specifier: workspace:*
+ version: link:../../../packages/react-router
'@squide/webpack-module-federation':
specifier: workspace:*
- version: link:../../packages/webpack-module-federation
+ version: link:../../../packages/webpack-module-federation
react:
specifier: 18.2.0
version: 18.2.0
@@ -353,48 +569,241 @@ importers:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
react-router-dom:
- specifier: 6.16.0
- version: 6.16.0(react-dom@18.2.0)(react@18.2.0)
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
devDependencies:
'@swc/core':
- specifier: 1.3.86
- version: 1.3.86(@swc/helpers@0.5.2)
+ specifier: 1.3.93
+ version: 1.3.93(@swc/helpers@0.5.3)
'@swc/helpers':
- specifier: 0.5.2
- version: 0.5.2
+ specifier: 0.5.3
+ version: 0.5.3
'@types/react':
- specifier: 18.2.22
- version: 18.2.22
+ specifier: 18.2.28
+ version: 18.2.28
'@types/react-dom':
- specifier: 18.2.7
- version: 18.2.7
+ specifier: 18.2.13
+ version: 18.2.13
'@types/webpack':
- specifier: 5.28.2
- version: 5.28.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
+ specifier: 5.28.3
+ version: 5.28.3(@swc/core@1.3.93)(webpack-cli@5.1.4)
'@workleap/browserslist-config':
specifier: 2.0.0
version: 2.0.0
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/swc-configs':
specifier: 2.1.2
- version: 2.1.2(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@swc/jest@0.2.29)(browserslist@4.21.10)
+ version: 2.1.2(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@swc/jest@0.2.29)(browserslist@4.22.1)
'@workleap/typescript-configs':
specifier: 3.0.2
version: 3.0.2(typescript@5.2.2)
'@workleap/webpack-configs':
- specifier: 1.0.8
- version: 1.0.8(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@types/webpack@5.28.2)(browserslist@4.21.10)(postcss@8.4.30)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ specifier: 1.1.0
+ version: 1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@types/webpack@5.28.3)(browserslist@4.22.1)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.89.0)
browserslist:
- specifier: 4.21.10
- version: 4.21.10
+ specifier: 4.22.1
+ version: 4.22.1
+ cross-env:
+ specifier: 7.0.3
+ version: 7.0.3
+ http-server:
+ specifier: 14.1.1
+ version: 14.1.1
+ nodemon:
+ specifier: 3.0.1
+ version: 3.0.1
+ typescript:
+ specifier: 5.2.2
+ version: 5.2.2
+ webpack:
+ specifier: 5.89.0
+ version: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ webpack-cli:
+ specifier: 5.1.4
+ version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
+ webpack-dev-server:
+ specifier: 4.15.1
+ version: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
+
+ samples/basic/shared:
+ devDependencies:
+ '@remix-run/router':
+ specifier: 1.10.0
+ version: 1.10.0
+ '@squide/react-router':
+ specifier: workspace:*
+ version: link:../../../packages/react-router
+ '@types/react':
+ specifier: 18.2.28
+ version: 18.2.28
+ '@types/react-dom':
+ specifier: 18.2.13
+ version: 18.2.13
+ '@workleap/eslint-plugin':
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
+ '@workleap/tsup-configs':
+ specifier: 3.0.1
+ version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
+ '@workleap/typescript-configs':
+ specifier: 3.0.2
+ version: 3.0.2(typescript@5.2.2)
+ nodemon:
+ specifier: 3.0.1
+ version: 3.0.1
+ react:
+ specifier: 18.2.0
+ version: 18.2.0
+ react-dom:
+ specifier: 18.2.0
+ version: 18.2.0(react@18.2.0)
+ react-router-dom:
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
+ tsup:
+ specifier: 7.2.0
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
+ typescript:
+ specifier: 5.2.2
+ version: 5.2.2
+
+ samples/basic/shell:
+ devDependencies:
+ '@basic/shared':
+ specifier: workspace:*
+ version: link:../shared
+ '@remix-run/router':
+ specifier: 1.10.0
+ version: 1.10.0
+ '@squide/react-router':
+ specifier: workspace:*
+ version: link:../../../packages/react-router
+ '@squide/webpack-module-federation':
+ specifier: workspace:*
+ version: link:../../../packages/webpack-module-federation
+ '@types/react':
+ specifier: 18.2.28
+ version: 18.2.28
+ '@types/react-dom':
+ specifier: 18.2.13
+ version: 18.2.13
+ '@workleap/eslint-plugin':
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
+ '@workleap/tsup-configs':
+ specifier: 3.0.1
+ version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
+ '@workleap/typescript-configs':
+ specifier: 3.0.2
+ version: 3.0.2(typescript@5.2.2)
+ nodemon:
+ specifier: 3.0.1
+ version: 3.0.1
+ react:
+ specifier: 18.2.0
+ version: 18.2.0
+ react-dom:
+ specifier: 18.2.0
+ version: 18.2.0(react@18.2.0)
+ react-router-dom:
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
+ tsup:
+ specifier: 7.2.0
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
+ typescript:
+ specifier: 5.2.2
+ version: 5.2.2
+
+ samples/endpoints/host:
+ dependencies:
+ '@endpoints/local-module':
+ specifier: workspace:*
+ version: link:../local-module
+ '@endpoints/shared':
+ specifier: workspace:*
+ version: link:../shared
+ '@endpoints/shell':
+ specifier: workspace:*
+ version: link:../shell
+ '@squide/msw':
+ specifier: workspace:*
+ version: link:../../../packages/msw
+ '@squide/react-router':
+ specifier: workspace:*
+ version: link:../../../packages/react-router
+ '@squide/webpack-module-federation':
+ specifier: workspace:*
+ version: link:../../../packages/webpack-module-federation
+ axios:
+ specifier: 1.5.1
+ version: 1.5.1(debug@4.3.4)
+ react:
+ specifier: 18.2.0
+ version: 18.2.0
+ react-dom:
+ specifier: 18.2.0
+ version: 18.2.0(react@18.2.0)
+ react-error-boundary:
+ specifier: 4.0.11
+ version: 4.0.11(react@18.2.0)
+ react-router-dom:
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
+ devDependencies:
+ '@squide/fakes':
+ specifier: workspace:*
+ version: link:../../../packages/fakes
+ '@swc/core':
+ specifier: 1.3.93
+ version: 1.3.93(@swc/helpers@0.5.3)
+ '@swc/helpers':
+ specifier: 0.5.3
+ version: 0.5.3
+ '@tanstack/react-query':
+ specifier: ^5.0.0
+ version: 5.0.0(react-dom@18.2.0)(react@18.2.0)
+ '@types/react':
+ specifier: 18.2.28
+ version: 18.2.28
+ '@types/react-dom':
+ specifier: 18.2.13
+ version: 18.2.13
+ '@types/webpack':
+ specifier: 5.28.3
+ version: 5.28.3(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ '@workleap/browserslist-config':
+ specifier: 2.0.0
+ version: 2.0.0
+ '@workleap/eslint-plugin':
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
+ '@workleap/swc-configs':
+ specifier: 2.1.2
+ version: 2.1.2(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@swc/jest@0.2.29)(browserslist@4.22.1)
+ '@workleap/typescript-configs':
+ specifier: 3.0.2
+ version: 3.0.2(typescript@5.2.2)
+ '@workleap/webpack-configs':
+ specifier: 1.1.0
+ version: 1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@types/webpack@5.28.3)(browserslist@4.22.1)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.89.0)
+ browserslist:
+ specifier: 4.22.1
+ version: 4.22.1
copyfiles:
specifier: 2.4.1
version: 2.4.1
+ cross-env:
+ specifier: 7.0.3
+ version: 7.0.3
http-server:
specifier: 14.1.1
version: 14.1.1
+ msw:
+ specifier: 1.3.2
+ version: 1.3.2(typescript@5.2.2)
nodemon:
specifier: 3.0.1
version: 3.0.1
@@ -402,63 +811,81 @@ importers:
specifier: 5.2.2
version: 5.2.2
webpack:
- specifier: 5.88.2
- version: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
+ specifier: 5.89.0
+ version: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
webpack-cli:
specifier: 5.1.4
- version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
webpack-dev-server:
specifier: 4.15.1
- version: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2)
+ version: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
- sample/local-module:
+ samples/endpoints/local-module:
dependencies:
- '@sample/shared':
+ '@endpoints/shared':
specifier: workspace:*
version: link:../shared
- '@sample/shell':
+ '@endpoints/shell':
specifier: workspace:*
version: link:../shell
'@squide/fakes':
specifier: workspace:*
- version: link:../../packages/fakes
+ version: link:../../../packages/fakes
+ '@squide/msw':
+ specifier: workspace:*
+ version: link:../../../packages/msw
'@squide/react-router':
specifier: workspace:*
- version: link:../../packages/react-router
+ version: link:../../../packages/react-router
+ '@tanstack/react-query':
+ specifier: ^5.0.0
+ version: 5.0.0(react-dom@18.2.0)(react@18.2.0)
+ axios:
+ specifier: 1.5.1
+ version: 1.5.1(debug@4.3.4)
+ msw:
+ specifier: 1.3.2
+ version: 1.3.2(typescript@5.2.2)
react:
specifier: 18.2.0
version: 18.2.0
react-dom:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
+ react-error-boundary:
+ specifier: 4.0.11
+ version: 4.0.11(react@18.2.0)
react-router-dom:
- specifier: 6.16.0
- version: 6.16.0(react-dom@18.2.0)(react@18.2.0)
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
devDependencies:
'@swc/core':
- specifier: 1.3.86
- version: 1.3.86(@swc/helpers@0.5.2)
+ specifier: 1.3.93
+ version: 1.3.93(@swc/helpers@0.5.3)
'@swc/helpers':
- specifier: 0.5.2
- version: 0.5.2
+ specifier: 0.5.3
+ version: 0.5.3
+ '@tanstack/react-query-devtools':
+ specifier: ^5.0.0
+ version: 5.0.1(@tanstack/react-query@5.0.0)(react-dom@18.2.0)(react@18.2.0)
'@types/react':
- specifier: 18.2.22
- version: 18.2.22
+ specifier: 18.2.28
+ version: 18.2.28
'@types/react-dom':
- specifier: 18.2.7
- version: 18.2.7
+ specifier: 18.2.13
+ version: 18.2.13
'@types/webpack':
- specifier: 5.28.2
- version: 5.28.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ specifier: 5.28.3
+ version: 5.28.3(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
'@workleap/browserslist-config':
specifier: 2.0.0
version: 2.0.0
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/swc-configs':
specifier: 2.1.2
- version: 2.1.2(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@swc/jest@0.2.29)(browserslist@4.21.10)
+ version: 2.1.2(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@swc/jest@0.2.29)(browserslist@4.22.1)
'@workleap/tsup-configs':
specifier: 3.0.1
version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
@@ -466,11 +893,11 @@ importers:
specifier: 3.0.2
version: 3.0.2(typescript@5.2.2)
'@workleap/webpack-configs':
- specifier: 1.0.8
- version: 1.0.8(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@types/webpack@5.28.2)(browserslist@4.21.10)(esbuild@0.18.20)(postcss@8.4.30)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ specifier: 1.1.0
+ version: 1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@types/webpack@5.28.3)(browserslist@4.22.1)(esbuild@0.18.20)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.89.0)
browserslist:
- specifier: 4.21.10
- version: 4.21.10
+ specifier: 4.22.1
+ version: 4.22.1
cross-env:
specifier: 7.0.3
version: 7.0.3
@@ -479,80 +906,98 @@ importers:
version: 3.0.1
tsup:
specifier: 7.2.0
- version: 7.2.0(@swc/core@1.3.86)(postcss@8.4.30)(ts-node@10.9.1)(typescript@5.2.2)
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
typescript:
specifier: 5.2.2
version: 5.2.2
webpack:
- specifier: 5.88.2
- version: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ specifier: 5.89.0
+ version: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
webpack-cli:
specifier: 5.1.4
- version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
webpack-dev-server:
specifier: 4.15.1
- version: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2)
+ version: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
- sample/remote-module:
+ samples/endpoints/remote-module:
dependencies:
- '@sample/shared':
+ '@endpoints/shared':
specifier: workspace:*
version: link:../shared
- '@sample/shell':
+ '@endpoints/shell':
specifier: workspace:*
version: link:../shell
'@squide/fakes':
specifier: workspace:*
- version: link:../../packages/fakes
+ version: link:../../../packages/fakes
+ '@squide/msw':
+ specifier: workspace:*
+ version: link:../../../packages/msw
'@squide/react-router':
specifier: workspace:*
- version: link:../../packages/react-router
+ version: link:../../../packages/react-router
'@squide/webpack-module-federation':
specifier: workspace:*
- version: link:../../packages/webpack-module-federation
+ version: link:../../../packages/webpack-module-federation
+ '@tanstack/react-query':
+ specifier: ^5.0.0
+ version: 5.0.0(react-dom@18.2.0)(react@18.2.0)
+ axios:
+ specifier: 1.5.1
+ version: 1.5.1(debug@4.3.4)
+ msw:
+ specifier: 1.3.2
+ version: 1.3.2(typescript@5.2.2)
react:
specifier: 18.2.0
version: 18.2.0
react-dom:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
+ react-error-boundary:
+ specifier: 4.0.11
+ version: 4.0.11(react@18.2.0)
react-router-dom:
- specifier: 6.16.0
- version: 6.16.0(react-dom@18.2.0)(react@18.2.0)
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
devDependencies:
'@swc/core':
- specifier: 1.3.86
- version: 1.3.86(@swc/helpers@0.5.2)
+ specifier: 1.3.93
+ version: 1.3.93(@swc/helpers@0.5.3)
'@swc/helpers':
- specifier: 0.5.2
- version: 0.5.2
+ specifier: 0.5.3
+ version: 0.5.3
+ '@tanstack/react-query-devtools':
+ specifier: ^5.0.0
+ version: 5.0.1(@tanstack/react-query@5.0.0)(react-dom@18.2.0)(react@18.2.0)
'@types/react':
- specifier: 18.2.22
- version: 18.2.22
+ specifier: 18.2.28
+ version: 18.2.28
'@types/react-dom':
- specifier: 18.2.7
- version: 18.2.7
+ specifier: 18.2.13
+ version: 18.2.13
'@types/webpack':
- specifier: 5.28.2
- version: 5.28.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
+ specifier: 5.28.3
+ version: 5.28.3(@swc/core@1.3.93)(webpack-cli@5.1.4)
'@workleap/browserslist-config':
specifier: 2.0.0
version: 2.0.0
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/swc-configs':
specifier: 2.1.2
- version: 2.1.2(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@swc/jest@0.2.29)(browserslist@4.21.10)
+ version: 2.1.2(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@swc/jest@0.2.29)(browserslist@4.22.1)
'@workleap/typescript-configs':
specifier: 3.0.2
version: 3.0.2(typescript@5.2.2)
'@workleap/webpack-configs':
- specifier: 1.0.8
- version: 1.0.8(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@types/webpack@5.28.2)(browserslist@4.21.10)(postcss@8.4.30)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ specifier: 1.1.0
+ version: 1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@types/webpack@5.28.3)(browserslist@4.22.1)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.89.0)
browserslist:
- specifier: 4.21.10
- version: 4.21.10
+ specifier: 4.22.1
+ version: 4.22.1
cross-env:
specifier: 7.0.3
version: 7.0.3
@@ -566,32 +1011,35 @@ importers:
specifier: 5.2.2
version: 5.2.2
webpack:
- specifier: 5.88.2
- version: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
+ specifier: 5.89.0
+ version: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
webpack-cli:
specifier: 5.1.4
- version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ version: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
webpack-dev-server:
specifier: 4.15.1
- version: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2)
+ version: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
- sample/shared:
+ samples/endpoints/shared:
devDependencies:
'@remix-run/router':
- specifier: 1.9.0
- version: 1.9.0
+ specifier: 1.10.0
+ version: 1.10.0
'@squide/react-router':
specifier: workspace:*
- version: link:../../packages/react-router
+ version: link:../../../packages/react-router
+ '@tanstack/react-query':
+ specifier: 5.0.0
+ version: 5.0.0(react-dom@18.2.0)(react@18.2.0)
'@types/react':
- specifier: 18.2.22
- version: 18.2.22
+ specifier: 18.2.28
+ version: 18.2.28
'@types/react-dom':
- specifier: 18.2.7
- version: 18.2.7
+ specifier: 18.2.13
+ version: 18.2.13
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/tsup-configs':
specifier: 3.0.1
version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
@@ -607,42 +1055,60 @@ importers:
react-dom:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
+ react-error-boundary:
+ specifier: 4.0.11
+ version: 4.0.11(react@18.2.0)
react-router-dom:
- specifier: 6.16.0
- version: 6.16.0(react-dom@18.2.0)(react@18.2.0)
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
tsup:
specifier: 7.2.0
- version: 7.2.0(@swc/core@1.3.86)(postcss@8.4.30)(ts-node@10.9.1)(typescript@5.2.2)
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
typescript:
specifier: 5.2.2
version: 5.2.2
- sample/shell:
+ samples/endpoints/shell:
devDependencies:
- '@remix-run/router':
- specifier: 1.9.0
- version: 1.9.0
- '@sample/shared':
+ '@endpoints/shared':
specifier: workspace:*
version: link:../shared
+ '@remix-run/router':
+ specifier: 1.10.0
+ version: 1.10.0
+ '@squide/fakes':
+ specifier: workspace:*
+ version: link:../../../packages/fakes
+ '@squide/msw':
+ specifier: workspace:*
+ version: link:../../../packages/msw
'@squide/react-router':
specifier: workspace:*
- version: link:../../packages/react-router
+ version: link:../../../packages/react-router
+ '@squide/webpack-module-federation':
+ specifier: workspace:*
+ version: link:../../../packages/webpack-module-federation
'@types/react':
- specifier: 18.2.22
- version: 18.2.22
+ specifier: 18.2.28
+ version: 18.2.28
'@types/react-dom':
- specifier: 18.2.7
- version: 18.2.7
+ specifier: 18.2.13
+ version: 18.2.13
'@workleap/eslint-plugin':
- specifier: 2.1.1
- version: 2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
+ specifier: 3.0.0
+ version: 3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
'@workleap/tsup-configs':
specifier: 3.0.1
version: 3.0.1(tsup@7.2.0)(typescript@5.2.2)
'@workleap/typescript-configs':
specifier: 3.0.2
version: 3.0.2(typescript@5.2.2)
+ axios:
+ specifier: 1.5.1
+ version: 1.5.1(debug@4.3.4)
+ msw:
+ specifier: 1.3.2
+ version: 1.3.2(typescript@5.2.2)
nodemon:
specifier: 3.0.1
version: 3.0.1
@@ -652,12 +1118,15 @@ importers:
react-dom:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
+ react-error-boundary:
+ specifier: 4.0.11
+ version: 4.0.11(react@18.2.0)
react-router-dom:
- specifier: 6.16.0
- version: 6.16.0(react-dom@18.2.0)(react@18.2.0)
+ specifier: 6.17.0
+ version: 6.17.0(react-dom@18.2.0)(react@18.2.0)
tsup:
specifier: 7.2.0
- version: 7.2.0(@swc/core@1.3.86)(postcss@8.4.30)(ts-node@10.9.1)(typescript@5.2.2)
+ version: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
typescript:
specifier: 5.2.2
version: 5.2.2
@@ -674,7 +1143,7 @@ packages:
engines: {node: '>=6.0.0'}
dependencies:
'@jridgewell/gen-mapping': 0.3.3
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
dev: true
/@babel/code-frame@7.22.13:
@@ -685,26 +1154,26 @@ packages:
chalk: 2.4.2
dev: true
- /@babel/compat-data@7.22.20:
- resolution: {integrity: sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==}
+ /@babel/compat-data@7.23.2:
+ resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==}
engines: {node: '>=6.9.0'}
dev: true
- /@babel/core@7.22.20:
- resolution: {integrity: sha512-Y6jd1ahLubuYweD/zJH+vvOY141v4f9igNQAQ+MBgq9JlHS2iTsZKn1aMsb3vGccZsXI16VzTBw52Xx0DWmtnA==}
+ /@babel/core@7.23.2:
+ resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@ampproject/remapping': 2.2.1
'@babel/code-frame': 7.22.13
- '@babel/generator': 7.22.15
+ '@babel/generator': 7.23.0
'@babel/helper-compilation-targets': 7.22.15
- '@babel/helper-module-transforms': 7.22.20(@babel/core@7.22.20)
- '@babel/helpers': 7.22.15
- '@babel/parser': 7.22.16
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2)
+ '@babel/helpers': 7.23.2
+ '@babel/parser': 7.23.0
'@babel/template': 7.22.15
- '@babel/traverse': 7.22.20
- '@babel/types': 7.22.19
- convert-source-map: 1.9.0
+ '@babel/traverse': 7.23.2
+ '@babel/types': 7.23.0
+ convert-source-map: 2.0.0
debug: 4.3.4(supports-color@9.4.0)
gensync: 1.0.0-beta.2
json5: 2.2.3
@@ -713,13 +1182,13 @@ packages:
- supports-color
dev: true
- /@babel/generator@7.22.15:
- resolution: {integrity: sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==}
+ /@babel/generator@7.23.0:
+ resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
'@jridgewell/gen-mapping': 0.3.3
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
jsesc: 2.5.2
dev: true
@@ -727,68 +1196,68 @@ packages:
resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
/@babel/helper-builder-binary-assignment-operator-visitor@7.22.15:
resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
/@babel/helper-compilation-targets@7.22.15:
resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/compat-data': 7.22.20
+ '@babel/compat-data': 7.23.2
'@babel/helper-validator-option': 7.22.15
- browserslist: 4.21.10
+ browserslist: 4.22.1
lru-cache: 5.1.1
semver: 6.3.1
dev: true
- /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.22.20):
+ /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-environment-visitor': 7.22.20
- '@babel/helper-function-name': 7.22.5
- '@babel/helper-member-expression-to-functions': 7.22.15
+ '@babel/helper-function-name': 7.23.0
+ '@babel/helper-member-expression-to-functions': 7.23.0
'@babel/helper-optimise-call-expression': 7.22.5
- '@babel/helper-replace-supers': 7.22.20(@babel/core@7.22.20)
+ '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2)
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
semver: 6.3.1
dev: true
- /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.22.20):
+ /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-annotate-as-pure': 7.22.5
regexpu-core: 5.3.2
semver: 6.3.1
dev: true
- /@babel/helper-define-polyfill-provider@0.4.2(@babel/core@7.22.20):
- resolution: {integrity: sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==}
+ /@babel/helper-define-polyfill-provider@0.4.3(@babel/core@7.23.2):
+ resolution: {integrity: sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==}
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-compilation-targets': 7.22.15
'@babel/helper-plugin-utils': 7.22.5
debug: 4.3.4(supports-color@9.4.0)
lodash.debounce: 4.0.8
- resolve: 1.22.6
+ resolve: 1.22.8
transitivePeerDependencies:
- supports-color
dev: true
@@ -798,42 +1267,42 @@ packages:
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helper-function-name@7.22.5:
- resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==}
+ /@babel/helper-function-name@7.23.0:
+ resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/template': 7.22.15
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
/@babel/helper-hoist-variables@7.22.5:
resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
- /@babel/helper-member-expression-to-functions@7.22.15:
- resolution: {integrity: sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==}
+ /@babel/helper-member-expression-to-functions@7.23.0:
+ resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
/@babel/helper-module-imports@7.22.15:
resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
- /@babel/helper-module-transforms@7.22.20(@babel/core@7.22.20):
- resolution: {integrity: sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A==}
+ /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-module-imports': 7.22.15
'@babel/helper-simple-access': 7.22.5
@@ -845,7 +1314,7 @@ packages:
resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
/@babel/helper-plugin-utils@7.22.5:
@@ -853,27 +1322,27 @@ packages:
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.22.20):
+ /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.2):
resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-wrap-function': 7.22.20
dev: true
- /@babel/helper-replace-supers@7.22.20(@babel/core@7.22.20):
+ /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.2):
resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-environment-visitor': 7.22.20
- '@babel/helper-member-expression-to-functions': 7.22.15
+ '@babel/helper-member-expression-to-functions': 7.23.0
'@babel/helper-optimise-call-expression': 7.22.5
dev: true
@@ -881,21 +1350,21 @@ packages:
resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
/@babel/helper-skip-transparent-expression-wrappers@7.22.5:
resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
/@babel/helper-split-export-declaration@7.22.6:
resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
/@babel/helper-string-parser@7.22.5:
@@ -917,18 +1386,18 @@ packages:
resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/helper-function-name': 7.22.5
+ '@babel/helper-function-name': 7.23.0
'@babel/template': 7.22.15
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
- /@babel/helpers@7.22.15:
- resolution: {integrity: sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==}
+ /@babel/helpers@7.23.2:
+ resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/template': 7.22.15
- '@babel/traverse': 7.22.20
- '@babel/types': 7.22.19
+ '@babel/traverse': 7.23.2
+ '@babel/types': 7.23.0
transitivePeerDependencies:
- supports-color
dev: true
@@ -942,1006 +1411,1005 @@ packages:
js-tokens: 4.0.0
dev: true
- /@babel/parser@7.22.16:
- resolution: {integrity: sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==}
+ /@babel/parser@7.23.0:
+ resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
'@babel/types': 7.22.19
dev: true
- /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.22.20):
+ /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.15(@babel/core@7.22.20):
+ /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.13.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
- '@babel/plugin-transform-optional-chaining': 7.22.15(@babel/core@7.22.20)
+ '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.2)
dev: true
- /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.20):
+ /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.2):
resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
dev: true
- /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.20):
+ /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.2):
resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.22.20):
+ /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.20):
+ /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.2):
resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.22.20):
+ /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.2):
resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.22.20):
+ /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.20):
+ /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.20):
+ /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.2):
resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.20):
+ /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.20):
+ /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.2):
resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.20):
+ /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.20):
+ /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.2):
resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.20):
+ /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.20):
+ /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.20):
+ /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.22.20):
+ /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.2):
resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.20):
+ /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.2):
resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.22.20):
+ /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.2):
resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-async-generator-functions@7.22.15(@babel/core@7.22.20):
- resolution: {integrity: sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==}
+ /@babel/plugin-transform-async-generator-functions@7.23.2(@babel/core@7.23.2):
+ resolution: {integrity: sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-plugin-utils': 7.22.5
- '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.22.20)
- '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.20)
+ '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.2)
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-module-imports': 7.22.15
'@babel/helper-plugin-utils': 7.22.5
- '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.22.20)
+ '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-block-scoping@7.22.15(@babel/core@7.22.20):
- resolution: {integrity: sha512-G1czpdJBZCtngoK1sJgloLiOHUnkb/bLZwqVZD8kXmq0ZnVfTTWUcs9OWtp0mBtYJ+4LQY1fllqBkOIPhXmFmw==}
+ /@babel/plugin-transform-block-scoping@7.23.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.22.20):
+ /@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.23.2):
resolution: {integrity: sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.12.0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.20)
+ '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-classes@7.22.15(@babel/core@7.22.20):
+ /@babel/plugin-transform-classes@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-compilation-targets': 7.22.15
'@babel/helper-environment-visitor': 7.22.20
- '@babel/helper-function-name': 7.22.5
+ '@babel/helper-function-name': 7.23.0
'@babel/helper-optimise-call-expression': 7.22.5
'@babel/helper-plugin-utils': 7.22.5
- '@babel/helper-replace-supers': 7.22.20(@babel/core@7.22.20)
+ '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2)
'@babel/helper-split-export-declaration': 7.22.6
globals: 11.12.0
dev: true
- /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
'@babel/template': 7.22.15
dev: true
- /@babel/plugin-transform-destructuring@7.22.15(@babel/core@7.22.20):
- resolution: {integrity: sha512-HzG8sFl1ZVGTme74Nw+X01XsUTqERVQ6/RLHo3XjGRzm7XD6QTtfS3NJotVgCGy8BzkDqRjRBD8dAyJn5TuvSQ==}
+ /@babel/plugin-transform-destructuring@7.23.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-dynamic-import@7.22.11(@babel/core@7.22.20):
+ /@babel/plugin-transform-dynamic-import@7.22.11(@babel/core@7.23.2):
resolution: {integrity: sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.20)
+ '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-export-namespace-from@7.22.11(@babel/core@7.22.20):
+ /@babel/plugin-transform-export-namespace-from@7.22.11(@babel/core@7.23.2):
resolution: {integrity: sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.20)
+ '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-for-of@7.22.15(@babel/core@7.22.20):
+ /@babel/plugin-transform-for-of@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-compilation-targets': 7.22.15
- '@babel/helper-function-name': 7.22.5
+ '@babel/helper-function-name': 7.23.0
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.22.20):
+ /@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.23.2):
resolution: {integrity: sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.20)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-literals@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-literals@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-logical-assignment-operators@7.22.11(@babel/core@7.22.20):
+ /@babel/plugin-transform-logical-assignment-operators@7.22.11(@babel/core@7.23.2):
resolution: {integrity: sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.20)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-modules-amd@7.22.5(@babel/core@7.22.20):
- resolution: {integrity: sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==}
+ /@babel/plugin-transform-modules-amd@7.23.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-module-transforms': 7.22.20(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-modules-commonjs@7.22.15(@babel/core@7.22.20):
- resolution: {integrity: sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==}
+ /@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-module-transforms': 7.22.20(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-simple-access': 7.22.5
dev: true
- /@babel/plugin-transform-modules-systemjs@7.22.11(@babel/core@7.22.20):
- resolution: {integrity: sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA==}
+ /@babel/plugin-transform-modules-systemjs@7.23.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-hoist-variables': 7.22.5
- '@babel/helper-module-transforms': 7.22.20(@babel/core@7.22.20)
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-validator-identifier': 7.22.20
dev: true
- /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-module-transforms': 7.22.20(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-nullish-coalescing-operator@7.22.11(@babel/core@7.22.20):
+ /@babel/plugin-transform-nullish-coalescing-operator@7.22.11(@babel/core@7.23.2):
resolution: {integrity: sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.20)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-numeric-separator@7.22.11(@babel/core@7.22.20):
+ /@babel/plugin-transform-numeric-separator@7.22.11(@babel/core@7.23.2):
resolution: {integrity: sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.20)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-object-rest-spread@7.22.15(@babel/core@7.22.20):
+ /@babel/plugin-transform-object-rest-spread@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/compat-data': 7.22.20
- '@babel/core': 7.22.20
+ '@babel/compat-data': 7.23.2
+ '@babel/core': 7.23.2
'@babel/helper-compilation-targets': 7.22.15
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.22.20)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
- '@babel/helper-replace-supers': 7.22.20(@babel/core@7.22.20)
+ '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.22.20):
+ /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.23.2):
resolution: {integrity: sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.20)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-optional-chaining@7.22.15(@babel/core@7.22.20):
- resolution: {integrity: sha512-ngQ2tBhq5vvSJw2Q2Z9i7ealNkpDMU0rGWnHPKqRZO0tzZ5tlaoz4hDvhXioOoaE0X2vfNss1djwg0DXlfu30A==}
+ /@babel/plugin-transform-optional-chaining@7.23.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
- '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.20)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-parameters@7.22.15(@babel/core@7.22.20):
+ /@babel/plugin-transform-parameters@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.22.20):
+ /@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.23.2):
resolution: {integrity: sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-annotate-as-pure': 7.22.5
- '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.20)
+ '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-react-constant-elements@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-react-constant-elements@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-BF5SXoO+nX3h5OhlN78XbbDrBOffv+AxPP2ENaJOVqjWCgBDeOY3WcaUcddutGSfoap+5NEQ/q/4I3WZIvgkXA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-react-display-name@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-react-display-name@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
- '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-react-jsx@7.22.15(@babel/core@7.22.20):
+ /@babel/plugin-transform-react-jsx@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-module-imports': 7.22.15
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.20)
- '@babel/types': 7.22.19
+ '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2)
+ '@babel/types': 7.23.0
dev: true
- /@babel/plugin-transform-react-pure-annotations@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-react-pure-annotations@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.22.20):
+ /@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.23.2):
resolution: {integrity: sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
regenerator-transform: 0.15.2
dev: true
- /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-spread@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-spread@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
dev: true
- /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-typescript@7.22.15(@babel/core@7.22.20):
+ /@babel/plugin-transform-typescript@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-annotate-as-pure': 7.22.5
- '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.20)
+ '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2)
dev: true
- /@babel/plugin-transform-unicode-escapes@7.22.10(@babel/core@7.22.20):
+ /@babel/plugin-transform-unicode-escapes@7.22.10(@babel/core@7.23.2):
resolution: {integrity: sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.22.20):
+ /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/preset-env@7.22.20(@babel/core@7.22.20):
- resolution: {integrity: sha512-11MY04gGC4kSzlPHRfvVkNAZhUxOvm7DCJ37hPDnUENwe06npjIRAfInEMTGSb4LZK5ZgDFkv5hw0lGebHeTyg==}
+ /@babel/preset-env@7.23.2(@babel/core@7.23.2):
+ resolution: {integrity: sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/compat-data': 7.22.20
- '@babel/core': 7.22.20
+ '@babel/compat-data': 7.23.2
+ '@babel/core': 7.23.2
'@babel/helper-compilation-targets': 7.22.15
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-validator-option': 7.22.15
- '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.20)
- '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.20)
- '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.20)
- '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.20)
- '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.20)
- '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.20)
- '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.20)
- '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.20)
- '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.20)
- '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.22.20)
- '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-async-generator-functions': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-block-scoping': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-class-static-block': 7.22.11(@babel/core@7.22.20)
- '@babel/plugin-transform-classes': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-destructuring': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-dynamic-import': 7.22.11(@babel/core@7.22.20)
- '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-export-namespace-from': 7.22.11(@babel/core@7.22.20)
- '@babel/plugin-transform-for-of': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-json-strings': 7.22.11(@babel/core@7.22.20)
- '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-logical-assignment-operators': 7.22.11(@babel/core@7.22.20)
- '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-modules-amd': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-modules-commonjs': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-modules-systemjs': 7.22.11(@babel/core@7.22.20)
- '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-nullish-coalescing-operator': 7.22.11(@babel/core@7.22.20)
- '@babel/plugin-transform-numeric-separator': 7.22.11(@babel/core@7.22.20)
- '@babel/plugin-transform-object-rest-spread': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-optional-catch-binding': 7.22.11(@babel/core@7.22.20)
- '@babel/plugin-transform-optional-chaining': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-private-property-in-object': 7.22.11(@babel/core@7.22.20)
- '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-regenerator': 7.22.10(@babel/core@7.22.20)
- '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-unicode-escapes': 7.22.10(@babel/core@7.22.20)
- '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.22.20)
- '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.22.20)
- '@babel/types': 7.22.19
- babel-plugin-polyfill-corejs2: 0.4.5(@babel/core@7.22.20)
- babel-plugin-polyfill-corejs3: 0.8.3(@babel/core@7.22.20)
- babel-plugin-polyfill-regenerator: 0.5.2(@babel/core@7.22.20)
- core-js-compat: 3.32.2
+ '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.15(@babel/core@7.23.2)
+ '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.15(@babel/core@7.23.2)
+ '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.2)
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.2)
+ '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.2)
+ '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.2)
+ '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.2)
+ '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.2)
+ '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-async-generator-functions': 7.23.2(@babel/core@7.23.2)
+ '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-block-scoping': 7.23.0(@babel/core@7.23.2)
+ '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-class-static-block': 7.22.11(@babel/core@7.23.2)
+ '@babel/plugin-transform-classes': 7.22.15(@babel/core@7.23.2)
+ '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-destructuring': 7.23.0(@babel/core@7.23.2)
+ '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-dynamic-import': 7.22.11(@babel/core@7.23.2)
+ '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-export-namespace-from': 7.22.11(@babel/core@7.23.2)
+ '@babel/plugin-transform-for-of': 7.22.15(@babel/core@7.23.2)
+ '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-json-strings': 7.22.11(@babel/core@7.23.2)
+ '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-logical-assignment-operators': 7.22.11(@babel/core@7.23.2)
+ '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-modules-amd': 7.23.0(@babel/core@7.23.2)
+ '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.2)
+ '@babel/plugin-transform-modules-systemjs': 7.23.0(@babel/core@7.23.2)
+ '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-nullish-coalescing-operator': 7.22.11(@babel/core@7.23.2)
+ '@babel/plugin-transform-numeric-separator': 7.22.11(@babel/core@7.23.2)
+ '@babel/plugin-transform-object-rest-spread': 7.22.15(@babel/core@7.23.2)
+ '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-optional-catch-binding': 7.22.11(@babel/core@7.23.2)
+ '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.2)
+ '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.2)
+ '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-private-property-in-object': 7.22.11(@babel/core@7.23.2)
+ '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-regenerator': 7.22.10(@babel/core@7.23.2)
+ '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-unicode-escapes': 7.22.10(@babel/core@7.23.2)
+ '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.23.2)
+ '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.2)
+ '@babel/types': 7.23.0
+ babel-plugin-polyfill-corejs2: 0.4.6(@babel/core@7.23.2)
+ babel-plugin-polyfill-corejs3: 0.8.5(@babel/core@7.23.2)
+ babel-plugin-polyfill-regenerator: 0.5.3(@babel/core@7.23.2)
+ core-js-compat: 3.33.0
semver: 6.3.1
transitivePeerDependencies:
- supports-color
dev: true
- /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.22.20):
+ /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.2):
resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==}
peerDependencies:
'@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
esutils: 2.0.3
dev: true
- /@babel/preset-react@7.22.15(@babel/core@7.22.20):
+ /@babel/preset-react@7.22.15(@babel/core@7.23.2):
resolution: {integrity: sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-validator-option': 7.22.15
- '@babel/plugin-transform-react-display-name': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-react-pure-annotations': 7.22.5(@babel/core@7.22.20)
+ '@babel/plugin-transform-react-display-name': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.2)
+ '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-react-pure-annotations': 7.22.5(@babel/core@7.23.2)
dev: true
- /@babel/preset-typescript@7.22.15(@babel/core@7.22.20):
- resolution: {integrity: sha512-HblhNmh6yM+cU4VwbBRpxFhxsTdfS1zsvH9W+gEjD0ARV9+8B4sNfpI6GuhePti84nuvhiwKS539jKPFHskA9A==}
+ /@babel/preset-typescript@7.23.2(@babel/core@7.23.2):
+ resolution: {integrity: sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-validator-option': 7.22.15
- '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-transform-modules-commonjs': 7.22.15(@babel/core@7.22.20)
- '@babel/plugin-transform-typescript': 7.22.15(@babel/core@7.22.20)
+ '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.2)
+ '@babel/plugin-transform-typescript': 7.22.15(@babel/core@7.23.2)
dev: true
/@babel/regjsgen@0.8.0:
resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==}
dev: true
- /@babel/runtime@7.22.15:
- resolution: {integrity: sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==}
+ /@babel/runtime@7.23.2:
+ resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==}
engines: {node: '>=6.9.0'}
dependencies:
regenerator-runtime: 0.14.0
- dev: true
/@babel/template@7.22.15:
resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.22.13
- '@babel/parser': 7.22.16
- '@babel/types': 7.22.19
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.23.0
dev: true
- /@babel/traverse@7.22.20:
- resolution: {integrity: sha512-eU260mPZbU7mZ0N+X10pxXhQFMGTeLb9eFS0mxehS8HZp9o1uSnFeWQuG1UPrlxgA7QoUzFhOnilHDp0AXCyHw==}
+ /@babel/traverse@7.23.2:
+ resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.22.13
- '@babel/generator': 7.22.15
+ '@babel/generator': 7.23.0
'@babel/helper-environment-visitor': 7.22.20
- '@babel/helper-function-name': 7.22.5
+ '@babel/helper-function-name': 7.23.0
'@babel/helper-hoist-variables': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
- '@babel/parser': 7.22.16
- '@babel/types': 7.22.19
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.23.0
debug: 4.3.4(supports-color@9.4.0)
globals: 11.12.0
transitivePeerDependencies:
@@ -1957,6 +2425,15 @@ packages:
to-fast-properties: 2.0.0
dev: true
+ /@babel/types@7.23.0:
+ resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-string-parser': 7.22.5
+ '@babel/helper-validator-identifier': 7.22.20
+ to-fast-properties: 2.0.0
+ dev: true
+
/@bcoe/v8-coverage@0.2.3:
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
dev: true
@@ -2006,7 +2483,7 @@ packages:
/@changesets/apply-release-plan@6.1.4:
resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==}
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@changesets/config': 2.3.1
'@changesets/get-version-range-type': 0.3.2
'@changesets/git': 2.0.0
@@ -2024,7 +2501,7 @@ packages:
/@changesets/assemble-release-plan@5.2.4:
resolution: {integrity: sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==}
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@changesets/errors': 0.1.4
'@changesets/get-dependents-graph': 1.3.6
'@changesets/types': 5.2.1
@@ -2052,7 +2529,7 @@ packages:
resolution: {integrity: sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==}
hasBin: true
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@changesets/apply-release-plan': 6.1.4
'@changesets/assemble-release-plan': 5.2.4
'@changesets/changelog-git': 0.1.14
@@ -2067,8 +2544,8 @@ packages:
'@changesets/types': 5.2.1
'@changesets/write': 0.2.3
'@manypkg/get-packages': 1.1.3
- '@types/is-ci': 3.0.0
- '@types/semver': 7.5.2
+ '@types/is-ci': 3.0.3
+ '@types/semver': 7.5.4
ansi-colors: 4.1.3
chalk: 2.4.2
enquirer: 2.4.1
@@ -2084,7 +2561,7 @@ packages:
semver: 7.5.4
spawndamnit: 2.0.0
term-size: 2.2.1
- tty-table: 4.2.1
+ tty-table: 4.2.2
dev: true
/@changesets/config@2.3.1:
@@ -2127,7 +2604,7 @@ packages:
/@changesets/get-release-plan@3.0.17:
resolution: {integrity: sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==}
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@changesets/assemble-release-plan': 5.2.4
'@changesets/config': 2.3.1
'@changesets/pre': 1.0.14
@@ -2143,7 +2620,7 @@ packages:
/@changesets/git@2.0.0:
resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==}
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@changesets/errors': 0.1.4
'@changesets/types': 5.2.1
'@manypkg/get-packages': 1.1.3
@@ -2168,7 +2645,7 @@ packages:
/@changesets/pre@1.0.14:
resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==}
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@changesets/errors': 0.1.4
'@changesets/types': 5.2.1
'@manypkg/get-packages': 1.1.3
@@ -2178,7 +2655,7 @@ packages:
/@changesets/read@0.5.9:
resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==}
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@changesets/git': 2.0.0
'@changesets/logger': 0.0.5
'@changesets/parse': 0.3.16
@@ -2199,7 +2676,7 @@ packages:
/@changesets/write@0.2.3:
resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==}
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@changesets/types': 5.2.1
fs-extra: 7.0.1
human-id: 1.0.2
@@ -2211,6 +2688,11 @@ packages:
engines: {node: '>=0.1.90'}
dev: true
+ /@colors/colors@1.6.0:
+ resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==}
+ engines: {node: '>=0.1.90'}
+ dev: true
+
/@cspotcode/source-map-support@0.8.1:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
@@ -2246,8 +2728,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/android-arm64@0.19.2:
- resolution: {integrity: sha512-lsB65vAbe90I/Qe10OjkmrdxSX4UJDjosDgb8sZUKcg3oefEuW2OT2Vozz8ef7wrJbMcmhvCC+hciF8jY/uAkw==}
+ /@esbuild/android-arm64@0.19.4:
+ resolution: {integrity: sha512-mRsi2vJsk4Bx/AFsNBqOH2fqedxn5L/moT58xgg51DjX1la64Z3Npicut2VbhvDFO26qjWtPMsVxCd80YTFVeg==}
engines: {node: '>=12'}
cpu: [arm64]
os: [android]
@@ -2263,8 +2745,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/android-arm@0.19.2:
- resolution: {integrity: sha512-tM8yLeYVe7pRyAu9VMi/Q7aunpLwD139EY1S99xbQkT4/q2qa6eA4ige/WJQYdJ8GBL1K33pPFhPfPdJ/WzT8Q==}
+ /@esbuild/android-arm@0.19.4:
+ resolution: {integrity: sha512-uBIbiYMeSsy2U0XQoOGVVcpIktjLMEKa7ryz2RLr7L/vTnANNEsPVAh4xOv7ondGz6ac1zVb0F8Jx20rQikffQ==}
engines: {node: '>=12'}
cpu: [arm]
os: [android]
@@ -2280,8 +2762,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/android-x64@0.19.2:
- resolution: {integrity: sha512-qK/TpmHt2M/Hg82WXHRc/W/2SGo/l1thtDHZWqFq7oi24AjZ4O/CpPSu6ZuYKFkEgmZlFoa7CooAyYmuvnaG8w==}
+ /@esbuild/android-x64@0.19.4:
+ resolution: {integrity: sha512-4iPufZ1TMOD3oBlGFqHXBpa3KFT46aLl6Vy7gwed0ZSYgHaZ/mihbYb4t7Z9etjkC9Al3ZYIoOaHrU60gcMy7g==}
engines: {node: '>=12'}
cpu: [x64]
os: [android]
@@ -2297,8 +2779,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/darwin-arm64@0.19.2:
- resolution: {integrity: sha512-Ora8JokrvrzEPEpZO18ZYXkH4asCdc1DLdcVy8TGf5eWtPO1Ie4WroEJzwI52ZGtpODy3+m0a2yEX9l+KUn0tA==}
+ /@esbuild/darwin-arm64@0.19.4:
+ resolution: {integrity: sha512-Lviw8EzxsVQKpbS+rSt6/6zjn9ashUZ7Tbuvc2YENgRl0yZTktGlachZ9KMJUsVjZEGFVu336kl5lBgDN6PmpA==}
engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
@@ -2314,8 +2796,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/darwin-x64@0.19.2:
- resolution: {integrity: sha512-tP+B5UuIbbFMj2hQaUr6EALlHOIOmlLM2FK7jeFBobPy2ERdohI4Ka6ZFjZ1ZYsrHE/hZimGuU90jusRE0pwDw==}
+ /@esbuild/darwin-x64@0.19.4:
+ resolution: {integrity: sha512-YHbSFlLgDwglFn0lAO3Zsdrife9jcQXQhgRp77YiTDja23FrC2uwnhXMNkAucthsf+Psr7sTwYEryxz6FPAVqw==}
engines: {node: '>=12'}
cpu: [x64]
os: [darwin]
@@ -2331,8 +2813,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/freebsd-arm64@0.19.2:
- resolution: {integrity: sha512-YbPY2kc0acfzL1VPVK6EnAlig4f+l8xmq36OZkU0jzBVHcOTyQDhnKQaLzZudNJQyymd9OqQezeaBgkTGdTGeQ==}
+ /@esbuild/freebsd-arm64@0.19.4:
+ resolution: {integrity: sha512-vz59ijyrTG22Hshaj620e5yhs2dU1WJy723ofc+KUgxVCM6zxQESmWdMuVmUzxtGqtj5heHyB44PjV/HKsEmuQ==}
engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
@@ -2348,8 +2830,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/freebsd-x64@0.19.2:
- resolution: {integrity: sha512-nSO5uZT2clM6hosjWHAsS15hLrwCvIWx+b2e3lZ3MwbYSaXwvfO528OF+dLjas1g3bZonciivI8qKR/Hm7IWGw==}
+ /@esbuild/freebsd-x64@0.19.4:
+ resolution: {integrity: sha512-3sRbQ6W5kAiVQRBWREGJNd1YE7OgzS0AmOGjDmX/qZZecq8NFlQsQH0IfXjjmD0XtUYqr64e0EKNFjMUlPL3Cw==}
engines: {node: '>=12'}
cpu: [x64]
os: [freebsd]
@@ -2365,8 +2847,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/linux-arm64@0.19.2:
- resolution: {integrity: sha512-ig2P7GeG//zWlU0AggA3pV1h5gdix0MA3wgB+NsnBXViwiGgY77fuN9Wr5uoCrs2YzaYfogXgsWZbm+HGr09xg==}
+ /@esbuild/linux-arm64@0.19.4:
+ resolution: {integrity: sha512-ZWmWORaPbsPwmyu7eIEATFlaqm0QGt+joRE9sKcnVUG3oBbr/KYdNE2TnkzdQwX6EDRdg/x8Q4EZQTXoClUqqA==}
engines: {node: '>=12'}
cpu: [arm64]
os: [linux]
@@ -2382,8 +2864,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/linux-arm@0.19.2:
- resolution: {integrity: sha512-Odalh8hICg7SOD7XCj0YLpYCEc+6mkoq63UnExDCiRA2wXEmGlK5JVrW50vZR9Qz4qkvqnHcpH+OFEggO3PgTg==}
+ /@esbuild/linux-arm@0.19.4:
+ resolution: {integrity: sha512-z/4ArqOo9EImzTi4b6Vq+pthLnepFzJ92BnofU1jgNlcVb+UqynVFdoXMCFreTK7FdhqAzH0vmdwW5373Hm9pg==}
engines: {node: '>=12'}
cpu: [arm]
os: [linux]
@@ -2399,8 +2881,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/linux-ia32@0.19.2:
- resolution: {integrity: sha512-mLfp0ziRPOLSTek0Gd9T5B8AtzKAkoZE70fneiiyPlSnUKKI4lp+mGEnQXcQEHLJAcIYDPSyBvsUbKUG2ri/XQ==}
+ /@esbuild/linux-ia32@0.19.4:
+ resolution: {integrity: sha512-EGc4vYM7i1GRUIMqRZNCTzJh25MHePYsnQfKDexD8uPTCm9mK56NIL04LUfX2aaJ+C9vyEp2fJ7jbqFEYgO9lQ==}
engines: {node: '>=12'}
cpu: [ia32]
os: [linux]
@@ -2416,8 +2898,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/linux-loong64@0.19.2:
- resolution: {integrity: sha512-hn28+JNDTxxCpnYjdDYVMNTR3SKavyLlCHHkufHV91fkewpIyQchS1d8wSbmXhs1fiYDpNww8KTFlJ1dHsxeSw==}
+ /@esbuild/linux-loong64@0.19.4:
+ resolution: {integrity: sha512-WVhIKO26kmm8lPmNrUikxSpXcgd6HDog0cx12BUfA2PkmURHSgx9G6vA19lrlQOMw+UjMZ+l3PpbtzffCxFDRg==}
engines: {node: '>=12'}
cpu: [loong64]
os: [linux]
@@ -2433,8 +2915,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/linux-mips64el@0.19.2:
- resolution: {integrity: sha512-KbXaC0Sejt7vD2fEgPoIKb6nxkfYW9OmFUK9XQE4//PvGIxNIfPk1NmlHmMg6f25x57rpmEFrn1OotASYIAaTg==}
+ /@esbuild/linux-mips64el@0.19.4:
+ resolution: {integrity: sha512-keYY+Hlj5w86hNp5JJPuZNbvW4jql7c1eXdBUHIJGTeN/+0QFutU3GrS+c27L+NTmzi73yhtojHk+lr2+502Mw==}
engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
@@ -2450,8 +2932,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/linux-ppc64@0.19.2:
- resolution: {integrity: sha512-dJ0kE8KTqbiHtA3Fc/zn7lCd7pqVr4JcT0JqOnbj4LLzYnp+7h8Qi4yjfq42ZlHfhOCM42rBh0EwHYLL6LEzcw==}
+ /@esbuild/linux-ppc64@0.19.4:
+ resolution: {integrity: sha512-tQ92n0WMXyEsCH4m32S21fND8VxNiVazUbU4IUGVXQpWiaAxOBvtOtbEt3cXIV3GEBydYsY8pyeRMJx9kn3rvw==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
@@ -2467,8 +2949,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/linux-riscv64@0.19.2:
- resolution: {integrity: sha512-7Z/jKNFufZ/bbu4INqqCN6DDlrmOTmdw6D0gH+6Y7auok2r02Ur661qPuXidPOJ+FSgbEeQnnAGgsVynfLuOEw==}
+ /@esbuild/linux-riscv64@0.19.4:
+ resolution: {integrity: sha512-tRRBey6fG9tqGH6V75xH3lFPpj9E8BH+N+zjSUCnFOX93kEzqS0WdyJHkta/mmJHn7MBaa++9P4ARiU4ykjhig==}
engines: {node: '>=12'}
cpu: [riscv64]
os: [linux]
@@ -2484,8 +2966,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/linux-s390x@0.19.2:
- resolution: {integrity: sha512-U+RinR6aXXABFCcAY4gSlv4CL1oOVvSSCdseQmGO66H+XyuQGZIUdhG56SZaDJQcLmrSfRmx5XZOWyCJPRqS7g==}
+ /@esbuild/linux-s390x@0.19.4:
+ resolution: {integrity: sha512-152aLpQqKZYhThiJ+uAM4PcuLCAOxDsCekIbnGzPKVBRUDlgaaAfaUl5NYkB1hgY6WN4sPkejxKlANgVcGl9Qg==}
engines: {node: '>=12'}
cpu: [s390x]
os: [linux]
@@ -2501,8 +2983,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/linux-x64@0.19.2:
- resolution: {integrity: sha512-oxzHTEv6VPm3XXNaHPyUTTte+3wGv7qVQtqaZCrgstI16gCuhNOtBXLEBkBREP57YTd68P0VgDgG73jSD8bwXQ==}
+ /@esbuild/linux-x64@0.19.4:
+ resolution: {integrity: sha512-Mi4aNA3rz1BNFtB7aGadMD0MavmzuuXNTaYL6/uiYIs08U7YMPETpgNn5oue3ICr+inKwItOwSsJDYkrE9ekVg==}
engines: {node: '>=12'}
cpu: [x64]
os: [linux]
@@ -2518,8 +3000,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/netbsd-x64@0.19.2:
- resolution: {integrity: sha512-WNa5zZk1XpTTwMDompZmvQLHszDDDN7lYjEHCUmAGB83Bgs20EMs7ICD+oKeT6xt4phV4NDdSi/8OfjPbSbZfQ==}
+ /@esbuild/netbsd-x64@0.19.4:
+ resolution: {integrity: sha512-9+Wxx1i5N/CYo505CTT7T+ix4lVzEdz0uCoYGxM5JDVlP2YdDC1Bdz+Khv6IbqmisT0Si928eAxbmGkcbiuM/A==}
engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
@@ -2535,8 +3017,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/openbsd-x64@0.19.2:
- resolution: {integrity: sha512-S6kI1aT3S++Dedb7vxIuUOb3oAxqxk2Rh5rOXOTYnzN8JzW1VzBd+IqPiSpgitu45042SYD3HCoEyhLKQcDFDw==}
+ /@esbuild/openbsd-x64@0.19.4:
+ resolution: {integrity: sha512-MFsHleM5/rWRW9EivFssop+OulYVUoVcqkyOkjiynKBCGBj9Lihl7kh9IzrreDyXa4sNkquei5/DTP4uCk25xw==}
engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
@@ -2552,8 +3034,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/sunos-x64@0.19.2:
- resolution: {integrity: sha512-VXSSMsmb+Z8LbsQGcBMiM+fYObDNRm8p7tkUDMPG/g4fhFX5DEFmjxIEa3N8Zr96SjsJ1woAhF0DUnS3MF3ARw==}
+ /@esbuild/sunos-x64@0.19.4:
+ resolution: {integrity: sha512-6Xq8SpK46yLvrGxjp6HftkDwPP49puU4OF0hEL4dTxqCbfx09LyrbUj/D7tmIRMj5D5FCUPksBbxyQhp8tmHzw==}
engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
@@ -2569,8 +3051,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/win32-arm64@0.19.2:
- resolution: {integrity: sha512-5NayUlSAyb5PQYFAU9x3bHdsqB88RC3aM9lKDAz4X1mo/EchMIT1Q+pSeBXNgkfNmRecLXA0O8xP+x8V+g/LKg==}
+ /@esbuild/win32-arm64@0.19.4:
+ resolution: {integrity: sha512-PkIl7Jq4mP6ke7QKwyg4fD4Xvn8PXisagV/+HntWoDEdmerB2LTukRZg728Yd1Fj+LuEX75t/hKXE2Ppk8Hh1w==}
engines: {node: '>=12'}
cpu: [arm64]
os: [win32]
@@ -2586,8 +3068,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/win32-ia32@0.19.2:
- resolution: {integrity: sha512-47gL/ek1v36iN0wL9L4Q2MFdujR0poLZMJwhO2/N3gA89jgHp4MR8DKCmwYtGNksbfJb9JoTtbkoe6sDhg2QTA==}
+ /@esbuild/win32-ia32@0.19.4:
+ resolution: {integrity: sha512-ga676Hnvw7/ycdKB53qPusvsKdwrWzEyJ+AtItHGoARszIqvjffTwaaW3b2L6l90i7MO9i+dlAW415INuRhSGg==}
engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
@@ -2603,8 +3085,8 @@ packages:
requiresBuild: true
optional: true
- /@esbuild/win32-x64@0.19.2:
- resolution: {integrity: sha512-tcuhV7ncXBqbt/Ybf0IyrMcwVOAPDckMK9rXNHtF17UTK18OKLpg08glminN06pt2WCoALhXdLfSPbVvK/6fxw==}
+ /@esbuild/win32-x64@0.19.4:
+ resolution: {integrity: sha512-HP0GDNla1T3ZL8Ko/SHAS2GgtjOg+VmWnnYLhuTksr++EnduYB0f3Y2LzHsUwb2iQ13JGoY6G3R8h6Du/WG6uA==}
engines: {node: '>=12'}
cpu: [x64]
os: [win32]
@@ -2612,18 +3094,18 @@ packages:
dev: true
optional: true
- /@eslint-community/eslint-utils@4.4.0(eslint@8.49.0):
+ /@eslint-community/eslint-utils@4.4.0(eslint@8.51.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
dependencies:
- eslint: 8.49.0
+ eslint: 8.51.0
eslint-visitor-keys: 3.4.3
dev: true
- /@eslint-community/regexpp@4.8.1:
- resolution: {integrity: sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==}
+ /@eslint-community/regexpp@4.9.1:
+ resolution: {integrity: sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
dev: true
@@ -2634,7 +3116,7 @@ packages:
ajv: 6.12.6
debug: 4.3.4(supports-color@9.4.0)
espree: 9.6.1
- globals: 13.21.0
+ globals: 13.23.0
ignore: 5.2.4
import-fresh: 3.3.0
js-yaml: 4.1.0
@@ -2644,8 +3126,8 @@ packages:
- supports-color
dev: true
- /@eslint/js@8.49.0:
- resolution: {integrity: sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==}
+ /@eslint/js@8.51.0:
+ resolution: {integrity: sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
@@ -2666,8 +3148,8 @@ packages:
resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==}
dev: true
- /@fastify/error@3.3.0:
- resolution: {integrity: sha512-dj7vjIn1Ar8sVXj2yAXiMNCJDmS9MQ9XMlIecX2dIzzhjSHCyKo4DdXjXMs7wKW2kj6yvVRSpuQjOZ3YLrh56w==}
+ /@fastify/error@3.4.0:
+ resolution: {integrity: sha512-e/mafFwbK3MNqxUcFBLgHhgxsF8UT1m8aj0dAlqEa2nJEgPsRtpHTZ3ObgrgkZ2M1eJHPTwgyUl/tXkvabsZdQ==}
dev: true
/@fastify/fast-json-stringify-compiler@4.3.0:
@@ -2698,12 +3180,12 @@ packages:
readable-stream: 4.4.2
dev: true
- /@grpc/grpc-js@1.9.3:
- resolution: {integrity: sha512-b8iWtdrYIeT5fdZdS4Br/6h/kuk0PW5EVBUGk1amSbrpL8DlktJD43CdcCWwRdd6+jgwHhADSbL9CsNnm6EUPA==}
+ /@grpc/grpc-js@1.9.6:
+ resolution: {integrity: sha512-yq3qTy23u++8zdvf+h4mz4ohDFi681JAkMZZPTKh8zmUVh0AKLisFlgxcn22FMNowXz15oJ6pqgwT7DJ+PdJvg==}
engines: {node: ^8.13.0 || >=10.10.0}
dependencies:
'@grpc/proto-loader': 0.7.10
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
dev: true
/@grpc/proto-loader@0.7.10:
@@ -2721,28 +3203,28 @@ packages:
resolution: {integrity: sha512-bAg//j0Lh0SFC0LhUrrgpO4FVScOBDt+my4YXeIo9lHi1aXXn6meaB/ycecjVfjyQLaGYWKPKu2C66rTgKIzMQ==}
engines: {node: '>=14'}
dependencies:
- '@grpc/grpc-js': 1.9.3
+ '@grpc/grpc-js': 1.9.6
'@opentelemetry/api': 1.6.0
- '@opentelemetry/core': 1.17.0(@opentelemetry/api@1.6.0)
+ '@opentelemetry/core': 1.17.1(@opentelemetry/api@1.6.0)
'@opentelemetry/exporter-metrics-otlp-grpc': 0.41.2(@opentelemetry/api@1.6.0)
'@opentelemetry/exporter-metrics-otlp-proto': 0.39.1(@opentelemetry/api@1.6.0)
'@opentelemetry/exporter-trace-otlp-grpc': 0.41.2(@opentelemetry/api@1.6.0)
'@opentelemetry/exporter-trace-otlp-proto': 0.41.2(@opentelemetry/api@1.6.0)
- '@opentelemetry/resources': 1.17.0(@opentelemetry/api@1.6.0)
- '@opentelemetry/sdk-metrics': 1.17.0(@opentelemetry/api@1.6.0)
+ '@opentelemetry/resources': 1.17.1(@opentelemetry/api@1.6.0)
+ '@opentelemetry/sdk-metrics': 1.17.1(@opentelemetry/api@1.6.0)
'@opentelemetry/sdk-node': 0.39.1(@opentelemetry/api@1.6.0)(supports-color@9.4.0)
- '@opentelemetry/sdk-trace-base': 1.17.0(@opentelemetry/api@1.6.0)
- axios: 1.5.0(debug@4.3.4)
+ '@opentelemetry/sdk-trace-base': 1.17.1(@opentelemetry/api@1.6.0)
+ axios: 1.5.1(debug@4.3.4)
transitivePeerDependencies:
- debug
- supports-color
dev: true
- /@humanwhocodes/config-array@0.11.11:
- resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==}
+ /@humanwhocodes/config-array@0.11.12:
+ resolution: {integrity: sha512-NlGesA1usRNn6ctHCZ21M4/dKPgW9Nn1FypRdIKKgZOKzkVV4T1FlK5mBiLhHBCDmEbdQG0idrcXlbZfksJ+RA==}
engines: {node: '>=10.10.0'}
dependencies:
- '@humanwhocodes/object-schema': 1.2.1
+ '@humanwhocodes/object-schema': 2.0.0
debug: 4.3.4(supports-color@9.4.0)
minimatch: 3.1.2
transitivePeerDependencies:
@@ -2759,8 +3241,8 @@ packages:
engines: {node: '>=10.10.0'}
dev: true
- /@humanwhocodes/object-schema@1.2.1:
- resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
+ /@humanwhocodes/object-schema@2.0.0:
+ resolution: {integrity: sha512-9S9QrXY2K0L4AGDcSgTi9vgiCcG8VcBv4Mp7/1hDPYoswIy6Z6KO5blYto82BT8M0MZNRWmCFLpCs3HlpYGGdw==}
dev: true
/@import-maps/resolve@1.0.1:
@@ -2800,7 +3282,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
chalk: 4.1.2
jest-message-util: 29.7.0
jest-util: 29.7.0
@@ -2821,14 +3303,14 @@ packages:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
ansi-escapes: 4.3.2
chalk: 4.1.2
- ci-info: 3.8.0
+ ci-info: 3.9.0
exit: 0.1.2
graceful-fs: 4.2.11
jest-changed-files: 29.7.0
- jest-config: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ jest-config: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
jest-haste-map: 29.7.0
jest-message-util: 29.7.0
jest-regex-util: 29.6.3
@@ -2863,7 +3345,7 @@ packages:
dependencies:
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
jest-mock: 29.7.0
dev: true
@@ -2890,7 +3372,7 @@ packages:
dependencies:
'@jest/types': 29.6.3
'@sinonjs/fake-timers': 10.3.0
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
jest-message-util: 29.7.0
jest-mock: 29.7.0
jest-util: 29.7.0
@@ -2922,15 +3404,15 @@ packages:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@jridgewell/trace-mapping': 0.3.19
- '@types/node': 20.6.3
+ '@jridgewell/trace-mapping': 0.3.20
+ '@types/node': 20.8.6
chalk: 4.1.2
collect-v8-coverage: 1.0.2
exit: 0.1.2
glob: 7.2.3
graceful-fs: 4.2.11
istanbul-lib-coverage: 3.2.0
- istanbul-lib-instrument: 6.0.0
+ istanbul-lib-instrument: 6.0.1
istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 4.0.1
istanbul-reports: 3.1.6
@@ -2940,7 +3422,7 @@ packages:
slash: 3.0.0
string-length: 4.0.2
strip-ansi: 6.0.1
- v8-to-istanbul: 9.1.0
+ v8-to-istanbul: 9.1.3
transitivePeerDependencies:
- supports-color
dev: true
@@ -2956,7 +3438,7 @@ packages:
resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
callsites: 3.1.0
graceful-fs: 4.2.11
dev: true
@@ -2967,7 +3449,7 @@ packages:
dependencies:
'@jest/console': 29.7.0
'@jest/types': 29.6.3
- '@types/istanbul-lib-coverage': 2.0.4
+ '@types/istanbul-lib-coverage': 2.0.5
collect-v8-coverage: 1.0.2
dev: true
@@ -2985,9 +3467,9 @@ packages:
resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@jest/types': 29.6.3
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
babel-plugin-istanbul: 6.1.1
chalk: 4.1.2
convert-source-map: 2.0.0
@@ -3008,10 +3490,10 @@ packages:
resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
- '@types/istanbul-lib-coverage': 2.0.4
- '@types/istanbul-reports': 3.0.1
- '@types/node': 20.6.3
- '@types/yargs': 16.0.5
+ '@types/istanbul-lib-coverage': 2.0.5
+ '@types/istanbul-reports': 3.0.3
+ '@types/node': 20.8.6
+ '@types/yargs': 16.0.7
chalk: 4.1.2
dev: true
@@ -3020,10 +3502,10 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/schemas': 29.6.3
- '@types/istanbul-lib-coverage': 2.0.4
- '@types/istanbul-reports': 3.0.1
- '@types/node': 20.6.3
- '@types/yargs': 17.0.24
+ '@types/istanbul-lib-coverage': 2.0.5
+ '@types/istanbul-reports': 3.0.3
+ '@types/node': 20.8.6
+ '@types/yargs': 17.0.29
chalk: 4.1.2
dev: true
@@ -3033,7 +3515,7 @@ packages:
dependencies:
'@jridgewell/set-array': 1.1.2
'@jridgewell/sourcemap-codec': 1.4.15
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
/@jridgewell/resolve-uri@3.1.1:
resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
@@ -3047,13 +3529,13 @@ packages:
resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
dependencies:
'@jridgewell/gen-mapping': 0.3.3
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
/@jridgewell/sourcemap-codec@1.4.15:
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
- /@jridgewell/trace-mapping@0.3.19:
- resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==}
+ /@jridgewell/trace-mapping@0.3.20:
+ resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==}
dependencies:
'@jridgewell/resolve-uri': 3.1.1
'@jridgewell/sourcemap-codec': 1.4.15
@@ -3076,7 +3558,7 @@ packages:
/@manypkg/find-root@1.1.0:
resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==}
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@types/node': 12.20.55
find-up: 4.1.0
fs-extra: 8.1.0
@@ -3085,7 +3567,7 @@ packages:
/@manypkg/get-packages@1.1.3:
resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==}
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@changesets/types': 4.1.0
'@manypkg/find-root': 1.1.0
fs-extra: 8.1.0
@@ -3111,12 +3593,34 @@ packages:
- supports-color
dev: true
+ /@mswjs/cookies@0.2.2:
+ resolution: {integrity: sha512-mlN83YSrcFgk7Dm1Mys40DLssI1KdJji2CMKN8eOlBqsTADYzj2+jWzsANsUTFbxDMWPD5e9bfA1RGqBpS3O1g==}
+ engines: {node: '>=14'}
+ dependencies:
+ '@types/set-cookie-parser': 2.4.5
+ set-cookie-parser: 2.6.0
+
+ /@mswjs/interceptors@0.17.10:
+ resolution: {integrity: sha512-N8x7eSLGcmUFNWZRxT1vsHvypzIRgQYdG0rJey/rZCy6zT/30qDt8Joj7FxzGNLSwXbeZqJOMqDurp7ra4hgbw==}
+ engines: {node: '>=14'}
+ dependencies:
+ '@open-draft/until': 1.0.3
+ '@types/debug': 4.1.10
+ '@xmldom/xmldom': 0.8.10
+ debug: 4.3.4(supports-color@9.4.0)
+ headers-polyfill: 3.2.5
+ outvariant: 1.4.0
+ strict-event-emitter: 0.2.8
+ web-encoding: 1.1.5
+ transitivePeerDependencies:
+ - supports-color
+
/@netlify/binary-info@1.0.0:
resolution: {integrity: sha512-4wMPu9iN3/HL97QblBsBay3E1etIciR84izI3U+4iALY+JHCrI+a2jO0qbAZ/nxKoegypYEaiiqWXylm+/zfrw==}
dev: true
- /@netlify/build-info@7.8.0:
- resolution: {integrity: sha512-4UnAaQUXoxMfs6KAMKPx8Pa5WwdGDcgIliyQpKhc4Xq3A2dgH+Uam9kS4aq5+4ZeHS9/eT1BKLKZPUOOF5ZQZg==}
+ /@netlify/build-info@7.10.1:
+ resolution: {integrity: sha512-bBEDehGo47ERzAHvOb0AZ/P5zNeDOzqpQFEGqc2djoLjBOcgDkRhyMxy7VZMBiaJ//ujxyTVIBXxrqVKWCpmrQ==}
engines: {node: ^14.16.0 || >=16.0.0}
hasBin: true
dependencies:
@@ -3127,12 +3631,12 @@ packages:
read-pkg: 7.1.0
semver: 7.5.4
toml: 3.0.0
- yaml: 2.3.2
+ yaml: 2.3.3
yargs: 17.7.2
dev: true
- /@netlify/build@29.21.1(@types/node@20.6.3)(debug@4.3.4):
- resolution: {integrity: sha512-9twzYq+X8nz16sttkjCB8F8nZIMVspa40P2u3p1h0SWwxk2zq4g3cd8QlZOaO1sfcKQDzzpQkvu+jQ06j2AMfw==}
+ /@netlify/build@29.23.1(@types/node@20.8.6)(debug@4.3.4):
+ resolution: {integrity: sha512-Rt5Depj9QwBdvRW+atwWThBsLcWgNIUq6ZA2ypGWTu5+FISXaX8Py5tWsaeIMc7TS5/ZZBcJWYn+gSkgH+FWQg==}
engines: {node: ^14.16.0 || >=16.0.0}
hasBin: true
dependencies:
@@ -3140,13 +3644,13 @@ packages:
'@honeycombio/opentelemetry-node': 0.5.0(debug@4.3.4)(supports-color@9.4.0)
'@netlify/cache-utils': 5.1.5
'@netlify/config': 20.9.0
- '@netlify/edge-bundler': 8.20.0
+ '@netlify/edge-bundler': 9.3.0(supports-color@9.4.0)
'@netlify/framework-info': 9.8.10
- '@netlify/functions-utils': 5.2.29(supports-color@9.4.0)
+ '@netlify/functions-utils': 5.2.36(supports-color@9.4.0)
'@netlify/git-utils': 5.1.1
'@netlify/plugins-list': 6.71.0
'@netlify/run-utils': 5.1.1
- '@netlify/zip-it-and-ship-it': 9.18.1(supports-color@9.4.0)
+ '@netlify/zip-it-and-ship-it': 9.25.1(supports-color@9.4.0)
'@opentelemetry/api': 1.6.0
'@sindresorhus/slugify': 2.2.1
ansi-escapes: 6.2.0
@@ -3179,7 +3683,7 @@ packages:
ps-list: 8.1.1
read-pkg-up: 9.1.0
readdirp: 3.6.0
- resolve: 2.0.0-next.4
+ resolve: 2.0.0-next.5
rfdc: 1.3.0
safe-json-stringify: 1.2.0
semver: 7.5.4
@@ -3187,7 +3691,7 @@ packages:
strip-ansi: 7.1.0
supports-color: 9.4.0
terminal-link: 3.0.0
- ts-node: 10.9.1(@types/node@20.6.3)(typescript@5.2.2)
+ ts-node: 10.9.1(@types/node@20.8.6)(typescript@5.2.2)
typescript: 5.2.2
uuid: 9.0.0
yargs: 17.7.2
@@ -3245,46 +3749,21 @@ packages:
yargs: 17.7.2
dev: true
- /@netlify/edge-bundler@8.19.1:
- resolution: {integrity: sha512-Erj0+dfRFMQjV3R+FX9NtCV35t6qU91rWKtsuawLzS6tAHLvrR8sOmyFxt5Neg4VPjAstYg1ik16lDak2LhQww==}
- engines: {node: ^14.16.0 || >=16.0.0}
- dependencies:
- '@import-maps/resolve': 1.0.1
- ajv: 8.12.0
- ajv-errors: 3.0.0(ajv@8.12.0)
- better-ajv-errors: 1.2.0(ajv@8.12.0)
- common-path-prefix: 3.0.0
- env-paths: 3.0.0
- execa: 6.1.0
- find-up: 6.3.0
- get-port: 6.1.2
- is-path-inside: 4.0.0
- jsonc-parser: 3.2.0
- node-fetch: 3.3.2
- node-stream-zip: 1.15.0
- p-retry: 5.1.2
- p-wait-for: 4.1.0
- path-key: 4.0.0
- regexp-tree: 0.1.27
- semver: 7.5.4
- tmp-promise: 3.0.3
- urlpattern-polyfill: 8.0.2
- uuid: 9.0.0
- dev: true
-
- /@netlify/edge-bundler@8.20.0:
- resolution: {integrity: sha512-eIDXLqAzz2XpGzPUKe6DKAjldFFTlyaZCQ6v8zrBJ60jKQde5/2tWM2yfHVW9seTehP/0ssLYZW2xmrIM+WqWQ==}
+ /@netlify/edge-bundler@9.3.0(supports-color@9.4.0):
+ resolution: {integrity: sha512-qKY4DKxBKn8TFbil5d7i71ztuOdRBfSXzYW9vN3t7WP0R4MKcgUg6nqo4a9llso/TNGlPv9tDrKq+w4jhpfGhA==}
engines: {node: ^14.16.0 || >=16.0.0}
dependencies:
'@import-maps/resolve': 1.0.1
+ '@vercel/nft': 0.24.3(supports-color@9.4.0)
ajv: 8.12.0
ajv-errors: 3.0.0(ajv@8.12.0)
better-ajv-errors: 1.2.0(ajv@8.12.0)
common-path-prefix: 3.0.0
env-paths: 3.0.0
- esbuild: 0.19.2
+ esbuild: 0.19.4
execa: 6.1.0
find-up: 6.3.0
+ get-package-name: 2.2.0
get-port: 6.1.2
is-path-inside: 4.0.0
jsonc-parser: 3.2.0
@@ -3298,6 +3777,9 @@ packages:
tmp-promise: 3.0.3
urlpattern-polyfill: 8.0.2
uuid: 9.0.0
+ transitivePeerDependencies:
+ - encoding
+ - supports-color
dev: true
/@netlify/framework-info@9.8.10:
@@ -3316,11 +3798,11 @@ packages:
semver: 7.5.4
dev: true
- /@netlify/functions-utils@5.2.29(supports-color@9.4.0):
- resolution: {integrity: sha512-ZISdLE1ha9xMv7smFQ2ey37Gjw3t1W450lhc+oc3vyCzWqjgZIfTRxG8YT30iiYiXonjvs9M63TE3c0ebVf1AQ==}
+ /@netlify/functions-utils@5.2.36(supports-color@9.4.0):
+ resolution: {integrity: sha512-wL4ViAg154CxGsWMvbkIGbKqPgYG2lgcyW18Q7fzuFj/PpJsTSh4QdnW3QrsL5oVtb5nX4zG7yRS65sVroXc+A==}
engines: {node: ^14.16.0 || >=16.0.0}
dependencies:
- '@netlify/zip-it-and-ship-it': 9.18.1(supports-color@9.4.0)
+ '@netlify/zip-it-and-ship-it': 9.25.3(supports-color@9.4.0)
cpy: 9.0.1
path-exists: 5.0.0
transitivePeerDependencies:
@@ -3469,8 +3951,8 @@ packages:
engines: {node: ^14.16.0 || >=16.0.0}
dev: true
- /@netlify/open-api@2.21.1:
- resolution: {integrity: sha512-64iTnYNZszY3Txc0V6sHRq4VUrL1P+A/jRmpA+9QxS+4KQqQFZB2O64XEWuEJABX3PKqpE0MNq2w10w8IM3pEQ==}
+ /@netlify/open-api@2.23.2:
+ resolution: {integrity: sha512-tVioUmq6CMUfe5Rd3KHAcSiwypNC6MJu3ZOgpLdyklQzkIjoVsTAAUK1lcNJQyOfahRzNxwQ9vyfv+Ngp43J4g==}
dev: true
/@netlify/plugins-list@6.71.0:
@@ -3485,32 +3967,82 @@ packages:
execa: 6.1.0
dev: true
- /@netlify/serverless-functions-api@1.7.3:
- resolution: {integrity: sha512-n6/7cJlSWvvbBlUOEAbkGyEld80S6KbG/ldQI9OhLfe1lTatgKmrTNIgqVNpaWpUdTgP2OHWFjmFBzkxxBWs5w==}
+ /@netlify/serverless-functions-api@1.10.0:
+ resolution: {integrity: sha512-KIKsfCEBjEGJWmSKvWshpVDtqNtlCq9RUP9dQoMrIzKaq5OZ4FbpGFnDfOxfie0wnZtg29NwsEOwyD3riWvtjQ==}
engines: {node: ^14.18.0 || >=16.0.0}
dependencies:
'@netlify/node-cookies': 0.1.0
urlpattern-polyfill: 8.0.2
dev: true
- /@netlify/zip-it-and-ship-it@9.18.1(supports-color@9.4.0):
- resolution: {integrity: sha512-XOIqPHUSe5Tstzf4QUrEaCm9dH0QGpm8M3efKcRQr8IXKM10zNH7SZ43ovyv3GxULpvbndLUtGi4bdARaMxAxw==}
+ /@netlify/serverless-functions-api@1.9.1:
+ resolution: {integrity: sha512-SxsaTczNwV/gjQbGZLKVGHWVVtITV6V42nZ2UKcWQot0PCEZ/2JUQ8m6o+fIMn74m5FmCKowlKOqLkAE43nV5Q==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ dependencies:
+ '@netlify/node-cookies': 0.1.0
+ urlpattern-polyfill: 8.0.2
+ dev: true
+
+ /@netlify/zip-it-and-ship-it@9.25.1(supports-color@9.4.0):
+ resolution: {integrity: sha512-uZKN5VRQncf5sB4KXqBe+hTUJz4b5FKcV+GcwKCUqgX+O25x5y7ADEONKB/v5uwIH0IqaDD6YHGxqayx89hmwg==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ hasBin: true
+ dependencies:
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.22.19
+ '@netlify/binary-info': 1.0.0
+ '@netlify/serverless-functions-api': 1.9.1
+ '@vercel/nft': 0.23.1(supports-color@9.4.0)
+ archiver: 6.0.1
+ common-path-prefix: 3.0.0
+ cp-file: 10.0.0
+ es-module-lexer: 1.3.1
+ esbuild: 0.19.4
+ execa: 6.1.0
+ filter-obj: 5.1.0
+ find-up: 6.3.0
+ glob: 8.1.0
+ is-builtin-module: 3.2.1
+ is-path-inside: 4.0.0
+ junk: 4.0.1
+ locate-path: 7.2.0
+ merge-options: 3.0.4
+ minimatch: 9.0.3
+ normalize-path: 3.0.0
+ p-map: 5.5.0
+ path-exists: 5.0.0
+ precinct: 11.0.5(supports-color@9.4.0)
+ require-package-name: 2.0.1
+ resolve: 2.0.0-next.5
+ semver: 7.5.4
+ tmp-promise: 3.0.3
+ toml: 3.0.0
+ unixify: 1.0.0
+ urlpattern-polyfill: 8.0.2
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - encoding
+ - supports-color
+ dev: true
+
+ /@netlify/zip-it-and-ship-it@9.25.3(supports-color@9.4.0):
+ resolution: {integrity: sha512-mL4fETvisfGgQ0cbJNsl04uwTfBtky2j26NYXt9Fh6/1RFVazhTOUg/8y/QrviSEIQkeIrea2JN9dbkR2Y+liQ==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
dependencies:
- '@babel/parser': 7.22.16
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.22.19
'@netlify/binary-info': 1.0.0
- '@netlify/serverless-functions-api': 1.7.3
+ '@netlify/serverless-functions-api': 1.10.0
'@vercel/nft': 0.23.1(supports-color@9.4.0)
archiver: 6.0.1
common-path-prefix: 3.0.0
cp-file: 10.0.0
es-module-lexer: 1.3.1
- esbuild: 0.19.2
+ esbuild: 0.19.4
execa: 6.1.0
filter-obj: 5.1.0
find-up: 6.3.0
- get-tsconfig: 4.7.0
glob: 8.1.0
is-builtin-module: 3.2.1
is-path-inside: 4.0.0
@@ -3523,7 +4055,7 @@ packages:
path-exists: 5.0.0
precinct: 11.0.5(supports-color@9.4.0)
require-package-name: 2.0.1
- resolve: 2.0.0-next.4
+ resolve: 2.0.0-next.5
semver: 7.5.4
tmp-promise: 3.0.3
toml: 3.0.0
@@ -3556,12 +4088,12 @@ packages:
fastq: 1.15.0
dev: true
- /@npmcli/config@6.3.0:
- resolution: {integrity: sha512-gV64pm5cQ7F2oeoSJ5HTfaKxjFsvC4dAbCsQbtbOkEOymM6iZI62yNGCOLjcq/rfYX9+wVn34ThxK7GZpUwWFg==}
+ /@npmcli/config@6.4.0:
+ resolution: {integrity: sha512-/fQjIbuNVIT/PbXvw178Tm97bxV0E0nVUFKHivMKtSI2pcs8xKdaWkHJxf9dTI0G/y5hp/KuCvgcUu5HwAtI1w==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
dependencies:
'@npmcli/map-workspaces': 3.0.4
- ci-info: 3.8.0
+ ci-info: 3.9.0
ini: 4.1.1
nopt: 7.2.0
proc-log: 3.0.0
@@ -3575,7 +4107,7 @@ packages:
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
dependencies:
'@npmcli/name-from-folder': 2.0.0
- glob: 10.3.4
+ glob: 10.3.10
minimatch: 9.0.3
read-package-json-fast: 3.0.2
dev: true
@@ -3625,8 +4157,8 @@ packages:
- encoding
dev: true
- /@octokit/openapi-types@18.0.0:
- resolution: {integrity: sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==}
+ /@octokit/openapi-types@18.1.1:
+ resolution: {integrity: sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==}
dev: true
/@octokit/plugin-paginate-rest@6.1.2(@octokit/core@4.2.4):
@@ -3700,15 +4232,18 @@ packages:
/@octokit/types@10.0.0:
resolution: {integrity: sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==}
dependencies:
- '@octokit/openapi-types': 18.0.0
+ '@octokit/openapi-types': 18.1.1
dev: true
/@octokit/types@9.3.2:
resolution: {integrity: sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==}
dependencies:
- '@octokit/openapi-types': 18.0.0
+ '@octokit/openapi-types': 18.1.1
dev: true
+ /@open-draft/until@1.0.3:
+ resolution: {integrity: sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==}
+
/@opentelemetry/api-logs@0.39.1:
resolution: {integrity: sha512-9BJ8lMcOzEN0lu+Qji801y707oFO4xT3db6cosPvl+k7ItUHKN5ofWqtSbM9gbt1H4JJ/4/2TVrqI9Rq7hNv6Q==}
engines: {node: '>=14'}
@@ -3757,14 +4292,14 @@ packages:
'@opentelemetry/semantic-conventions': 1.15.2
dev: true
- /@opentelemetry/core@1.17.0(@opentelemetry/api@1.6.0):
- resolution: {integrity: sha512-tfnl3h+UefCgx1aeN2xtrmr6BmdWGKXypk0pflQR0urFS40aE88trnkOMc2HTJZbMrqEEl4HsaBeFhwLVXsrJg==}
+ /@opentelemetry/core@1.17.1(@opentelemetry/api@1.6.0):
+ resolution: {integrity: sha512-I6LrZvl1FF97FQXPR0iieWQmKnGxYtMbWA1GrAXnLUR+B1Hn2m8KqQNEIlZAucyv00GBgpWkpllmULmZfG8P3g==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.7.0'
dependencies:
'@opentelemetry/api': 1.6.0
- '@opentelemetry/semantic-conventions': 1.17.0
+ '@opentelemetry/semantic-conventions': 1.17.1
dev: true
/@opentelemetry/exporter-jaeger@1.13.0(@opentelemetry/api@1.6.0):
@@ -3786,7 +4321,7 @@ packages:
peerDependencies:
'@opentelemetry/api': ^1.3.0
dependencies:
- '@grpc/grpc-js': 1.9.3
+ '@grpc/grpc-js': 1.9.6
'@opentelemetry/api': 1.6.0
'@opentelemetry/core': 1.15.2(@opentelemetry/api@1.6.0)
'@opentelemetry/exporter-metrics-otlp-http': 0.41.2(@opentelemetry/api@1.6.0)
@@ -3846,7 +4381,7 @@ packages:
peerDependencies:
'@opentelemetry/api': ^1.0.0
dependencies:
- '@grpc/grpc-js': 1.9.3
+ '@grpc/grpc-js': 1.9.6
'@opentelemetry/api': 1.6.0
'@opentelemetry/core': 1.13.0(@opentelemetry/api@1.6.0)
'@opentelemetry/otlp-grpc-exporter-base': 0.39.1(@opentelemetry/api@1.6.0)
@@ -3861,7 +4396,7 @@ packages:
peerDependencies:
'@opentelemetry/api': ^1.0.0
dependencies:
- '@grpc/grpc-js': 1.9.3
+ '@grpc/grpc-js': 1.9.6
'@opentelemetry/api': 1.6.0
'@opentelemetry/core': 1.15.2(@opentelemetry/api@1.6.0)
'@opentelemetry/otlp-grpc-exporter-base': 0.41.2(@opentelemetry/api@1.6.0)
@@ -3967,7 +4502,7 @@ packages:
peerDependencies:
'@opentelemetry/api': ^1.0.0
dependencies:
- '@grpc/grpc-js': 1.9.3
+ '@grpc/grpc-js': 1.9.6
'@opentelemetry/api': 1.6.0
'@opentelemetry/core': 1.13.0(@opentelemetry/api@1.6.0)
'@opentelemetry/otlp-exporter-base': 0.39.1(@opentelemetry/api@1.6.0)
@@ -3980,7 +4515,7 @@ packages:
peerDependencies:
'@opentelemetry/api': ^1.0.0
dependencies:
- '@grpc/grpc-js': 1.9.3
+ '@grpc/grpc-js': 1.9.6
'@opentelemetry/api': 1.6.0
'@opentelemetry/core': 1.15.2(@opentelemetry/api@1.6.0)
'@opentelemetry/otlp-exporter-base': 0.41.2(@opentelemetry/api@1.6.0)
@@ -4083,15 +4618,15 @@ packages:
'@opentelemetry/semantic-conventions': 1.15.2
dev: true
- /@opentelemetry/resources@1.17.0(@opentelemetry/api@1.6.0):
- resolution: {integrity: sha512-+u0ciVnj8lhuL/qGRBPeVYvk7fL+H/vOddfvmOeJaA1KC+5/3UED1c9KoZQlRsNT5Kw1FaK8LkY2NVLYfOVZQw==}
+ /@opentelemetry/resources@1.17.1(@opentelemetry/api@1.6.0):
+ resolution: {integrity: sha512-M2e5emqg5I7qRKqlzKx0ROkcPyF8PbcSaWEdsm72od9txP7Z/Pl8PDYOyu80xWvbHAWk5mDxOF6v3vNdifzclA==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.7.0'
dependencies:
'@opentelemetry/api': 1.6.0
- '@opentelemetry/core': 1.17.0(@opentelemetry/api@1.6.0)
- '@opentelemetry/semantic-conventions': 1.17.0
+ '@opentelemetry/core': 1.17.1(@opentelemetry/api@1.6.0)
+ '@opentelemetry/semantic-conventions': 1.17.1
dev: true
/@opentelemetry/sdk-logs@0.39.1(@opentelemetry/api-logs@0.39.1)(@opentelemetry/api@1.6.0):
@@ -4144,15 +4679,15 @@ packages:
lodash.merge: 4.6.2
dev: true
- /@opentelemetry/sdk-metrics@1.17.0(@opentelemetry/api@1.6.0):
- resolution: {integrity: sha512-HlWM27yGmYuwCoVRe3yg2PqKnIsq0kEF0HQgvkeDWz2NYkq9fFaSspR6kvjxUTbghAlZrabiqbgyKoYpYaXS3w==}
+ /@opentelemetry/sdk-metrics@1.17.1(@opentelemetry/api@1.6.0):
+ resolution: {integrity: sha512-eHdpsMCKhKhwznxvEfls8Wv3y4ZBWkkXlD3m7vtHIiWBqsMHspWSfie1s07mM45i/bBCf6YBMgz17FUxIXwmZA==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.3.0 <1.7.0'
dependencies:
'@opentelemetry/api': 1.6.0
- '@opentelemetry/core': 1.17.0(@opentelemetry/api@1.6.0)
- '@opentelemetry/resources': 1.17.0(@opentelemetry/api@1.6.0)
+ '@opentelemetry/core': 1.17.1(@opentelemetry/api@1.6.0)
+ '@opentelemetry/resources': 1.17.1(@opentelemetry/api@1.6.0)
lodash.merge: 4.6.2
dev: true
@@ -4203,16 +4738,16 @@ packages:
'@opentelemetry/semantic-conventions': 1.15.2
dev: true
- /@opentelemetry/sdk-trace-base@1.17.0(@opentelemetry/api@1.6.0):
- resolution: {integrity: sha512-2T5HA1/1iE36Q9eg6D4zYlC4Y4GcycI1J6NsHPKZY9oWfAxWsoYnRlkPfUqyY5XVtocCo/xHpnJvGNHwzT70oQ==}
+ /@opentelemetry/sdk-trace-base@1.17.1(@opentelemetry/api@1.6.0):
+ resolution: {integrity: sha512-pfSJJSjZj5jkCJUQZicSpzN8Iz9UKMryPWikZRGObPnJo6cUSoKkjZh6BM3j+D47G4olMBN+YZKYqkFM1L6zNA==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.7.0'
dependencies:
'@opentelemetry/api': 1.6.0
- '@opentelemetry/core': 1.17.0(@opentelemetry/api@1.6.0)
- '@opentelemetry/resources': 1.17.0(@opentelemetry/api@1.6.0)
- '@opentelemetry/semantic-conventions': 1.17.0
+ '@opentelemetry/core': 1.17.1(@opentelemetry/api@1.6.0)
+ '@opentelemetry/resources': 1.17.1(@opentelemetry/api@1.6.0)
+ '@opentelemetry/semantic-conventions': 1.17.1
dev: true
/@opentelemetry/sdk-trace-node@1.13.0(@opentelemetry/api@1.6.0):
@@ -4240,8 +4775,8 @@ packages:
engines: {node: '>=14'}
dev: true
- /@opentelemetry/semantic-conventions@1.17.0:
- resolution: {integrity: sha512-+fguCd2d8d2qruk0H0DsCEy2CTK3t0Tugg7MhZ/UQMvmewbZLNnJ6heSYyzIZWG5IPfAXzoj4f4F/qpM7l4VBA==}
+ /@opentelemetry/semantic-conventions@1.17.1:
+ resolution: {integrity: sha512-xbR2U+2YjauIuo42qmE8XyJK6dYeRMLJuOlUP5SO4auET4VtOHOzgkRVOq+Ik18N+Xf3YPcqJs9dZMiDddz1eQ==}
engines: {node: '>=14'}
dev: true
@@ -4264,7 +4799,7 @@ packages:
tslib: 2.6.2
dev: true
- /@pmmmwh/react-refresh-webpack-plugin@0.5.11(@types/webpack@5.28.2)(react-refresh@0.14.0)(webpack-dev-server@4.15.1)(webpack@5.88.2):
+ /@pmmmwh/react-refresh-webpack-plugin@0.5.11(@types/webpack@5.28.3)(react-refresh@0.14.0)(webpack-dev-server@4.15.1)(webpack@5.89.0):
resolution: {integrity: sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ==}
engines: {node: '>= 10.13'}
peerDependencies:
@@ -4290,10 +4825,10 @@ packages:
webpack-plugin-serve:
optional: true
dependencies:
- '@types/webpack': 5.28.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
+ '@types/webpack': 5.28.3(@swc/core@1.3.93)(webpack-cli@5.1.4)
ansi-html-community: 0.0.8
common-path-prefix: 3.0.0
- core-js-pure: 3.32.2
+ core-js-pure: 3.33.0
error-stack-parser: 2.1.4
find-up: 5.0.0
html-entities: 2.4.0
@@ -4301,11 +4836,11 @@ packages:
react-refresh: 0.14.0
schema-utils: 3.3.0
source-map: 0.7.4
- webpack: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
- webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2)
+ webpack: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
dev: true
- /@pmmmwh/react-refresh-webpack-plugin@0.5.11(react-refresh@0.14.0)(webpack@5.88.2):
+ /@pmmmwh/react-refresh-webpack-plugin@0.5.11(react-refresh@0.14.0)(webpack@5.89.0):
resolution: {integrity: sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ==}
engines: {node: '>= 10.13'}
peerDependencies:
@@ -4333,7 +4868,7 @@ packages:
dependencies:
ansi-html-community: 0.0.8
common-path-prefix: 3.0.0
- core-js-pure: 3.32.2
+ core-js-pure: 3.33.0
error-stack-parser: 2.1.4
find-up: 5.0.0
html-entities: 2.4.0
@@ -4341,7 +4876,7 @@ packages:
react-refresh: 0.14.0
schema-utils: 3.3.0
source-map: 0.7.4
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
dev: true
/@pnpm/config.env-replace@1.1.0:
@@ -4408,8 +4943,8 @@ packages:
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
dev: true
- /@remix-run/router@1.9.0:
- resolution: {integrity: sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA==}
+ /@remix-run/router@1.10.0:
+ resolution: {integrity: sha512-Lm+fYpMfZoEucJ7cMxgt4dYt8jLfbpwRCzAjm9UgSLOkmlqo9gupxt6YX3DY0Fk155NT9l17d/ydi+964uS9Lw==}
engines: {node: '>=14.0.0'}
/@rollup/pluginutils@4.2.1:
@@ -4480,101 +5015,101 @@ packages:
lodash: 4.17.21
dev: true
- /@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.22.20):
+ /@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.23.2):
resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==}
engines: {node: '>=14'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
dev: true
- /@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.22.20):
+ /@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.23.2):
resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==}
engines: {node: '>=14'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
dev: true
- /@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.22.20):
+ /@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.23.2):
resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==}
engines: {node: '>=14'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
dev: true
- /@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.22.20):
+ /@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.23.2):
resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==}
engines: {node: '>=14'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
dev: true
- /@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.22.20):
+ /@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.23.2):
resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==}
engines: {node: '>=14'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
dev: true
- /@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.22.20):
+ /@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.23.2):
resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==}
engines: {node: '>=14'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
dev: true
- /@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.22.20):
+ /@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.23.2):
resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==}
engines: {node: '>=14'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
dev: true
- /@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.22.20):
+ /@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.23.2):
resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==}
engines: {node: '>=12'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
dev: true
- /@svgr/babel-preset@8.1.0(@babel/core@7.22.20):
+ /@svgr/babel-preset@8.1.0(@babel/core@7.23.2):
resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==}
engines: {node: '>=14'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.20
- '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.22.20)
- '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.22.20)
- '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.22.20)
- '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.22.20)
- '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.22.20)
- '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.22.20)
- '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.22.20)
- '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.23.2)
+ '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.23.2)
+ '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.23.2)
+ '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.23.2)
+ '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.23.2)
+ '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.23.2)
+ '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.23.2)
+ '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.23.2)
dev: true
/@svgr/core@8.1.0(typescript@5.2.2):
resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==}
engines: {node: '>=14'}
dependencies:
- '@babel/core': 7.22.20
- '@svgr/babel-preset': 8.1.0(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.23.2)
camelcase: 6.3.0
cosmiconfig: 8.3.6(typescript@5.2.2)
snake-case: 3.0.4
@@ -4587,7 +5122,7 @@ packages:
resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==}
engines: {node: '>=14'}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
entities: 4.5.0
dev: true
@@ -4597,8 +5132,8 @@ packages:
peerDependencies:
'@svgr/core': '*'
dependencies:
- '@babel/core': 7.22.20
- '@svgr/babel-preset': 8.1.0(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.23.2)
'@svgr/core': 8.1.0(typescript@5.2.2)
'@svgr/hast-util-to-babel-ast': 8.0.0
svg-parser: 2.0.4
@@ -4624,11 +5159,11 @@ packages:
resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==}
engines: {node: '>=14'}
dependencies:
- '@babel/core': 7.22.20
- '@babel/plugin-transform-react-constant-elements': 7.22.5(@babel/core@7.22.20)
- '@babel/preset-env': 7.22.20(@babel/core@7.22.20)
- '@babel/preset-react': 7.22.15(@babel/core@7.22.20)
- '@babel/preset-typescript': 7.22.15(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/plugin-transform-react-constant-elements': 7.22.5(@babel/core@7.23.2)
+ '@babel/preset-env': 7.23.2(@babel/core@7.23.2)
+ '@babel/preset-react': 7.22.15(@babel/core@7.23.2)
+ '@babel/preset-typescript': 7.23.2(@babel/core@7.23.2)
'@svgr/core': 8.1.0(typescript@5.2.2)
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0)
'@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0)(typescript@5.2.2)
@@ -4637,88 +5172,88 @@ packages:
- typescript
dev: true
- /@swc/core-darwin-arm64@1.3.86:
- resolution: {integrity: sha512-hMvSDms0sJJHNtRa3Vhmr9StWN1vmikbf5VE0IZUYGnF1/JZTkXU1h6CdNUY4Hr6i7uCZjH6BEhxFHX1JtKV4w==}
+ /@swc/core-darwin-arm64@1.3.93:
+ resolution: {integrity: sha512-gEKgk7FVIgltnIfDO6GntyuQBBlAYg5imHpRgLxB1zSI27ijVVkksc6QwISzFZAhKYaBWIsFSVeL9AYSziAF7A==}
engines: {node: '>=10'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
optional: true
- /@swc/core-darwin-x64@1.3.86:
- resolution: {integrity: sha512-Jro6HVH4uSOBM7tTDaQNKLNc8BJV7n+SO+Ft2HAZINyeKJS/8MfEYneG7Vmqg18gv00c6dz9AOCcyz+BR7BFkQ==}
+ /@swc/core-darwin-x64@1.3.93:
+ resolution: {integrity: sha512-ZQPxm/fXdDQtn3yrYSL/gFfA8OfZ5jTi33yFQq6vcg/Y8talpZ+MgdSlYM0FkLrZdMTYYTNFiuBQuuvkA+av+Q==}
engines: {node: '>=10'}
cpu: [x64]
os: [darwin]
requiresBuild: true
optional: true
- /@swc/core-linux-arm-gnueabihf@1.3.86:
- resolution: {integrity: sha512-wYB9m0pzXJVSzedXSl4JwS3gKtvcPinpe9MbkddezpqL7OjyDP6pHHW9qIucsfgCrtMtbPC2nqulXLPtAAyIjw==}
+ /@swc/core-linux-arm-gnueabihf@1.3.93:
+ resolution: {integrity: sha512-OYFMMI2yV+aNe3wMgYhODxHdqUB/jrK0SEMHHS44GZpk8MuBXEF+Mcz4qjkY5Q1EH7KVQqXb/gVWwdgTHpjM2A==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
requiresBuild: true
optional: true
- /@swc/core-linux-arm64-gnu@1.3.86:
- resolution: {integrity: sha512-fR44IyK5cdCaO8cC++IEH0Jn03tWnunJnjzA99LxlE5TRInSIOvFm+g5OSUQZDAvEXmQ38sd31LO2HOoDS1Edw==}
+ /@swc/core-linux-arm64-gnu@1.3.93:
+ resolution: {integrity: sha512-BT4dT78odKnJMNiq5HdjBsv29CiIdcCcImAPxeFqAeFw1LL6gh9nzI8E96oWc+0lVT5lfhoesCk4Qm7J6bty8w==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
requiresBuild: true
optional: true
- /@swc/core-linux-arm64-musl@1.3.86:
- resolution: {integrity: sha512-EUPfdbK4dUk/nkX3Vmv/47XH+DqHOa9JI0CTthvJ8/ZXei1MKDUsUc+tI1zMQX2uCuSkSWsEIEpCmA0tMwFhtw==}
+ /@swc/core-linux-arm64-musl@1.3.93:
+ resolution: {integrity: sha512-yH5fWEl1bktouC0mhh0Chuxp7HEO4uCtS/ly1Vmf18gs6wZ8DOOkgAEVv2dNKIryy+Na++ljx4Ym7C8tSJTrLw==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
requiresBuild: true
optional: true
- /@swc/core-linux-x64-gnu@1.3.86:
- resolution: {integrity: sha512-snVZZWv8XgNVaKrTxtO3rUN+BbbB6I8Fqwe8zM/DWGJ096J13r89doQ48x5ZyO+bW4D48eZIWP5pdfSW7oBE3w==}
+ /@swc/core-linux-x64-gnu@1.3.93:
+ resolution: {integrity: sha512-OFUdx64qvrGJhXKEyxosHxgoUVgba2ztYh7BnMiU5hP8lbI8G13W40J0SN3CmFQwPP30+3oEbW7LWzhKEaYjlg==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
requiresBuild: true
optional: true
- /@swc/core-linux-x64-musl@1.3.86:
- resolution: {integrity: sha512-PnnksUJymEJkdnbV2orOSOSB441UqsxYbJge9zbr5UTRXUfWO3eFRV0iTBegjTlOQGbW6yN+YRSDkenTbmCI6g==}
+ /@swc/core-linux-x64-musl@1.3.93:
+ resolution: {integrity: sha512-4B8lSRwEq1XYm6xhxHhvHmKAS7pUp1Q7E33NQ2TlmFhfKvCOh86qvThcjAOo57x8DRwmpvEVrqvpXtYagMN6Ig==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
requiresBuild: true
optional: true
- /@swc/core-win32-arm64-msvc@1.3.86:
- resolution: {integrity: sha512-XlGEGyHwLndm08VvgeAPGj40L+Hx575MQC+2fsyB1uSNUN+uf7fvke+wc7k50a92CaQe/8foLyIR5faayozEJA==}
+ /@swc/core-win32-arm64-msvc@1.3.93:
+ resolution: {integrity: sha512-BHShlxtkven8ZjjvZ5QR6sC5fZCJ9bMujEkiha6W4cBUTY7ce7qGFyHmQd+iPC85d9kD/0cCiX/Xez8u0BhO7w==}
engines: {node: '>=10'}
cpu: [arm64]
os: [win32]
requiresBuild: true
optional: true
- /@swc/core-win32-ia32-msvc@1.3.86:
- resolution: {integrity: sha512-U1BhZa1x9yn+wZGTQmt1cYR79a0FzW/wL6Jas1Pn0bykKLxdRU4mCeZt2P+T3buLm8jr8LpPWiCrbvr658PzwA==}
+ /@swc/core-win32-ia32-msvc@1.3.93:
+ resolution: {integrity: sha512-nEwNWnz4JzYAK6asVvb92yeylfxMYih7eMQOnT7ZVlZN5ba9WF29xJ6kcQKs9HRH6MvWhz9+wRgv3FcjlU6HYA==}
engines: {node: '>=10'}
cpu: [ia32]
os: [win32]
requiresBuild: true
optional: true
- /@swc/core-win32-x64-msvc@1.3.86:
- resolution: {integrity: sha512-wRoQUajqpE3wITHhZVj/6BPu/QwHriFHLHuJA+9y6PeGtUtTmntL42aBKXIFhfL767dYFtohyNg1uZ9eqbGyGQ==}
+ /@swc/core-win32-x64-msvc@1.3.93:
+ resolution: {integrity: sha512-jibQ0zUr4kwJaQVwgmH+svS04bYTPnPw/ZkNInzxS+wFAtzINBYcU8s2PMWbDb2NGYiRSEeoSGyAvS9H+24JFA==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
requiresBuild: true
optional: true
- /@swc/core@1.3.86(@swc/helpers@0.5.2):
- resolution: {integrity: sha512-bEXUtm37bcmJ3q+geG7Zy4rJNUzpxalXQUrrqX1ZoGj3HRtzdeVZ0L/um3fG2j16qe61t8TX/OIZ2G6j6dkG/w==}
+ /@swc/core@1.3.93(@swc/helpers@0.5.3):
+ resolution: {integrity: sha512-690GRr1wUGmGYZHk7fUduX/JUwViMF2o74mnZYIWEcJaCcd9MQfkhsxPBtjeg6tF+h266/Cf3RPYhsFBzzxXcA==}
engines: {node: '>=10'}
requiresBuild: true
peerDependencies:
@@ -4727,33 +5262,37 @@ packages:
'@swc/helpers':
optional: true
dependencies:
- '@swc/helpers': 0.5.2
+ '@swc/counter': 0.1.2
+ '@swc/helpers': 0.5.3
'@swc/types': 0.1.5
optionalDependencies:
- '@swc/core-darwin-arm64': 1.3.86
- '@swc/core-darwin-x64': 1.3.86
- '@swc/core-linux-arm-gnueabihf': 1.3.86
- '@swc/core-linux-arm64-gnu': 1.3.86
- '@swc/core-linux-arm64-musl': 1.3.86
- '@swc/core-linux-x64-gnu': 1.3.86
- '@swc/core-linux-x64-musl': 1.3.86
- '@swc/core-win32-arm64-msvc': 1.3.86
- '@swc/core-win32-ia32-msvc': 1.3.86
- '@swc/core-win32-x64-msvc': 1.3.86
-
- /@swc/helpers@0.5.2:
- resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==}
+ '@swc/core-darwin-arm64': 1.3.93
+ '@swc/core-darwin-x64': 1.3.93
+ '@swc/core-linux-arm-gnueabihf': 1.3.93
+ '@swc/core-linux-arm64-gnu': 1.3.93
+ '@swc/core-linux-arm64-musl': 1.3.93
+ '@swc/core-linux-x64-gnu': 1.3.93
+ '@swc/core-linux-x64-musl': 1.3.93
+ '@swc/core-win32-arm64-msvc': 1.3.93
+ '@swc/core-win32-ia32-msvc': 1.3.93
+ '@swc/core-win32-x64-msvc': 1.3.93
+
+ /@swc/counter@0.1.2:
+ resolution: {integrity: sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==}
+
+ /@swc/helpers@0.5.3:
+ resolution: {integrity: sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==}
dependencies:
tslib: 2.6.2
- /@swc/jest@0.2.29(@swc/core@1.3.86):
+ /@swc/jest@0.2.29(@swc/core@1.3.93):
resolution: {integrity: sha512-8reh5RvHBsSikDC3WGCd5ZTd2BXKkyOdK7QwynrCH58jk2cQFhhHhFBg/jvnWZehUQe/EoOImLENc9/DwbBFow==}
engines: {npm: '>= 7.0.0'}
peerDependencies:
'@swc/core': '*'
dependencies:
'@jest/create-cache-key-function': 27.5.1
- '@swc/core': 1.3.86(@swc/helpers@0.5.2)
+ '@swc/core': 1.3.93(@swc/helpers@0.5.3)
jsonc-parser: 3.2.0
dev: true
@@ -4767,13 +5306,49 @@ packages:
defer-to-connect: 2.0.1
dev: true
+ /@tanstack/query-core@5.0.0:
+ resolution: {integrity: sha512-Y1BpiA6BblJd/UlVqxEVeAG7IACn568YJuTTItAiecBI7En+33g780kg+/8lhgl+BzcUPN7o+NjBrSRGJoemyQ==}
+
+ /@tanstack/query-devtools@5.0.0:
+ resolution: {integrity: sha512-WATg9+nreAmtTRHzxvCFN6j4ucUVbkJNd8ErcYmf7Y6GsJw/BGscd4rWS7cdAP7zfTcPjHjGaRB041pcv8dNvA==}
+ dev: true
+
+ /@tanstack/react-query-devtools@5.0.1(@tanstack/react-query@5.0.0)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-AM1Cx29jnryisTDLetjQB5eg46ax8th1/qADqfV/leWmKEQGCVohkT+JmpXEGQJ4X6MzJYiyoC6YQBdS82jR+w==}
+ peerDependencies:
+ '@tanstack/react-query': ^5.0.0
+ react: ^18.0.0
+ react-dom: ^18.0.0
+ dependencies:
+ '@tanstack/query-devtools': 5.0.0
+ '@tanstack/react-query': 5.0.0(react-dom@18.2.0)(react@18.2.0)
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: true
+
+ /@tanstack/react-query@5.0.0(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-diQoC8FNBcO5Uf5yuaJlXthTtbO1xM8kzOX+pSBUMT9n/cqQ/u1wJGCtukvhDWA+6j07WmIj4bfqNbd2KOB6jQ==}
+ peerDependencies:
+ react: ^18.0.0
+ react-dom: ^18.0.0
+ react-native: '*'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+ dependencies:
+ '@tanstack/query-core': 5.0.0
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+
/@testing-library/dom@9.3.3:
resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==}
engines: {node: '>=14'}
dependencies:
'@babel/code-frame': 7.22.13
- '@babel/runtime': 7.22.15
- '@types/aria-query': 5.0.1
+ '@babel/runtime': 7.23.2
+ '@types/aria-query': 5.0.3
aria-query: 5.1.3
chalk: 4.1.2
dom-accessibility-api: 0.5.16
@@ -4788,9 +5363,9 @@ packages:
react: ^18.0.0
react-dom: ^18.0.0
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
'@testing-library/dom': 9.3.3
- '@types/react-dom': 18.2.7
+ '@types/react-dom': 18.2.13
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: true
@@ -4828,164 +5403,166 @@ packages:
/@types/acorn@4.0.6:
resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==}
dependencies:
- '@types/estree': 1.0.1
+ '@types/estree': 1.0.3
dev: true
- /@types/aria-query@5.0.1:
- resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==}
+ /@types/aria-query@5.0.3:
+ resolution: {integrity: sha512-0Z6Tr7wjKJIk4OUEjVUQMtyunLDy339vcMaj38Kpj6jM2OE1p3S4kXExKZ7a3uXQAPCoy3sbrP1wibDKaf39oA==}
dev: true
- /@types/babel__core@7.20.2:
- resolution: {integrity: sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==}
+ /@types/babel__core@7.20.3:
+ resolution: {integrity: sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==}
dependencies:
- '@babel/parser': 7.22.16
- '@babel/types': 7.22.19
- '@types/babel__generator': 7.6.5
- '@types/babel__template': 7.4.2
- '@types/babel__traverse': 7.20.2
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.23.0
+ '@types/babel__generator': 7.6.6
+ '@types/babel__template': 7.4.3
+ '@types/babel__traverse': 7.20.3
dev: true
- /@types/babel__generator@7.6.5:
- resolution: {integrity: sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==}
+ /@types/babel__generator@7.6.6:
+ resolution: {integrity: sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w==}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
- /@types/babel__template@7.4.2:
- resolution: {integrity: sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==}
+ /@types/babel__template@7.4.3:
+ resolution: {integrity: sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ==}
dependencies:
- '@babel/parser': 7.22.16
- '@babel/types': 7.22.19
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.23.0
dev: true
- /@types/babel__traverse@7.20.2:
- resolution: {integrity: sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==}
+ /@types/babel__traverse@7.20.3:
+ resolution: {integrity: sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw==}
dependencies:
- '@babel/types': 7.22.19
+ '@babel/types': 7.23.0
dev: true
- /@types/body-parser@1.19.3:
- resolution: {integrity: sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==}
+ /@types/body-parser@1.19.4:
+ resolution: {integrity: sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==}
dependencies:
- '@types/connect': 3.4.36
- '@types/node': 20.6.3
+ '@types/connect': 3.4.37
+ '@types/node': 20.8.6
- /@types/bonjour@3.5.11:
- resolution: {integrity: sha512-isGhjmBtLIxdHBDl2xGwUzEM8AOyOvWsADWq7rqirdi/ZQoHnLWErHvsThcEzTX8juDRiZtzp2Qkv5bgNh6mAg==}
+ /@types/bonjour@3.5.12:
+ resolution: {integrity: sha512-ky0kWSqXVxSqgqJvPIkgFkcn4C8MnRog308Ou8xBBIVo39OmUFy+jqNe0nPwLCDFxUpmT9EvT91YzOJgkDRcFg==}
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
- /@types/concat-stream@2.0.0:
- resolution: {integrity: sha512-t3YCerNM7NTVjLuICZo5gYAXYoDvpuuTceCcFQWcDQz26kxUR5uIWolxbIR5jRNIXpMqhOpW/b8imCR1LEmuJw==}
+ /@types/concat-stream@2.0.1:
+ resolution: {integrity: sha512-v5HP9ZsRbzFq5XRo2liUZPKzwbGK5SuGVMWZjE6iJOm/JNdESk3/rkfcPe0lcal0C32PTLVlYUYqGpMGNdDsDg==}
dependencies:
- '@types/node': 18.17.18
+ '@types/node': 20.8.6
dev: true
- /@types/connect-history-api-fallback@1.5.1:
- resolution: {integrity: sha512-iaQslNbARe8fctL5Lk+DsmgWOM83lM+7FzP0eQUJs1jd3kBE8NWqBTIT2S8SqQOJjxvt2eyIjpOuYeRXq2AdMw==}
+ /@types/connect-history-api-fallback@1.5.2:
+ resolution: {integrity: sha512-gX2j9x+NzSh4zOhnRPSdPPmTepS4DfxES0AvIFv3jGv5QyeAJf6u6dY5/BAoAJU9Qq1uTvwOku8SSC2GnCRl6Q==}
dependencies:
- '@types/express-serve-static-core': 4.17.36
- '@types/node': 20.6.3
+ '@types/express-serve-static-core': 4.17.38
+ '@types/node': 20.8.6
- /@types/connect@3.4.36:
- resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==}
+ /@types/connect@3.4.37:
+ resolution: {integrity: sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==}
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
+
+ /@types/cookie@0.4.1:
+ resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==}
- /@types/debug@4.1.8:
- resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==}
+ /@types/debug@4.1.10:
+ resolution: {integrity: sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==}
dependencies:
- '@types/ms': 0.7.31
- dev: true
+ '@types/ms': 0.7.33
- /@types/eslint-scope@3.7.4:
- resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==}
+ /@types/eslint-scope@3.7.6:
+ resolution: {integrity: sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ==}
dependencies:
- '@types/eslint': 8.44.2
- '@types/estree': 1.0.1
+ '@types/eslint': 8.44.6
+ '@types/estree': 1.0.3
- /@types/eslint@8.44.2:
- resolution: {integrity: sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==}
+ /@types/eslint@8.44.6:
+ resolution: {integrity: sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw==}
dependencies:
- '@types/estree': 1.0.1
- '@types/json-schema': 7.0.13
+ '@types/estree': 1.0.3
+ '@types/json-schema': 7.0.14
- /@types/estree-jsx@1.0.0:
- resolution: {integrity: sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ==}
+ /@types/estree-jsx@1.0.2:
+ resolution: {integrity: sha512-GNBWlGBMjiiiL5TSkvPtOteuXsiVitw5MYGY1UYlrAq0SKyczsls6sCD7TZ8fsjRsvCVxml7EbyjJezPb3DrSA==}
dependencies:
- '@types/estree': 1.0.1
+ '@types/estree': 1.0.3
dev: true
- /@types/estree@1.0.1:
- resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
+ /@types/estree@1.0.3:
+ resolution: {integrity: sha512-CS2rOaoQ/eAgAfcTfq6amKG7bsN+EMcgGY4FAFQdvSj2y1ixvOZTUA9mOtCai7E1SYu283XNw7urKK30nP3wkQ==}
- /@types/express-serve-static-core@4.17.36:
- resolution: {integrity: sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q==}
+ /@types/express-serve-static-core@4.17.38:
+ resolution: {integrity: sha512-hXOtc0tuDHZPFwwhuBJXPbjemWtXnJjbvuuyNH2Y5Z6in+iXc63c4eXYDc7GGGqHy+iwYqAJMdaItqdnbcBKmg==}
dependencies:
- '@types/node': 20.6.3
- '@types/qs': 6.9.8
- '@types/range-parser': 1.2.4
- '@types/send': 0.17.1
+ '@types/node': 20.8.6
+ '@types/qs': 6.9.9
+ '@types/range-parser': 1.2.6
+ '@types/send': 0.17.3
- /@types/express@4.17.17:
- resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==}
+ /@types/express@4.17.20:
+ resolution: {integrity: sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==}
dependencies:
- '@types/body-parser': 1.19.3
- '@types/express-serve-static-core': 4.17.36
- '@types/qs': 6.9.8
- '@types/serve-static': 1.15.2
+ '@types/body-parser': 1.19.4
+ '@types/express-serve-static-core': 4.17.38
+ '@types/qs': 6.9.9
+ '@types/serve-static': 1.15.4
- /@types/graceful-fs@4.1.6:
- resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==}
+ /@types/graceful-fs@4.1.8:
+ resolution: {integrity: sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw==}
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
dev: true
- /@types/hast@2.3.6:
- resolution: {integrity: sha512-47rJE80oqPmFdVDCD7IheXBrVdwuBgsYwoczFvKmwfo2Mzsnt+V9OONsYauFmICb6lQPpCuXYJWejBNs4pDJRg==}
+ /@types/hast@2.3.7:
+ resolution: {integrity: sha512-EVLigw5zInURhzfXUM65eixfadfsHKomGKUakToXo84t8gGIJuTcD2xooM2See7GyQ7DRtYjhCHnSUQez8JaLw==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
dev: true
/@types/html-minifier-terser@6.1.0:
resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==}
- /@types/http-cache-semantics@4.0.2:
- resolution: {integrity: sha512-FD+nQWA2zJjh4L9+pFXqWOi0Hs1ryBCfI+985NjluQ1p8EYtoLvjLOKidXBtZ4/IcxDX4o8/E8qDS3540tNliw==}
+ /@types/http-cache-semantics@4.0.3:
+ resolution: {integrity: sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA==}
dev: true
- /@types/http-errors@2.0.2:
- resolution: {integrity: sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==}
+ /@types/http-errors@2.0.3:
+ resolution: {integrity: sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA==}
- /@types/http-proxy@1.17.12:
- resolution: {integrity: sha512-kQtujO08dVtQ2wXAuSFfk9ASy3sug4+ogFR8Kd8UgP8PEuc1/G/8yjYRmp//PcDNJEUKOza/MrQu15bouEUCiw==}
+ /@types/http-proxy@1.17.13:
+ resolution: {integrity: sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw==}
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
- /@types/is-ci@3.0.0:
- resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==}
+ /@types/is-ci@3.0.3:
+ resolution: {integrity: sha512-FdHbjLiN2e8fk9QYQyVYZrK8svUDJpxSaSWLUga8EZS1RGAvvrqM9zbVARBtQuYPeLgnJxM2xloOswPwj1o2cQ==}
dependencies:
- ci-info: 3.8.0
+ ci-info: 3.9.0
dev: true
- /@types/is-empty@1.2.1:
- resolution: {integrity: sha512-a3xgqnFTuNJDm1fjsTjHocYJ40Cz3t8utYpi5GNaxzrJC2HSD08ym+whIL7fNqiqBCdM9bcqD1H/tORWAFXoZw==}
+ /@types/is-empty@1.2.2:
+ resolution: {integrity: sha512-BmFyKRHSsE+LFmOUQIYMg/8UJ+fNX3fxev0/OXGKWxUldHD8/bQYhXsTF7wR8woS0h8CWdLK39REjQ/Fxm6bFg==}
dev: true
- /@types/istanbul-lib-coverage@2.0.4:
- resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
+ /@types/istanbul-lib-coverage@2.0.5:
+ resolution: {integrity: sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==}
dev: true
- /@types/istanbul-lib-report@3.0.0:
- resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==}
+ /@types/istanbul-lib-report@3.0.2:
+ resolution: {integrity: sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==}
dependencies:
- '@types/istanbul-lib-coverage': 2.0.4
+ '@types/istanbul-lib-coverage': 2.0.5
dev: true
- /@types/istanbul-reports@3.0.1:
- resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==}
+ /@types/istanbul-reports@3.0.3:
+ resolution: {integrity: sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==}
dependencies:
- '@types/istanbul-lib-report': 3.0.0
+ '@types/istanbul-lib-report': 3.0.2
dev: true
/@types/jest@29.5.5:
@@ -4995,83 +5572,87 @@ packages:
pretty-format: 29.7.0
dev: true
+ /@types/js-levenshtein@1.1.2:
+ resolution: {integrity: sha512-/NCbMABw2uacuyE16Iwka1EzREDD50/W2ggRBad0y1WHBvAkvR9OEINxModVY7D428gXBe0igeVX7bUc9GaslQ==}
+
/@types/jsdom@20.0.1:
resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==}
dependencies:
- '@types/node': 20.6.3
- '@types/tough-cookie': 4.0.3
+ '@types/node': 20.8.6
+ '@types/tough-cookie': 4.0.4
parse5: 7.1.2
dev: true
- /@types/json-schema@7.0.13:
- resolution: {integrity: sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==}
+ /@types/json-schema@7.0.14:
+ resolution: {integrity: sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==}
/@types/json5@0.0.29:
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
dev: true
- /@types/mdast@3.0.12:
- resolution: {integrity: sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==}
+ /@types/mdast@3.0.14:
+ resolution: {integrity: sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
dev: true
- /@types/mime@1.3.2:
- resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==}
+ /@types/mime@1.3.4:
+ resolution: {integrity: sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==}
- /@types/mime@3.0.1:
- resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==}
+ /@types/mime@3.0.3:
+ resolution: {integrity: sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ==}
- /@types/minimist@1.2.2:
- resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
+ /@types/minimist@1.2.4:
+ resolution: {integrity: sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ==}
dev: true
- /@types/ms@0.7.31:
- resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
- dev: true
+ /@types/ms@0.7.33:
+ resolution: {integrity: sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==}
/@types/node@12.20.55:
resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
dev: true
- /@types/node@18.17.18:
- resolution: {integrity: sha512-/4QOuy3ZpV7Ya1GTRz5CYSz3DgkKpyUptXuQ5PPce7uuyJAOR7r9FhkmxJfvcNUXyklbC63a+YvB3jxy7s9ngw==}
+ /@types/node@18.18.6:
+ resolution: {integrity: sha512-wf3Vz+jCmOQ2HV1YUJuCWdL64adYxumkrxtc+H1VUQlnQI04+5HtH+qZCOE21lBE7gIrt+CwX2Wv8Acrw5Ak6w==}
dev: true
- /@types/node@20.6.3:
- resolution: {integrity: sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA==}
+ /@types/node@20.8.6:
+ resolution: {integrity: sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==}
+ dependencies:
+ undici-types: 5.25.3
- /@types/normalize-package-data@2.4.1:
- resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
+ /@types/normalize-package-data@2.4.3:
+ resolution: {integrity: sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==}
dev: true
- /@types/prop-types@15.7.6:
- resolution: {integrity: sha512-RK/kBbYOQQHLYj9Z95eh7S6t7gq4Ojt/NT8HTk8bWVhA5DaF+5SMnxHKkP4gPNN3wAZkKP+VjAf0ebtYzf+fxg==}
+ /@types/prop-types@15.7.9:
+ resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==}
dev: true
- /@types/qs@6.9.8:
- resolution: {integrity: sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==}
+ /@types/qs@6.9.9:
+ resolution: {integrity: sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==}
- /@types/range-parser@1.2.4:
- resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
+ /@types/range-parser@1.2.6:
+ resolution: {integrity: sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA==}
- /@types/react-dom@18.2.7:
- resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==}
+ /@types/react-dom@18.2.13:
+ resolution: {integrity: sha512-eJIUv7rPP+EC45uNYp/ThhSpE16k22VJUknt5OLoH9tbXoi8bMhwLf5xRuWMywamNbWzhrSmU7IBJfPup1+3fw==}
dependencies:
- '@types/react': 18.2.22
+ '@types/react': 18.2.28
dev: true
- /@types/react-test-renderer@18.0.2:
- resolution: {integrity: sha512-tJzMn+9GHDrdrLe0O4rwJELDfTrmdJbCn/UdYyzjlnPiXYXDl5FBNzdw4PVk2R3hJvSHKFjZcRgvZc12lV0p5Q==}
+ /@types/react-test-renderer@18.0.3:
+ resolution: {integrity: sha512-4wcNLnY6nIT+L6g94CpzL4CXX2P18JvKPU9CDlaHr3DnbP3GiaQLhDotJqjWlVqOcE4UhLRjp0MtxqwuNKONnA==}
dependencies:
- '@types/react': 18.2.22
+ '@types/react': 18.2.28
dev: true
- /@types/react@18.2.22:
- resolution: {integrity: sha512-60fLTOLqzarLED2O3UQImc/lsNRgG0jE/a1mPW9KjMemY0LMITWEsbS4VvZ4p6rorEHd5YKxxmMKSDK505GHpA==}
+ /@types/react@18.2.28:
+ resolution: {integrity: sha512-ad4aa/RaaJS3hyGz0BGegdnSRXQBkd1CCYDCdNjBPg90UUpLgo+WlJqb9fMYUxtehmzF3PJaTWqRZjko6BRzBg==}
dependencies:
- '@types/prop-types': 15.7.6
- '@types/scheduler': 0.16.3
+ '@types/prop-types': 15.7.9
+ '@types/scheduler': 0.16.5
csstype: 3.1.2
dev: true
@@ -5082,63 +5663,68 @@ packages:
resolution: {integrity: sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==}
dev: true
- /@types/scheduler@0.16.3:
- resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==}
+ /@types/scheduler@0.16.5:
+ resolution: {integrity: sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==}
dev: true
- /@types/semver@7.5.2:
- resolution: {integrity: sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==}
+ /@types/semver@7.5.4:
+ resolution: {integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==}
dev: true
- /@types/send@0.17.1:
- resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==}
+ /@types/send@0.17.3:
+ resolution: {integrity: sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug==}
+ dependencies:
+ '@types/mime': 1.3.4
+ '@types/node': 20.8.6
+
+ /@types/serve-index@1.9.3:
+ resolution: {integrity: sha512-4KG+yMEuvDPRrYq5fyVm/I2uqAJSAwZK9VSa+Zf+zUq9/oxSSvy3kkIqyL+jjStv6UCVi8/Aho0NHtB1Fwosrg==}
dependencies:
- '@types/mime': 1.3.2
- '@types/node': 20.6.3
+ '@types/express': 4.17.20
- /@types/serve-index@1.9.1:
- resolution: {integrity: sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==}
+ /@types/serve-static@1.15.4:
+ resolution: {integrity: sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw==}
dependencies:
- '@types/express': 4.17.17
+ '@types/http-errors': 2.0.3
+ '@types/mime': 3.0.3
+ '@types/node': 20.8.6
- /@types/serve-static@1.15.2:
- resolution: {integrity: sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==}
+ /@types/set-cookie-parser@2.4.5:
+ resolution: {integrity: sha512-ZPmztaAQ4rbnW/WTUnT1dwSENQo4bjGqxCSeyK+gZxmd+zJl/QAeF6dpEXcS5UEJX22HwiggFSaY8nE1nRmkbg==}
dependencies:
- '@types/http-errors': 2.0.2
- '@types/mime': 3.0.1
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
- /@types/sockjs@0.3.33:
- resolution: {integrity: sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==}
+ /@types/sockjs@0.3.35:
+ resolution: {integrity: sha512-tIF57KB+ZvOBpAQwSaACfEu7htponHXaFzP7RfKYgsOS0NoYnn+9+jzp7bbq4fWerizI3dTB4NfAZoyeQKWJLw==}
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
- /@types/stack-utils@2.0.1:
- resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
+ /@types/stack-utils@2.0.2:
+ resolution: {integrity: sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw==}
dev: true
- /@types/supports-color@8.1.1:
- resolution: {integrity: sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==}
+ /@types/supports-color@8.1.2:
+ resolution: {integrity: sha512-nhs1D8NjNueBqRBhBTsc81g90g7VBD4wnMTMy9oP+QIldHuJkE655QTL2D1jkj3LyCd+Q5Y69oOpfxN1l0eCMA==}
dev: true
- /@types/tough-cookie@4.0.3:
- resolution: {integrity: sha512-THo502dA5PzG/sfQH+42Lw3fvmYkceefOspdCwpHRul8ik2Jv1K8I5OZz1AT3/rs46kwgMCe9bSBmDLYkkOMGg==}
+ /@types/tough-cookie@4.0.4:
+ resolution: {integrity: sha512-95Sfz4nvMAb0Nl9DTxN3j64adfwfbBPEYq14VN7zT5J5O2M9V6iZMIIQU1U+pJyl9agHYHNCqhCXgyEtIRRa5A==}
dev: true
- /@types/triple-beam@1.3.3:
- resolution: {integrity: sha512-6tOUG+nVHn0cJbVp25JFayS5UE6+xlbcNF9Lo9mU7U0zk3zeUShZied4YEQZjy1JBF043FSkdXw8YkUJuVtB5g==}
+ /@types/triple-beam@1.3.4:
+ resolution: {integrity: sha512-HlJjF3wxV4R2VQkFpKe0YqJLilYNgtRtsqqZtby7RkVsSs+i+vbyzjtUwpFEdUCKcrGzCiEJE7F/0mKjh0sunA==}
dev: true
- /@types/unist@2.0.8:
- resolution: {integrity: sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==}
+ /@types/unist@2.0.9:
+ resolution: {integrity: sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ==}
dev: true
- /@types/webpack@5.28.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4):
- resolution: {integrity: sha512-7tcxyrIOd7WGimZIcWU6pDsNh2edGGnwYExOvd3l/nMvuxqwVPrFXnnTbYCnplqV9BJoU7Mo2mfFtiH8CNFvYw==}
+ /@types/webpack@5.28.3(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4):
+ resolution: {integrity: sha512-Hd0GBzpP0mO2ZKChw2V7flK45m01/2g9FalpMum2X66uouzG3P1vkxvOtLVzAWLna4N9h0s2sVjND9Slnlef8A==}
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
tapable: 2.2.1
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
transitivePeerDependencies:
- '@swc/core'
- esbuild
@@ -5146,12 +5732,12 @@ packages:
- webpack-cli
dev: true
- /@types/webpack@5.28.2(@swc/core@1.3.86)(webpack-cli@5.1.4):
- resolution: {integrity: sha512-7tcxyrIOd7WGimZIcWU6pDsNh2edGGnwYExOvd3l/nMvuxqwVPrFXnnTbYCnplqV9BJoU7Mo2mfFtiH8CNFvYw==}
+ /@types/webpack@5.28.3(@swc/core@1.3.93)(webpack-cli@5.1.4):
+ resolution: {integrity: sha512-Hd0GBzpP0mO2ZKChw2V7flK45m01/2g9FalpMum2X66uouzG3P1vkxvOtLVzAWLna4N9h0s2sVjND9Slnlef8A==}
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
tapable: 2.2.1
- webpack: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
+ webpack: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
transitivePeerDependencies:
- '@swc/core'
- esbuild
@@ -5159,37 +5745,37 @@ packages:
- webpack-cli
dev: true
- /@types/ws@8.5.5:
- resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==}
+ /@types/ws@8.5.8:
+ resolution: {integrity: sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg==}
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
- /@types/yargs-parser@21.0.0:
- resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
+ /@types/yargs-parser@21.0.2:
+ resolution: {integrity: sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw==}
dev: true
- /@types/yargs@16.0.5:
- resolution: {integrity: sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==}
+ /@types/yargs@16.0.7:
+ resolution: {integrity: sha512-lQcYmxWuOfJq4IncK88/nwud9rwr1F04CFc5xzk0k4oKVyz/AI35TfsXmhjf6t8zp8mpCOi17BfvuNWx+zrYkg==}
dependencies:
- '@types/yargs-parser': 21.0.0
+ '@types/yargs-parser': 21.0.2
dev: true
- /@types/yargs@17.0.24:
- resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==}
+ /@types/yargs@17.0.29:
+ resolution: {integrity: sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA==}
dependencies:
- '@types/yargs-parser': 21.0.0
+ '@types/yargs-parser': 21.0.2
dev: true
- /@types/yauzl@2.10.0:
- resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==}
+ /@types/yauzl@2.10.2:
+ resolution: {integrity: sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA==}
requiresBuild: true
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
dev: true
optional: true
- /@typescript-eslint/eslint-plugin@6.7.2(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(typescript@5.2.2):
- resolution: {integrity: sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==}
+ /@typescript-eslint/eslint-plugin@6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
'@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
@@ -5199,14 +5785,14 @@ packages:
typescript:
optional: true
dependencies:
- '@eslint-community/regexpp': 4.8.1
- '@typescript-eslint/parser': 6.7.2(eslint@8.49.0)(typescript@5.2.2)
- '@typescript-eslint/scope-manager': 6.7.2
- '@typescript-eslint/type-utils': 6.7.2(eslint@8.49.0)(typescript@5.2.2)
- '@typescript-eslint/utils': 6.7.2(eslint@8.49.0)(typescript@5.2.2)
- '@typescript-eslint/visitor-keys': 6.7.2
+ '@eslint-community/regexpp': 4.9.1
+ '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
+ '@typescript-eslint/scope-manager': 6.8.0
+ '@typescript-eslint/type-utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
+ '@typescript-eslint/utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
+ '@typescript-eslint/visitor-keys': 6.8.0
debug: 4.3.4(supports-color@9.4.0)
- eslint: 8.49.0
+ eslint: 8.51.0
graphemer: 1.4.0
ignore: 5.2.4
natural-compare: 1.4.0
@@ -5217,8 +5803,8 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/parser@6.7.2(eslint@8.49.0)(typescript@5.2.2):
- resolution: {integrity: sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==}
+ /@typescript-eslint/parser@6.8.0(eslint@8.51.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
@@ -5227,12 +5813,12 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/scope-manager': 6.7.2
- '@typescript-eslint/types': 6.7.2
- '@typescript-eslint/typescript-estree': 6.7.2(typescript@5.2.2)
- '@typescript-eslint/visitor-keys': 6.7.2
+ '@typescript-eslint/scope-manager': 6.8.0
+ '@typescript-eslint/types': 6.8.0
+ '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.2.2)
+ '@typescript-eslint/visitor-keys': 6.8.0
debug: 4.3.4(supports-color@9.4.0)
- eslint: 8.49.0
+ eslint: 8.51.0
typescript: 5.2.2
transitivePeerDependencies:
- supports-color
@@ -5246,16 +5832,16 @@ packages:
'@typescript-eslint/visitor-keys': 5.62.0
dev: true
- /@typescript-eslint/scope-manager@6.7.2:
- resolution: {integrity: sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==}
+ /@typescript-eslint/scope-manager@6.8.0:
+ resolution: {integrity: sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==}
engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
- '@typescript-eslint/types': 6.7.2
- '@typescript-eslint/visitor-keys': 6.7.2
+ '@typescript-eslint/types': 6.8.0
+ '@typescript-eslint/visitor-keys': 6.8.0
dev: true
- /@typescript-eslint/type-utils@6.7.2(eslint@8.49.0)(typescript@5.2.2):
- resolution: {integrity: sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==}
+ /@typescript-eslint/type-utils@6.8.0(eslint@8.51.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
@@ -5264,10 +5850,10 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/typescript-estree': 6.7.2(typescript@5.2.2)
- '@typescript-eslint/utils': 6.7.2(eslint@8.49.0)(typescript@5.2.2)
+ '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.2.2)
+ '@typescript-eslint/utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
debug: 4.3.4(supports-color@9.4.0)
- eslint: 8.49.0
+ eslint: 8.51.0
ts-api-utils: 1.0.3(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
@@ -5279,8 +5865,8 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
- /@typescript-eslint/types@6.7.2:
- resolution: {integrity: sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==}
+ /@typescript-eslint/types@6.8.0:
+ resolution: {integrity: sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==}
engines: {node: ^16.0.0 || >=18.0.0}
dev: true
@@ -5305,8 +5891,8 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/typescript-estree@6.7.2(typescript@5.2.2):
- resolution: {integrity: sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==}
+ /@typescript-eslint/typescript-estree@6.8.0(typescript@5.2.2):
+ resolution: {integrity: sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
typescript: '*'
@@ -5314,8 +5900,8 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/types': 6.7.2
- '@typescript-eslint/visitor-keys': 6.7.2
+ '@typescript-eslint/types': 6.8.0
+ '@typescript-eslint/visitor-keys': 6.8.0
debug: 4.3.4(supports-color@9.4.0)
globby: 11.1.0
is-glob: 4.0.3
@@ -5326,19 +5912,19 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/utils@5.62.0(eslint@8.49.0)(typescript@5.2.2):
+ /@typescript-eslint/utils@5.62.0(eslint@8.51.0)(typescript@5.2.2):
resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.49.0)
- '@types/json-schema': 7.0.13
- '@types/semver': 7.5.2
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0)
+ '@types/json-schema': 7.0.14
+ '@types/semver': 7.5.4
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(supports-color@9.4.0)(typescript@5.2.2)
- eslint: 8.49.0
+ eslint: 8.51.0
eslint-scope: 5.1.1
semver: 7.5.4
transitivePeerDependencies:
@@ -5346,19 +5932,19 @@ packages:
- typescript
dev: true
- /@typescript-eslint/utils@6.7.2(eslint@8.49.0)(typescript@5.2.2):
- resolution: {integrity: sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==}
+ /@typescript-eslint/utils@6.8.0(eslint@8.51.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.49.0)
- '@types/json-schema': 7.0.13
- '@types/semver': 7.5.2
- '@typescript-eslint/scope-manager': 6.7.2
- '@typescript-eslint/types': 6.7.2
- '@typescript-eslint/typescript-estree': 6.7.2(typescript@5.2.2)
- eslint: 8.49.0
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0)
+ '@types/json-schema': 7.0.14
+ '@types/semver': 7.5.4
+ '@typescript-eslint/scope-manager': 6.8.0
+ '@typescript-eslint/types': 6.8.0
+ '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.2.2)
+ eslint: 8.51.0
semver: 7.5.4
transitivePeerDependencies:
- supports-color
@@ -5373,11 +5959,11 @@ packages:
eslint-visitor-keys: 3.4.3
dev: true
- /@typescript-eslint/visitor-keys@6.7.2:
- resolution: {integrity: sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==}
+ /@typescript-eslint/visitor-keys@6.8.0:
+ resolution: {integrity: sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==}
engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
- '@typescript-eslint/types': 6.7.2
+ '@typescript-eslint/types': 6.8.0
eslint-visitor-keys: 3.4.3
dev: true
@@ -5402,6 +5988,27 @@ packages:
- supports-color
dev: true
+ /@vercel/nft@0.24.3(supports-color@9.4.0):
+ resolution: {integrity: sha512-IyBdIxmFAeGZnEfMgt4QrGK7XX4lWazlQj34HEi9dw04/WeDBJ7r1yaOIO5tTf9pbfvwUFodj9b0H+NDGGoOMg==}
+ engines: {node: '>=16'}
+ hasBin: true
+ dependencies:
+ '@mapbox/node-pre-gyp': 1.0.11(supports-color@9.4.0)
+ '@rollup/pluginutils': 4.2.1
+ acorn: 8.10.0
+ async-sema: 3.1.1
+ bindings: 1.5.0
+ estree-walker: 2.0.2
+ glob: 7.2.3
+ graceful-fs: 4.2.11
+ micromatch: 4.0.5
+ node-gyp-build: 4.6.1
+ resolve-from: 5.0.0
+ transitivePeerDependencies:
+ - encoding
+ - supports-color
+ dev: true
+
/@webassemblyjs/ast@1.11.6:
resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==}
dependencies:
@@ -5493,27 +6100,27 @@ packages:
'@webassemblyjs/ast': 1.11.6
'@xtuc/long': 4.2.2
- /@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.88.2):
+ /@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.89.0):
resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==}
engines: {node: '>=14.15.0'}
peerDependencies:
webpack: 5.x.x
webpack-cli: 5.x.x
dependencies:
- webpack: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
- webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ webpack: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
- /@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.88.2):
+ /@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.89.0):
resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==}
engines: {node: '>=14.15.0'}
peerDependencies:
webpack: 5.x.x
webpack-cli: 5.x.x
dependencies:
- webpack: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
- webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ webpack: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
- /@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.1)(webpack@5.88.2):
+ /@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.1)(webpack@5.89.0):
resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==}
engines: {node: '>=14.15.0'}
peerDependencies:
@@ -5524,16 +6131,16 @@ packages:
webpack-dev-server:
optional: true
dependencies:
- webpack: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
- webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2)
- webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2)
+ webpack: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
+ webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
/@workleap/browserslist-config@2.0.0:
resolution: {integrity: sha512-FPaGB35ALxtIWMmi1yrai1uyI+EKrkCwzLl6UAaHwcPoIhHBWqUPMlhP3N5wpY1+HyYFzKeOIk847re3javgiw==}
dev: true
- /@workleap/eslint-plugin@2.1.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2):
- resolution: {integrity: sha512-lTemTwgotQP4KKtN5LGDu/nkLSdtHM1+rqmkWmilVfxVfzYnpRJYCjmB1OtSCVZZTreP0oU+xwkgo9MQdJfoIQ==}
+ /@workleap/eslint-plugin@3.0.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-GRvezpKhUW/UcjQrzTQ6T9KsF3Hr6UnCMS137+VVMjGd0hfGdUMwUf9rMpe2L2pFKlYfJRXuvHoVTzBlnVUPeg==}
peerDependencies:
'@typescript-eslint/parser': '*'
eslint: '*'
@@ -5546,17 +6153,17 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/eslint-plugin': 6.7.2(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(typescript@5.2.2)
- '@typescript-eslint/parser': 6.7.2(eslint@8.49.0)(typescript@5.2.2)
- eslint: 8.49.0
- eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)
- eslint-plugin-jest: 27.4.0(@typescript-eslint/eslint-plugin@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2)
- eslint-plugin-jsx-a11y: 6.7.1(eslint@8.49.0)
- eslint-plugin-mdx: 2.2.0(eslint@8.49.0)
- eslint-plugin-react: 7.33.2(eslint@8.49.0)
- eslint-plugin-react-hooks: 4.6.0(eslint@8.49.0)
- eslint-plugin-storybook: 0.6.13(eslint@8.49.0)(typescript@5.2.2)
- eslint-plugin-testing-library: 6.0.1(eslint@8.49.0)(typescript@5.2.2)
+ '@typescript-eslint/eslint-plugin': 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(typescript@5.2.2)
+ '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
+ eslint: 8.51.0
+ eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)
+ eslint-plugin-jest: 27.4.2(@typescript-eslint/eslint-plugin@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2)
+ eslint-plugin-jsx-a11y: 6.7.1(eslint@8.51.0)
+ eslint-plugin-mdx: 2.2.0(eslint@8.51.0)
+ eslint-plugin-react: 7.33.2(eslint@8.51.0)
+ eslint-plugin-react-hooks: 4.6.0(eslint@8.51.0)
+ eslint-plugin-storybook: 0.6.15(eslint@8.51.0)(typescript@5.2.2)
+ eslint-plugin-testing-library: 6.1.0(eslint@8.51.0)(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
- eslint-import-resolver-typescript
@@ -5565,7 +6172,7 @@ packages:
- supports-color
dev: true
- /@workleap/swc-configs@2.1.2(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@swc/jest@0.2.29)(browserslist@4.21.10):
+ /@workleap/swc-configs@2.1.2(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@swc/jest@0.2.29)(browserslist@4.22.1):
resolution: {integrity: sha512-qMTxLKvNoTys4YxXtvIRWVQiuB46FfCajVpgVrMshtAA3Zydtjy4IGirCOGcalcSbuc12mOseBpxiLV9wayneg==}
peerDependencies:
'@swc/core': '*'
@@ -5578,10 +6185,10 @@ packages:
browserslist:
optional: true
dependencies:
- '@swc/core': 1.3.86(@swc/helpers@0.5.2)
- '@swc/helpers': 0.5.2
- '@swc/jest': 0.2.29(@swc/core@1.3.86)
- browserslist: 4.21.10
+ '@swc/core': 1.3.93(@swc/helpers@0.5.3)
+ '@swc/helpers': 0.5.3
+ '@swc/jest': 0.2.29(@swc/core@1.3.93)
+ browserslist: 4.22.1
dev: true
/@workleap/tsup-configs@3.0.1(tsup@7.2.0)(typescript@5.2.2):
@@ -5590,7 +6197,7 @@ packages:
tsup: '*'
typescript: '*'
dependencies:
- tsup: 7.2.0(@swc/core@1.3.86)(postcss@8.4.30)(ts-node@10.9.1)(typescript@5.2.2)
+ tsup: 7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2)
typescript: 5.2.2
dev: true
@@ -5602,8 +6209,8 @@ packages:
typescript: 5.2.2
dev: true
- /@workleap/webpack-configs@1.0.8(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@types/webpack@5.28.2)(browserslist@4.21.10)(esbuild@0.18.20)(postcss@8.4.30)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.88.2):
- resolution: {integrity: sha512-AVTvHu5qeFVbfp9eA4KftUU8gJRRx7Rcx17jO4gGtFpLf4ADSGi4fE6eDNwGbGgHlhRrZTPYjCyHLNwPID+Pfg==}
+ /@workleap/webpack-configs@1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@types/webpack@5.28.3)(browserslist@4.22.1)(esbuild@0.18.20)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.89.0):
+ resolution: {integrity: sha512-bz5xU0LYdrTTOe+PVTgHrn+dBoLBURGxZx7xTckJ8q9H6DaRWAT9NbRTSzbG2N+Wer2pRISdvkeJ7MmubD11ng==}
peerDependencies:
'@swc/core': '*'
'@swc/helpers': '*'
@@ -5615,21 +6222,21 @@ packages:
webpack-dev-server:
optional: true
dependencies:
- '@pmmmwh/react-refresh-webpack-plugin': 0.5.11(@types/webpack@5.28.2)(react-refresh@0.14.0)(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ '@pmmmwh/react-refresh-webpack-plugin': 0.5.11(@types/webpack@5.28.3)(react-refresh@0.14.0)(webpack-dev-server@4.15.1)(webpack@5.89.0)
'@svgr/webpack': 8.1.0(typescript@5.2.2)
- '@swc/core': 1.3.86(@swc/helpers@0.5.2)
- '@swc/helpers': 0.5.2
- browserslist: 4.21.10
- css-loader: 6.8.1(webpack@5.88.2)
- html-webpack-plugin: 5.5.3(webpack@5.88.2)
- mini-css-extract-plugin: 2.7.6(webpack@5.88.2)
- postcss: 8.4.30
- postcss-loader: 7.3.3(postcss@8.4.30)(typescript@5.2.2)(webpack@5.88.2)
- style-loader: 3.3.3(webpack@5.88.2)
- swc-loader: 0.2.3(@swc/core@1.3.86)(webpack@5.88.2)
- terser-webpack-plugin: 5.3.9(@swc/core@1.3.86)(esbuild@0.18.20)(webpack@5.88.2)
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
- webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2)
+ '@swc/core': 1.3.93(@swc/helpers@0.5.3)
+ '@swc/helpers': 0.5.3
+ browserslist: 4.22.1
+ css-loader: 6.8.1(webpack@5.89.0)
+ html-webpack-plugin: 5.5.3(webpack@5.89.0)
+ mini-css-extract-plugin: 2.7.6(webpack@5.89.0)
+ postcss: 8.4.31
+ postcss-loader: 7.3.3(postcss@8.4.31)(typescript@5.2.2)(webpack@5.89.0)
+ style-loader: 3.3.3(webpack@5.89.0)
+ swc-loader: 0.2.3(@swc/core@1.3.93)(webpack@5.89.0)
+ terser-webpack-plugin: 5.3.9(@swc/core@1.3.93)(esbuild@0.18.20)(webpack@5.89.0)
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
transitivePeerDependencies:
- '@types/webpack'
- esbuild
@@ -5643,8 +6250,8 @@ packages:
- webpack-plugin-serve
dev: true
- /@workleap/webpack-configs@1.0.8(@swc/core@1.3.86)(@swc/helpers@0.5.2)(@types/webpack@5.28.2)(browserslist@4.21.10)(postcss@8.4.30)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.88.2):
- resolution: {integrity: sha512-AVTvHu5qeFVbfp9eA4KftUU8gJRRx7Rcx17jO4gGtFpLf4ADSGi4fE6eDNwGbGgHlhRrZTPYjCyHLNwPID+Pfg==}
+ /@workleap/webpack-configs@1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(@types/webpack@5.28.3)(browserslist@4.22.1)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack-dev-server@4.15.1)(webpack@5.89.0):
+ resolution: {integrity: sha512-bz5xU0LYdrTTOe+PVTgHrn+dBoLBURGxZx7xTckJ8q9H6DaRWAT9NbRTSzbG2N+Wer2pRISdvkeJ7MmubD11ng==}
peerDependencies:
'@swc/core': '*'
'@swc/helpers': '*'
@@ -5656,21 +6263,21 @@ packages:
webpack-dev-server:
optional: true
dependencies:
- '@pmmmwh/react-refresh-webpack-plugin': 0.5.11(@types/webpack@5.28.2)(react-refresh@0.14.0)(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ '@pmmmwh/react-refresh-webpack-plugin': 0.5.11(@types/webpack@5.28.3)(react-refresh@0.14.0)(webpack-dev-server@4.15.1)(webpack@5.89.0)
'@svgr/webpack': 8.1.0(typescript@5.2.2)
- '@swc/core': 1.3.86(@swc/helpers@0.5.2)
- '@swc/helpers': 0.5.2
- browserslist: 4.21.10
- css-loader: 6.8.1(webpack@5.88.2)
- html-webpack-plugin: 5.5.3(webpack@5.88.2)
- mini-css-extract-plugin: 2.7.6(webpack@5.88.2)
- postcss: 8.4.30
- postcss-loader: 7.3.3(postcss@8.4.30)(typescript@5.2.2)(webpack@5.88.2)
- style-loader: 3.3.3(webpack@5.88.2)
- swc-loader: 0.2.3(@swc/core@1.3.86)(webpack@5.88.2)
- terser-webpack-plugin: 5.3.9(@swc/core@1.3.86)(webpack@5.88.2)
- webpack: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
- webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2)
+ '@swc/core': 1.3.93(@swc/helpers@0.5.3)
+ '@swc/helpers': 0.5.3
+ browserslist: 4.22.1
+ css-loader: 6.8.1(webpack@5.89.0)
+ html-webpack-plugin: 5.5.3(webpack@5.89.0)
+ mini-css-extract-plugin: 2.7.6(webpack@5.89.0)
+ postcss: 8.4.31
+ postcss-loader: 7.3.3(postcss@8.4.31)(typescript@5.2.2)(webpack@5.89.0)
+ style-loader: 3.3.3(webpack@5.89.0)
+ swc-loader: 0.2.3(@swc/core@1.3.93)(webpack@5.89.0)
+ terser-webpack-plugin: 5.3.9(@swc/core@1.3.93)(webpack@5.89.0)
+ webpack: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
transitivePeerDependencies:
- '@types/webpack'
- esbuild
@@ -5684,8 +6291,8 @@ packages:
- webpack-plugin-serve
dev: true
- /@workleap/webpack-configs@1.0.8(@swc/core@1.3.86)(@swc/helpers@0.5.2)(browserslist@4.21.10)(esbuild@0.18.20)(postcss@8.4.30)(react-refresh@0.14.0)(typescript@5.2.2)(webpack@5.88.2):
- resolution: {integrity: sha512-AVTvHu5qeFVbfp9eA4KftUU8gJRRx7Rcx17jO4gGtFpLf4ADSGi4fE6eDNwGbGgHlhRrZTPYjCyHLNwPID+Pfg==}
+ /@workleap/webpack-configs@1.1.0(@swc/core@1.3.93)(@swc/helpers@0.5.3)(browserslist@4.22.1)(esbuild@0.18.20)(postcss@8.4.31)(react-refresh@0.14.0)(typescript@5.2.2)(webpack@5.89.0):
+ resolution: {integrity: sha512-bz5xU0LYdrTTOe+PVTgHrn+dBoLBURGxZx7xTckJ8q9H6DaRWAT9NbRTSzbG2N+Wer2pRISdvkeJ7MmubD11ng==}
peerDependencies:
'@swc/core': '*'
'@swc/helpers': '*'
@@ -5697,20 +6304,20 @@ packages:
webpack-dev-server:
optional: true
dependencies:
- '@pmmmwh/react-refresh-webpack-plugin': 0.5.11(react-refresh@0.14.0)(webpack@5.88.2)
+ '@pmmmwh/react-refresh-webpack-plugin': 0.5.11(react-refresh@0.14.0)(webpack@5.89.0)
'@svgr/webpack': 8.1.0(typescript@5.2.2)
- '@swc/core': 1.3.86(@swc/helpers@0.5.2)
- '@swc/helpers': 0.5.2
- browserslist: 4.21.10
- css-loader: 6.8.1(webpack@5.88.2)
- html-webpack-plugin: 5.5.3(webpack@5.88.2)
- mini-css-extract-plugin: 2.7.6(webpack@5.88.2)
- postcss: 8.4.30
- postcss-loader: 7.3.3(postcss@8.4.30)(typescript@5.2.2)(webpack@5.88.2)
- style-loader: 3.3.3(webpack@5.88.2)
- swc-loader: 0.2.3(@swc/core@1.3.86)(webpack@5.88.2)
- terser-webpack-plugin: 5.3.9(@swc/core@1.3.86)(esbuild@0.18.20)(webpack@5.88.2)
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ '@swc/core': 1.3.93(@swc/helpers@0.5.3)
+ '@swc/helpers': 0.5.3
+ browserslist: 4.22.1
+ css-loader: 6.8.1(webpack@5.89.0)
+ html-webpack-plugin: 5.5.3(webpack@5.89.0)
+ mini-css-extract-plugin: 2.7.6(webpack@5.89.0)
+ postcss: 8.4.31
+ postcss-loader: 7.3.3(postcss@8.4.31)(typescript@5.2.2)(webpack@5.89.0)
+ style-loader: 3.3.3(webpack@5.89.0)
+ swc-loader: 0.2.3(@swc/core@1.3.93)(webpack@5.89.0)
+ terser-webpack-plugin: 5.3.9(@swc/core@1.3.93)(esbuild@0.18.20)(webpack@5.89.0)
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
transitivePeerDependencies:
- '@types/webpack'
- esbuild
@@ -5798,12 +6405,21 @@ packages:
p-event: 5.0.1
dev: true
+ /@xmldom/xmldom@0.8.10:
+ resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==}
+ engines: {node: '>=10.0.0'}
+
/@xtuc/ieee754@1.2.0:
resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
/@xtuc/long@4.2.2:
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
+ /@zxing/text-encoding@0.9.0:
+ resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==}
+ requiresBuild: true
+ optional: true
+
/abab@2.0.6:
resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==}
dev: true
@@ -5972,7 +6588,6 @@ packages:
engines: {node: '>=8'}
dependencies:
type-fest: 0.21.3
- dev: true
/ansi-escapes@5.0.0:
resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==}
@@ -6034,7 +6649,6 @@ packages:
engines: {node: '>=8'}
dependencies:
color-convert: 2.0.1
- dev: true
/ansi-styles@5.2.0:
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
@@ -6308,7 +6922,6 @@ packages:
/asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
- dev: true
/atob@2.1.2:
resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==}
@@ -6324,7 +6937,6 @@ packages:
/available-typed-arrays@1.0.5:
resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
engines: {node: '>= 0.4'}
- dev: true
/avvio@8.2.1:
resolution: {integrity: sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==}
@@ -6336,20 +6948,19 @@ packages:
- supports-color
dev: true
- /axe-core@4.8.1:
- resolution: {integrity: sha512-9l850jDDPnKq48nbad8SiEelCv4OrUWrKab/cPj0GScVg6cb6NbCCt/Ulk26QEq5jP9NnGr04Bit1BHyV6r5CQ==}
+ /axe-core@4.8.2:
+ resolution: {integrity: sha512-/dlp0fxyM3R8YW7MFzaHWXrf4zzbr0vaYb23VBFCl83R7nWNPg/yaQw2Dc8jzCMmDVLhSdzH8MjrsuIUuvX+6g==}
engines: {node: '>=4'}
dev: true
- /axios@1.5.0(debug@4.3.4):
- resolution: {integrity: sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==}
+ /axios@1.5.1(debug@4.3.4):
+ resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==}
dependencies:
follow-redirects: 1.15.3(debug@4.3.4)
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
- dev: true
/axobject-query@3.2.1:
resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==}
@@ -6361,17 +6972,17 @@ packages:
resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==}
dev: true
- /babel-jest@29.7.0(@babel/core@7.22.20):
+ /babel-jest@29.7.0(@babel/core@7.23.2):
resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
'@babel/core': ^7.8.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@jest/transform': 29.7.0
- '@types/babel__core': 7.20.2
+ '@types/babel__core': 7.20.3
babel-plugin-istanbul: 6.1.1
- babel-preset-jest: 29.6.3(@babel/core@7.22.20)
+ babel-preset-jest: 29.6.3(@babel/core@7.23.2)
chalk: 4.1.2
graceful-fs: 4.2.11
slash: 3.0.0
@@ -6397,76 +7008,76 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/template': 7.22.15
- '@babel/types': 7.22.19
- '@types/babel__core': 7.20.2
- '@types/babel__traverse': 7.20.2
+ '@babel/types': 7.23.0
+ '@types/babel__core': 7.20.3
+ '@types/babel__traverse': 7.20.3
dev: true
- /babel-plugin-polyfill-corejs2@0.4.5(@babel/core@7.22.20):
- resolution: {integrity: sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==}
+ /babel-plugin-polyfill-corejs2@0.4.6(@babel/core@7.23.2):
+ resolution: {integrity: sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==}
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
dependencies:
- '@babel/compat-data': 7.22.20
- '@babel/core': 7.22.20
- '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.20)
+ '@babel/compat-data': 7.23.2
+ '@babel/core': 7.23.2
+ '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2)
semver: 6.3.1
transitivePeerDependencies:
- supports-color
dev: true
- /babel-plugin-polyfill-corejs3@0.8.3(@babel/core@7.22.20):
- resolution: {integrity: sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==}
+ /babel-plugin-polyfill-corejs3@0.8.5(@babel/core@7.23.2):
+ resolution: {integrity: sha512-Q6CdATeAvbScWPNLB8lzSO7fgUVBkQt6zLgNlfyeCr/EQaEQR+bWiBYYPYAFyE528BMjRhL+1QBMOI4jc/c5TA==}
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.20)
- core-js-compat: 3.32.2
+ '@babel/core': 7.23.2
+ '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2)
+ core-js-compat: 3.33.0
transitivePeerDependencies:
- supports-color
dev: true
- /babel-plugin-polyfill-regenerator@0.5.2(@babel/core@7.22.20):
- resolution: {integrity: sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==}
+ /babel-plugin-polyfill-regenerator@0.5.3(@babel/core@7.23.2):
+ resolution: {integrity: sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==}
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
dependencies:
- '@babel/core': 7.22.20
- '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.20)
+ '@babel/core': 7.23.2
+ '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2)
transitivePeerDependencies:
- supports-color
dev: true
- /babel-preset-current-node-syntax@1.0.1(@babel/core@7.22.20):
+ /babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.2):
resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
- '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.20)
- '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.20)
- '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.20)
- '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.20)
- '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.20)
- '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.20)
- '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.20)
- dev: true
-
- /babel-preset-jest@29.6.3(@babel/core@7.22.20):
+ '@babel/core': 7.23.2
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.2)
+ '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.2)
+ dev: true
+
+ /babel-preset-jest@29.6.3(@babel/core@7.23.2):
resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
babel-plugin-jest-hoist: 29.6.3
- babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.20)
+ babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2)
dev: true
/backoff@2.5.0:
@@ -6485,7 +7096,6 @@ packages:
/base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
- dev: true
/base@0.11.2:
resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==}
@@ -6561,6 +7171,13 @@ packages:
file-uri-to-path: 1.0.0
dev: true
+ /bl@4.1.0:
+ resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
+ dependencies:
+ buffer: 5.7.1
+ inherits: 2.0.4
+ readable-stream: 3.6.2
+
/bl@5.1.0:
resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==}
dependencies:
@@ -6666,15 +7283,15 @@ packages:
wcwidth: 1.0.1
dev: true
- /browserslist@4.21.10:
- resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==}
+ /browserslist@4.22.1:
+ resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
- caniuse-lite: 1.0.30001538
- electron-to-chromium: 1.4.525
+ caniuse-lite: 1.0.30001551
+ electron-to-chromium: 1.4.559
node-releases: 2.0.13
- update-browserslist-db: 1.0.11(browserslist@4.21.10)
+ update-browserslist-db: 1.0.13(browserslist@4.22.1)
/bs-logger@0.2.6:
resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==}
@@ -6705,7 +7322,6 @@ packages:
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
- dev: true
/buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
@@ -6742,8 +7358,8 @@ packages:
run-applescript: 5.0.0
dev: true
- /bundle-require@4.0.1(esbuild@0.18.20):
- resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==}
+ /bundle-require@4.0.2(esbuild@0.18.20):
+ resolution: {integrity: sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
peerDependencies:
esbuild: '>=0.17'
@@ -6790,14 +7406,14 @@ packages:
engines: {node: '>=14.16'}
dev: true
- /cacheable-request@10.2.13:
- resolution: {integrity: sha512-3SD4rrMu1msNGEtNSt8Od6enwdo//U9s4ykmXfA2TD58kcLkCobtCDiby7kNyj7a/Q7lz/mAesAFI54rTdnvBA==}
+ /cacheable-request@10.2.14:
+ resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==}
engines: {node: '>=14.16'}
dependencies:
- '@types/http-cache-semantics': 4.0.2
+ '@types/http-cache-semantics': 4.0.3
get-stream: 6.0.1
http-cache-semantics: 4.1.1
- keyv: 4.5.3
+ keyv: 4.5.4
mimic-response: 4.0.0
normalize-url: 8.0.0
responselike: 3.0.0
@@ -6811,7 +7427,7 @@ packages:
/call-bind@1.0.2:
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
dependencies:
- function-bind: 1.1.1
+ function-bind: 1.1.2
get-intrinsic: 1.2.1
/callsite@1.0.0:
@@ -6853,8 +7469,8 @@ packages:
engines: {node: '>=14.16'}
dev: true
- /caniuse-lite@1.0.30001538:
- resolution: {integrity: sha512-HWJnhnID+0YMtGlzcp3T9drmBJUVDchPJ08tpUGFLs9CYlwWPH2uLgpHn8fND5pCgXVtnGS3H4QR9XLMHVNkHw==}
+ /caniuse-lite@1.0.30001551:
+ resolution: {integrity: sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==}
/ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
@@ -6886,7 +7502,6 @@ packages:
dependencies:
ansi-styles: 4.3.0
supports-color: 7.2.0
- dev: true
/chalk@5.2.0:
resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==}
@@ -6928,7 +7543,6 @@ packages:
/chardet@0.7.0:
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
- dev: true
/chokidar@3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
@@ -6958,6 +7572,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /ci-info@3.9.0:
+ resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
+ engines: {node: '>=8'}
+ dev: true
+
/cjs-module-lexer@1.2.3:
resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==}
dev: true
@@ -7006,6 +7625,12 @@ packages:
restore-cursor: 2.0.0
dev: true
+ /cli-cursor@3.1.0:
+ resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
+ engines: {node: '>=8'}
+ dependencies:
+ restore-cursor: 3.1.0
+
/cli-cursor@4.0.0:
resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -7023,7 +7648,6 @@ packages:
/cli-spinners@2.9.1:
resolution: {integrity: sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==}
engines: {node: '>=6'}
- dev: true
/cli-truncate@0.2.1:
resolution: {integrity: sha512-f4r4yJnbT++qUPI9NR4XLDLq41gQ+uqnPItWG0F5ZkehuNiTTa3EY0S4AqTSUOeJ7/zU41oWPQSNkW5BqPL9bg==}
@@ -7037,6 +7661,10 @@ packages:
resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==}
dev: true
+ /cli-width@3.0.0:
+ resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==}
+ engines: {node: '>= 10'}
+
/cliui@6.0.0:
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
dependencies:
@@ -7060,7 +7688,6 @@ packages:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 7.0.0
- dev: true
/clone-deep@4.0.1:
resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==}
@@ -7073,7 +7700,6 @@ packages:
/clone@1.0.4:
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
engines: {node: '>=0.8'}
- dev: true
/co@4.6.0:
resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
@@ -7108,7 +7734,6 @@ packages:
engines: {node: '>=7.0.0'}
dependencies:
color-name: 1.1.4
- dev: true
/color-name@1.1.3:
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
@@ -7116,7 +7741,6 @@ packages:
/color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
- dev: true
/color-string@1.9.1:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
@@ -7175,7 +7799,6 @@ packages:
engines: {node: '>= 0.8'}
dependencies:
delayed-stream: 1.0.0
- dev: true
/commander@10.0.1:
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
@@ -7315,10 +7938,6 @@ packages:
resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
engines: {node: '>= 0.6'}
- /convert-source-map@1.9.0:
- resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
- dev: true
-
/convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
dev: true
@@ -7326,6 +7945,10 @@ packages:
/cookie-signature@1.0.6:
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
+ /cookie@0.4.2:
+ resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==}
+ engines: {node: '>= 0.6'}
+
/cookie@0.5.0:
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
engines: {node: '>= 0.6'}
@@ -7364,14 +7987,14 @@ packages:
yargs: 16.2.0
dev: true
- /core-js-compat@3.32.2:
- resolution: {integrity: sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ==}
+ /core-js-compat@3.33.0:
+ resolution: {integrity: sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==}
dependencies:
- browserslist: 4.21.10
+ browserslist: 4.22.1
dev: true
- /core-js-pure@3.32.2:
- resolution: {integrity: sha512-Y2rxThOuNywTjnX/PgA5vWM6CZ9QB9sz9oGeCixV8MqXZO70z/5SHzf9EeBrEBK0PN36DnEBBu9O/aGWzKuMZQ==}
+ /core-js-pure@3.33.0:
+ resolution: {integrity: sha512-FKSIDtJnds/YFIEaZ4HszRX7hkxGpNKM7FC9aJ9WLJbSd3lD4vOltFuVIBLR8asSx9frkTSqL0dw90SKQxgKrg==}
requiresBuild: true
dev: true
@@ -7446,7 +8069,7 @@ packages:
readable-stream: 3.6.2
dev: true
- /create-jest@29.7.0(@types/node@20.6.3)(ts-node@10.9.1):
+ /create-jest@29.7.0(@types/node@20.8.6)(ts-node@10.9.1):
resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -7455,7 +8078,7 @@ packages:
chalk: 4.1.2
exit: 0.1.2
graceful-fs: 4.2.11
- jest-config: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ jest-config: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
jest-util: 29.7.0
prompts: 2.4.2
transitivePeerDependencies:
@@ -7507,21 +8130,21 @@ packages:
type-fest: 1.4.0
dev: true
- /css-loader@6.8.1(webpack@5.88.2):
+ /css-loader@6.8.1(webpack@5.89.0):
resolution: {integrity: sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==}
engines: {node: '>= 12.13.0'}
peerDependencies:
webpack: ^5.0.0
dependencies:
- icss-utils: 5.1.0(postcss@8.4.30)
- postcss: 8.4.30
- postcss-modules-extract-imports: 3.0.0(postcss@8.4.30)
- postcss-modules-local-by-default: 4.0.3(postcss@8.4.30)
- postcss-modules-scope: 3.0.0(postcss@8.4.30)
- postcss-modules-values: 4.0.0(postcss@8.4.30)
+ icss-utils: 5.1.0(postcss@8.4.31)
+ postcss: 8.4.31
+ postcss-modules-extract-imports: 3.0.0(postcss@8.4.31)
+ postcss-modules-local-by-default: 4.0.3(postcss@8.4.31)
+ postcss-modules-scope: 3.0.0(postcss@8.4.31)
+ postcss-modules-values: 4.0.0(postcss@8.4.31)
postcss-value-parser: 4.2.0
semver: 7.5.4
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
dev: true
/css-select@4.3.0:
@@ -7802,15 +8425,14 @@ packages:
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
dependencies:
clone: 1.0.4
- dev: true
/defer-to-connect@2.0.1:
resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
engines: {node: '>=10'}
dev: true
- /define-data-property@1.1.0:
- resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==}
+ /define-data-property@1.1.1:
+ resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==}
engines: {node: '>= 0.4'}
dependencies:
get-intrinsic: 1.2.1
@@ -7831,7 +8453,7 @@ packages:
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
engines: {node: '>= 0.4'}
dependencies:
- define-data-property: 1.1.0
+ define-data-property: 1.1.1
has-property-descriptors: 1.0.0
object-keys: 1.1.1
dev: true
@@ -7861,7 +8483,6 @@ packages:
/delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
- dev: true
/delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
@@ -7937,8 +8558,8 @@ packages:
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
dependencies:
is-url: 1.2.4
- postcss: 8.4.30
- postcss-values-parser: 6.0.2(postcss@8.4.30)
+ postcss: 8.4.31
+ postcss-values-parser: 6.0.2(postcss@8.4.31)
dev: true
/detective-sass@5.0.3:
@@ -8129,8 +8750,8 @@ packages:
/ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
- /electron-to-chromium@1.4.525:
- resolution: {integrity: sha512-GIZ620hDK4YmIqAWkscG4W6RwY6gOx1y5J6f4JUQwctiJrqH2oxZYU4mXHi35oV32tr630UcepBzSBGJ/WYcZA==}
+ /electron-to-chromium@1.4.559:
+ resolution: {integrity: sha512-iS7KhLYCSJbdo3rUSkhDTVuFNCV34RKs2UaB9Ecr7VlqzjjWW//0nfsFF5dtDmyXlZQaDYYtID5fjtC/6lpRug==}
/elegant-spinner@1.0.1:
resolution: {integrity: sha512-B+ZM+RXvRqQaAmkMlO/oSe5nMUOaUnyfGYCEHoR8wrXsZR2mA0XVibsxV1bvTwxdRWah1PkQqso2EzhILGHtEQ==}
@@ -8144,7 +8765,6 @@ packages:
/emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
- dev: true
/emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
@@ -8242,7 +8862,7 @@ packages:
get-symbol-description: 1.0.0
globalthis: 1.0.3
gopd: 1.0.1
- has: 1.0.3
+ has: 1.0.4
has-property-descriptors: 1.0.0
has-proto: 1.0.1
has-symbols: 1.0.3
@@ -8255,7 +8875,7 @@ packages:
is-string: 1.0.7
is-typed-array: 1.1.12
is-weakref: 1.0.2
- object-inspect: 1.12.3
+ object-inspect: 1.13.0
object-keys: 1.1.1
object.assign: 4.1.4
regexp.prototype.flags: 1.5.1
@@ -8294,7 +8914,7 @@ packages:
define-properties: 1.2.1
es-abstract: 1.22.2
es-set-tostringtag: 2.0.1
- function-bind: 1.1.1
+ function-bind: 1.1.2
get-intrinsic: 1.2.1
globalthis: 1.0.3
has-property-descriptors: 1.0.0
@@ -8313,14 +8933,14 @@ packages:
engines: {node: '>= 0.4'}
dependencies:
get-intrinsic: 1.2.1
- has: 1.0.3
+ has: 1.0.4
has-tostringtag: 1.0.0
dev: true
/es-shim-unscopables@1.0.0:
resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==}
dependencies:
- has: 1.0.3
+ has: 1.0.4
dev: true
/es-to-primitive@1.2.1:
@@ -8365,34 +8985,34 @@ packages:
'@esbuild/win32-ia32': 0.18.20
'@esbuild/win32-x64': 0.18.20
- /esbuild@0.19.2:
- resolution: {integrity: sha512-G6hPax8UbFakEj3hWO0Vs52LQ8k3lnBhxZWomUJDxfz3rZTLqF5k/FCzuNdLx2RbpBiQQF9H9onlDDH1lZsnjg==}
+ /esbuild@0.19.4:
+ resolution: {integrity: sha512-x7jL0tbRRpv4QUyuDMjONtWFciygUxWaUM1kMX2zWxI0X2YWOt7MSA0g4UdeSiHM8fcYVzpQhKYOycZwxTdZkA==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
optionalDependencies:
- '@esbuild/android-arm': 0.19.2
- '@esbuild/android-arm64': 0.19.2
- '@esbuild/android-x64': 0.19.2
- '@esbuild/darwin-arm64': 0.19.2
- '@esbuild/darwin-x64': 0.19.2
- '@esbuild/freebsd-arm64': 0.19.2
- '@esbuild/freebsd-x64': 0.19.2
- '@esbuild/linux-arm': 0.19.2
- '@esbuild/linux-arm64': 0.19.2
- '@esbuild/linux-ia32': 0.19.2
- '@esbuild/linux-loong64': 0.19.2
- '@esbuild/linux-mips64el': 0.19.2
- '@esbuild/linux-ppc64': 0.19.2
- '@esbuild/linux-riscv64': 0.19.2
- '@esbuild/linux-s390x': 0.19.2
- '@esbuild/linux-x64': 0.19.2
- '@esbuild/netbsd-x64': 0.19.2
- '@esbuild/openbsd-x64': 0.19.2
- '@esbuild/sunos-x64': 0.19.2
- '@esbuild/win32-arm64': 0.19.2
- '@esbuild/win32-ia32': 0.19.2
- '@esbuild/win32-x64': 0.19.2
+ '@esbuild/android-arm': 0.19.4
+ '@esbuild/android-arm64': 0.19.4
+ '@esbuild/android-x64': 0.19.4
+ '@esbuild/darwin-arm64': 0.19.4
+ '@esbuild/darwin-x64': 0.19.4
+ '@esbuild/freebsd-arm64': 0.19.4
+ '@esbuild/freebsd-x64': 0.19.4
+ '@esbuild/linux-arm': 0.19.4
+ '@esbuild/linux-arm64': 0.19.4
+ '@esbuild/linux-ia32': 0.19.4
+ '@esbuild/linux-loong64': 0.19.4
+ '@esbuild/linux-mips64el': 0.19.4
+ '@esbuild/linux-ppc64': 0.19.4
+ '@esbuild/linux-riscv64': 0.19.4
+ '@esbuild/linux-s390x': 0.19.4
+ '@esbuild/linux-x64': 0.19.4
+ '@esbuild/netbsd-x64': 0.19.4
+ '@esbuild/openbsd-x64': 0.19.4
+ '@esbuild/sunos-x64': 0.19.4
+ '@esbuild/win32-arm64': 0.19.4
+ '@esbuild/win32-ia32': 0.19.4
+ '@esbuild/win32-x64': 0.19.4
dev: true
/escalade@3.1.1:
@@ -8410,7 +9030,6 @@ packages:
/escape-string-regexp@1.0.5:
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
engines: {node: '>=0.8.0'}
- dev: true
/escape-string-regexp@2.0.0:
resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
@@ -8444,12 +9063,12 @@ packages:
dependencies:
debug: 3.2.7(supports-color@5.5.0)
is-core-module: 2.13.0
- resolve: 1.22.6
+ resolve: 1.22.8
transitivePeerDependencies:
- supports-color
dev: true
- /eslint-mdx@2.2.0(eslint@8.49.0):
+ /eslint-mdx@2.2.0(eslint@8.51.0):
resolution: {integrity: sha512-AriN6lCW6KhWQ9GEiXapR1DokKHefOUqKvCmHxnE9puCWYhWiycU2SNKH8jmrasDBreZ+RtJDLi+RcUNLJatjg==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
peerDependencies:
@@ -8457,7 +9076,7 @@ packages:
dependencies:
acorn: 8.10.0
acorn-jsx: 5.3.2(acorn@8.10.0)
- eslint: 8.49.0
+ eslint: 8.51.0
espree: 9.6.1
estree-util-visit: 1.2.1
remark-mdx: 2.3.0
@@ -8474,7 +9093,7 @@ packages:
- supports-color
dev: true
- /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.7.2)(eslint-import-resolver-node@0.3.9)(eslint@8.49.0):
+ /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-node@0.3.9)(eslint@8.51.0):
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
engines: {node: '>=4'}
peerDependencies:
@@ -8495,15 +9114,15 @@ packages:
eslint-import-resolver-webpack:
optional: true
dependencies:
- '@typescript-eslint/parser': 6.7.2(eslint@8.49.0)(typescript@5.2.2)
+ '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
debug: 3.2.7(supports-color@5.5.0)
- eslint: 8.49.0
+ eslint: 8.51.0
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
dev: true
- /eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.7.2)(eslint@8.49.0):
+ /eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.8.0)(eslint@8.51.0):
resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==}
engines: {node: '>=4'}
peerDependencies:
@@ -8513,17 +9132,17 @@ packages:
'@typescript-eslint/parser':
optional: true
dependencies:
- '@typescript-eslint/parser': 6.7.2(eslint@8.49.0)(typescript@5.2.2)
+ '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
array-includes: 3.1.7
array.prototype.findlastindex: 1.2.3
array.prototype.flat: 1.3.2
array.prototype.flatmap: 1.3.2
debug: 3.2.7(supports-color@5.5.0)
doctrine: 2.1.0
- eslint: 8.49.0
+ eslint: 8.51.0
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.7.2)(eslint-import-resolver-node@0.3.9)(eslint@8.49.0)
- has: 1.0.3
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-node@0.3.9)(eslint@8.51.0)
+ has: 1.0.4
is-core-module: 2.13.0
is-glob: 4.0.3
minimatch: 3.1.2
@@ -8538,8 +9157,8 @@ packages:
- supports-color
dev: true
- /eslint-plugin-jest@27.4.0(@typescript-eslint/eslint-plugin@6.7.2)(eslint@8.49.0)(jest@29.7.0)(typescript@5.2.2):
- resolution: {integrity: sha512-ukVeKmMPAUA5SWjHenvyyXnirKfHKMdOsTZdn5tZx5EW05HGVQwBohigjFZGGj3zuv1cV6hc82FvWv6LdIbkgg==}
+ /eslint-plugin-jest@27.4.2(@typescript-eslint/eslint-plugin@6.8.0)(eslint@8.51.0)(jest@29.7.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-3Nfvv3wbq2+PZlRTf2oaAWXWwbdBejFRBR2O8tAO67o+P8zno+QGbcDYaAXODlreXVg+9gvWhKKmG2rgfb8GEg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
'@typescript-eslint/eslint-plugin': ^5.0.0 || ^6.0.0
@@ -8551,32 +9170,32 @@ packages:
jest:
optional: true
dependencies:
- '@typescript-eslint/eslint-plugin': 6.7.2(@typescript-eslint/parser@6.7.2)(eslint@8.49.0)(typescript@5.2.2)
- '@typescript-eslint/utils': 5.62.0(eslint@8.49.0)(typescript@5.2.2)
- eslint: 8.49.0
- jest: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ '@typescript-eslint/eslint-plugin': 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(typescript@5.2.2)
+ '@typescript-eslint/utils': 5.62.0(eslint@8.51.0)(typescript@5.2.2)
+ eslint: 8.51.0
+ jest: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
transitivePeerDependencies:
- supports-color
- typescript
dev: true
- /eslint-plugin-jsx-a11y@6.7.1(eslint@8.49.0):
+ /eslint-plugin-jsx-a11y@6.7.1(eslint@8.51.0):
resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==}
engines: {node: '>=4.0'}
peerDependencies:
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
aria-query: 5.3.0
array-includes: 3.1.7
array.prototype.flatmap: 1.3.2
ast-types-flow: 0.0.7
- axe-core: 4.8.1
+ axe-core: 4.8.2
axobject-query: 3.2.1
damerau-levenshtein: 1.0.8
emoji-regex: 9.2.2
- eslint: 8.49.0
- has: 1.0.3
+ eslint: 8.51.0
+ has: 1.0.4
jsx-ast-utils: 3.3.5
language-tags: 1.0.5
minimatch: 3.1.2
@@ -8585,27 +9204,27 @@ packages:
semver: 6.3.1
dev: true
- /eslint-plugin-markdown@3.0.1(eslint@8.49.0):
+ /eslint-plugin-markdown@3.0.1(eslint@8.51.0):
resolution: {integrity: sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
- eslint: 8.49.0
+ eslint: 8.51.0
mdast-util-from-markdown: 0.8.5
transitivePeerDependencies:
- supports-color
dev: true
- /eslint-plugin-mdx@2.2.0(eslint@8.49.0):
+ /eslint-plugin-mdx@2.2.0(eslint@8.51.0):
resolution: {integrity: sha512-OseoMXUIr8iy3E0me+wJLVAxuB0kxHP1plxuYAJDynzorzOj2OKv8Fhr+rIOJ32zfl3bnEWsqFnUiCnyznr1JQ==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
peerDependencies:
eslint: '>=8.0.0'
dependencies:
- eslint: 8.49.0
- eslint-mdx: 2.2.0(eslint@8.49.0)
- eslint-plugin-markdown: 3.0.1(eslint@8.49.0)
+ eslint: 8.51.0
+ eslint-mdx: 2.2.0(eslint@8.51.0)
+ eslint-plugin-markdown: 3.0.1(eslint@8.51.0)
remark-mdx: 2.3.0
remark-parse: 10.0.2
remark-stringify: 10.0.3
@@ -8616,16 +9235,16 @@ packages:
- supports-color
dev: true
- /eslint-plugin-react-hooks@4.6.0(eslint@8.49.0):
+ /eslint-plugin-react-hooks@4.6.0(eslint@8.51.0):
resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
engines: {node: '>=10'}
peerDependencies:
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
dependencies:
- eslint: 8.49.0
+ eslint: 8.51.0
dev: true
- /eslint-plugin-react@7.33.2(eslint@8.49.0):
+ /eslint-plugin-react@7.33.2(eslint@8.51.0):
resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==}
engines: {node: '>=4'}
peerDependencies:
@@ -8636,7 +9255,7 @@ packages:
array.prototype.tosorted: 1.1.2
doctrine: 2.1.0
es-iterator-helpers: 1.0.15
- eslint: 8.49.0
+ eslint: 8.51.0
estraverse: 5.3.0
jsx-ast-utils: 3.3.5
minimatch: 3.1.2
@@ -8645,20 +9264,20 @@ packages:
object.hasown: 1.1.3
object.values: 1.1.7
prop-types: 15.8.1
- resolve: 2.0.0-next.4
+ resolve: 2.0.0-next.5
semver: 6.3.1
string.prototype.matchall: 4.0.10
dev: true
- /eslint-plugin-storybook@0.6.13(eslint@8.49.0)(typescript@5.2.2):
- resolution: {integrity: sha512-smd+CS0WH1jBqUEJ3znGS7DU4ayBE9z6lkQAK2yrSUv1+rq8BT/tiI5C/rKE7rmiqiAfojtNYZRhzo5HrulccQ==}
+ /eslint-plugin-storybook@0.6.15(eslint@8.51.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-lAGqVAJGob47Griu29KXYowI4G7KwMoJDOkEip8ujikuDLxU+oWJ1l0WL6F2oDO4QiyUFXvtDkEkISMOPzo+7w==}
engines: {node: 12.x || 14.x || >= 16}
peerDependencies:
eslint: '>=6'
dependencies:
'@storybook/csf': 0.0.1
- '@typescript-eslint/utils': 5.62.0(eslint@8.49.0)(typescript@5.2.2)
- eslint: 8.49.0
+ '@typescript-eslint/utils': 5.62.0(eslint@8.51.0)(typescript@5.2.2)
+ eslint: 8.51.0
requireindex: 1.2.0
ts-dedent: 2.2.0
transitivePeerDependencies:
@@ -8666,14 +9285,14 @@ packages:
- typescript
dev: true
- /eslint-plugin-testing-library@6.0.1(eslint@8.49.0)(typescript@5.2.2):
- resolution: {integrity: sha512-CEYtjpcF3hAaQtYsTZqciR7s5z+T0LCMTwJeW+pz6kBnGtc866wAKmhaiK2Gsjc2jWNP7Gt6zhNr2DE1ZW4e+g==}
+ /eslint-plugin-testing-library@6.1.0(eslint@8.51.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-r7kE+az3tbp8vyRwfyAGZ6V/xw+XvdWFPicIo6jbOPZoossOFDeHizARqPGV6gEkyF8hyCFhhH3mlQOGS3N5Sg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'}
peerDependencies:
eslint: ^7.5.0 || ^8.0.0
dependencies:
- '@typescript-eslint/utils': 5.62.0(eslint@8.49.0)(typescript@5.2.2)
- eslint: 8.49.0
+ '@typescript-eslint/utils': 5.62.0(eslint@8.51.0)(typescript@5.2.2)
+ eslint: 8.51.0
transitivePeerDependencies:
- supports-color
- typescript
@@ -8699,16 +9318,16 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
- /eslint@8.49.0:
- resolution: {integrity: sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==}
+ /eslint@8.51.0:
+ resolution: {integrity: sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.49.0)
- '@eslint-community/regexpp': 4.8.1
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0)
+ '@eslint-community/regexpp': 4.9.1
'@eslint/eslintrc': 2.1.2
- '@eslint/js': 8.49.0
- '@humanwhocodes/config-array': 0.11.11
+ '@eslint/js': 8.51.0
+ '@humanwhocodes/config-array': 0.11.12
'@humanwhocodes/module-importer': 1.0.1
'@nodelib/fs.walk': 1.2.8
ajv: 6.12.6
@@ -8726,7 +9345,7 @@ packages:
file-entry-cache: 6.0.1
find-up: 5.0.0
glob-parent: 6.0.2
- globals: 13.21.0
+ globals: 13.23.0
graphemer: 1.4.0
ignore: 5.2.4
imurmurhash: 0.1.4
@@ -8788,8 +9407,8 @@ packages:
/estree-util-visit@1.2.1:
resolution: {integrity: sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==}
dependencies:
- '@types/estree-jsx': 1.0.0
- '@types/unist': 2.0.8
+ '@types/estree-jsx': 1.0.2
+ '@types/unist': 2.0.9
dev: true
/estree-walker@2.0.2:
@@ -8986,7 +9605,6 @@ packages:
chardet: 0.7.0
iconv-lite: 0.4.24
tmp: 0.0.33
- dev: true
/extglob@2.0.4:
resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==}
@@ -9013,13 +9631,13 @@ packages:
get-stream: 5.2.0
yauzl: 2.10.0
optionalDependencies:
- '@types/yauzl': 2.10.0
+ '@types/yauzl': 2.10.2
transitivePeerDependencies:
- supports-color
dev: true
- /fast-content-type-parse@1.0.0:
- resolution: {integrity: sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==}
+ /fast-content-type-parse@1.1.0:
+ resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==}
dev: true
/fast-decode-uri-component@1.0.1:
@@ -9101,21 +9719,21 @@ packages:
resolution: {integrity: sha512-tzuY1tgWJo2Y6qEKwmLhFvACUmr68Io2pqP/sDKU71KRM6A6R3DrCDqLGqANbeLZcKUfdfY58ut35CGqemcTgg==}
dependencies:
'@fastify/ajv-compiler': 3.5.0
- '@fastify/error': 3.3.0
+ '@fastify/error': 3.4.0
'@fastify/fast-json-stringify-compiler': 4.3.0
abstract-logging: 2.0.1
avvio: 8.2.1
- fast-content-type-parse: 1.0.0
+ fast-content-type-parse: 1.1.0
fast-json-stringify: 5.8.0
- find-my-way: 7.6.2
+ find-my-way: 7.7.0
light-my-request: 5.11.0
- pino: 8.15.1
+ pino: 8.16.0
process-warning: 2.2.0
proxy-addr: 2.0.7
rfdc: 1.3.0
secure-json-parse: 2.7.0
semver: 7.5.4
- tiny-lru: 11.0.1
+ tiny-lru: 11.2.3
transitivePeerDependencies:
- supports-color
dev: true
@@ -9202,7 +9820,6 @@ packages:
engines: {node: '>=8'}
dependencies:
escape-string-regexp: 1.0.5
- dev: true
/figures@4.0.1:
resolution: {integrity: sha512-rElJwkA/xS04Vfg+CaZodpso7VqBknOYbzi6I76hI4X80RUjkSxO2oAyPmGbuXUppywjqndOrQDl817hDnI++w==}
@@ -9224,7 +9841,7 @@ packages:
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
engines: {node: ^10.12.0 || >=12.0.0}
dependencies:
- flat-cache: 3.1.0
+ flat-cache: 3.1.1
dev: true
/file-type@18.5.0:
@@ -9294,8 +9911,8 @@ packages:
transitivePeerDependencies:
- supports-color
- /find-my-way@7.6.2:
- resolution: {integrity: sha512-0OjHn1b1nCX3eVbm9ByeEHiscPYiHLfhei1wOUU9qffQkk98wE0Lo8VrVYfSGMgnSnDh86DxedduAnBf4nwUEw==}
+ /find-my-way@7.7.0:
+ resolution: {integrity: sha512-+SrHpvQ52Q6W9f3wJoJBbAQULJuNEEQwBvlvYwACDhBTLOTMiQ0HYWh4+vC3OivGP2ENcTI1oKlFA2OepJNjhQ==}
engines: {node: '>=14'}
dependencies:
fast-deep-equal: 3.1.3
@@ -9333,15 +9950,19 @@ packages:
pkg-dir: 4.2.0
dev: true
- /flat-cache@3.1.0:
- resolution: {integrity: sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==}
+ /flat-cache@3.1.1:
+ resolution: {integrity: sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==}
engines: {node: '>=12.0.0'}
dependencies:
flatted: 3.2.9
- keyv: 4.5.3
+ keyv: 4.5.4
rimraf: 3.0.2
dev: true
+ /flat@5.0.2:
+ resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
+ hasBin: true
+
/flatted@3.2.9:
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
dev: true
@@ -9378,7 +9999,6 @@ packages:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
dependencies:
is-callable: 1.2.7
- dev: true
/for-in@1.0.2:
resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==}
@@ -9405,7 +10025,6 @@ packages:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
- dev: true
/format@0.2.2:
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
@@ -9472,8 +10091,8 @@ packages:
minipass: 3.3.6
dev: true
- /fs-monkey@1.0.4:
- resolution: {integrity: sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==}
+ /fs-monkey@1.0.5:
+ resolution: {integrity: sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==}
/fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
@@ -9485,8 +10104,8 @@ packages:
requiresBuild: true
optional: true
- /function-bind@1.1.1:
- resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+ /function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
/function.prototype.name@1.1.6:
resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
@@ -9538,16 +10157,20 @@ packages:
/get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
- dev: true
/get-intrinsic@1.2.1:
resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
dependencies:
- function-bind: 1.1.1
- has: 1.0.3
+ function-bind: 1.1.2
+ has: 1.0.4
has-proto: 1.0.1
has-symbols: 1.0.3
+ /get-package-name@2.2.0:
+ resolution: {integrity: sha512-LmCKVxioe63Fy6KDAQ/mmCSOSSRUE/x4zdrMD+7dU8quF3bGpzvP8mOmq4Dgce3nzU9AgkVDotucNOOg7c27BQ==}
+ engines: {node: '>= 12.0.0'}
+ dev: true
+
/get-package-type@0.1.0:
resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==}
engines: {node: '>=8.0.0'}
@@ -9582,12 +10205,6 @@ packages:
get-intrinsic: 1.2.1
dev: true
- /get-tsconfig@4.7.0:
- resolution: {integrity: sha512-pmjiZ7xtB8URYm74PlGJozDNyhvsVLUcpBa8DZBG3bWHwaHa9bPiRpiSfovw+fjhwONSCWKRyk+JQHEGZmMrzw==}
- dependencies:
- resolve-pkg-maps: 1.0.0
- dev: true
-
/get-value@2.0.6:
resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==}
engines: {node: '>=0.10.0'}
@@ -9629,15 +10246,15 @@ packages:
/glob-to-regexp@0.4.1:
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
- /glob@10.3.4:
- resolution: {integrity: sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==}
+ /glob@10.3.10:
+ resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==}
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
dependencies:
foreground-child: 3.1.1
- jackspeak: 2.3.3
+ jackspeak: 2.3.6
minimatch: 9.0.3
- minipass: 7.0.3
+ minipass: 7.0.4
path-scurry: 1.10.1
dev: true
@@ -9693,8 +10310,8 @@ packages:
engines: {node: '>=4'}
dev: true
- /globals@13.21.0:
- resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==}
+ /globals@13.23.0:
+ resolution: {integrity: sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==}
engines: {node: '>=8'}
dependencies:
type-fest: 0.20.2
@@ -9742,7 +10359,6 @@ packages:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
dependencies:
get-intrinsic: 1.2.1
- dev: true
/got@12.6.1:
resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==}
@@ -9751,7 +10367,7 @@ packages:
'@sindresorhus/is': 5.6.0
'@szmarczak/http-timer': 5.0.1
cacheable-lookup: 7.0.0
- cacheable-request: 10.2.13
+ cacheable-request: 10.2.14
decompress-response: 6.0.0
form-data-encoder: 2.1.4
get-stream: 6.0.1
@@ -9776,6 +10392,10 @@ packages:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
dev: true
+ /graphql@16.8.1:
+ resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==}
+ engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
+
/handle-thing@2.0.1:
resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==}
@@ -9828,7 +10448,6 @@ packages:
engines: {node: '>= 0.4'}
dependencies:
has-symbols: 1.0.3
- dev: true
/has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
@@ -9870,11 +10489,9 @@ packages:
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: true
- /has@1.0.3:
- resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+ /has@1.0.4:
+ resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==}
engines: {node: '>= 0.4.0'}
- dependencies:
- function-bind: 1.1.1
/hasbin@1.2.3:
resolution: {integrity: sha512-CCd8e/w2w28G8DyZvKgiHnQJ/5XXDz6qiUHnthvtag/6T5acUeN5lqq+HMoBqcmgWueWDhiCplrw0Kb1zDACRg==}
@@ -9895,6 +10512,9 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
+ /headers-polyfill@3.2.5:
+ resolution: {integrity: sha512-tUCGvt191vNSQgttSyJoibR+VO+I6+iCHIUdhzEMJKE+EAL8BwCN7fUOZlY4ofOelNHsK+gEjxB/B+9N3EWtdA==}
+
/hexer@1.5.0:
resolution: {integrity: sha512-dyrPC8KzBzUJ19QTIo1gXNqIISRXQ0NwteW6OeQHRN4ZuZeHkdODfj0zHBdOlHbRY8GqbqK57C9oWSvQZizFsg==}
engines: {node: '>= 0.10.x'}
@@ -9957,9 +10577,9 @@ packages:
he: 1.2.0
param-case: 3.0.4
relateurl: 0.2.7
- terser: 5.20.0
+ terser: 5.22.0
- /html-webpack-plugin@5.5.3(webpack@5.88.2):
+ /html-webpack-plugin@5.5.3(webpack@5.89.0):
resolution: {integrity: sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==}
engines: {node: '>=10.13.0'}
peerDependencies:
@@ -9970,7 +10590,7 @@ packages:
lodash: 4.17.21
pretty-error: 4.0.0
tapable: 2.2.1
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
/htmlparser2@6.1.0:
resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==}
@@ -10031,7 +10651,7 @@ packages:
- supports-color
dev: true
- /http-proxy-middleware@2.0.6(@types/express@4.17.17):
+ /http-proxy-middleware@2.0.6(@types/express@4.17.20):
resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==}
engines: {node: '>=12.0.0'}
peerDependencies:
@@ -10040,8 +10660,8 @@ packages:
'@types/express':
optional: true
dependencies:
- '@types/express': 4.17.17
- '@types/http-proxy': 1.17.12
+ '@types/express': 4.17.20
+ '@types/http-proxy': 1.17.13
http-proxy: 1.18.1(debug@4.3.4)
is-glob: 4.0.3
is-plain-obj: 3.0.0
@@ -10058,7 +10678,7 @@ packages:
'@types/express':
optional: true
dependencies:
- '@types/http-proxy': 1.17.12
+ '@types/http-proxy': 1.17.13
http-proxy: 1.18.1(debug@4.3.4)
is-glob: 4.0.3
is-plain-obj: 3.0.0
@@ -10149,18 +10769,17 @@ packages:
safer-buffer: 2.1.2
dev: true
- /icss-utils@5.1.0(postcss@8.4.30):
+ /icss-utils@5.1.0(postcss@8.4.31):
resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==}
engines: {node: ^10 || ^12 || >= 14}
peerDependencies:
postcss: ^8.1.0
dependencies:
- postcss: 8.4.30
+ postcss: 8.4.31
dev: true
/ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
- dev: true
/ignore-by-default@1.0.1:
resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
@@ -10275,6 +10894,26 @@ packages:
through: 2.3.8
dev: true
+ /inquirer@8.2.6:
+ resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==}
+ engines: {node: '>=12.0.0'}
+ dependencies:
+ ansi-escapes: 4.3.2
+ chalk: 4.1.2
+ cli-cursor: 3.1.0
+ cli-width: 3.0.0
+ external-editor: 3.1.0
+ figures: 3.2.0
+ lodash: 4.17.21
+ mute-stream: 0.0.8
+ ora: 5.4.1
+ run-async: 2.4.1
+ rxjs: 7.8.1
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ through: 2.3.8
+ wrap-ansi: 6.2.0
+
/inspect-with-kind@1.0.5:
resolution: {integrity: sha512-MAQUJuIo7Xqk8EVNP+6d3CKq9c80hi4tjIbIAT6lmGW9W6WzlHiu9PS8uSuUYU+Do+j1baiFp3H25XEVxDIG2g==}
dependencies:
@@ -10286,7 +10925,7 @@ packages:
engines: {node: '>= 0.4'}
dependencies:
get-intrinsic: 1.2.1
- has: 1.0.3
+ has: 1.0.4
side-channel: 1.0.4
dev: true
@@ -10344,7 +10983,6 @@ packages:
dependencies:
call-bind: 1.0.2
has-tostringtag: 1.0.0
- dev: true
/is-array-buffer@3.0.2:
resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
@@ -10408,19 +11046,18 @@ packages:
/is-callable@1.2.7:
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
engines: {node: '>= 0.4'}
- dev: true
/is-ci@3.0.1:
resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==}
hasBin: true
dependencies:
- ci-info: 3.8.0
+ ci-info: 3.9.0
dev: true
/is-core-module@2.13.0:
resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==}
dependencies:
- has: 1.0.3
+ has: 1.0.4
/is-data-descriptor@0.1.4:
resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==}
@@ -10521,7 +11158,6 @@ packages:
/is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
- dev: true
/is-fullwidth-code-point@4.0.0:
resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
@@ -10538,7 +11174,6 @@ packages:
engines: {node: '>= 0.4'}
dependencies:
has-tostringtag: 1.0.0
- dev: true
/is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
@@ -10570,6 +11205,10 @@ packages:
is-path-inside: 3.0.3
dev: true
+ /is-interactive@1.0.0:
+ resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
+ engines: {node: '>=8'}
+
/is-interactive@2.0.0:
resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==}
engines: {node: '>=12'}
@@ -10584,6 +11223,9 @@ packages:
engines: {node: '>= 0.4'}
dev: true
+ /is-node-process@1.2.0:
+ resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==}
+
/is-npm@6.0.0:
resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -10725,12 +11367,15 @@ packages:
engines: {node: '>= 0.4'}
dependencies:
which-typed-array: 1.1.11
- dev: true
/is-typedarray@1.0.0:
resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
dev: true
+ /is-unicode-supported@0.1.0:
+ resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
+ engines: {node: '>=10'}
+
/is-unicode-supported@1.3.0:
resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==}
engines: {node: '>=12'}
@@ -10816,8 +11461,8 @@ packages:
resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
engines: {node: '>=8'}
dependencies:
- '@babel/core': 7.22.20
- '@babel/parser': 7.22.16
+ '@babel/core': 7.23.2
+ '@babel/parser': 7.23.0
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.0
semver: 6.3.1
@@ -10825,12 +11470,12 @@ packages:
- supports-color
dev: true
- /istanbul-lib-instrument@6.0.0:
- resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==}
+ /istanbul-lib-instrument@6.0.1:
+ resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==}
engines: {node: '>=10'}
dependencies:
- '@babel/core': 7.22.20
- '@babel/parser': 7.22.16
+ '@babel/core': 7.23.2
+ '@babel/parser': 7.23.0
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.0
semver: 7.5.4
@@ -10876,8 +11521,8 @@ packages:
set-function-name: 2.0.1
dev: true
- /jackspeak@2.3.3:
- resolution: {integrity: sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg==}
+ /jackspeak@2.3.6:
+ resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
engines: {node: '>=14'}
dependencies:
'@isaacs/cliui': 8.0.2
@@ -10913,7 +11558,7 @@ packages:
'@jest/expect': 29.7.0
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
chalk: 4.1.2
co: 4.6.0
dedent: 1.5.1
@@ -10926,7 +11571,7 @@ packages:
jest-util: 29.7.0
p-limit: 3.1.0
pretty-format: 29.7.0
- pure-rand: 6.0.3
+ pure-rand: 6.0.4
slash: 3.0.0
stack-utils: 2.0.6
transitivePeerDependencies:
@@ -10934,7 +11579,7 @@ packages:
- supports-color
dev: true
- /jest-cli@29.7.0(@types/node@20.6.3)(ts-node@10.9.1):
+ /jest-cli@29.7.0(@types/node@20.8.6)(ts-node@10.9.1):
resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -10948,10 +11593,10 @@ packages:
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
chalk: 4.1.2
- create-jest: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ create-jest: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
exit: 0.1.2
import-local: 3.1.0
- jest-config: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ jest-config: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
jest-util: 29.7.0
jest-validate: 29.7.0
yargs: 17.7.2
@@ -10962,7 +11607,7 @@ packages:
- ts-node
dev: true
- /jest-config@29.7.0(@types/node@20.6.3)(ts-node@10.9.1):
+ /jest-config@29.7.0(@types/node@20.8.6)(ts-node@10.9.1):
resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
@@ -10974,13 +11619,13 @@ packages:
ts-node:
optional: true
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
'@jest/test-sequencer': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.6.3
- babel-jest: 29.7.0(@babel/core@7.22.20)
+ '@types/node': 20.8.6
+ babel-jest: 29.7.0(@babel/core@7.23.2)
chalk: 4.1.2
- ci-info: 3.8.0
+ ci-info: 3.9.0
deepmerge: 4.3.1
glob: 7.2.3
graceful-fs: 4.2.11
@@ -10997,7 +11642,7 @@ packages:
pretty-format: 29.7.0
slash: 3.0.0
strip-json-comments: 3.1.1
- ts-node: 10.9.1(@types/node@20.6.3)(typescript@5.2.2)
+ ts-node: 10.9.1(@types/node@20.8.6)(typescript@5.2.2)
transitivePeerDependencies:
- babel-plugin-macros
- supports-color
@@ -11044,7 +11689,7 @@ packages:
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
'@types/jsdom': 20.0.1
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
jest-mock: 29.7.0
jest-util: 29.7.0
jsdom: 20.0.3
@@ -11061,7 +11706,7 @@ packages:
'@jest/environment': 29.7.0
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
jest-mock: 29.7.0
jest-util: 29.7.0
dev: true
@@ -11081,8 +11726,8 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/graceful-fs': 4.1.6
- '@types/node': 20.6.3
+ '@types/graceful-fs': 4.1.8
+ '@types/node': 20.8.6
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.11
@@ -11119,7 +11764,7 @@ packages:
dependencies:
'@babel/code-frame': 7.22.13
'@jest/types': 29.6.3
- '@types/stack-utils': 2.0.1
+ '@types/stack-utils': 2.0.2
chalk: 4.1.2
graceful-fs: 4.2.11
micromatch: 4.0.5
@@ -11133,7 +11778,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
jest-util: 29.7.0
dev: true
@@ -11174,7 +11819,7 @@ packages:
jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0)
jest-util: 29.7.0
jest-validate: 29.7.0
- resolve: 1.22.6
+ resolve: 1.22.8
resolve.exports: 2.0.2
slash: 3.0.0
dev: true
@@ -11188,7 +11833,7 @@ packages:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
chalk: 4.1.2
emittery: 0.13.1
graceful-fs: 4.2.11
@@ -11219,7 +11864,7 @@ packages:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
chalk: 4.1.2
cjs-module-lexer: 1.2.3
collect-v8-coverage: 1.0.2
@@ -11242,15 +11887,15 @@ packages:
resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@babel/core': 7.22.20
- '@babel/generator': 7.22.15
- '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.20)
- '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.20)
- '@babel/types': 7.22.19
+ '@babel/core': 7.23.2
+ '@babel/generator': 7.23.0
+ '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2)
+ '@babel/types': 7.23.0
'@jest/expect-utils': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.20)
+ babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2)
chalk: 4.1.2
expect: 29.7.0
graceful-fs: 4.2.11
@@ -11271,9 +11916,9 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
chalk: 4.1.2
- ci-info: 3.8.0
+ ci-info: 3.9.0
graceful-fs: 4.2.11
picomatch: 2.3.1
dev: true
@@ -11308,7 +11953,7 @@ packages:
dependencies:
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
@@ -11320,7 +11965,7 @@ packages:
resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
engines: {node: '>= 10.13.0'}
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
merge-stream: 2.0.0
supports-color: 8.1.1
@@ -11328,13 +11973,13 @@ packages:
resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
jest-util: 29.7.0
merge-stream: 2.0.0
supports-color: 8.1.1
dev: true
- /jest@29.7.0(@types/node@20.6.3)(ts-node@10.9.1):
+ /jest@29.7.0(@types/node@20.8.6)(ts-node@10.9.1):
resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -11347,7 +11992,7 @@ packages:
'@jest/core': 29.7.0(ts-node@10.9.1)
'@jest/types': 29.6.3
import-local: 3.1.0
- jest-cli: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ jest-cli: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
@@ -11365,6 +12010,10 @@ packages:
engines: {node: '>=10'}
dev: true
+ /js-levenshtein@1.1.6:
+ resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
+ engines: {node: '>=0.10.0'}
+
/js-string-escape@1.0.1:
resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==}
engines: {node: '>= 0.8'}
@@ -11541,8 +12190,8 @@ packages:
mimic-fn: 4.0.0
dev: true
- /keyv@4.5.3:
- resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==}
+ /keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
dependencies:
json-buffer: 3.0.1
dev: true
@@ -11591,7 +12240,7 @@ packages:
dependencies:
commander: 10.0.1
dotenv: 16.3.1
- winston: 3.10.0
+ winston: 3.11.0
dev: true
/language-subtag-registry@0.3.22:
@@ -11611,8 +12260,8 @@ packages:
package-json: 8.1.1
dev: true
- /launch-editor@2.6.0:
- resolution: {integrity: sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==}
+ /launch-editor@2.6.1:
+ resolution: {integrity: sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==}
dependencies:
picocolors: 1.0.0
shell-quote: 1.8.1
@@ -11712,7 +12361,7 @@ packages:
/load-plugin@5.1.0:
resolution: {integrity: sha512-Lg1CZa1CFj2CbNaxijTL6PCbzd4qGTlZov+iH2p5Xwy/ApcZJh+i6jMN2cYePouTfjJfrNu3nXFdEw8LvbjPFQ==}
dependencies:
- '@npmcli/config': 6.3.0
+ '@npmcli/config': 6.4.0
import-meta-resolve: 2.2.2
dev: true
@@ -11827,6 +12476,13 @@ packages:
chalk: 1.1.3
dev: true
+ /log-symbols@4.1.0:
+ resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
+ engines: {node: '>=10'}
+ dependencies:
+ chalk: 4.1.2
+ is-unicode-supported: 0.1.0
+
/log-symbols@5.1.0:
resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==}
engines: {node: '>=12'}
@@ -11855,11 +12511,12 @@ packages:
wrap-ansi: 8.1.0
dev: true
- /logform@2.5.1:
- resolution: {integrity: sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==}
+ /logform@2.6.0:
+ resolution: {integrity: sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==}
+ engines: {node: '>= 12.0.0'}
dependencies:
- '@colors/colors': 1.5.0
- '@types/triple-beam': 1.3.3
+ '@colors/colors': 1.6.0
+ '@types/triple-beam': 1.3.4
fecha: 4.2.3
ms: 2.1.3
safe-stable-stringify: 2.4.3
@@ -12009,7 +12666,7 @@ packages:
/mdast-util-from-markdown@0.8.5:
resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==}
dependencies:
- '@types/mdast': 3.0.12
+ '@types/mdast': 3.0.14
mdast-util-to-string: 2.0.0
micromark: 2.11.4
parse-entities: 2.0.0
@@ -12021,8 +12678,8 @@ packages:
/mdast-util-from-markdown@1.3.1:
resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==}
dependencies:
- '@types/mdast': 3.0.12
- '@types/unist': 2.0.8
+ '@types/mdast': 3.0.14
+ '@types/unist': 2.0.9
decode-named-character-reference: 1.0.2
mdast-util-to-string: 3.2.0
micromark: 3.2.0
@@ -12040,9 +12697,9 @@ packages:
/mdast-util-mdx-expression@1.3.2:
resolution: {integrity: sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==}
dependencies:
- '@types/estree-jsx': 1.0.0
- '@types/hast': 2.3.6
- '@types/mdast': 3.0.12
+ '@types/estree-jsx': 1.0.2
+ '@types/hast': 2.3.7
+ '@types/mdast': 3.0.14
mdast-util-from-markdown: 1.3.1
mdast-util-to-markdown: 1.5.0
transitivePeerDependencies:
@@ -12052,10 +12709,10 @@ packages:
/mdast-util-mdx-jsx@2.1.4:
resolution: {integrity: sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==}
dependencies:
- '@types/estree-jsx': 1.0.0
- '@types/hast': 2.3.6
- '@types/mdast': 3.0.12
- '@types/unist': 2.0.8
+ '@types/estree-jsx': 1.0.2
+ '@types/hast': 2.3.7
+ '@types/mdast': 3.0.14
+ '@types/unist': 2.0.9
ccount: 2.0.1
mdast-util-from-markdown: 1.3.1
mdast-util-to-markdown: 1.5.0
@@ -12083,9 +12740,9 @@ packages:
/mdast-util-mdxjs-esm@1.3.1:
resolution: {integrity: sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==}
dependencies:
- '@types/estree-jsx': 1.0.0
- '@types/hast': 2.3.6
- '@types/mdast': 3.0.12
+ '@types/estree-jsx': 1.0.2
+ '@types/hast': 2.3.7
+ '@types/mdast': 3.0.14
mdast-util-from-markdown: 1.3.1
mdast-util-to-markdown: 1.5.0
transitivePeerDependencies:
@@ -12095,15 +12752,15 @@ packages:
/mdast-util-phrasing@3.0.1:
resolution: {integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==}
dependencies:
- '@types/mdast': 3.0.12
+ '@types/mdast': 3.0.14
unist-util-is: 5.2.1
dev: true
/mdast-util-to-markdown@1.5.0:
resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==}
dependencies:
- '@types/mdast': 3.0.12
- '@types/unist': 2.0.8
+ '@types/mdast': 3.0.14
+ '@types/unist': 2.0.9
longest-streak: 3.1.0
mdast-util-phrasing: 3.0.1
mdast-util-to-string: 3.2.0
@@ -12119,7 +12776,7 @@ packages:
/mdast-util-to-string@3.2.0:
resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==}
dependencies:
- '@types/mdast': 3.0.12
+ '@types/mdast': 3.0.14
dev: true
/mdn-data@2.0.28:
@@ -12138,7 +12795,7 @@ packages:
resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==}
engines: {node: '>= 4.0.0'}
dependencies:
- fs-monkey: 1.0.4
+ fs-monkey: 1.0.5
/memoize-one@6.0.0:
resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==}
@@ -12148,7 +12805,7 @@ packages:
resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==}
engines: {node: '>=8'}
dependencies:
- '@types/minimist': 1.2.2
+ '@types/minimist': 1.2.4
camelcase-keys: 6.2.2
decamelize-keys: 1.1.1
hard-rejection: 2.1.0
@@ -12215,7 +12872,7 @@ packages:
/micromark-extension-mdx-expression@1.0.8:
resolution: {integrity: sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==}
dependencies:
- '@types/estree': 1.0.1
+ '@types/estree': 1.0.3
micromark-factory-mdx-expression: 1.0.9
micromark-factory-space: 1.1.0
micromark-util-character: 1.2.0
@@ -12229,7 +12886,7 @@ packages:
resolution: {integrity: sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==}
dependencies:
'@types/acorn': 4.0.6
- '@types/estree': 1.0.1
+ '@types/estree': 1.0.3
estree-util-is-identifier-name: 2.1.0
micromark-factory-mdx-expression: 1.0.9
micromark-factory-space: 1.1.0
@@ -12249,7 +12906,7 @@ packages:
/micromark-extension-mdxjs-esm@1.0.5:
resolution: {integrity: sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==}
dependencies:
- '@types/estree': 1.0.1
+ '@types/estree': 1.0.3
micromark-core-commonmark: 1.1.0
micromark-util-character: 1.2.0
micromark-util-events-to-acorn: 1.2.3
@@ -12293,7 +12950,7 @@ packages:
/micromark-factory-mdx-expression@1.0.9:
resolution: {integrity: sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==}
dependencies:
- '@types/estree': 1.0.1
+ '@types/estree': 1.0.3
micromark-util-character: 1.2.0
micromark-util-events-to-acorn: 1.2.3
micromark-util-symbol: 1.1.0
@@ -12379,8 +13036,8 @@ packages:
resolution: {integrity: sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==}
dependencies:
'@types/acorn': 4.0.6
- '@types/estree': 1.0.1
- '@types/unist': 2.0.8
+ '@types/estree': 1.0.3
+ '@types/unist': 2.0.9
estree-util-visit: 1.2.1
micromark-util-symbol: 1.1.0
micromark-util-types: 1.1.0
@@ -12441,7 +13098,7 @@ packages:
/micromark@3.2.0:
resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==}
dependencies:
- '@types/debug': 4.1.8
+ '@types/debug': 4.1.10
debug: 4.3.4(supports-color@9.4.0)
decode-named-character-reference: 1.0.2
micromark-core-commonmark: 1.1.0
@@ -12540,14 +13197,14 @@ packages:
engines: {node: '>=4'}
dev: true
- /mini-css-extract-plugin@2.7.6(webpack@5.88.2):
+ /mini-css-extract-plugin@2.7.6(webpack@5.89.0):
resolution: {integrity: sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==}
engines: {node: '>= 12.13.0'}
peerDependencies:
webpack: ^5.0.0
dependencies:
schema-utils: 4.2.0
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
dev: true
/minimalistic-assert@1.0.1:
@@ -12597,8 +13254,8 @@ packages:
engines: {node: '>=8'}
dev: true
- /minipass@7.0.3:
- resolution: {integrity: sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==}
+ /minipass@7.0.4:
+ resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
engines: {node: '>=16 || 14 >=14.17'}
dev: true
@@ -12677,6 +13334,41 @@ packages:
/ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ /msw@1.3.2(typescript@5.2.2):
+ resolution: {integrity: sha512-wKLhFPR+NitYTkQl5047pia0reNGgf0P6a1eTnA5aNlripmiz0sabMvvHcicE8kQ3/gZcI0YiPFWmYfowfm3lA==}
+ engines: {node: '>=14'}
+ hasBin: true
+ requiresBuild: true
+ peerDependencies:
+ typescript: '>= 4.4.x <= 5.2.x'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@mswjs/cookies': 0.2.2
+ '@mswjs/interceptors': 0.17.10
+ '@open-draft/until': 1.0.3
+ '@types/cookie': 0.4.1
+ '@types/js-levenshtein': 1.1.2
+ chalk: 4.1.2
+ chokidar: 3.5.3
+ cookie: 0.4.2
+ graphql: 16.8.1
+ headers-polyfill: 3.2.5
+ inquirer: 8.2.6
+ is-node-process: 1.2.0
+ js-levenshtein: 1.1.6
+ node-fetch: 2.7.0
+ outvariant: 1.4.0
+ path-to-regexp: 6.2.1
+ strict-event-emitter: 0.4.6
+ type-fest: 2.19.0
+ typescript: 5.2.2
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - encoding
+ - supports-color
+
/multicast-dns@7.2.5:
resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==}
hasBin: true
@@ -12697,6 +13389,9 @@ packages:
resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==}
dev: true
+ /mute-stream@0.0.8:
+ resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
+
/mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
dependencies:
@@ -12751,21 +13446,21 @@ packages:
resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==}
dev: true
- /netlify-cli@16.4.1(@types/node@20.6.3):
- resolution: {integrity: sha512-HRigS1GNctNr7tV6VxedYWpaskP25+Xb4dEiMzCD9kuR1lQoo1wyjUJL9Pp7xtaQDiC1ddcBl5oOU5Hj+H2HOg==}
+ /netlify-cli@16.8.0(@types/node@20.8.6):
+ resolution: {integrity: sha512-Eg/jrszkJE1EAcU8yOGpENxcIiYdB25wI5UeCb4EZrI079n9nrgW8ttGPaR1cY8zhWUcExweJ3iv4i1iQfGBQA==}
engines: {node: '>=16.16.0'}
hasBin: true
requiresBuild: true
dependencies:
'@bugsnag/js': 7.20.2
'@fastify/static': 6.10.2
- '@netlify/build': 29.21.1(@types/node@20.6.3)(debug@4.3.4)
- '@netlify/build-info': 7.8.0
+ '@netlify/build': 29.23.1(@types/node@20.8.6)(debug@4.3.4)
+ '@netlify/build-info': 7.10.1
'@netlify/config': 20.9.0
- '@netlify/edge-bundler': 8.19.1
+ '@netlify/edge-bundler': 9.3.0(supports-color@9.4.0)
'@netlify/local-functions-proxy': 1.1.1
- '@netlify/serverless-functions-api': 1.7.3
- '@netlify/zip-it-and-ship-it': 9.18.1(supports-color@9.4.0)
+ '@netlify/serverless-functions-api': 1.9.1
+ '@netlify/zip-it-and-ship-it': 9.25.1(supports-color@9.4.0)
'@octokit/rest': 19.0.13
ansi-escapes: 6.2.0
ansi-styles: 6.2.1
@@ -12907,7 +13602,7 @@ packages:
resolution: {integrity: sha512-ByFz8S08HWVKd9r/lkTahZX7xSq4IRyPCUvuaduI4GHyQaSWEdVNK1krC05vlhL9W0SzDn8Yjowh0Ru4PKrOYw==}
engines: {node: ^14.16.0 || >=16.0.0}
dependencies:
- '@netlify/open-api': 2.21.1
+ '@netlify/open-api': 2.23.2
lodash-es: 4.17.21
micro-api-client: 3.3.0
node-fetch: 3.3.2
@@ -12949,7 +13644,6 @@ packages:
optional: true
dependencies:
whatwg-url: 5.0.0
- dev: true
/node-fetch@3.3.2:
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
@@ -12980,7 +13674,7 @@ packages:
resolution: {integrity: sha512-jn9vOIK/nfqoFCcpK89/VCVaLg1IHE6UVfDOzvqmANaJ/rWCTEdH8RZ1V278nv2jr36BJdyQXIAavBLXpzdlag==}
engines: {node: '>=14'}
dependencies:
- '@babel/parser': 7.22.16
+ '@babel/parser': 7.23.0
dev: true
/node-stream-zip@1.15.0:
@@ -13064,7 +13758,7 @@ packages:
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
dependencies:
hosted-git-info: 2.8.9
- resolve: 1.22.6
+ resolve: 1.22.8
semver: 5.7.2
validate-npm-package-license: 3.0.4
dev: true
@@ -13150,8 +13844,8 @@ packages:
kind-of: 3.2.2
dev: true
- /object-inspect@1.12.3:
- resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
+ /object-inspect@1.13.0:
+ resolution: {integrity: sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g==}
/object-is@1.1.5:
resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==}
@@ -13240,8 +13934,9 @@ packages:
resolution: {integrity: sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg==}
dev: true
- /on-exit-leak-free@2.1.0:
- resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==}
+ /on-exit-leak-free@2.1.2:
+ resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
+ engines: {node: '>=14.0.0'}
dev: true
/on-finished@2.4.1:
@@ -13325,6 +14020,20 @@ packages:
type-check: 0.4.0
dev: true
+ /ora@5.4.1:
+ resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ bl: 4.1.0
+ chalk: 4.1.2
+ cli-cursor: 3.1.0
+ cli-spinners: 2.9.1
+ is-interactive: 1.0.0
+ is-unicode-supported: 0.1.0
+ log-symbols: 4.1.0
+ strip-ansi: 6.0.1
+ wcwidth: 1.0.1
+
/ora@6.3.1:
resolution: {integrity: sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -13351,12 +14060,14 @@ packages:
/os-tmpdir@1.0.2:
resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
engines: {node: '>=0.10.0'}
- dev: true
/outdent@0.5.0:
resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==}
dev: true
+ /outvariant@1.4.0:
+ resolution: {integrity: sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==}
+
/p-cancelable@3.0.0:
resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==}
engines: {node: '>=12.20'}
@@ -13554,7 +14265,7 @@ packages:
/parse-entities@4.0.1:
resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
character-entities: 2.0.2
character-entities-legacy: 3.0.0
character-reference-invalid: 2.0.1
@@ -13651,12 +14362,15 @@ packages:
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
lru-cache: 10.0.1
- minipass: 7.0.3
+ minipass: 7.0.4
dev: true
/path-to-regexp@0.1.7:
resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
+ /path-to-regexp@6.2.1:
+ resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==}
+
/path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
@@ -13699,21 +14413,21 @@ packages:
resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==}
dev: true
- /pino@8.15.1:
- resolution: {integrity: sha512-Cp4QzUQrvWCRJaQ8Lzv0mJzXVk4z2jlq8JNKMGaixC2Pz5L4l2p95TkuRvYbrEbe85NQsDKrAd4zalf7Ml6WiA==}
+ /pino@8.16.0:
+ resolution: {integrity: sha512-UUmvQ/7KTZt/vHjhRrnyS7h+J7qPBQnpG80V56xmIC+o9IqYmQOw/UIny9S9zYDfRBR0ClouCr464EkBMIT7Fw==}
hasBin: true
dependencies:
atomic-sleep: 1.0.0
fast-redact: 3.3.0
- on-exit-leak-free: 2.1.0
+ on-exit-leak-free: 2.1.2
pino-abstract-transport: 1.1.0
pino-std-serializers: 6.2.2
process-warning: 2.2.0
quick-format-unescaped: 4.0.4
real-require: 0.2.0
safe-stable-stringify: 2.4.3
- sonic-boom: 3.3.0
- thread-stream: 2.4.0
+ sonic-boom: 3.7.0
+ thread-stream: 2.4.1
dev: true
/pirates@4.0.6:
@@ -13750,7 +14464,7 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
- /postcss-load-config@4.0.1(postcss@8.4.30)(ts-node@10.9.1):
+ /postcss-load-config@4.0.1(postcss@8.4.31)(ts-node@10.9.1):
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
engines: {node: '>= 14'}
peerDependencies:
@@ -13763,12 +14477,12 @@ packages:
optional: true
dependencies:
lilconfig: 2.1.0
- postcss: 8.4.30
- ts-node: 10.9.1(@types/node@20.6.3)(typescript@5.2.2)
- yaml: 2.3.2
+ postcss: 8.4.31
+ ts-node: 10.9.1(@types/node@20.8.6)(typescript@5.2.2)
+ yaml: 2.3.3
dev: true
- /postcss-loader@7.3.3(postcss@8.4.30)(typescript@5.2.2)(webpack@5.88.2):
+ /postcss-loader@7.3.3(postcss@8.4.31)(typescript@5.2.2)(webpack@5.89.0):
resolution: {integrity: sha512-YgO/yhtevGO/vJePCQmTxiaEwER94LABZN0ZMT4A0vsak9TpO+RvKRs7EmJ8peIlB9xfXCsS7M8LjqncsUZ5HA==}
engines: {node: '>= 14.15.0'}
peerDependencies:
@@ -13777,52 +14491,52 @@ packages:
dependencies:
cosmiconfig: 8.3.6(typescript@5.2.2)
jiti: 1.20.0
- postcss: 8.4.30
+ postcss: 8.4.31
semver: 7.5.4
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
transitivePeerDependencies:
- typescript
dev: true
- /postcss-modules-extract-imports@3.0.0(postcss@8.4.30):
+ /postcss-modules-extract-imports@3.0.0(postcss@8.4.31):
resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==}
engines: {node: ^10 || ^12 || >= 14}
peerDependencies:
postcss: ^8.1.0
dependencies:
- postcss: 8.4.30
+ postcss: 8.4.31
dev: true
- /postcss-modules-local-by-default@4.0.3(postcss@8.4.30):
+ /postcss-modules-local-by-default@4.0.3(postcss@8.4.31):
resolution: {integrity: sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==}
engines: {node: ^10 || ^12 || >= 14}
peerDependencies:
postcss: ^8.1.0
dependencies:
- icss-utils: 5.1.0(postcss@8.4.30)
- postcss: 8.4.30
+ icss-utils: 5.1.0(postcss@8.4.31)
+ postcss: 8.4.31
postcss-selector-parser: 6.0.13
postcss-value-parser: 4.2.0
dev: true
- /postcss-modules-scope@3.0.0(postcss@8.4.30):
+ /postcss-modules-scope@3.0.0(postcss@8.4.31):
resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==}
engines: {node: ^10 || ^12 || >= 14}
peerDependencies:
postcss: ^8.1.0
dependencies:
- postcss: 8.4.30
+ postcss: 8.4.31
postcss-selector-parser: 6.0.13
dev: true
- /postcss-modules-values@4.0.0(postcss@8.4.30):
+ /postcss-modules-values@4.0.0(postcss@8.4.31):
resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==}
engines: {node: ^10 || ^12 || >= 14}
peerDependencies:
postcss: ^8.1.0
dependencies:
- icss-utils: 5.1.0(postcss@8.4.30)
- postcss: 8.4.30
+ icss-utils: 5.1.0(postcss@8.4.31)
+ postcss: 8.4.31
dev: true
/postcss-selector-parser@6.0.13:
@@ -13837,7 +14551,7 @@ packages:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
dev: true
- /postcss-values-parser@6.0.2(postcss@8.4.30):
+ /postcss-values-parser@6.0.2(postcss@8.4.31):
resolution: {integrity: sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==}
engines: {node: '>=10'}
peerDependencies:
@@ -13845,12 +14559,12 @@ packages:
dependencies:
color-name: 1.1.4
is-url-superb: 4.0.0
- postcss: 8.4.30
+ postcss: 8.4.31
quote-unquote: 1.0.0
dev: true
- /postcss@8.4.30:
- resolution: {integrity: sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==}
+ /postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
nanoid: 3.3.6
@@ -14001,7 +14715,7 @@ packages:
'@protobufjs/path': 1.1.2
'@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.0
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
long: 5.2.3
dev: true
@@ -14014,7 +14728,6 @@ packages:
/proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
- dev: true
/ps-list@8.1.1:
resolution: {integrity: sha512-OPS9kEJYVmiO48u/B9qneqhkMvgCxT+Tm28VCEJpheTpl8cJ0ffZRRNgS5mrQRTrX5yRTpaJ+hRDeefXYmmorQ==}
@@ -14058,8 +14771,8 @@ packages:
escape-goat: 4.0.0
dev: true
- /pure-rand@6.0.3:
- resolution: {integrity: sha512-KddyFewCsO0j3+np81IQ+SweXLDnDQTs5s67BOnrYmYe/yNmUhttQyGsYzy8yUnoljGAQ9sl38YB4vH8ur7Y+w==}
+ /pure-rand@6.0.4:
+ resolution: {integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==}
dev: true
/qs@6.11.0:
@@ -14157,6 +14870,14 @@ packages:
react: 18.2.0
scheduler: 0.23.0
+ /react-error-boundary@4.0.11(react@18.2.0):
+ resolution: {integrity: sha512-U13ul67aP5DOSPNSCWQ/eO0AQEYzEFkVljULQIjMV0KlffTAhxuDoBKdO0pb/JZ8mDhMKFZ9NZi0BmLGUiNphw==}
+ peerDependencies:
+ react: '>=16.13.1'
+ dependencies:
+ '@babel/runtime': 7.23.2
+ react: 18.2.0
+
/react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
dev: true
@@ -14174,25 +14895,25 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
- /react-router-dom@6.16.0(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg==}
+ /react-router-dom@6.17.0(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-qWHkkbXQX+6li0COUUPKAUkxjNNqPJuiBd27dVwQGDNsuFBdMbrS6UZ0CLYc4CsbdLYTckn4oB4tGDuPZpPhaQ==}
engines: {node: '>=14.0.0'}
peerDependencies:
react: '>=16.8'
react-dom: '>=16.8'
dependencies:
- '@remix-run/router': 1.9.0
+ '@remix-run/router': 1.10.0
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
- react-router: 6.16.0(react@18.2.0)
+ react-router: 6.17.0(react@18.2.0)
- /react-router@6.16.0(react@18.2.0):
- resolution: {integrity: sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA==}
+ /react-router@6.17.0(react@18.2.0):
+ resolution: {integrity: sha512-YJR3OTJzi3zhqeJYADHANCGPUu9J+6fT5GLv82UWRGSxu6oJYCKVmxUcaBQuGm9udpWmPsvpme/CdHumqgsoaA==}
engines: {node: '>=14.0.0'}
peerDependencies:
react: '>=16.8'
dependencies:
- '@remix-run/router': 1.9.0
+ '@remix-run/router': 1.10.0
react: 18.2.0
/react-shallow-renderer@16.15.0(react@18.2.0):
@@ -14252,7 +14973,7 @@ packages:
resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==}
engines: {node: '>=8'}
dependencies:
- '@types/normalize-package-data': 2.4.1
+ '@types/normalize-package-data': 2.4.3
normalize-package-data: 2.5.0
parse-json: 5.2.0
type-fest: 0.6.0
@@ -14262,7 +14983,7 @@ packages:
resolution: {integrity: sha512-5iOehe+WF75IccPc30bWTbpdDQLOCc3Uu8bi3Dte3Eueij81yx1Mrufk8qBx/YAbR4uL1FdUr+7BKXDwEtisXg==}
engines: {node: '>=12.20'}
dependencies:
- '@types/normalize-package-data': 2.4.1
+ '@types/normalize-package-data': 2.4.3
normalize-package-data: 3.0.3
parse-json: 5.2.0
type-fest: 2.19.0
@@ -14356,7 +15077,7 @@ packages:
resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==}
engines: {node: '>= 10.13.0'}
dependencies:
- resolve: 1.22.6
+ resolve: 1.22.8
/redent@3.0.0:
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
@@ -14391,12 +15112,11 @@ packages:
/regenerator-runtime@0.14.0:
resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
- dev: true
/regenerator-transform@0.15.2:
resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==}
dependencies:
- '@babel/runtime': 7.22.15
+ '@babel/runtime': 7.23.2
dev: true
/regex-not@1.0.2:
@@ -14470,7 +15190,7 @@ packages:
/remark-parse@10.0.2:
resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==}
dependencies:
- '@types/mdast': 3.0.12
+ '@types/mdast': 3.0.14
mdast-util-from-markdown: 1.3.1
unified: 10.1.2
transitivePeerDependencies:
@@ -14480,7 +15200,7 @@ packages:
/remark-stringify@10.0.3:
resolution: {integrity: sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==}
dependencies:
- '@types/mdast': 3.0.12
+ '@types/mdast': 3.0.14
mdast-util-to-markdown: 1.5.0
unified: 10.1.2
dev: true
@@ -14511,7 +15231,6 @@ packages:
/require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
- dev: true
/require-from-string@2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
@@ -14523,7 +15242,7 @@ packages:
dependencies:
debug: 4.3.4(supports-color@9.4.0)
module-details-from-path: 1.0.3
- resolve: 1.22.6
+ resolve: 1.22.8
transitivePeerDependencies:
- supports-color
dev: true
@@ -14563,10 +15282,6 @@ packages:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
- /resolve-pkg-maps@1.0.0:
- resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
- dev: true
-
/resolve-url@0.2.1:
resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==}
deprecated: https://github.com/lydell/resolve-url#deprecated
@@ -14577,16 +15292,16 @@ packages:
engines: {node: '>=10'}
dev: true
- /resolve@1.22.6:
- resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==}
+ /resolve@1.22.8:
+ resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
hasBin: true
dependencies:
is-core-module: 2.13.0
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
- /resolve@2.0.0-next.4:
- resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==}
+ /resolve@2.0.0-next.5:
+ resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==}
hasBin: true
dependencies:
is-core-module: 2.13.0
@@ -14609,6 +15324,13 @@ packages:
signal-exit: 3.0.7
dev: true
+ /restore-cursor@3.1.0:
+ resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
+ engines: {node: '>=8'}
+ dependencies:
+ onetime: 5.1.2
+ signal-exit: 3.0.7
+
/restore-cursor@4.0.0:
resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -14651,8 +15373,8 @@ packages:
dependencies:
glob: 7.2.3
- /rollup@3.29.2:
- resolution: {integrity: sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==}
+ /rollup@3.29.4:
+ resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
@@ -14669,7 +15391,6 @@ packages:
/run-async@2.4.1:
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
engines: {node: '>=0.12.0'}
- dev: true
/run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
@@ -14684,6 +15405,11 @@ packages:
tslib: 1.14.1
dev: true
+ /rxjs@7.8.1:
+ resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
+ dependencies:
+ tslib: 2.6.2
+
/sade@1.8.1:
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
engines: {node: '>=6'}
@@ -14755,7 +15481,7 @@ packages:
resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==}
engines: {node: '>= 10.13.0'}
dependencies:
- '@types/json-schema': 7.0.13
+ '@types/json-schema': 7.0.14
ajv: 6.12.6
ajv-keywords: 3.5.2(ajv@6.12.6)
@@ -14763,7 +15489,7 @@ packages:
resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==}
engines: {node: '>= 12.13.0'}
dependencies:
- '@types/json-schema': 7.0.13
+ '@types/json-schema': 7.0.14
ajv: 8.12.0
ajv-formats: 2.1.1(ajv@8.12.0)
ajv-keywords: 5.1.0(ajv@8.12.0)
@@ -14873,13 +15599,12 @@ packages:
/set-cookie-parser@2.6.0:
resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==}
- dev: true
/set-function-name@2.0.1:
resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==}
engines: {node: '>= 0.4'}
dependencies:
- define-data-property: 1.1.0
+ define-data-property: 1.1.1
functions-have-names: 1.2.3
has-property-descriptors: 1.0.0
dev: true
@@ -14940,7 +15665,7 @@ packages:
dependencies:
call-bind: 1.0.2
get-intrinsic: 1.2.1
- object-inspect: 1.12.3
+ object-inspect: 1.13.0
/signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
@@ -15049,8 +15774,8 @@ packages:
uuid: 8.3.2
websocket-driver: 0.7.4
- /sonic-boom@3.3.0:
- resolution: {integrity: sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==}
+ /sonic-boom@3.7.0:
+ resolution: {integrity: sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==}
dependencies:
atomic-sleep: 1.0.0
dev: true
@@ -15135,7 +15860,7 @@ packages:
resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
dependencies:
spdx-expression-parse: 3.0.1
- spdx-license-ids: 3.0.15
+ spdx-license-ids: 3.0.16
dev: true
/spdx-exceptions@2.3.0:
@@ -15146,11 +15871,11 @@ packages:
resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
dependencies:
spdx-exceptions: 2.3.0
- spdx-license-ids: 3.0.15
+ spdx-license-ids: 3.0.16
dev: true
- /spdx-license-ids@3.0.15:
- resolution: {integrity: sha512-lpT8hSQp9jAKp9mhtBU4Xjon8LPGBvLIuBiSVhMEtmLecTh2mO0tlqrAMp47tBXzMr13NJMQ2lf7RpQGLJ3HsQ==}
+ /spdx-license-ids@3.0.16:
+ resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==}
dev: true
/spdy-transport@3.0.0:
@@ -15263,6 +15988,14 @@ packages:
queue-tick: 1.0.1
dev: true
+ /strict-event-emitter@0.2.8:
+ resolution: {integrity: sha512-KDf/ujU8Zud3YaLtMCcTI4xkZlZVIYxTLr+XIULexP+77EEVWixeXroLUXQXiVtH4XH2W7jr/3PT1v3zBuvc3A==}
+ dependencies:
+ events: 3.3.0
+
+ /strict-event-emitter@0.4.6:
+ resolution: {integrity: sha512-12KWeb+wixJohmnwNFerbyiBrAlq5qJLwIt38etRtKtmmHyDSoGlIqFE9wx+4IwG0aDjI7GV8tc8ZccjWZZtTg==}
+
/string-length@4.0.2:
resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
engines: {node: '>=10'}
@@ -15299,7 +16032,6 @@ packages:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
- dev: true
/string-width@5.1.2:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
@@ -15464,13 +16196,13 @@ packages:
peek-readable: 5.0.0
dev: true
- /style-loader@3.3.3(webpack@5.88.2):
+ /style-loader@3.3.3(webpack@5.89.0):
resolution: {integrity: sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw==}
engines: {node: '>= 12.13.0'}
peerDependencies:
webpack: ^5.0.0
dependencies:
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
dev: true
/sucrase@3.34.0:
@@ -15504,7 +16236,6 @@ packages:
engines: {node: '>=8'}
dependencies:
has-flag: 4.0.0
- dev: true
/supports-color@8.1.1:
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
@@ -15545,14 +16276,14 @@ packages:
picocolors: 1.0.0
dev: true
- /swc-loader@0.2.3(@swc/core@1.3.86)(webpack@5.88.2):
+ /swc-loader@0.2.3(@swc/core@1.3.93)(webpack@5.89.0):
resolution: {integrity: sha512-D1p6XXURfSPleZZA/Lipb3A8pZ17fP4NObZvFCDjK/OKljroqDpPmsBdTraWhVBqUNpcWBQY1imWdoPScRlQ7A==}
peerDependencies:
'@swc/core': ^1.2.147
webpack: '>=2'
dependencies:
- '@swc/core': 1.3.86(@swc/helpers@0.5.2)
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ '@swc/core': 1.3.93(@swc/helpers@0.5.3)
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
dev: true
/symbol-observable@1.2.0:
@@ -15637,7 +16368,7 @@ packages:
supports-hyperlinks: 2.3.0
dev: true
- /terser-webpack-plugin@5.3.9(@swc/core@1.3.86)(esbuild@0.18.20)(webpack@5.88.2):
+ /terser-webpack-plugin@5.3.9(@swc/core@1.3.93)(esbuild@0.18.20)(webpack@5.89.0):
resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==}
engines: {node: '>= 10.13.0'}
peerDependencies:
@@ -15653,16 +16384,16 @@ packages:
uglify-js:
optional: true
dependencies:
- '@jridgewell/trace-mapping': 0.3.19
- '@swc/core': 1.3.86(@swc/helpers@0.5.2)
+ '@jridgewell/trace-mapping': 0.3.20
+ '@swc/core': 1.3.93(@swc/helpers@0.5.3)
esbuild: 0.18.20
jest-worker: 27.5.1
schema-utils: 3.3.0
serialize-javascript: 6.0.1
- terser: 5.20.0
- webpack: 5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4)
+ terser: 5.22.0
+ webpack: 5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4)
- /terser-webpack-plugin@5.3.9(@swc/core@1.3.86)(webpack@5.88.2):
+ /terser-webpack-plugin@5.3.9(@swc/core@1.3.93)(webpack@5.89.0):
resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==}
engines: {node: '>= 10.13.0'}
peerDependencies:
@@ -15678,16 +16409,16 @@ packages:
uglify-js:
optional: true
dependencies:
- '@jridgewell/trace-mapping': 0.3.19
- '@swc/core': 1.3.86(@swc/helpers@0.5.2)
+ '@jridgewell/trace-mapping': 0.3.20
+ '@swc/core': 1.3.93(@swc/helpers@0.5.3)
jest-worker: 27.5.1
schema-utils: 3.3.0
serialize-javascript: 6.0.1
- terser: 5.20.0
- webpack: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
+ terser: 5.22.0
+ webpack: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
- /terser@5.20.0:
- resolution: {integrity: sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==}
+ /terser@5.22.0:
+ resolution: {integrity: sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw==}
engines: {node: '>=10'}
hasBin: true
dependencies:
@@ -15726,8 +16457,8 @@ packages:
any-promise: 1.3.0
dev: true
- /thread-stream@2.4.0:
- resolution: {integrity: sha512-xZYtOtmnA63zj04Q+F9bdEay5r47bvpo1CaNqsKi7TpoJHcotUez8Fkfo2RJWpW91lnnaApdpRbVwCWsy+ifcw==}
+ /thread-stream@2.4.1:
+ resolution: {integrity: sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==}
dependencies:
real-require: 0.2.0
dev: true
@@ -15765,7 +16496,6 @@ packages:
/through@2.3.8:
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
- dev: true
/thunky@1.1.0:
resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==}
@@ -15775,8 +16505,8 @@ packages:
engines: {node: '>=4'}
dev: true
- /tiny-lru@11.0.1:
- resolution: {integrity: sha512-iNgFugVuQgBKrqeO/mpiTTgmBsTP0WL6yeuLfLs/Ctf0pI/ixGqIRm8sDCwMcXGe9WWvt2sGXI5mNqZbValmJg==}
+ /tiny-lru@11.2.3:
+ resolution: {integrity: sha512-mF9jPTrvN7UHk0bekOk3RlFdFwfyS4CJYVsGc7nInL3pVgUCYj5r9X6GpZBFQgLr0TKJo8Dp+F3oRvYzxU9xiA==}
engines: {node: '>=12'}
dev: true
@@ -15796,7 +16526,6 @@ packages:
engines: {node: '>=0.6.0'}
dependencies:
os-tmpdir: 1.0.2
- dev: true
/tmp@0.2.1:
resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==}
@@ -15896,7 +16625,6 @@ packages:
/tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
- dev: true
/tr46@1.0.1:
resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
@@ -15955,7 +16683,7 @@ packages:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
dev: true
- /ts-jest@29.1.1(@babel/core@7.22.20)(esbuild@0.18.20)(jest@29.7.0)(typescript@5.2.2):
+ /ts-jest@29.1.1(@babel/core@7.23.2)(esbuild@0.18.20)(jest@29.7.0)(typescript@5.2.2):
resolution: {integrity: sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -15976,11 +16704,11 @@ packages:
esbuild:
optional: true
dependencies:
- '@babel/core': 7.22.20
+ '@babel/core': 7.23.2
bs-logger: 0.2.6
esbuild: 0.18.20
fast-json-stable-stringify: 2.1.0
- jest: 29.7.0(@types/node@20.6.3)(ts-node@10.9.1)
+ jest: 29.7.0(@types/node@20.8.6)(ts-node@10.9.1)
jest-util: 29.7.0
json5: 2.2.3
lodash.memoize: 4.1.2
@@ -15990,7 +16718,7 @@ packages:
yargs-parser: 21.1.1
dev: true
- /ts-node@10.9.1(@types/node@20.6.3)(typescript@5.2.2):
+ /ts-node@10.9.1(@types/node@20.8.6)(typescript@5.2.2):
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
@@ -16009,7 +16737,7 @@ packages:
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
- '@types/node': 20.6.3
+ '@types/node': 20.8.6
acorn: 8.10.0
acorn-walk: 8.2.0
arg: 4.1.3
@@ -16037,7 +16765,7 @@ packages:
/tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
- /tsup@7.2.0(@swc/core@1.3.86)(postcss@8.4.30)(ts-node@10.9.1)(typescript@5.2.2):
+ /tsup@7.2.0(@swc/core@1.3.93)(postcss@8.4.31)(ts-node@10.9.1)(typescript@5.2.2):
resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==}
engines: {node: '>=16.14'}
hasBin: true
@@ -16053,8 +16781,8 @@ packages:
typescript:
optional: true
dependencies:
- '@swc/core': 1.3.86(@swc/helpers@0.5.2)
- bundle-require: 4.0.1(esbuild@0.18.20)
+ '@swc/core': 1.3.93(@swc/helpers@0.5.3)
+ bundle-require: 4.0.2(esbuild@0.18.20)
cac: 6.7.14
chokidar: 3.5.3
debug: 4.3.4(supports-color@9.4.0)
@@ -16062,10 +16790,10 @@ packages:
execa: 5.1.1
globby: 11.1.0
joycon: 3.1.1
- postcss: 8.4.30
- postcss-load-config: 4.0.1(postcss@8.4.30)(ts-node@10.9.1)
+ postcss: 8.4.31
+ postcss-load-config: 4.0.1(postcss@8.4.31)(ts-node@10.9.1)
resolve-from: 5.0.0
- rollup: 3.29.2
+ rollup: 3.29.4
source-map: 0.8.0-beta.0
sucrase: 3.34.0
tree-kill: 1.2.2
@@ -16085,8 +16813,8 @@ packages:
typescript: 5.2.2
dev: true
- /tty-table@4.2.1:
- resolution: {integrity: sha512-xz0uKo+KakCQ+Dxj1D/tKn2FSyreSYWzdkL/BYhgN6oMW808g8QRMuh1atAV9fjTPbWBjfbkKQpI/5rEcnAc7g==}
+ /tty-table@4.2.2:
+ resolution: {integrity: sha512-2gvCArMZLxgvpZ2NvQKdnYWIFLe7I/z5JClMuhrDXunmKgSZcQKcZRjN9XjAFiToMz2pUo1dEIXyrm0AwgV5Tw==}
engines: {node: '>=8.0.0'}
hasBin: true
dependencies:
@@ -16124,7 +16852,6 @@ packages:
/type-fest@0.21.3:
resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
engines: {node: '>=10'}
- dev: true
/type-fest@0.6.0:
resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
@@ -16144,7 +16871,6 @@ packages:
/type-fest@2.19.0:
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
engines: {node: '>=12.20'}
- dev: true
/type-fest@3.13.1:
resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==}
@@ -16210,7 +16936,6 @@ packages:
resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
engines: {node: '>=14.17'}
hasBin: true
- dev: true
/uid-safe@2.1.5:
resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==}
@@ -16244,6 +16969,9 @@ packages:
resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==}
dev: true
+ /undici-types@5.25.3:
+ resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==}
+
/unicode-canonical-property-names-ecmascript@2.0.0:
resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==}
engines: {node: '>=4'}
@@ -16270,11 +16998,11 @@ packages:
/unified-engine@10.1.0:
resolution: {integrity: sha512-5+JDIs4hqKfHnJcVCxTid1yBoI/++FfF/1PFdSMpaftZZZY+qg2JFruRbf7PaIwa9KgLotXQV3gSjtY0IdcFGQ==}
dependencies:
- '@types/concat-stream': 2.0.0
- '@types/debug': 4.1.8
- '@types/is-empty': 1.2.1
- '@types/node': 18.17.18
- '@types/unist': 2.0.8
+ '@types/concat-stream': 2.0.1
+ '@types/debug': 4.1.10
+ '@types/is-empty': 1.2.2
+ '@types/node': 18.18.6
+ '@types/unist': 2.0.9
concat-stream: 2.0.0
debug: 4.3.4(supports-color@9.4.0)
fault: 2.0.1
@@ -16291,7 +17019,7 @@ packages:
vfile-message: 3.1.4
vfile-reporter: 7.0.5
vfile-statistics: 2.0.1
- yaml: 2.3.2
+ yaml: 2.3.3
transitivePeerDependencies:
- supports-color
dev: true
@@ -16299,7 +17027,7 @@ packages:
/unified@10.1.2:
resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
bail: 2.0.2
extend: 3.0.2
is-buffer: 2.0.5
@@ -16335,51 +17063,51 @@ packages:
/unist-util-inspect@7.0.2:
resolution: {integrity: sha512-Op0XnmHUl6C2zo/yJCwhXQSm/SmW22eDZdWP2qdf4WpGrgO1ZxFodq+5zFyeRGasFjJotAnLgfuD1jkcKqiH1Q==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
dev: true
/unist-util-is@5.2.1:
resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
dev: true
/unist-util-position-from-estree@1.1.2:
resolution: {integrity: sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
dev: true
/unist-util-remove-position@4.0.2:
resolution: {integrity: sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
unist-util-visit: 4.1.2
dev: true
/unist-util-stringify-position@2.0.3:
resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
dev: true
/unist-util-stringify-position@3.0.3:
resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
dev: true
/unist-util-visit-parents@5.1.3:
resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
unist-util-is: 5.2.1
dev: true
/unist-util-visit@4.1.2:
resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
unist-util-is: 5.2.1
unist-util-visit-parents: 5.1.3
dev: true
@@ -16437,13 +17165,13 @@ packages:
engines: {node: '>=8'}
dev: true
- /update-browserslist-db@1.0.11(browserslist@4.21.10):
- resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
+ /update-browserslist-db@1.0.13(browserslist@4.22.1):
+ resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
dependencies:
- browserslist: 4.21.10
+ browserslist: 4.22.1
escalade: 3.1.1
picocolors: 1.0.0
@@ -16500,6 +17228,15 @@ packages:
/util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+ /util@0.12.5:
+ resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==}
+ dependencies:
+ inherits: 2.0.4
+ is-arguments: 1.1.1
+ is-generator-function: 1.0.10
+ is-typed-array: 1.1.12
+ which-typed-array: 1.1.11
+
/utila@0.4.0:
resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==}
@@ -16531,13 +17268,13 @@ packages:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
dev: true
- /v8-to-istanbul@9.1.0:
- resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==}
+ /v8-to-istanbul@9.1.3:
+ resolution: {integrity: sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==}
engines: {node: '>=10.12.0'}
dependencies:
- '@jridgewell/trace-mapping': 0.3.19
- '@types/istanbul-lib-coverage': 2.0.4
- convert-source-map: 1.9.0
+ '@jridgewell/trace-mapping': 0.3.20
+ '@types/istanbul-lib-coverage': 2.0.5
+ convert-source-map: 2.0.0
dev: true
/validate-npm-package-license@3.0.4:
@@ -16561,14 +17298,14 @@ packages:
/vfile-message@3.1.4:
resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
unist-util-stringify-position: 3.0.3
dev: true
/vfile-reporter@7.0.5:
resolution: {integrity: sha512-NdWWXkv6gcd7AZMvDomlQbK3MqFWL1RlGzMn++/O2TI+68+nqxCPTvLugdOtfSzXmjh+xUyhp07HhlrbJjT+mw==}
dependencies:
- '@types/supports-color': 8.1.1
+ '@types/supports-color': 8.1.2
string-width: 5.1.2
supports-color: 9.4.0
unist-util-stringify-position: 3.0.3
@@ -16595,7 +17332,7 @@ packages:
/vfile@5.3.7:
resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==}
dependencies:
- '@types/unist': 2.0.8
+ '@types/unist': 2.0.9
is-buffer: 2.0.5
unist-util-stringify-position: 3.0.3
vfile-message: 3.1.4
@@ -16646,7 +17383,13 @@ packages:
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
dependencies:
defaults: 1.0.4
- dev: true
+
+ /web-encoding@1.1.5:
+ resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==}
+ dependencies:
+ util: 0.12.5
+ optionalDependencies:
+ '@zxing/text-encoding': 0.9.0
/web-streams-polyfill@3.2.1:
resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==}
@@ -16655,7 +17398,6 @@ packages:
/webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
- dev: true
/webidl-conversions@4.0.2:
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
@@ -16666,7 +17408,7 @@ packages:
engines: {node: '>=12'}
dev: true
- /webpack-cli@5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2):
+ /webpack-cli@5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0):
resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==}
engines: {node: '>=14.15.0'}
hasBin: true
@@ -16684,9 +17426,9 @@ packages:
optional: true
dependencies:
'@discoveryjs/json-ext': 0.5.7
- '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.88.2)
- '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.88.2)
- '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.89.0)
+ '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.89.0)
+ '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.1)(webpack@5.89.0)
colorette: 2.0.20
commander: 10.0.1
cross-spawn: 7.0.3
@@ -16695,11 +17437,11 @@ packages:
import-local: 3.1.0
interpret: 3.1.1
rechoir: 0.8.0
- webpack: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
- webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.88.2)
- webpack-merge: 5.9.0
+ webpack: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ webpack-dev-server: 4.15.1(webpack-cli@5.1.4)(webpack@5.89.0)
+ webpack-merge: 5.10.0
- /webpack-dev-middleware@5.3.3(webpack@5.88.2):
+ /webpack-dev-middleware@5.3.3(webpack@5.89.0):
resolution: {integrity: sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==}
engines: {node: '>= 12.13.0'}
peerDependencies:
@@ -16710,9 +17452,9 @@ packages:
mime-types: 2.1.35
range-parser: 1.2.1
schema-utils: 4.2.0
- webpack: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
+ webpack: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
- /webpack-dev-server@4.15.1(webpack-cli@5.1.4)(webpack@5.88.2):
+ /webpack-dev-server@4.15.1(webpack-cli@5.1.4)(webpack@5.89.0):
resolution: {integrity: sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==}
engines: {node: '>= 12.13.0'}
hasBin: true
@@ -16725,13 +17467,13 @@ packages:
webpack-cli:
optional: true
dependencies:
- '@types/bonjour': 3.5.11
- '@types/connect-history-api-fallback': 1.5.1
- '@types/express': 4.17.17
- '@types/serve-index': 1.9.1
- '@types/serve-static': 1.15.2
- '@types/sockjs': 0.3.33
- '@types/ws': 8.5.5
+ '@types/bonjour': 3.5.12
+ '@types/connect-history-api-fallback': 1.5.2
+ '@types/express': 4.17.20
+ '@types/serve-index': 1.9.3
+ '@types/serve-static': 1.15.4
+ '@types/sockjs': 0.3.35
+ '@types/ws': 8.5.8
ansi-html-community: 0.0.8
bonjour-service: 1.1.1
chokidar: 3.5.3
@@ -16742,9 +17484,9 @@ packages:
express: 4.18.2
graceful-fs: 4.2.11
html-entities: 2.4.0
- http-proxy-middleware: 2.0.6(@types/express@4.17.17)
+ http-proxy-middleware: 2.0.6(@types/express@4.17.20)
ipaddr.js: 2.1.0
- launch-editor: 2.6.0
+ launch-editor: 2.6.1
open: 8.4.2
p-retry: 4.6.2
rimraf: 3.0.2
@@ -16753,9 +17495,9 @@ packages:
serve-index: 1.9.1
sockjs: 0.3.24
spdy: 4.0.2
- webpack: 5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4)
- webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2)
- webpack-dev-middleware: 5.3.3(webpack@5.88.2)
+ webpack: 5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4)
+ webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
+ webpack-dev-middleware: 5.3.3(webpack@5.89.0)
ws: 8.14.2
transitivePeerDependencies:
- bufferutil
@@ -16763,19 +17505,20 @@ packages:
- supports-color
- utf-8-validate
- /webpack-merge@5.9.0:
- resolution: {integrity: sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==}
+ /webpack-merge@5.10.0:
+ resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==}
engines: {node: '>=10.0.0'}
dependencies:
clone-deep: 4.0.1
+ flat: 5.0.2
wildcard: 2.0.1
/webpack-sources@3.2.3:
resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
engines: {node: '>=10.13.0'}
- /webpack@5.88.2(@swc/core@1.3.86)(esbuild@0.18.20)(webpack-cli@5.1.4):
- resolution: {integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==}
+ /webpack@5.89.0(@swc/core@1.3.93)(esbuild@0.18.20)(webpack-cli@5.1.4):
+ resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==}
engines: {node: '>=10.13.0'}
hasBin: true
peerDependencies:
@@ -16784,14 +17527,14 @@ packages:
webpack-cli:
optional: true
dependencies:
- '@types/eslint-scope': 3.7.4
- '@types/estree': 1.0.1
+ '@types/eslint-scope': 3.7.6
+ '@types/estree': 1.0.3
'@webassemblyjs/ast': 1.11.6
'@webassemblyjs/wasm-edit': 1.11.6
'@webassemblyjs/wasm-parser': 1.11.6
acorn: 8.10.0
acorn-import-assertions: 1.9.0(acorn@8.10.0)
- browserslist: 4.21.10
+ browserslist: 4.22.1
chrome-trace-event: 1.0.3
enhanced-resolve: 5.15.0
es-module-lexer: 1.3.1
@@ -16805,17 +17548,17 @@ packages:
neo-async: 2.6.2
schema-utils: 3.3.0
tapable: 2.2.1
- terser-webpack-plugin: 5.3.9(@swc/core@1.3.86)(esbuild@0.18.20)(webpack@5.88.2)
+ terser-webpack-plugin: 5.3.9(@swc/core@1.3.93)(esbuild@0.18.20)(webpack@5.89.0)
watchpack: 2.4.0
- webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
webpack-sources: 3.2.3
transitivePeerDependencies:
- '@swc/core'
- esbuild
- uglify-js
- /webpack@5.88.2(@swc/core@1.3.86)(webpack-cli@5.1.4):
- resolution: {integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==}
+ /webpack@5.89.0(@swc/core@1.3.93)(webpack-cli@5.1.4):
+ resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==}
engines: {node: '>=10.13.0'}
hasBin: true
peerDependencies:
@@ -16824,14 +17567,14 @@ packages:
webpack-cli:
optional: true
dependencies:
- '@types/eslint-scope': 3.7.4
- '@types/estree': 1.0.1
+ '@types/eslint-scope': 3.7.6
+ '@types/estree': 1.0.3
'@webassemblyjs/ast': 1.11.6
'@webassemblyjs/wasm-edit': 1.11.6
'@webassemblyjs/wasm-parser': 1.11.6
acorn: 8.10.0
acorn-import-assertions: 1.9.0(acorn@8.10.0)
- browserslist: 4.21.10
+ browserslist: 4.22.1
chrome-trace-event: 1.0.3
enhanced-resolve: 5.15.0
es-module-lexer: 1.3.1
@@ -16845,9 +17588,9 @@ packages:
neo-async: 2.6.2
schema-utils: 3.3.0
tapable: 2.2.1
- terser-webpack-plugin: 5.3.9(@swc/core@1.3.86)(webpack@5.88.2)
+ terser-webpack-plugin: 5.3.9(@swc/core@1.3.93)(webpack@5.89.0)
watchpack: 2.4.0
- webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.88.2)
+ webpack-cli: 5.1.4(webpack-dev-server@4.15.1)(webpack@5.89.0)
webpack-sources: 3.2.3
transitivePeerDependencies:
- '@swc/core'
@@ -16896,7 +17639,6 @@ packages:
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
- dev: true
/whatwg-url@7.1.0:
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
@@ -16964,7 +17706,6 @@ packages:
for-each: 0.3.3
gopd: 1.0.1
has-tostringtag: 1.0.0
- dev: true
/which@1.3.1:
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
@@ -17003,30 +17744,30 @@ packages:
execa: 5.1.1
dev: true
- /winston-transport@4.5.0:
- resolution: {integrity: sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==}
- engines: {node: '>= 6.4.0'}
+ /winston-transport@4.6.0:
+ resolution: {integrity: sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==}
+ engines: {node: '>= 12.0.0'}
dependencies:
- logform: 2.5.1
+ logform: 2.6.0
readable-stream: 3.6.2
triple-beam: 1.4.1
dev: true
- /winston@3.10.0:
- resolution: {integrity: sha512-nT6SIDaE9B7ZRO0u3UvdrimG0HkB7dSTAgInQnNR2SOPJ4bvq5q79+pXLftKmP52lJGW15+H5MCK0nM9D3KB/g==}
+ /winston@3.11.0:
+ resolution: {integrity: sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==}
engines: {node: '>= 12.0.0'}
dependencies:
- '@colors/colors': 1.5.0
+ '@colors/colors': 1.6.0
'@dabh/diagnostics': 2.0.3
async: 3.2.4
is-stream: 2.0.1
- logform: 2.5.1
+ logform: 2.6.0
one-time: 1.0.0
readable-stream: 3.6.2
safe-stable-stringify: 2.4.3
stack-trace: 0.0.10
triple-beam: 1.4.1
- winston-transport: 4.5.0
+ winston-transport: 4.6.0
dev: true
/winston@3.8.2:
@@ -17037,13 +17778,13 @@ packages:
'@dabh/diagnostics': 2.0.3
async: 3.2.4
is-stream: 2.0.1
- logform: 2.5.1
+ logform: 2.6.0
one-time: 1.0.0
readable-stream: 3.6.2
safe-stable-stringify: 2.4.3
stack-trace: 0.0.10
triple-beam: 1.4.1
- winston-transport: 4.5.0
+ winston-transport: 4.6.0
dev: true
/wrap-ansi@3.0.1:
@@ -17061,7 +17802,6 @@ packages:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
- dev: true
/wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
@@ -17070,7 +17810,6 @@ packages:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
- dev: true
/wrap-ansi@8.1.0:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
@@ -17151,7 +17890,6 @@ packages:
/y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
- dev: true
/yallist@2.1.2:
resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
@@ -17165,8 +17903,8 @@ packages:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: true
- /yaml@2.3.2:
- resolution: {integrity: sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==}
+ /yaml@2.3.3:
+ resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==}
engines: {node: '>= 14'}
dev: true
@@ -17186,7 +17924,6 @@ packages:
/yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
- dev: true
/yargs@15.4.1:
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
@@ -17229,7 +17966,6 @@ packages:
string-width: 4.2.3
y18n: 5.0.8
yargs-parser: 21.1.1
- dev: true
/yauzl@2.10.0:
resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index f4525e8e8..4145d02cd 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,3 +1,3 @@
packages:
- "packages/*"
- - "sample/*"
+ - "samples/**"
diff --git a/sample/another-remote-module/src/dev/App.tsx b/sample/another-remote-module/src/dev/App.tsx
deleted file mode 100644
index 6a2681bad..000000000
--- a/sample/another-remote-module/src/dev/App.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { useAppRouter } from "@sample/shell";
-import { Suspense, lazy } from "react";
-import { RouterProvider } from "react-router-dom";
-import { sessionManager } from "./session.ts";
-
-const DevHome = lazy(() => import("./DevHome.tsx"));
-
-export function App() {
- const router = useAppRouter(sessionManager, {
- managedRoutes: [
- {
- index: true,
- element:
- }
- ]
- });
-
- return (
- Loading...}>
- Loading...}
- />
-
- );
-}
diff --git a/sample/another-remote-module/src/register.tsx b/sample/another-remote-module/src/register.tsx
deleted file mode 100644
index 3ebef14a6..000000000
--- a/sample/another-remote-module/src/register.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
-
-import { lazy } from "react";
-
-const FederatedTabsLayout = lazy(() => import("@sample/shared/FederatedTabsLayout.tsx"));
-
-export const register: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- path: "/federated-tabs",
- element:
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/federated-tabs",
- label: "Tabs"
- }
- ]);
-};
diff --git a/sample/another-remote-module/tsconfig.json b/sample/another-remote-module/tsconfig.json
deleted file mode 100644
index 7d155fc83..000000000
--- a/sample/another-remote-module/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": "@workleap/typescript-configs/web-application.json",
- "compilerOptions": {
- "paths": {
- "@squide/core": ["../../packages/core/src/index.ts"],
- "@squide/react-router": ["../../packages/react-router/src/index.ts"],
- "@squide/webpack-module-federation": ["../../packages/webpack-module-federation/src/index.ts"],
- "@squide/webpack-module-federation/defineConfig.js": ["../../packages/webpack-module-federation/src/defineConfig.js"],
- "@sample/shell": ["../shell/src/index.ts"],
- "@sample/shared": ["../shared/src/index.ts"],
- "@sample/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"]
- }
- },
- "exclude": ["dist", "node_modules"]
-}
diff --git a/sample/host/src/App.tsx b/sample/host/src/App.tsx
deleted file mode 100644
index e842e6f3a..000000000
--- a/sample/host/src/App.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { BackgroundColorContext } from "@sample/shared";
-import { useAppRouter } from "@sample/shell";
-import { useAreModulesReady } from "@squide/webpack-module-federation";
-import { Suspense, lazy } from "react";
-import { RouterProvider } from "react-router-dom";
-import { sessionManager } from "./session.ts";
-
-const Home = lazy(() => import("./Home.tsx"));
-
-export function App() {
- // Re-render the app once all the remotes are registered.
- // Otherwise, the remotes routes won't be added to the router.
- const isReady = useAreModulesReady();
-
- const router = useAppRouter(sessionManager, {
- managedRoutes: [
- {
- index: true,
- element:
- }
- ]
- });
-
- if (!isReady) {
- return Loading...
;
- }
-
- return (
-
- Loading...}>
- Loading...}
- />
-
-
- );
-}
diff --git a/sample/host/src/Home.tsx b/sample/host/src/Home.tsx
deleted file mode 100644
index dabd91ccc..000000000
--- a/sample/host/src/Home.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-export default function Home() {
- return (
-
- );
-}
diff --git a/sample/host/tsconfig.json b/sample/host/tsconfig.json
deleted file mode 100644
index fbe17d9ff..000000000
--- a/sample/host/tsconfig.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "extends": "@workleap/typescript-configs/web-application.json",
- "compilerOptions": {
- "paths": {
- "@squide/core": ["../../packages/core/src/index.ts"],
- "@squide/react-router": ["../../packages/react-router/src/index.ts"],
- "@squide/webpack-module-federation": ["../../packages/webpack-module-federation/src/index.ts"],
- "@squide/webpack-module-federation/defineConfig.js": ["../../packages/webpack-module-federation/src/defineConfig.js"],
- "@squide/fakes": ["../../packages/fakes/src/index.ts"],
- "@sample/shell": ["../shell/src/index.ts"],
- "@sample/shared": ["../shared/src/index.ts"],
- "@sample/local-module": ["../local-module/src/register.ts"]
- }
- },
- "exclude": ["dist", "node_modules"]
-}
diff --git a/sample/local-module/src/About.tsx b/sample/local-module/src/About.tsx
deleted file mode 100644
index 4182599df..000000000
--- a/sample/local-module/src/About.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Link } from "react-router-dom";
-
-export default function About() {
- return (
-
-
About
-
Hey again!
-
Go back to home
-
- );
-}
diff --git a/sample/local-module/src/Message.tsx b/sample/local-module/src/Message.tsx
deleted file mode 100644
index 399aceb87..000000000
--- a/sample/local-module/src/Message.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { useCallback, useState, type ChangeEvent } from "react";
-
-import { useApplicationEventBusDispatcher } from "@sample/shared";
-import { Link } from "react-router-dom";
-
-export default function Message() {
- const [message, setMessage] = useState("");
-
- const handleTextChange = useCallback((event: ChangeEvent) => {
- setMessage(event.target.value);
- }, []);
-
- const dispatch = useApplicationEventBusDispatcher();
-
- const handleSendMessage = useCallback(() => {
- dispatch("write-to-host", message);
- setMessage("");
- }, [dispatch, setMessage, message]);
-
- return (
-
-
Messaging
-
Send a message to the host application:
-
-
-
Send
-
Hint: have a look at your console log :)
-
Go back to home
-
- );
-}
diff --git a/sample/local-module/src/WorkleapTab.tsx b/sample/local-module/src/WorkleapTab.tsx
deleted file mode 100644
index ac562d112..000000000
--- a/sample/local-module/src/WorkleapTab.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-export default function WorkleapTab() {
- return (
-
-
This is the Workleap tab from @sample/local-module !
-
- );
-}
diff --git a/sample/local-module/src/dev/App.tsx b/sample/local-module/src/dev/App.tsx
deleted file mode 100644
index 6a2681bad..000000000
--- a/sample/local-module/src/dev/App.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { useAppRouter } from "@sample/shell";
-import { Suspense, lazy } from "react";
-import { RouterProvider } from "react-router-dom";
-import { sessionManager } from "./session.ts";
-
-const DevHome = lazy(() => import("./DevHome.tsx"));
-
-export function App() {
- const router = useAppRouter(sessionManager, {
- managedRoutes: [
- {
- index: true,
- element:
- }
- ]
- });
-
- return (
- Loading...}>
- Loading...}
- />
-
- );
-}
diff --git a/sample/local-module/src/dev/registerTabsPage.tsx b/sample/local-module/src/dev/registerTabsPage.tsx
deleted file mode 100644
index 4c4b91daa..000000000
--- a/sample/local-module/src/dev/registerTabsPage.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
-import { lazy } from "react";
-
-const FederatedTabsLayout = lazy(() => import("@sample/shared/FederatedTabsLayout.tsx"));
-
-export const registerTabsPage: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- path: "/federated-tabs",
- element:
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/federated-tabs",
- label: "Tabs"
- }
- ]);
-};
diff --git a/sample/local-module/src/register.tsx b/sample/local-module/src/register.tsx
deleted file mode 100644
index 271ecb89e..000000000
--- a/sample/local-module/src/register.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import type { AppContext } from "@sample/shared";
-import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
-import { lazy } from "react";
-
-const About = lazy(() => import("./About.tsx"));
-const Message = lazy(() => import("./Message.tsx"));
-const WorkleapTab = lazy(() => import("./WorkleapTab.tsx"));
-
-export const register: ModuleRegisterFunction = (runtime, context) => {
- console.log("Local module context: ", context);
-
- runtime.registerRoutes([
- {
- path: "/about",
- element:
- },
- {
- path: "/message",
- element:
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/about",
- label: "About"
- },
- {
- to: "/message",
- label: "Message",
- // Higher numbers gets rendered first.
- priority: 999,
- // Will be forwarded to the host application render function.
- additionalProps: {
- highlight: true
- }
- }
- ]);
-
- ///////
-
- runtime.registerRoutes([
- {
- index: true,
- element:
- }
- ], { layoutPath: "/federated-tabs" });
-
- runtime.registerNavigationItems([
- {
- to: "/federated-tabs",
- label: "Workleap"
- }
- ], { menuId: "/federated-tabs" });
-};
diff --git a/sample/local-module/tsconfig.json b/sample/local-module/tsconfig.json
deleted file mode 100644
index 1b3ab1298..000000000
--- a/sample/local-module/tsconfig.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "extends": "@workleap/typescript-configs/library.json",
- "compilerOptions": {
- "paths": {
- "@squide/core": ["../../packages/core/src/index.ts"],
- "@squide/react-router": ["../../packages/react-router/src/index.ts"],
- "@sample/shell": ["../shell/src/index.ts"],
- "@sample/shared": ["../shared/src/index.ts"],
- "@sample/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"]
- }
- },
- "exclude": ["dist", "node_modules"]
-}
diff --git a/sample/remote-module/src/ColoredPage.tsx b/sample/remote-module/src/ColoredPage.tsx
deleted file mode 100644
index 54c2b0869..000000000
--- a/sample/remote-module/src/ColoredPage.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { useBackgroundColor } from "@sample/shared";
-
-export default function ColoredPage() {
- const backgroundColor = useBackgroundColor();
-
- return (
-
- The background color is "{backgroundColor}"
-
- );
-}
diff --git a/sample/remote-module/src/Fetch.tsx b/sample/remote-module/src/Fetch.tsx
deleted file mode 100644
index 85176a34a..000000000
--- a/sample/remote-module/src/Fetch.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { useLoaderData } from "react-router-dom";
-
-interface Character {
- id: number;
- name: string;
- species: string;
-}
-
-export default function Fetch() {
- const characters = useLoaderData() as Character[];
-
- return (
-
-
Fetch
-
An example fetching data with React Router loaders.
-
- {characters.map(x => {
- return (
-
- Id: {x.id}
- -
- Name: {x.name}
- -
- Species: {x.species}
-
- );
- })}
-
-
- );
-}
diff --git a/sample/remote-module/src/Hoisted.tsx b/sample/remote-module/src/Hoisted.tsx
deleted file mode 100644
index f2612d277..000000000
--- a/sample/remote-module/src/Hoisted.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Link } from "react-router-dom";
-
-export default function Hoisted() {
- return (
-
-
Hoisted
-
Hello from a remote module! I have been hoisted at the top of React Router routes declaration and therefore doesn't inherit from the root layout and error boundary.
-
Go back to home
-
- );
-}
diff --git a/sample/remote-module/src/OfficevibeTab.tsx b/sample/remote-module/src/OfficevibeTab.tsx
deleted file mode 100644
index 4c0369934..000000000
--- a/sample/remote-module/src/OfficevibeTab.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-export default function OfficevibeTab() {
- return (
-
-
This is the Officevibe tab from @sample/remote-module !
-
- );
-}
diff --git a/sample/remote-module/src/Remote.tsx b/sample/remote-module/src/Remote.tsx
deleted file mode 100644
index 459e7cb89..000000000
--- a/sample/remote-module/src/Remote.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Link } from "react-router-dom";
-
-export default function Remote() {
- return (
-
-
Remote
-
Hello from a remote module!
-
Go back to home
-
- );
-}
diff --git a/sample/remote-module/src/SkillsTab.tsx b/sample/remote-module/src/SkillsTab.tsx
deleted file mode 100644
index 9ecca7a29..000000000
--- a/sample/remote-module/src/SkillsTab.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-export default function SkillsTab() {
- return (
-
-
This is the Skills tab from @sample/remote-module !
-
- );
-}
diff --git a/sample/remote-module/src/dev/App.tsx b/sample/remote-module/src/dev/App.tsx
deleted file mode 100644
index b0bcf1d07..000000000
--- a/sample/remote-module/src/dev/App.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { BackgroundColorContext } from "@sample/shared";
-import { useAppRouter } from "@sample/shell";
-import { Suspense, lazy } from "react";
-import { RouterProvider } from "react-router-dom";
-import { sessionManager } from "./session.ts";
-
-const DevHome = lazy(() => import("./DevHome.tsx"));
-
-export function App() {
- const router = useAppRouter(sessionManager, {
- managedRoutes: [
- {
- index: true,
- element:
- }
- ]
- });
-
- return (
-
- Loading...}>
- Loading...}
- />
-
-
- );
-}
diff --git a/sample/remote-module/src/dev/registerTabsPage.tsx b/sample/remote-module/src/dev/registerTabsPage.tsx
deleted file mode 100644
index 4c4b91daa..000000000
--- a/sample/remote-module/src/dev/registerTabsPage.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
-import { lazy } from "react";
-
-const FederatedTabsLayout = lazy(() => import("@sample/shared/FederatedTabsLayout.tsx"));
-
-export const registerTabsPage: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- path: "/federated-tabs",
- element:
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/federated-tabs",
- label: "Tabs"
- }
- ]);
-};
diff --git a/sample/remote-module/src/register.tsx b/sample/remote-module/src/register.tsx
deleted file mode 100644
index fc1b58ae5..000000000
--- a/sample/remote-module/src/register.tsx
+++ /dev/null
@@ -1,116 +0,0 @@
-import { BackgroundColorContext } from "@sample/shared";
-import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
-import { lazy } from "react";
-
-const CustomLayout = lazy(() => import("./CustomLayout.tsx"));
-const Remote = lazy(() => import("./Remote.tsx"));
-const Fetch = lazy(() => import("./Fetch.tsx"));
-const Hoisted = lazy(() => import("./Hoisted.tsx"));
-const OfficevibeTab = lazy(() => import("./OfficevibeTab.tsx"));
-const SkillsTab = lazy(() => import("./SkillsTab.tsx"));
-const ColoredPage = lazy(() => import("./ColoredPage.tsx"));
-
-export const register: ModuleRegisterFunction = runtime => {
- runtime.registerRoutes([
- {
- path: "/remote",
- element:
- },
- {
- path: "/fetch",
- element: ,
- loader: async function loader() {
- return fetch("https://rickandmortyapi.com/api/character/1,2,3,4,5", {
- method: "GET",
- headers: {
- "Accept": "application/json"
- }
- });
- }
- },
- {
- hoist: true,
- path: "/hoisted",
- element: ,
- children: [
- {
- index: true,
- element:
- }
- ]
- },
- {
- path: "/no-context-override",
- element:
- },
- {
- path: "/context-override",
- element: (
-
-
-
- )
- }
- ]);
-
- runtime.registerNavigationItems([
- {
- to: "/remote",
- label: "Remote"
- },
- {
- to: "/fetch",
- label: "Fetch"
- },
- {
- to: "/hoisted",
- label: Hoisted
- },
- {
- label: "Section",
- children: [
- {
- to: "#",
- label: "Child 1"
- },
- {
- to: "#",
- label: "Child 2"
- }
- ]
- },
- {
- to: "/no-context-override",
- label: "No context override"
- },
- {
- to: "/context-override",
- label: "Context override"
- }
- ]);
-
- ///////
-
- runtime.registerRoutes([
- {
- path: "/federated-tabs/officevibe",
- element:
- },
- {
- path: "/federated-tabs/skills",
- element:
- }
- ], { layoutPath: "/federated-tabs" });
-
- runtime.registerNavigationItems([
- {
- to: "/federated-tabs/officevibe",
- label: "Officevibe"
- },
- {
- to: "/federated-tabs/skills",
- label: "Skills",
- priority: 999
- }
- ], { menuId: "/federated-tabs" });
-};
diff --git a/sample/remote-module/tsconfig.json b/sample/remote-module/tsconfig.json
deleted file mode 100644
index 7d155fc83..000000000
--- a/sample/remote-module/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": "@workleap/typescript-configs/web-application.json",
- "compilerOptions": {
- "paths": {
- "@squide/core": ["../../packages/core/src/index.ts"],
- "@squide/react-router": ["../../packages/react-router/src/index.ts"],
- "@squide/webpack-module-federation": ["../../packages/webpack-module-federation/src/index.ts"],
- "@squide/webpack-module-federation/defineConfig.js": ["../../packages/webpack-module-federation/src/defineConfig.js"],
- "@sample/shell": ["../shell/src/index.ts"],
- "@sample/shared": ["../shared/src/index.ts"],
- "@sample/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"]
- }
- },
- "exclude": ["dist", "node_modules"]
-}
diff --git a/sample/shell/src/Logout.tsx b/sample/shell/src/Logout.tsx
deleted file mode 100644
index f07efb2f7..000000000
--- a/sample/shell/src/Logout.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import type { SessionManager } from "@sample/shared";
-import { Link } from "react-router-dom";
-
-export interface LogoutProps {
- sessionManager: SessionManager;
-}
-
-export default function Logout({ sessionManager }: LogoutProps) {
- sessionManager.clearSession();
-
- return (
-
- Logged out
- You are logged out from the application!
- Log in again
-
- );
-}
diff --git a/sample/shell/src/NoMatch.tsx b/sample/shell/src/NoMatch.tsx
deleted file mode 100644
index ed72fe0cf..000000000
--- a/sample/shell/src/NoMatch.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Link } from "react-router-dom";
-
-export interface NoMatchProps {
- path: string;
-}
-
-export default function NoMatch({ path }: NoMatchProps) {
- return (
-
-
404
-
We can't find the path "{path}".
-
Go back home
-
- );
-}
diff --git a/sample/shell/src/index.ts b/sample/shell/src/index.ts
deleted file mode 100644
index f6cf0a585..000000000
--- a/sample/shell/src/index.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export * from "./AuthenticatedLayout.tsx";
-export * from "./AuthenticationBoundary.tsx";
-export * from "./Login.tsx";
-export * from "./Logout.tsx";
-export * from "./ModuleErrorBoundary.tsx";
-export * from "./NoMatch.tsx";
-export * from "./RootErrorBoundary.tsx";
-export * from "./RootLayout.tsx";
-export * from "./useAppRouter.tsx";
-
diff --git a/sample/shell/src/useAppRouter.tsx b/sample/shell/src/useAppRouter.tsx
deleted file mode 100644
index a08776f5e..000000000
--- a/sample/shell/src/useAppRouter.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import { useHoistedRoutes, useRoutes, type Route } from "@squide/react-router";
-import { lazy, useCallback, useMemo, useState } from "react";
-import { AuthenticationBoundary } from "./AuthenticationBoundary.tsx";
-import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
-import { RootLayout } from "./RootLayout.tsx";
-// Importing the Router type to prevent: error TS2742: The inferred type of 'useAppRouter' cannot be named without a reference
-import type { Router } from "@remix-run/router";
-import type { SessionManager } from "@sample/shared";
-import { createBrowserRouter } from "react-router-dom";
-
-export interface UseAppRouterOptions {
- managedRoutes?: Route[];
- rootRoutes?: Route[];
-}
-
-const AuthenticatedLayout = lazy(() => import("./AuthenticatedLayout.tsx"));
-const ModuleErrorBoundary = lazy(() => import("./ModuleErrorBoundary.tsx"));
-const Login = lazy(() => import("./Login.tsx"));
-const Logout = lazy(() => import("./Logout.tsx"));
-const NoMatch = lazy(() => import("./NoMatch.tsx"));
-
-export function useAppRouter(sessionManager: SessionManager, options: UseAppRouterOptions = {}): Router {
- const {
- managedRoutes: hostManagedRoutes = [],
- rootRoutes = []
- } = options;
-
- // Reuse the same array reference through re-renders.
- const [memoizedManagedRoutes] = useState(hostManagedRoutes);
- const [memoizedRootRoutes] = useState(rootRoutes);
-
- const routes = useRoutes();
-
- const wrapManagedRoutes = useCallback((managedRoutes: Route[]) => {
- return {
- // Pathless route to declare a root layout and a root error boundary.
- element: ,
- children: [
- {
- errorElement: ,
- children: [
- {
- path: "/login",
- element:
- },
- {
- path: "/logout",
- element:
- },
- {
- // Pathless route to declare an authenticated boundary.
- element: ,
- children: [
- {
- // Pathless route to declare an authenticated layout.
- element: ,
- children: [
- {
- // Pathless route to declare an error boundary inside the layout instead of outside.
- // It's quite useful to prevent losing the layout when an unmanaged error occurs.
- errorElement: ,
- children: [
- ...memoizedManagedRoutes,
- ...managedRoutes
- ]
- }
- ]
- }
- ]
- },
- {
- path: "*",
- element:
- }
- ]
- }
- ]
- };
- }, []);
-
- // Using the useHoistedRoutes hook allow routes hoisted by modules to be rendered at the root of the router instead of under the root layout.
- // To disallow the hoisting functionality, remove this hook and add the routes directly.
- const hoistedRoutes = useHoistedRoutes(routes, wrapManagedRoutes);
-
- const router = useMemo(() => {
- return createBrowserRouter([...hoistedRoutes, ...memoizedRootRoutes]);
- }, [hoistedRoutes, memoizedRootRoutes]);
-
- return router;
-}
diff --git a/sample/shell/tsconfig.json b/sample/shell/tsconfig.json
deleted file mode 100644
index ed6188feb..000000000
--- a/sample/shell/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "extends": "@workleap/typescript-configs/library.json",
- "compilerOptions": {
- "paths": {
- "@squide/core": ["../../packages/core/src/index.ts"],
- "@squide/react-router": ["../../packages/react-router/src/index.ts"],
- "@sample/shared": ["../shared/src/index.ts"]
- }
- },
- "exclude": ["dist", "node_modules"]
-}
diff --git a/sample/another-remote-module/.browserslistrc b/samples/basic/another-remote-module/.browserslistrc
similarity index 100%
rename from sample/another-remote-module/.browserslistrc
rename to samples/basic/another-remote-module/.browserslistrc
diff --git a/sample/another-remote-module/.eslintrc.json b/samples/basic/another-remote-module/.eslintrc.json
similarity index 100%
rename from sample/another-remote-module/.eslintrc.json
rename to samples/basic/another-remote-module/.eslintrc.json
diff --git a/sample/host/nodemon.json b/samples/basic/another-remote-module/nodemon.json
similarity index 100%
rename from sample/host/nodemon.json
rename to samples/basic/another-remote-module/nodemon.json
diff --git a/sample/another-remote-module/package.json b/samples/basic/another-remote-module/package.json
similarity index 59%
rename from sample/another-remote-module/package.json
rename to samples/basic/another-remote-module/package.json
index 3f56c715c..b18b2022a 100644
--- a/sample/another-remote-module/package.json
+++ b/samples/basic/another-remote-module/package.json
@@ -1,5 +1,5 @@
{
- "name": "@sample/another-remote-module",
+ "name": "@basic/another-remote-module",
"author": "Workleap",
"version": "0.0.0",
"description": "Another remote module to showcase @squide.",
@@ -7,38 +7,39 @@
"license": "Apache-2.0",
"type": "module",
"scripts": {
- "dev": "webpack serve --config webpack.dev.js",
- "dev-local": "cross-env LOCAL=true webpack serve --config webpack.dev.js",
+ "dev": "nodemon",
+ "dev-isolated": "cross-env ISOLATED=true pnpm dev",
"build": "webpack --config webpack.build.js",
"serve-build": "pnpm build && pnpm http-server dist -p 8082 -P http://localhost:8082? -c-1"
},
"devDependencies": {
- "@swc/core": "1.3.86",
- "@swc/helpers": "0.5.2",
- "@types/react": "18.2.22",
- "@types/react-dom": "18.2.7",
- "@types/webpack": "5.28.2",
+ "@swc/core": "1.3.93",
+ "@swc/helpers": "0.5.3",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@types/webpack": "5.28.3",
"@workleap/browserslist-config": "2.0.0",
- "@workleap/eslint-plugin": "2.1.1",
+ "@workleap/eslint-plugin": "3.0.0",
"@workleap/swc-configs": "2.1.2",
"@workleap/typescript-configs": "3.0.2",
- "@workleap/webpack-configs": "1.0.8",
- "browserslist": "4.21.10",
+ "@workleap/webpack-configs": "1.1.0",
+ "browserslist": "4.22.1",
"cross-env": "7.0.3",
"http-server": "14.1.1",
+ "nodemon": "3.0.1",
"typescript": "5.2.2",
- "webpack": "5.88.2",
+ "webpack": "5.89.0",
"webpack-cli": "5.1.4",
"webpack-dev-server": "4.15.1"
},
"dependencies": {
- "@sample/shared": "workspace:*",
- "@sample/shell": "workspace:*",
+ "@basic/shared": "workspace:*",
+ "@basic/shell": "workspace:*",
"@squide/fakes": "workspace:*",
"@squide/react-router": "workspace:*",
"@squide/webpack-module-federation": "workspace:*",
"react": "18.2.0",
"react-dom": "18.2.0",
- "react-router-dom": "6.16.0"
+ "react-router-dom": "6.17.0"
}
}
diff --git a/sample/another-remote-module/public/index.html b/samples/basic/another-remote-module/public/index.html
similarity index 100%
rename from sample/another-remote-module/public/index.html
rename to samples/basic/another-remote-module/public/index.html
diff --git a/samples/basic/another-remote-module/src/dev/App.tsx b/samples/basic/another-remote-module/src/dev/App.tsx
new file mode 100644
index 000000000..0dd186ccd
--- /dev/null
+++ b/samples/basic/another-remote-module/src/dev/App.tsx
@@ -0,0 +1,5 @@
+import { AppRouter } from "@basic/shell";
+
+export function App() {
+ return ;
+}
diff --git a/samples/basic/another-remote-module/src/dev/DevHomePage.tsx b/samples/basic/another-remote-module/src/dev/DevHomePage.tsx
new file mode 100644
index 000000000..d3a4e66a0
--- /dev/null
+++ b/samples/basic/another-remote-module/src/dev/DevHomePage.tsx
@@ -0,0 +1,8 @@
+export function DevHomePage() {
+ return (
+
+
Another remote module development home page
+
Hey!
+
+ );
+}
diff --git a/sample/remote-module/src/dev/index.tsx b/samples/basic/another-remote-module/src/dev/index.tsx
similarity index 66%
rename from sample/remote-module/src/dev/index.tsx
rename to samples/basic/another-remote-module/src/dev/index.tsx
index 046ff94fa..0b01b35ba 100644
--- a/sample/remote-module/src/dev/index.tsx
+++ b/samples/basic/another-remote-module/src/dev/index.tsx
@@ -1,10 +1,11 @@
+import { registerShell } from "@basic/shell";
import { ConsoleLogger, Runtime, RuntimeContext, registerLocalModules } from "@squide/react-router";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
-import { register } from "../register.tsx";
+import { register as registerModule } from "../register.tsx";
import { App } from "./App.tsx";
-import { registerTabsPage } from "./registerTabsPage.tsx";
-import { sessionAccessor } from "./session.ts";
+import { registerDev } from "./register.tsx";
+import { sessionAccessor, sessionManager } from "./session.ts";
// Create the shell runtime.
// Services, loggers and sessionAccessor could be reuse through a shared packages or faked when in isolation.
@@ -13,9 +14,7 @@ const runtime = new Runtime({
sessionAccessor
});
-// Registering the remote module as a static module because the "register" function
-// is local when developing in isolation.
-registerLocalModules([register, registerTabsPage], runtime);
+registerLocalModules([registerShell(sessionManager), registerDev, registerModule], runtime);
const root = createRoot(document.getElementById("root")!);
diff --git a/samples/basic/another-remote-module/src/dev/register.tsx b/samples/basic/another-remote-module/src/dev/register.tsx
new file mode 100644
index 000000000..9628ce656
--- /dev/null
+++ b/samples/basic/another-remote-module/src/dev/register.tsx
@@ -0,0 +1,9 @@
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { DevHomePage } from "./DevHomePage.tsx";
+
+export const registerDev: ModuleRegisterFunction = runtime => {
+ runtime.registerRoute({
+ index: true,
+ element:
+ });
+};
diff --git a/sample/remote-module/src/dev/session.ts b/samples/basic/another-remote-module/src/dev/session.ts
similarity index 83%
rename from sample/remote-module/src/dev/session.ts
rename to samples/basic/another-remote-module/src/dev/session.ts
index de7dd2e90..3432fc0a9 100644
--- a/sample/remote-module/src/dev/session.ts
+++ b/samples/basic/another-remote-module/src/dev/session.ts
@@ -1,4 +1,4 @@
-import type { Session, SessionManager } from "@sample/shared";
+import type { Session, SessionManager } from "@basic/shared";
import { LocalStorageSessionManager } from "@squide/fakes";
import type { SessionAccessorFunction } from "@squide/react-router";
diff --git a/samples/basic/another-remote-module/src/register.tsx b/samples/basic/another-remote-module/src/register.tsx
new file mode 100644
index 000000000..3cef24975
--- /dev/null
+++ b/samples/basic/another-remote-module/src/register.tsx
@@ -0,0 +1,23 @@
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+
+function registerRoutes(runtime: Runtime) {
+ runtime.registerRoute({
+ path: "/federated-tabs",
+ lazy: async () => {
+ const { FederatedTabsLayout } = await import("@basic/shared/FederatedTabsLayout.tsx");
+
+ return {
+ element:
+ };
+ }
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Tabs",
+ to: "/federated-tabs"
+ });
+}
+
+export const register: ModuleRegisterFunction = runtime => {
+ registerRoutes(runtime);
+};
diff --git a/sample/another-remote-module/swc.build.js b/samples/basic/another-remote-module/swc.build.js
similarity index 100%
rename from sample/another-remote-module/swc.build.js
rename to samples/basic/another-remote-module/swc.build.js
diff --git a/sample/another-remote-module/swc.dev.js b/samples/basic/another-remote-module/swc.dev.js
similarity index 100%
rename from sample/another-remote-module/swc.dev.js
rename to samples/basic/another-remote-module/swc.dev.js
diff --git a/samples/basic/another-remote-module/tsconfig.json b/samples/basic/another-remote-module/tsconfig.json
new file mode 100644
index 000000000..6df5c8822
--- /dev/null
+++ b/samples/basic/another-remote-module/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "extends": "@workleap/typescript-configs/web-application.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"],
+ "@basic/shell": ["../shell/src/index.ts"],
+ "@basic/shared": ["../shared/src/index.ts"],
+ "@basic/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"]
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/sample/another-remote-module/webpack.build.js b/samples/basic/another-remote-module/webpack.build.js
similarity index 84%
rename from sample/another-remote-module/webpack.build.js
rename to samples/basic/another-remote-module/webpack.build.js
index 901112abf..4d719fb71 100644
--- a/sample/another-remote-module/webpack.build.js
+++ b/samples/basic/another-remote-module/webpack.build.js
@@ -4,11 +4,11 @@ import { defineBuildRemoteModuleConfig } from "@squide/webpack-module-federation
import { swcConfig } from "./swc.build.js";
// The trailing / is very important, otherwise paths will not be resolved correctly.
-const publicPath = process.env.NETLIFY === "true" ? "https://squide-another-remote-module.netlify.app/" : "http://localhost:8082/";
+const publicPath = process.env.NETLIFY === "true" ? "https://squide-basic-another-remote-module.netlify.app/" : "http://localhost:8082/";
export default defineBuildRemoteModuleConfig(swcConfig, "remote2", publicPath, {
sharedDependencies: {
- "@sample/shared": {
+ "@basic/shared": {
singleton: true
}
},
diff --git a/sample/another-remote-module/webpack.dev.js b/samples/basic/another-remote-module/webpack.dev.js
similarity index 79%
rename from sample/another-remote-module/webpack.dev.js
rename to samples/basic/another-remote-module/webpack.dev.js
index 1ab2db4f8..5ba9bfc0b 100644
--- a/sample/another-remote-module/webpack.dev.js
+++ b/samples/basic/another-remote-module/webpack.dev.js
@@ -7,10 +7,10 @@ import { swcConfig } from "./swc.dev.js";
let config;
-if (!process.env.LOCAL) {
+if (!process.env.ISOLATED) {
config = defineDevRemoteModuleConfig(swcConfig, "remote2", 8082, {
sharedDependencies: {
- "@sample/shared": {
+ "@basic/shared": {
singleton: true
}
},
@@ -20,7 +20,9 @@ if (!process.env.LOCAL) {
});
} else {
config = defineDevConfig(swcConfig, {
- entry: path.resolve("./src/dev/index.tsx")
+ cache: false,
+ entry: path.resolve("./src/dev/index.tsx"),
+ overlay: false
});
}
diff --git a/sample/host/.browserslistrc b/samples/basic/host/.browserslistrc
similarity index 100%
rename from sample/host/.browserslistrc
rename to samples/basic/host/.browserslistrc
diff --git a/sample/host/.eslintrc.json b/samples/basic/host/.eslintrc.json
similarity index 100%
rename from sample/host/.eslintrc.json
rename to samples/basic/host/.eslintrc.json
diff --git a/sample/host/_redirects b/samples/basic/host/_redirects
similarity index 100%
rename from sample/host/_redirects
rename to samples/basic/host/_redirects
diff --git a/sample/remote-module/nodemon.json b/samples/basic/host/nodemon.json
similarity index 100%
rename from sample/remote-module/nodemon.json
rename to samples/basic/host/nodemon.json
diff --git a/sample/host/package.json b/samples/basic/host/package.json
similarity index 65%
rename from sample/host/package.json
rename to samples/basic/host/package.json
index 99d343f52..137b6fa3c 100644
--- a/sample/host/package.json
+++ b/samples/basic/host/package.json
@@ -1,5 +1,5 @@
{
- "name": "@sample/host",
+ "name": "@basic/host",
"author": "Workleap",
"version": "0.0.0",
"description": "Host application to showcase @squide.",
@@ -11,37 +11,38 @@
"build": "pnpm build:webpack && pnpm build:copy-redirects",
"build:webpack": "webpack --config webpack.build.js",
"build:copy-redirects": "copyfiles _redirects dist",
+ "build:copy-public-files": "copyfiles -u 1 public/favicon.png dist",
"serve-build": "pnpm build && pnpm http-server dist -p 8080 -P http://localhost:8080? -c-1"
},
"devDependencies": {
- "@swc/core": "1.3.86",
- "@swc/helpers": "0.5.2",
- "@types/react": "18.2.22",
- "@types/react-dom": "18.2.7",
- "@types/webpack": "5.28.2",
+ "@squide/fakes": "workspace:*",
+ "@swc/core": "1.3.93",
+ "@swc/helpers": "0.5.3",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@types/webpack": "5.28.3",
"@workleap/browserslist-config": "2.0.0",
- "@workleap/eslint-plugin": "2.1.1",
+ "@workleap/eslint-plugin": "3.0.0",
"@workleap/swc-configs": "2.1.2",
"@workleap/typescript-configs": "3.0.2",
- "@workleap/webpack-configs": "1.0.8",
- "browserslist": "4.21.10",
+ "@workleap/webpack-configs": "1.1.0",
+ "browserslist": "4.22.1",
"copyfiles": "2.4.1",
"http-server": "14.1.1",
"nodemon": "3.0.1",
"typescript": "5.2.2",
- "webpack": "5.88.2",
+ "webpack": "5.89.0",
"webpack-cli": "5.1.4",
"webpack-dev-server": "4.15.1"
},
"dependencies": {
- "@sample/local-module": "workspace:*",
- "@sample/shared": "workspace:*",
- "@sample/shell": "workspace:*",
- "@squide/fakes": "workspace:*",
+ "@basic/local-module": "workspace:*",
+ "@basic/shared": "workspace:*",
+ "@basic/shell": "workspace:*",
"@squide/react-router": "workspace:*",
"@squide/webpack-module-federation": "workspace:*",
"react": "18.2.0",
"react-dom": "18.2.0",
- "react-router-dom": "6.16.0"
+ "react-router-dom": "6.17.0"
}
}
diff --git a/sample/host/public/favicon.png b/samples/basic/host/public/favicon.png
similarity index 100%
rename from sample/host/public/favicon.png
rename to samples/basic/host/public/favicon.png
diff --git a/sample/host/public/index.html b/samples/basic/host/public/index.html
similarity index 100%
rename from sample/host/public/index.html
rename to samples/basic/host/public/index.html
diff --git a/samples/basic/host/src/App.tsx b/samples/basic/host/src/App.tsx
new file mode 100644
index 000000000..e4b0d3f46
--- /dev/null
+++ b/samples/basic/host/src/App.tsx
@@ -0,0 +1,10 @@
+import { BackgroundColorContext } from "@basic/shared";
+import { AppRouter } from "@basic/shell";
+
+export function App() {
+ return (
+
+
+
+ );
+}
diff --git a/samples/basic/host/src/HomePage.tsx b/samples/basic/host/src/HomePage.tsx
new file mode 100644
index 000000000..67e69ac92
--- /dev/null
+++ b/samples/basic/host/src/HomePage.tsx
@@ -0,0 +1,11 @@
+export function HomePage() {
+ return (
+ <>
+ Home Page
+ This page is served by @basic/host
+ Hey! Welcome to this basic sample showcasing a few features of Squide.
+ >
+ );
+}
+
+export const Component = HomePage;
diff --git a/samples/basic/host/src/OfficevibeTab.tsx b/samples/basic/host/src/OfficevibeTab.tsx
new file mode 100644
index 000000000..fea1c1d07
--- /dev/null
+++ b/samples/basic/host/src/OfficevibeTab.tsx
@@ -0,0 +1,10 @@
+export function OfficevibeTab() {
+ return (
+ <>
+ Officevibe
+ This tab is served by @basic/host
+ >
+ );
+}
+
+export const Component = OfficevibeTab;
diff --git a/sample/host/src/bootstrap.tsx b/samples/basic/host/src/bootstrap.tsx
similarity index 57%
rename from sample/host/src/bootstrap.tsx
rename to samples/basic/host/src/bootstrap.tsx
index 3b041d3aa..413ba62d0 100644
--- a/sample/host/src/bootstrap.tsx
+++ b/samples/basic/host/src/bootstrap.tsx
@@ -1,20 +1,22 @@
-import { register as registerLocalModule } from "@sample/local-module";
-import { isNetlify, type AppContext } from "@sample/shared";
+import { registerLocalModule } from "@basic/local-module";
+import { isNetlify, type AppContext } from "@basic/shared";
+import { registerShell } from "@basic/shell";
import { ConsoleLogger, Runtime, RuntimeContext, registerLocalModules } from "@squide/react-router";
import { registerRemoteModules, type RemoteDefinition } from "@squide/webpack-module-federation";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { App } from "./App.tsx";
-import { sessionAccessor } from "./session.ts";
+import { registerHost } from "./register.tsx";
+import { sessionAccessor, sessionManager } from "./session.ts";
const Remotes: RemoteDefinition[] = [
{
name: "remote1",
- url: isNetlify ? "https://squide-remote-module.netlify.app" : "http://localhost:8081"
+ url: isNetlify ? "https://squide-basic-remote-module.netlify.app" : "http://localhost:8081"
},
{
name: "remote2",
- url: isNetlify ? "https://squide-another-remote-module.netlify.app" : "http://localhost:8082"
+ url: isNetlify ? "https://squide-basic-another-remote-module.netlify.app" : "http://localhost:8082"
}
];
@@ -27,7 +29,7 @@ const context: AppContext = {
name: "Test app"
};
-registerLocalModules([registerLocalModule], runtime, { context });
+registerLocalModules([registerShell(sessionManager, { host: "@basic/host" }), registerHost, registerLocalModule], runtime, { context });
registerRemoteModules(Remotes, runtime, { context });
diff --git a/sample/host/src/index.ts b/samples/basic/host/src/index.ts
similarity index 100%
rename from sample/host/src/index.ts
rename to samples/basic/host/src/index.ts
diff --git a/samples/basic/host/src/register.tsx b/samples/basic/host/src/register.tsx
new file mode 100644
index 000000000..bf2860e0a
--- /dev/null
+++ b/samples/basic/host/src/register.tsx
@@ -0,0 +1,24 @@
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+
+export const registerHost: ModuleRegisterFunction = runtime => {
+ runtime.registerRoute({
+ index: true,
+ lazy: () => import("./HomePage.tsx")
+ });
+
+ // Register federated tab.
+
+ runtime.registerRoute({
+ path: "/federated-tabs/officevibe",
+ lazy: () => import("./OfficevibeTab.tsx")
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Officevibe",
+ to: "/federated-tabs/officevibe"
+ }, {
+ menuId: "/federated-tabs"
+ });
+};
diff --git a/sample/host/src/session.ts b/samples/basic/host/src/session.ts
similarity index 83%
rename from sample/host/src/session.ts
rename to samples/basic/host/src/session.ts
index de7dd2e90..3432fc0a9 100644
--- a/sample/host/src/session.ts
+++ b/samples/basic/host/src/session.ts
@@ -1,4 +1,4 @@
-import type { Session, SessionManager } from "@sample/shared";
+import type { Session, SessionManager } from "@basic/shared";
import { LocalStorageSessionManager } from "@squide/fakes";
import type { SessionAccessorFunction } from "@squide/react-router";
diff --git a/sample/host/swc.build.js b/samples/basic/host/swc.build.js
similarity index 100%
rename from sample/host/swc.build.js
rename to samples/basic/host/swc.build.js
diff --git a/sample/host/swc.dev.js b/samples/basic/host/swc.dev.js
similarity index 100%
rename from sample/host/swc.dev.js
rename to samples/basic/host/swc.dev.js
diff --git a/samples/basic/host/tsconfig.json b/samples/basic/host/tsconfig.json
new file mode 100644
index 000000000..677fbc79d
--- /dev/null
+++ b/samples/basic/host/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "@workleap/typescript-configs/web-application.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"],
+ "@basic/shell": ["../shell/src/index.ts"],
+ "@basic/shared": ["../shared/src/index.ts"],
+ "@basic/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"],
+ "@basic/local-module": ["../local-module/src/register.ts"]
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/sample/host/webpack.build.js b/samples/basic/host/webpack.build.js
similarity index 78%
rename from sample/host/webpack.build.js
rename to samples/basic/host/webpack.build.js
index 815e9f443..1f8fc3f7c 100644
--- a/sample/host/webpack.build.js
+++ b/samples/basic/host/webpack.build.js
@@ -4,12 +4,13 @@ import { defineBuildHostConfig } from "@squide/webpack-module-federation/defineC
import { swcConfig } from "./swc.build.js";
// The trailing / is very important, otherwise paths will not be resolved correctly.
-const publicPath = process.env.NETLIFY === "true" ? "https://squide-host.netlify.app/" : "http://localhost:8080/";
+const publicPath = process.env.NETLIFY === "true" ? "https://squide-basic-host.netlify.app/" : "http://localhost:8080/";
export default defineBuildHostConfig(swcConfig, "host", publicPath, {
sharedDependencies: {
- "@sample/shared": {
- singleton: true
+ "@basic/shared": {
+ singleton: true,
+ eager: true
}
},
environmentVariables: {
diff --git a/sample/host/webpack.dev.js b/samples/basic/host/webpack.dev.js
similarity index 89%
rename from sample/host/webpack.dev.js
rename to samples/basic/host/webpack.dev.js
index 092270968..442f63890 100644
--- a/sample/host/webpack.dev.js
+++ b/samples/basic/host/webpack.dev.js
@@ -4,8 +4,9 @@ import { defineDevHostConfig } from "@squide/webpack-module-federation/defineCon
import { swcConfig } from "./swc.dev.js";
export default defineDevHostConfig(swcConfig, "host", 8080, {
+ overlay: false,
sharedDependencies: {
- "@sample/shared": {
+ "@basic/shared": {
singleton: true,
eager: true
}
diff --git a/sample/local-module/.browserslistrc b/samples/basic/local-module/.browserslistrc
similarity index 100%
rename from sample/local-module/.browserslistrc
rename to samples/basic/local-module/.browserslistrc
diff --git a/sample/local-module/.eslintrc.json b/samples/basic/local-module/.eslintrc.json
similarity index 100%
rename from sample/local-module/.eslintrc.json
rename to samples/basic/local-module/.eslintrc.json
diff --git a/sample/local-module/nodemon.local.json b/samples/basic/local-module/nodemon.isolated.json
similarity index 100%
rename from sample/local-module/nodemon.local.json
rename to samples/basic/local-module/nodemon.isolated.json
diff --git a/sample/local-module/nodemon.json b/samples/basic/local-module/nodemon.json
similarity index 100%
rename from sample/local-module/nodemon.json
rename to samples/basic/local-module/nodemon.json
diff --git a/sample/local-module/package.json b/samples/basic/local-module/package.json
similarity index 63%
rename from sample/local-module/package.json
rename to samples/basic/local-module/package.json
index f10d3a378..7e2cf6bc9 100644
--- a/sample/local-module/package.json
+++ b/samples/basic/local-module/package.json
@@ -1,5 +1,5 @@
{
- "name": "@sample/local-module",
+ "name": "@basic/local-module",
"author": "Workleap",
"version": "0.0.0",
"description": "Local module to showcase @squide.",
@@ -15,43 +15,47 @@
},
"scripts": {
"dev": "nodemon",
- "dev-local": "nodemon --config nodemon.local.json",
+ "dev-isolated": "nodemon --config nodemon.isolated.json",
"build": "tsup --config ./tsup.build.ts",
"serve-build": "pnpm build"
},
"peerDependencies": {
+ "@basic/shared": "*",
+ "@basic/shell": "*",
+ "@squide/fakes": "*",
+ "@squide/react-router": "*",
"react": "*",
"react-dom": "*",
"react-router-dom": "*"
},
"devDependencies": {
- "@swc/core": "1.3.86",
- "@swc/helpers": "0.5.2",
- "@types/react": "18.2.22",
- "@types/react-dom": "18.2.7",
- "@types/webpack": "5.28.2",
+ "@swc/core": "1.3.93",
+ "@swc/helpers": "0.5.3",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@types/webpack": "5.28.3",
"@workleap/browserslist-config": "2.0.0",
- "@workleap/eslint-plugin": "2.1.1",
+ "@workleap/eslint-plugin": "3.0.0",
"@workleap/swc-configs": "2.1.2",
"@workleap/tsup-configs": "3.0.1",
"@workleap/typescript-configs": "3.0.2",
- "@workleap/webpack-configs": "1.0.8",
- "browserslist": "4.21.10",
+ "@workleap/webpack-configs": "1.1.0",
+ "browserslist": "4.22.1",
"cross-env": "7.0.3",
"nodemon": "3.0.1",
"tsup": "7.2.0",
"typescript": "5.2.2",
- "webpack": "5.88.2",
+ "webpack": "5.89.0",
"webpack-cli": "5.1.4",
"webpack-dev-server": "4.15.1"
},
"dependencies": {
- "@sample/shared": "workspace:*",
- "@sample/shell": "workspace:*",
+ "@basic/shared": "workspace:*",
+ "@basic/shell": "workspace:*",
"@squide/fakes": "workspace:*",
"@squide/react-router": "workspace:*",
"react": "18.2.0",
"react-dom": "18.2.0",
- "react-router-dom": "6.16.0"
+ "react-router-dom": "6.17.0"
}
}
diff --git a/sample/local-module/public/index.html b/samples/basic/local-module/public/index.html
similarity index 100%
rename from sample/local-module/public/index.html
rename to samples/basic/local-module/public/index.html
diff --git a/samples/basic/local-module/src/MessagePage.tsx b/samples/basic/local-module/src/MessagePage.tsx
new file mode 100644
index 000000000..5a982f451
--- /dev/null
+++ b/samples/basic/local-module/src/MessagePage.tsx
@@ -0,0 +1,42 @@
+import { useApplicationEventBusDispatcher } from "@basic/shared";
+import { useCallback, useState, type ChangeEvent } from "react";
+import { Link } from "react-router-dom";
+
+export function MessagePage() {
+ const [message, setMessage] = useState("");
+
+ const handleTextChange = useCallback((event: ChangeEvent) => {
+ setMessage(event.target.value);
+ }, []);
+
+ const dispatch = useApplicationEventBusDispatcher();
+
+ const handleSendMessage = useCallback(() => {
+ dispatch("write-to-host", message);
+ setMessage("");
+ }, [dispatch, setMessage, message]);
+
+ return (
+ <>
+ Messaging
+ This page is served by @basic/local-module
+
+
There are a few distinctive features that are showcased with this pages:
+
+ The navigation item for this page has a priority of 999
, which renders it as the first item of the navbar.
+ The navigation item for this page use custom additional props to highlight
the item in the navbar.
+ The "Send a message" feature showcase how Squide's event bus works.
+
+
+ Send a message
+ Send the following to the host application:
+
+
+ Send
+ Hint: have a look at your console log once the message has been sent :)
+ Go back to home
+ >
+ );
+}
+
+export const Component = MessagePage;
diff --git a/samples/basic/local-module/src/WorkleapTab.tsx b/samples/basic/local-module/src/WorkleapTab.tsx
new file mode 100644
index 000000000..d2158f15d
--- /dev/null
+++ b/samples/basic/local-module/src/WorkleapTab.tsx
@@ -0,0 +1,16 @@
+export function WorkleapTab() {
+ return (
+ <>
+ Workleap
+ This tab is served by @basic/local-module
+
+
There are a few distinctive features that are showcased with this tab:
+
+ The tab is marked as the index
, which makes him the default tab to be showned.
+
+
+ >
+ );
+}
+
+export const Component = WorkleapTab;
diff --git a/samples/basic/local-module/src/dev/App.tsx b/samples/basic/local-module/src/dev/App.tsx
new file mode 100644
index 000000000..0dd186ccd
--- /dev/null
+++ b/samples/basic/local-module/src/dev/App.tsx
@@ -0,0 +1,5 @@
+import { AppRouter } from "@basic/shell";
+
+export function App() {
+ return ;
+}
diff --git a/sample/another-remote-module/src/dev/DevHome.tsx b/samples/basic/local-module/src/dev/DevHome.tsx
similarity index 78%
rename from sample/another-remote-module/src/dev/DevHome.tsx
rename to samples/basic/local-module/src/dev/DevHome.tsx
index 8b9043ec5..113d1f3d9 100644
--- a/sample/another-remote-module/src/dev/DevHome.tsx
+++ b/samples/basic/local-module/src/dev/DevHome.tsx
@@ -1,4 +1,4 @@
-export default function DevHome() {
+export function DevHome() {
return (
Remote module development home page
diff --git a/sample/local-module/src/dev/index.tsx b/samples/basic/local-module/src/dev/index.tsx
similarity index 66%
rename from sample/local-module/src/dev/index.tsx
rename to samples/basic/local-module/src/dev/index.tsx
index 046ff94fa..42d730435 100644
--- a/sample/local-module/src/dev/index.tsx
+++ b/samples/basic/local-module/src/dev/index.tsx
@@ -1,10 +1,11 @@
+import { registerShell } from "@basic/shell";
import { ConsoleLogger, Runtime, RuntimeContext, registerLocalModules } from "@squide/react-router";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
-import { register } from "../register.tsx";
+import { registerLocalModule } from "../register.tsx";
import { App } from "./App.tsx";
-import { registerTabsPage } from "./registerTabsPage.tsx";
-import { sessionAccessor } from "./session.ts";
+import { registerDev } from "./register.tsx";
+import { sessionAccessor, sessionManager } from "./session.ts";
// Create the shell runtime.
// Services, loggers and sessionAccessor could be reuse through a shared packages or faked when in isolation.
@@ -13,9 +14,7 @@ const runtime = new Runtime({
sessionAccessor
});
-// Registering the remote module as a static module because the "register" function
-// is local when developing in isolation.
-registerLocalModules([register, registerTabsPage], runtime);
+registerLocalModules([registerShell(sessionManager), registerDev, registerLocalModule], runtime);
const root = createRoot(document.getElementById("root")!);
diff --git a/samples/basic/local-module/src/dev/register.tsx b/samples/basic/local-module/src/dev/register.tsx
new file mode 100644
index 000000000..126befcb1
--- /dev/null
+++ b/samples/basic/local-module/src/dev/register.tsx
@@ -0,0 +1,19 @@
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { DevHome } from "./DevHome.tsx";
+
+export const registerDev: ModuleRegisterFunction
= runtime => {
+ runtime.registerRoute({
+ index: true,
+ element:
+ });
+
+ runtime.registerRoute({
+ path: "/federated-tabs",
+ lazy: () => import("@basic/shared/FederatedTabsLayout.tsx")
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Tabs",
+ to: "/federated-tabs"
+ });
+};
diff --git a/sample/local-module/src/dev/session.ts b/samples/basic/local-module/src/dev/session.ts
similarity index 83%
rename from sample/local-module/src/dev/session.ts
rename to samples/basic/local-module/src/dev/session.ts
index de7dd2e90..3432fc0a9 100644
--- a/sample/local-module/src/dev/session.ts
+++ b/samples/basic/local-module/src/dev/session.ts
@@ -1,4 +1,4 @@
-import type { Session, SessionManager } from "@sample/shared";
+import type { Session, SessionManager } from "@basic/shared";
import { LocalStorageSessionManager } from "@squide/fakes";
import type { SessionAccessorFunction } from "@squide/react-router";
diff --git a/samples/basic/local-module/src/register.tsx b/samples/basic/local-module/src/register.tsx
new file mode 100644
index 000000000..a05f90a75
--- /dev/null
+++ b/samples/basic/local-module/src/register.tsx
@@ -0,0 +1,42 @@
+import type { AppContext } from "@basic/shared";
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+
+function registerRoutes(runtime: Runtime) {
+ runtime.registerRoute({
+ path: "/message",
+ lazy: () => import("./MessagePage.tsx")
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Message",
+ // Higher numbers gets rendered first.
+ $priority: 999,
+ // Will be forwarded to the host application render function.
+ $additionalProps: {
+ highlight: true
+ },
+ to: "/message"
+ });
+
+ // Register federated tabs.
+
+ runtime.registerRoute({
+ index: true,
+ lazy: () => import("./WorkleapTab.tsx")
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Workleap",
+ to: "/federated-tabs"
+ }, {
+ menuId: "/federated-tabs"
+ });
+}
+
+export const registerLocalModule: ModuleRegisterFunction = (runtime, context) => {
+ console.log("Local module context: ", context);
+
+ registerRoutes(runtime);
+};
diff --git a/sample/local-module/swc.config.js b/samples/basic/local-module/swc.config.js
similarity index 100%
rename from sample/local-module/swc.config.js
rename to samples/basic/local-module/swc.config.js
diff --git a/samples/basic/local-module/tsconfig.json b/samples/basic/local-module/tsconfig.json
new file mode 100644
index 000000000..78cd9986f
--- /dev/null
+++ b/samples/basic/local-module/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "extends": "@workleap/typescript-configs/library.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"],
+ "@basic/shell": ["../shell/src/index.ts"],
+ "@basic/shared": ["../shared/src/index.ts"],
+ "@basic/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"]
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/sample/shared/tsup.build.ts b/samples/basic/local-module/tsup.build.ts
similarity index 100%
rename from sample/shared/tsup.build.ts
rename to samples/basic/local-module/tsup.build.ts
diff --git a/sample/shared/tsup.dev.ts b/samples/basic/local-module/tsup.dev.ts
similarity index 100%
rename from sample/shared/tsup.dev.ts
rename to samples/basic/local-module/tsup.dev.ts
diff --git a/sample/local-module/webpack.config.js b/samples/basic/local-module/webpack.config.js
similarity index 70%
rename from sample/local-module/webpack.config.js
rename to samples/basic/local-module/webpack.config.js
index 442f96b30..b40ae89ea 100644
--- a/sample/local-module/webpack.config.js
+++ b/samples/basic/local-module/webpack.config.js
@@ -5,6 +5,8 @@ import path from "node:path";
import { swcConfig } from "./swc.config.js";
export default defineDevConfig(swcConfig, {
- entry: path.resolve("./src/dev/index.tsx")
+ cache: false,
+ entry: path.resolve("./src/dev/index.tsx"),
+ overlay: false
});
diff --git a/sample/remote-module/.browserslistrc b/samples/basic/remote-module/.browserslistrc
similarity index 100%
rename from sample/remote-module/.browserslistrc
rename to samples/basic/remote-module/.browserslistrc
diff --git a/sample/remote-module/.eslintrc.json b/samples/basic/remote-module/.eslintrc.json
similarity index 100%
rename from sample/remote-module/.eslintrc.json
rename to samples/basic/remote-module/.eslintrc.json
diff --git a/samples/basic/remote-module/nodemon.json b/samples/basic/remote-module/nodemon.json
new file mode 100644
index 000000000..7a5919df8
--- /dev/null
+++ b/samples/basic/remote-module/nodemon.json
@@ -0,0 +1,5 @@
+{
+ "watch": ["swc.dev.js", "webpack.dev.js"],
+ "exec": "webpack serve --config webpack.dev.js",
+ "verbose": true
+}
diff --git a/sample/remote-module/package.json b/samples/basic/remote-module/package.json
similarity index 64%
rename from sample/remote-module/package.json
rename to samples/basic/remote-module/package.json
index 710f2b848..cde8fafc7 100644
--- a/sample/remote-module/package.json
+++ b/samples/basic/remote-module/package.json
@@ -1,5 +1,5 @@
{
- "name": "@sample/remote-module",
+ "name": "@basic/remote-module",
"author": "Workleap",
"version": "0.0.0",
"description": "Remote module to showcase @squide.",
@@ -8,38 +8,38 @@
"type": "module",
"scripts": {
"dev": "nodemon",
- "dev-local": "cross-env LOCAL=true nodemon",
+ "dev-isolated": "cross-env ISOLATED=true nodemon",
"build": "webpack --config webpack.build.js",
"serve-build": "pnpm build && pnpm http-server dist -p 8081 -P http://localhost:8081? -c-1"
},
"devDependencies": {
- "@swc/core": "1.3.86",
- "@swc/helpers": "0.5.2",
- "@types/react": "18.2.22",
- "@types/react-dom": "18.2.7",
- "@types/webpack": "5.28.2",
+ "@swc/core": "1.3.93",
+ "@swc/helpers": "0.5.3",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@types/webpack": "5.28.3",
"@workleap/browserslist-config": "2.0.0",
- "@workleap/eslint-plugin": "2.1.1",
+ "@workleap/eslint-plugin": "3.0.0",
"@workleap/swc-configs": "2.1.2",
"@workleap/typescript-configs": "3.0.2",
- "@workleap/webpack-configs": "1.0.8",
- "browserslist": "4.21.10",
+ "@workleap/webpack-configs": "1.1.0",
+ "browserslist": "4.22.1",
"cross-env": "7.0.3",
"http-server": "14.1.1",
"nodemon": "3.0.1",
"typescript": "5.2.2",
- "webpack": "5.88.2",
+ "webpack": "5.89.0",
"webpack-cli": "5.1.4",
"webpack-dev-server": "4.15.1"
},
"dependencies": {
- "@sample/shared": "workspace:*",
- "@sample/shell": "workspace:*",
+ "@basic/shared": "workspace:*",
+ "@basic/shell": "workspace:*",
"@squide/fakes": "workspace:*",
"@squide/react-router": "workspace:*",
"@squide/webpack-module-federation": "workspace:*",
"react": "18.2.0",
"react-dom": "18.2.0",
- "react-router-dom": "6.16.0"
+ "react-router-dom": "6.17.0"
}
}
diff --git a/sample/remote-module/public/index.html b/samples/basic/remote-module/public/index.html
similarity index 100%
rename from sample/remote-module/public/index.html
rename to samples/basic/remote-module/public/index.html
diff --git a/samples/basic/remote-module/src/ColoredPage.tsx b/samples/basic/remote-module/src/ColoredPage.tsx
new file mode 100644
index 000000000..8817514b2
--- /dev/null
+++ b/samples/basic/remote-module/src/ColoredPage.tsx
@@ -0,0 +1,27 @@
+import { useBackgroundColor } from "@basic/shared";
+import { Link } from "react-router-dom";
+
+export function ColoredPage() {
+ const backgroundColor = useBackgroundColor();
+
+ return (
+ <>
+ Colored page
+ This page is served by @basic/remote-module
+
+
There are a few distinctive features that are showcased with this page:
+
+ This page demonstrates that a React context defined in an host application can be overried in a remote module.
+ {/* eslint-disable-next-line max-len */}
+ The host application React context define that background color as blue and the nested React context in the remote module override the background color to be red .
+ Toggle between the Context override and No context override pages to view the difference.
+
+
+
+
The background color is "{backgroundColor}"
+
+ >
+ );
+}
+
+export const Component = ColoredPage;
diff --git a/samples/basic/remote-module/src/CustomLayout.tsx b/samples/basic/remote-module/src/CustomLayout.tsx
new file mode 100644
index 000000000..54b03f125
--- /dev/null
+++ b/samples/basic/remote-module/src/CustomLayout.tsx
@@ -0,0 +1,13 @@
+import { Outlet } from "react-router-dom";
+
+export function CustomLayout() {
+ return (
+
+
Custom layout
+
This layout is served by @basic/remote-module
+
+
+ );
+}
+
+export const Component = CustomLayout;
diff --git a/samples/basic/remote-module/src/HoistedPage.tsx b/samples/basic/remote-module/src/HoistedPage.tsx
new file mode 100644
index 000000000..04ddc81cf
--- /dev/null
+++ b/samples/basic/remote-module/src/HoistedPage.tsx
@@ -0,0 +1,21 @@
+import { Link } from "react-router-dom";
+
+export function HoistedPage() {
+ return (
+ <>
+ Hoisted
+ This page is served by @basic/remote-module
+
+
There are a few distinctive features that are showcased with this page:
+
+ This page is using Squide hoist feature, meaning that it doesn't inherit from the root layout and error boundary.
+ This page navigation item's label is defined with a custom component, allowing the navigation item color to be rendered green.
+
+
+ This is an hoisted page!
+ Go back to home
+ >
+ );
+}
+
+export const Component = HoistedPage;
diff --git a/samples/basic/remote-module/src/SkillsTab.tsx b/samples/basic/remote-module/src/SkillsTab.tsx
new file mode 100644
index 000000000..34af4fa60
--- /dev/null
+++ b/samples/basic/remote-module/src/SkillsTab.tsx
@@ -0,0 +1,16 @@
+export function SkillsTab() {
+ return (
+ <>
+ Skills
+ This tab is served by @basic/remote-module
+
+
There are a few distinctive features that are showcased with this tab:
+
+ The tab has a priority of 999
, which renders it as the first tab header.
+
+
+ >
+ );
+}
+
+export const Component = SkillsTab;
diff --git a/samples/basic/remote-module/src/dev/App.tsx b/samples/basic/remote-module/src/dev/App.tsx
new file mode 100644
index 000000000..217247939
--- /dev/null
+++ b/samples/basic/remote-module/src/dev/App.tsx
@@ -0,0 +1,11 @@
+import { BackgroundColorContext } from "@basic/shared";
+import { AppRouter } from "@basic/shell";
+
+export function App() {
+ return (
+
+
+
+ );
+}
+
diff --git a/sample/remote-module/src/dev/DevHome.tsx b/samples/basic/remote-module/src/dev/DevHome.tsx
similarity index 78%
rename from sample/remote-module/src/dev/DevHome.tsx
rename to samples/basic/remote-module/src/dev/DevHome.tsx
index 8b9043ec5..113d1f3d9 100644
--- a/sample/remote-module/src/dev/DevHome.tsx
+++ b/samples/basic/remote-module/src/dev/DevHome.tsx
@@ -1,4 +1,4 @@
-export default function DevHome() {
+export function DevHome() {
return (
Remote module development home page
diff --git a/sample/another-remote-module/src/dev/index.tsx b/samples/basic/remote-module/src/dev/index.tsx
similarity index 71%
rename from sample/another-remote-module/src/dev/index.tsx
rename to samples/basic/remote-module/src/dev/index.tsx
index c5fc3269a..af125f7c2 100644
--- a/sample/another-remote-module/src/dev/index.tsx
+++ b/samples/basic/remote-module/src/dev/index.tsx
@@ -1,9 +1,11 @@
+import { registerShell } from "@basic/shell";
import { ConsoleLogger, Runtime, RuntimeContext, registerLocalModules } from "@squide/react-router";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
-import { register } from "../register.tsx";
+import { register as registerModule } from "../register.tsx";
import { App } from "./App.tsx";
-import { sessionAccessor } from "./session.ts";
+import { registerDev } from "./register.tsx";
+import { sessionAccessor, sessionManager } from "./session.ts";
// Create the shell runtime.
// Services, loggers and sessionAccessor could be reuse through a shared packages or faked when in isolation.
@@ -14,7 +16,7 @@ const runtime = new Runtime({
// Registering the remote module as a static module because the "register" function
// is local when developing in isolation.
-registerLocalModules([register], runtime);
+registerLocalModules([registerShell(sessionManager), registerDev, registerModule], runtime);
const root = createRoot(document.getElementById("root")!);
diff --git a/samples/basic/remote-module/src/dev/register.tsx b/samples/basic/remote-module/src/dev/register.tsx
new file mode 100644
index 000000000..126befcb1
--- /dev/null
+++ b/samples/basic/remote-module/src/dev/register.tsx
@@ -0,0 +1,19 @@
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { DevHome } from "./DevHome.tsx";
+
+export const registerDev: ModuleRegisterFunction
= runtime => {
+ runtime.registerRoute({
+ index: true,
+ element:
+ });
+
+ runtime.registerRoute({
+ path: "/federated-tabs",
+ lazy: () => import("@basic/shared/FederatedTabsLayout.tsx")
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Tabs",
+ to: "/federated-tabs"
+ });
+};
diff --git a/sample/another-remote-module/src/dev/session.ts b/samples/basic/remote-module/src/dev/session.ts
similarity index 83%
rename from sample/another-remote-module/src/dev/session.ts
rename to samples/basic/remote-module/src/dev/session.ts
index de7dd2e90..3432fc0a9 100644
--- a/sample/another-remote-module/src/dev/session.ts
+++ b/samples/basic/remote-module/src/dev/session.ts
@@ -1,4 +1,4 @@
-import type { Session, SessionManager } from "@sample/shared";
+import type { Session, SessionManager } from "@basic/shared";
import { LocalStorageSessionManager } from "@squide/fakes";
import type { SessionAccessorFunction } from "@squide/react-router";
diff --git a/samples/basic/remote-module/src/register.tsx b/samples/basic/remote-module/src/register.tsx
new file mode 100644
index 000000000..921e4064b
--- /dev/null
+++ b/samples/basic/remote-module/src/register.tsx
@@ -0,0 +1,90 @@
+import { BackgroundColorContext } from "@basic/shared";
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+
+function registerRoutes(runtime: Runtime) {
+ runtime.registerRoute({
+ path: "/hoisted",
+ lazy: () => import("./CustomLayout.tsx"),
+ children: [
+ {
+ index: true,
+ lazy: () => import("./HoistedPage.tsx")
+ }
+ ]
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ path: "/no-context-override",
+ lazy: () => import("./ColoredPage.tsx")
+ });
+
+ runtime.registerRoute({
+ path: "/context-override",
+ lazy: async () => {
+ const { ColoredPage } = await import("./ColoredPage.tsx");
+
+ return {
+ element: (
+
+
+
+ )
+ };
+ }
+ });
+
+ runtime.registerNavigationItem({
+ $label: Hoisted ,
+ to: "/hoisted"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Section",
+ $priority: -30,
+ children: [
+ {
+ to: "#",
+ $label: "Child 1"
+ },
+ {
+ to: "#",
+ $label: "Child 2"
+ }
+ ]
+ });
+
+ runtime.registerNavigationItem({
+ $label: "No context override",
+ $priority: -20,
+ to: "/no-context-override"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Context override",
+ $priority: -10,
+ to: "/context-override"
+ });
+
+ // Register federated tab.
+
+ runtime.registerRoute({
+ path: "/federated-tabs/skills",
+ lazy: () => import("./SkillsTab.tsx")
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Skills",
+ $priority: 999,
+ to: "/federated-tabs/skills"
+ }, {
+ menuId: "/federated-tabs"
+ });
+}
+
+export const register: ModuleRegisterFunction = runtime => {
+ registerRoutes(runtime);
+};
diff --git a/sample/remote-module/swc.build.js b/samples/basic/remote-module/swc.build.js
similarity index 100%
rename from sample/remote-module/swc.build.js
rename to samples/basic/remote-module/swc.build.js
diff --git a/sample/remote-module/swc.dev.js b/samples/basic/remote-module/swc.dev.js
similarity index 100%
rename from sample/remote-module/swc.dev.js
rename to samples/basic/remote-module/swc.dev.js
diff --git a/samples/basic/remote-module/tsconfig.json b/samples/basic/remote-module/tsconfig.json
new file mode 100644
index 000000000..6df5c8822
--- /dev/null
+++ b/samples/basic/remote-module/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "extends": "@workleap/typescript-configs/web-application.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"],
+ "@basic/shell": ["../shell/src/index.ts"],
+ "@basic/shared": ["../shared/src/index.ts"],
+ "@basic/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"]
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/sample/remote-module/webpack.build.js b/samples/basic/remote-module/webpack.build.js
similarity index 85%
rename from sample/remote-module/webpack.build.js
rename to samples/basic/remote-module/webpack.build.js
index 9197cf8ab..eafe5f592 100644
--- a/sample/remote-module/webpack.build.js
+++ b/samples/basic/remote-module/webpack.build.js
@@ -4,11 +4,11 @@ import { defineBuildRemoteModuleConfig } from "@squide/webpack-module-federation
import { swcConfig } from "./swc.build.js";
// The trailing / is very important, otherwise paths will not be resolved correctly.
-const publicPath = process.env.NETLIFY === "true" ? "https://squide-remote-module.netlify.app/" : "http://localhost:8081/";
+const publicPath = process.env.NETLIFY === "true" ? "https://squide-basic-remote-module.netlify.app/" : "http://localhost:8081/";
export default defineBuildRemoteModuleConfig(swcConfig, "remote1", publicPath, {
sharedDependencies: {
- "@sample/shared": {
+ "@basic/shared": {
singleton: true
}
},
diff --git a/sample/remote-module/webpack.dev.js b/samples/basic/remote-module/webpack.dev.js
similarity index 79%
rename from sample/remote-module/webpack.dev.js
rename to samples/basic/remote-module/webpack.dev.js
index 4e29997c1..830bcc7b2 100644
--- a/sample/remote-module/webpack.dev.js
+++ b/samples/basic/remote-module/webpack.dev.js
@@ -7,10 +7,10 @@ import { swcConfig } from "./swc.dev.js";
let config;
-if (!process.env.LOCAL) {
+if (!process.env.ISOLATED) {
config = defineDevRemoteModuleConfig(swcConfig, "remote1", 8081, {
sharedDependencies: {
- "@sample/shared": {
+ "@basic/shared": {
singleton: true
}
},
@@ -20,7 +20,9 @@ if (!process.env.LOCAL) {
});
} else {
config = defineDevConfig(swcConfig, {
- entry: path.resolve("./src/dev/index.tsx")
+ cache: false,
+ entry: path.resolve("./src/dev/index.tsx"),
+ overlay: false
});
}
diff --git a/sample/shared/.eslintrc.json b/samples/basic/shared/.eslintrc.json
similarity index 100%
rename from sample/shared/.eslintrc.json
rename to samples/basic/shared/.eslintrc.json
diff --git a/sample/shared/nodemon.json b/samples/basic/shared/nodemon.json
similarity index 100%
rename from sample/shared/nodemon.json
rename to samples/basic/shared/nodemon.json
diff --git a/sample/shared/package.json b/samples/basic/shared/package.json
similarity index 83%
rename from sample/shared/package.json
rename to samples/basic/shared/package.json
index e41d19ca7..03db34e7d 100644
--- a/sample/shared/package.json
+++ b/samples/basic/shared/package.json
@@ -1,5 +1,5 @@
{
- "name": "@sample/shared",
+ "name": "@basic/shared",
"author": "Workleap",
"version": "0.0.0",
"description": "Shared package to showcase @squide.",
@@ -30,17 +30,17 @@
"react-router-dom": "*"
},
"devDependencies": {
- "@remix-run/router": "1.9.0",
+ "@remix-run/router": "1.10.0",
"@squide/react-router": "workspace:*",
- "@types/react": "18.2.22",
- "@types/react-dom": "18.2.7",
- "@workleap/eslint-plugin": "2.1.1",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@workleap/eslint-plugin": "3.0.0",
"@workleap/tsup-configs": "3.0.1",
"@workleap/typescript-configs": "3.0.2",
"nodemon": "3.0.1",
"react": "18.2.0",
"react-dom": "18.2.0",
- "react-router-dom": "6.16.0",
+ "react-router-dom": "6.17.0",
"tsup": "7.2.0",
"typescript": "5.2.2"
}
diff --git a/sample/shared/src/BackgroundColorContext.ts b/samples/basic/shared/src/BackgroundColorContext.ts
similarity index 100%
rename from sample/shared/src/BackgroundColorContext.ts
rename to samples/basic/shared/src/BackgroundColorContext.ts
diff --git a/sample/shared/src/FederatedTabsLayout.tsx b/samples/basic/shared/src/FederatedTabsLayout.tsx
similarity index 50%
rename from sample/shared/src/FederatedTabsLayout.tsx
rename to samples/basic/shared/src/FederatedTabsLayout.tsx
index 922455d9c..0f1a3efa1 100644
--- a/sample/shared/src/FederatedTabsLayout.tsx
+++ b/samples/basic/shared/src/FederatedTabsLayout.tsx
@@ -2,6 +2,10 @@ import { useNavigationItems, useRenderedNavigationItems, type NavigationLinkRend
import { Suspense } from "react";
import { Link, Outlet } from "react-router-dom";
+export interface FederatedTabsLayoutProps {
+ host?: string;
+}
+
const renderItem: RenderItemFunction = (item, index, level) => {
const { label, linkProps } = item as NavigationLinkRenderProps;
@@ -22,21 +26,33 @@ const renderSection: RenderSectionFunction = elements => {
);
};
-export default function FederatedTabsLayout() {
+export function FederatedTabsLayout({ host }: FederatedTabsLayoutProps) {
const navigationItems = useNavigationItems("/federated-tabs");
const renderedTabs = useRenderedNavigationItems(navigationItems, renderItem, renderSection);
return (
-
-
Every tab is registered by a different module and is lazy loaded.
+ <>
+
Tabs
+ {host &&
This layout is served by {host}
}
+
+
There are a few distinctive features that are showcased with this pages:
+
+ This is a nested layout that renders tabs registered by distinct modules . This is what we call "Federated Tabs".
+ Every tab is lazy loaded with React Router.
+ Every tab has its own URL, allowing direct hit to the tab.
+ This layout takes cares of rendering a loading screen while a tab is being loaded.
+
+
{renderedTabs}
-
-
+ >
);
}
+export const Component = FederatedTabsLayout;
+
diff --git a/sample/shared/src/appContext.ts b/samples/basic/shared/src/appContext.ts
similarity index 100%
rename from sample/shared/src/appContext.ts
rename to samples/basic/shared/src/appContext.ts
diff --git a/sample/shared/src/eventBus.ts b/samples/basic/shared/src/eventBus.ts
similarity index 100%
rename from sample/shared/src/eventBus.ts
rename to samples/basic/shared/src/eventBus.ts
diff --git a/sample/shared/src/index.ts b/samples/basic/shared/src/index.ts
similarity index 100%
rename from sample/shared/src/index.ts
rename to samples/basic/shared/src/index.ts
diff --git a/sample/shared/src/isNetlify.ts b/samples/basic/shared/src/isNetlify.ts
similarity index 100%
rename from sample/shared/src/isNetlify.ts
rename to samples/basic/shared/src/isNetlify.ts
diff --git a/sample/shared/src/session.ts b/samples/basic/shared/src/session.ts
similarity index 100%
rename from sample/shared/src/session.ts
rename to samples/basic/shared/src/session.ts
diff --git a/samples/basic/shared/tsconfig.json b/samples/basic/shared/tsconfig.json
new file mode 100644
index 000000000..3e87a3590
--- /dev/null
+++ b/samples/basic/shared/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "extends": "@workleap/typescript-configs/library.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"]
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/sample/shell/tsup.build.ts b/samples/basic/shared/tsup.build.ts
similarity index 100%
rename from sample/shell/tsup.build.ts
rename to samples/basic/shared/tsup.build.ts
diff --git a/sample/shell/tsup.dev.ts b/samples/basic/shared/tsup.dev.ts
similarity index 100%
rename from sample/shell/tsup.dev.ts
rename to samples/basic/shared/tsup.dev.ts
diff --git a/sample/shell/.eslintrc.json b/samples/basic/shell/.eslintrc.json
similarity index 100%
rename from sample/shell/.eslintrc.json
rename to samples/basic/shell/.eslintrc.json
diff --git a/sample/shell/nodemon.json b/samples/basic/shell/nodemon.json
similarity index 100%
rename from sample/shell/nodemon.json
rename to samples/basic/shell/nodemon.json
diff --git a/sample/shell/package.json b/samples/basic/shell/package.json
similarity index 70%
rename from sample/shell/package.json
rename to samples/basic/shell/package.json
index 88faaf723..8f0558a8d 100644
--- a/sample/shell/package.json
+++ b/samples/basic/shell/package.json
@@ -1,5 +1,5 @@
{
- "name": "@sample/shell",
+ "name": "@basic/shell",
"author": "Workleap",
"version": "0.0.0",
"description": "Application shell package to showcase @squide.",
@@ -19,25 +19,27 @@
"serve-build": "pnpm build"
},
"peerDependencies": {
- "@sample/shared": "*",
+ "@basic/shared": "*",
"@squide/react-router": "*",
+ "@squide/webpack-module-federation": "*",
"react": "*",
"react-dom": "*",
"react-router-dom": "*"
},
"devDependencies": {
- "@remix-run/router": "1.9.0",
- "@sample/shared": "workspace:*",
+ "@basic/shared": "workspace:*",
+ "@remix-run/router": "1.10.0",
"@squide/react-router": "workspace:*",
- "@types/react": "18.2.22",
- "@types/react-dom": "18.2.7",
- "@workleap/eslint-plugin": "2.1.1",
+ "@squide/webpack-module-federation": "workspace:*",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@workleap/eslint-plugin": "3.0.0",
"@workleap/tsup-configs": "3.0.1",
"@workleap/typescript-configs": "3.0.2",
"nodemon": "3.0.1",
"react": "18.2.0",
"react-dom": "18.2.0",
- "react-router-dom": "6.16.0",
+ "react-router-dom": "6.17.0",
"tsup": "7.2.0",
"typescript": "5.2.2"
}
diff --git a/samples/basic/shell/src/AppRouter.tsx b/samples/basic/shell/src/AppRouter.tsx
new file mode 100644
index 000000000..dd33dcb1e
--- /dev/null
+++ b/samples/basic/shell/src/AppRouter.tsx
@@ -0,0 +1,23 @@
+import { useRoutes } from "@squide/react-router";
+import { useAreModulesReady } from "@squide/webpack-module-federation";
+import { useMemo } from "react";
+import { RouterProvider, createBrowserRouter } from "react-router-dom";
+
+export function AppRouter() {
+ const routes = useRoutes();
+
+ // Re-render the app once all the remotes are registered, otherwise the remotes routes won't be added to the router.
+ const areModulesReady = useAreModulesReady();
+
+ const router = useMemo(() => {
+ return createBrowserRouter(routes);
+ }, [routes]);
+
+ if (!areModulesReady) {
+ return Loading...
;
+ }
+
+ return (
+
+ );
+}
diff --git a/sample/shell/src/AuthenticatedLayout.tsx b/samples/basic/shell/src/AuthenticatedLayout.tsx
similarity index 76%
rename from sample/shell/src/AuthenticatedLayout.tsx
rename to samples/basic/shell/src/AuthenticatedLayout.tsx
index a899f46aa..9d82ae590 100644
--- a/sample/shell/src/AuthenticatedLayout.tsx
+++ b/samples/basic/shell/src/AuthenticatedLayout.tsx
@@ -1,7 +1,7 @@
-import { useApplicationEventBusListener, type Session } from "@sample/shared";
+import { useApplicationEventBusListener, type Session, type SessionManager } from "@basic/shared";
import { isNavigationLink, useNavigationItems, useRenderedNavigationItems, useSession, type NavigationLinkRenderProps, type NavigationSectionRenderProps, type RenderItemFunction, type RenderSectionFunction } from "@squide/react-router";
-import { Suspense, useCallback, type ReactNode } from "react";
-import { Link, Outlet } from "react-router-dom";
+import { Suspense, useCallback, type MouseEvent, type ReactNode } from "react";
+import { Link, Outlet, useNavigate } from "react-router-dom";
type RenderLinkItemFunction = (item: NavigationLinkRenderProps, index: number, level: number) => ReactNode;
@@ -40,17 +40,30 @@ const renderSection: RenderSectionFunction = (elements, index, level) => {
);
};
-export default function AuthenticatedLayout() {
+export interface AuthenticatedLayoutProps {
+ sessionManager: SessionManager;
+}
+
+export function AuthenticatedLayout({ sessionManager }: AuthenticatedLayoutProps) {
const session = useSession() as Session;
+ const navigate = useNavigate();
+
const handleModulesMessage = useCallback((data: unknown) => {
console.log("[sample] Message received from a module: ", data);
}, []);
useApplicationEventBusListener("write-to-host", handleModulesMessage);
- const navigationItems = useNavigationItems();
+ const handleDisconnect = useCallback((event: MouseEvent) => {
+ event.preventDefault();
+ sessionManager.clearSession();
+
+ navigate("/logout");
+ }, [navigate, sessionManager]);
+
+ const navigationItems = useNavigationItems();
const renderedNavigationItems = useRenderedNavigationItems(navigationItems, renderItem, renderSection);
return (
@@ -60,10 +73,10 @@ export default function AuthenticatedLayout() {
{renderedNavigationItems}
- (User: {session.user.name} )
+ (User: {session?.user?.name} )
- Disconnect
+ Disconnect
Loading... }>
diff --git a/sample/shell/src/AuthenticationBoundary.tsx b/samples/basic/shell/src/AuthenticationBoundary.tsx
similarity index 82%
rename from sample/shell/src/AuthenticationBoundary.tsx
rename to samples/basic/shell/src/AuthenticationBoundary.tsx
index 70181e056..cc247d65d 100644
--- a/sample/shell/src/AuthenticationBoundary.tsx
+++ b/samples/basic/shell/src/AuthenticationBoundary.tsx
@@ -4,3 +4,5 @@ import { Navigate, Outlet } from "react-router-dom";
export function AuthenticationBoundary() {
return useIsAuthenticated() ? : ;
}
+
+export const Component = AuthenticationBoundary;
diff --git a/sample/shell/src/Login.tsx b/samples/basic/shell/src/LoginPage.tsx
similarity index 82%
rename from sample/shell/src/Login.tsx
rename to samples/basic/shell/src/LoginPage.tsx
index ff6f75a9e..da0931a8b 100644
--- a/sample/shell/src/Login.tsx
+++ b/samples/basic/shell/src/LoginPage.tsx
@@ -1,13 +1,14 @@
-import type { SessionManager } from "@sample/shared";
+import type { SessionManager } from "@basic/shared";
import { useIsAuthenticated } from "@squide/react-router";
import { useCallback, useState, type ChangeEvent, type MouseEvent } from "react";
import { Navigate, useNavigate } from "react-router-dom";
export interface LoginProps {
sessionManager: SessionManager;
+ host?: string;
}
-export default function Login({ sessionManager }: LoginProps) {
+export function LoginPage({ sessionManager, host }: LoginProps) {
const [username, setUserName] = useState("");
const [password, setPassword] = useState("");
@@ -25,7 +26,7 @@ export default function Login({ sessionManager }: LoginProps) {
navigate("/");
}
- }, [username, password, navigate]);
+ }, [username, password, navigate, sessionManager]);
const handleUserNameChange = useCallback((event: ChangeEvent) => {
setUserName(event.target.value);
@@ -42,8 +43,9 @@ export default function Login({ sessionManager }: LoginProps) {
}
return (
-
+ <>
Login
+ {host && This page is served by {host}
}
-
+ >
);
}
diff --git a/samples/basic/shell/src/LogoutPage.tsx b/samples/basic/shell/src/LogoutPage.tsx
new file mode 100644
index 000000000..d5768df8c
--- /dev/null
+++ b/samples/basic/shell/src/LogoutPage.tsx
@@ -0,0 +1,18 @@
+import { Link } from "react-router-dom";
+
+export interface LogoutPageProps {
+ host?: string;
+}
+
+export function LogoutPage({ host }: LogoutPageProps) {
+ return (
+ <>
+ Logged out
+ {host && This page is served by {host}
}
+ You are logged out from the application!
+ Log in again
+ >
+ );
+}
+
+export const Component = LogoutPage;
diff --git a/sample/shell/src/ModuleErrorBoundary.tsx b/samples/basic/shell/src/ModuleErrorBoundary.tsx
similarity index 59%
rename from sample/shell/src/ModuleErrorBoundary.tsx
rename to samples/basic/shell/src/ModuleErrorBoundary.tsx
index 4546415b8..e7f4676e6 100644
--- a/sample/shell/src/ModuleErrorBoundary.tsx
+++ b/samples/basic/shell/src/ModuleErrorBoundary.tsx
@@ -1,4 +1,5 @@
import { useLogger } from "@squide/react-router";
+import { useCallback, useEffect } from "react";
import { isRouteErrorResponse, useLocation, useRouteError } from "react-router-dom";
function getErrorMessage(error: unknown) {
@@ -11,18 +12,28 @@ function getErrorMessage(error: unknown) {
: JSON.stringify(error);
}
-export default function ModuleErrorBoundary() {
+export function ModuleErrorBoundary() {
const error = useRouteError();
const location = useLocation();
const logger = useLogger();
- logger.error(`[sample] An unmanaged error occurred while rendering the route with path ${location.pathname}`, error);
+ const handleReloadButtonClick = useCallback(() => {
+ window.location.reload();
+ }, []);
+
+ useEffect(() => {
+ logger.error(`[shell] An unmanaged error occurred while rendering the route with path ${location.pathname}`, error);
+ }, [location.pathname, error, logger]);
return (
Unmanaged error
An unmanaged error occurred inside a module. Still, other parts of the application are fully functional!
π {getErrorMessage(error)}
+
+
Reload
);
}
+
+export const ErrorBoundary = ModuleErrorBoundary;
diff --git a/samples/basic/shell/src/NoMatchPage.tsx b/samples/basic/shell/src/NoMatchPage.tsx
new file mode 100644
index 000000000..0631ad90e
--- /dev/null
+++ b/samples/basic/shell/src/NoMatchPage.tsx
@@ -0,0 +1,17 @@
+import { Link } from "react-router-dom";
+
+export interface NoMatchPageProps {
+ path: string;
+ host?: string;
+}
+
+export function NoMatchPage({ path, host }: NoMatchPageProps) {
+ return (
+ <>
+ 404
+ {host && This page is served by {host}
}
+ We can't find the path "{path}".
+ Go back home
+ >
+ );
+}
diff --git a/sample/shell/src/RootErrorBoundary.tsx b/samples/basic/shell/src/RootErrorBoundary.tsx
similarity index 68%
rename from sample/shell/src/RootErrorBoundary.tsx
rename to samples/basic/shell/src/RootErrorBoundary.tsx
index 7cdbe5fed..c3c995fd8 100644
--- a/sample/shell/src/RootErrorBoundary.tsx
+++ b/samples/basic/shell/src/RootErrorBoundary.tsx
@@ -1,4 +1,5 @@
import { useLogger } from "@squide/react-router";
+import { useCallback } from "react";
import { isRouteErrorResponse, useLocation, useRouteError } from "react-router-dom";
function getErrorMessage(error: unknown) {
@@ -16,13 +17,19 @@ export function RootErrorBoundary() {
const location = useLocation();
const logger = useLogger();
- logger.error(`[sample] An unmanaged error occurred while rendering the route with path ${location.pathname}`, error);
+ const handleReloadButtonClick = useCallback(() => {
+ window.location.reload();
+ }, []);
+
+ logger.error(`[shell] An unmanaged error occurred while rendering the route with path ${location.pathname}`, error);
return (
Unmanaged error
An unmanaged error occurred and the application is broken, try refreshing your browser.
π {getErrorMessage(error)}
+
+
Reload
);
}
diff --git a/sample/shell/src/RootLayout.tsx b/samples/basic/shell/src/RootLayout.tsx
similarity index 100%
rename from sample/shell/src/RootLayout.tsx
rename to samples/basic/shell/src/RootLayout.tsx
diff --git a/samples/basic/shell/src/index.ts b/samples/basic/shell/src/index.ts
new file mode 100644
index 000000000..5e03e14a7
--- /dev/null
+++ b/samples/basic/shell/src/index.ts
@@ -0,0 +1,3 @@
+export * from "./AppRouter.tsx";
+export * from "./register.tsx";
+
diff --git a/samples/basic/shell/src/register.tsx b/samples/basic/shell/src/register.tsx
new file mode 100644
index 000000000..9cba8b74e
--- /dev/null
+++ b/samples/basic/shell/src/register.tsx
@@ -0,0 +1,107 @@
+import type { SessionManager } from "@basic/shared";
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { ManagedRoutes } from "@squide/react-router";
+import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
+import { RootLayout } from "./RootLayout.tsx";
+
+export interface RegisterShellOptions {
+ // This is only for demo purposed, do not copy this.
+ host?: string;
+}
+
+function registerRoutes(runtime: Runtime, sessionManager: SessionManager, host?: string) {
+ runtime.registerRoute({
+ // Pathless route to declare a root layout.
+ $visibility: "public",
+ element: ,
+ children: [
+ {
+ // Pathless route to declare a root error boundary.
+ // Public pages like the login and logout pages will be rendered under this pathless route.
+ $visibility: "public",
+ $name: "root-error-boundary",
+ errorElement: ,
+ children: [
+ {
+ // Pathless route to declare an authenticated boundary.
+ lazy: () => import("./AuthenticationBoundary.tsx"),
+ children: [
+ {
+ // Pathless route to declare an authenticated layout.
+ lazy: async () => {
+ const { AuthenticatedLayout } = await import("./AuthenticatedLayout.tsx");
+
+ return {
+ element:
+ };
+ },
+ children: [
+ {
+ // Pathless route to declare an error boundary inside the layout instead of outside.
+ // It's quite useful to prevent losing the layout when an unmanaged error occurs.
+ lazy: () => import("./ModuleErrorBoundary.tsx"),
+ children: [
+ ManagedRoutes
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ $visibility: "public",
+ path: "/login",
+ lazy: async () => {
+ const { LoginPage } = await import("./LoginPage.tsx");
+
+ return {
+ element:
+ };
+ }
+ }, {
+ parentName: "root-error-boundary"
+ });
+
+ runtime.registerRoute({
+ $visibility: "public",
+ path: "/logout",
+ lazy: async () => {
+ const { LogoutPage } = await import("./LogoutPage.tsx");
+
+ return {
+ element:
+ };
+ }
+ }, {
+ parentName: "root-error-boundary"
+ });
+
+ runtime.registerRoute({
+ $visibility: "public",
+ path: "*",
+ lazy: async () => {
+ const { NoMatchPage } = await import("./NoMatchPage.tsx");
+
+ return {
+ element:
+ };
+ }
+ }, {
+ parentName: "root-error-boundary"
+ });
+}
+
+export function registerShell(sessionManager: SessionManager, { host }: RegisterShellOptions = {}) {
+ const register: ModuleRegisterFunction = runtime => {
+ registerRoutes(runtime, sessionManager, host);
+ };
+
+ return register;
+}
diff --git a/samples/basic/shell/tsconfig.json b/samples/basic/shell/tsconfig.json
new file mode 100644
index 000000000..c76e50dcc
--- /dev/null
+++ b/samples/basic/shell/tsconfig.json
@@ -0,0 +1,15 @@
+{
+ "extends": "@workleap/typescript-configs/library.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"],
+ "@basic/shared": ["../shared/src/index.ts"],
+ "@basic/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"]
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/samples/basic/shell/tsup.build.ts b/samples/basic/shell/tsup.build.ts
new file mode 100644
index 000000000..1b2c65a89
--- /dev/null
+++ b/samples/basic/shell/tsup.build.ts
@@ -0,0 +1,3 @@
+import { defineBuildConfig } from "@workleap/tsup-configs";
+
+export default defineBuildConfig();
diff --git a/samples/basic/shell/tsup.dev.ts b/samples/basic/shell/tsup.dev.ts
new file mode 100644
index 000000000..8aa2904c8
--- /dev/null
+++ b/samples/basic/shell/tsup.dev.ts
@@ -0,0 +1,3 @@
+import { defineDevConfig } from "@workleap/tsup-configs";
+
+export default defineDevConfig();
diff --git a/samples/endpoints/host/.browserslistrc b/samples/endpoints/host/.browserslistrc
new file mode 100644
index 000000000..f8a8f866a
--- /dev/null
+++ b/samples/endpoints/host/.browserslistrc
@@ -0,0 +1 @@
+extends @workleap/browserslist-config
diff --git a/samples/endpoints/host/.eslintrc.json b/samples/endpoints/host/.eslintrc.json
new file mode 100644
index 000000000..ab20e5046
--- /dev/null
+++ b/samples/endpoints/host/.eslintrc.json
@@ -0,0 +1,5 @@
+{
+ "$schema": "https://json.schemastore.org/eslintrc",
+ "root": true,
+ "extends": "plugin:@workleap/web-application"
+}
diff --git a/samples/endpoints/host/_redirects b/samples/endpoints/host/_redirects
new file mode 100644
index 000000000..7797f7c6a
--- /dev/null
+++ b/samples/endpoints/host/_redirects
@@ -0,0 +1 @@
+/* /index.html 200
diff --git a/samples/endpoints/host/mocks/browser.ts b/samples/endpoints/host/mocks/browser.ts
new file mode 100644
index 000000000..01d2b0321
--- /dev/null
+++ b/samples/endpoints/host/mocks/browser.ts
@@ -0,0 +1,7 @@
+import { setupWorker, type RestHandler } from "msw";
+
+export function startMsw(moduleRequestHandlers: RestHandler[]) {
+ const worker = setupWorker(...moduleRequestHandlers);
+
+ worker.start();
+}
diff --git a/samples/endpoints/host/mocks/characterHandlers.ts b/samples/endpoints/host/mocks/characterHandlers.ts
new file mode 100644
index 000000000..d6d090e58
--- /dev/null
+++ b/samples/endpoints/host/mocks/characterHandlers.ts
@@ -0,0 +1,341 @@
+/* eslint-disable max-len */
+
+import { rest, type RestHandler } from "msw";
+
+export const characterHandlers: RestHandler[] = [
+ rest.get("/api/character/1,2,3,4,5", async (req, res, ctx) => {
+ return res(
+ ctx.status(200),
+ ctx.json([{
+ "id": 1,
+ "name": "Rick Sanchez",
+ "status": "Alive",
+ "species": "Human",
+ "type": "",
+ "gender": "Male",
+ "origin": {
+ "name": "Earth (C-137)",
+ "url": "https://rickandmortyapi.com/api/location/1"
+ },
+ "location": {
+ "name": "Citadel of Ricks",
+ "url": "https://rickandmortyapi.com/api/location/3"
+ },
+ "image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg",
+ "episode": [
+ "https://rickandmortyapi.com/api/episode/1",
+ "https://rickandmortyapi.com/api/episode/2",
+ "https://rickandmortyapi.com/api/episode/3",
+ "https://rickandmortyapi.com/api/episode/4",
+ "https://rickandmortyapi.com/api/episode/5",
+ "https://rickandmortyapi.com/api/episode/6",
+ "https://rickandmortyapi.com/api/episode/7",
+ "https://rickandmortyapi.com/api/episode/8",
+ "https://rickandmortyapi.com/api/episode/9",
+ "https://rickandmortyapi.com/api/episode/10",
+ "https://rickandmortyapi.com/api/episode/11",
+ "https://rickandmortyapi.com/api/episode/12",
+ "https://rickandmortyapi.com/api/episode/13",
+ "https://rickandmortyapi.com/api/episode/14",
+ "https://rickandmortyapi.com/api/episode/15",
+ "https://rickandmortyapi.com/api/episode/16",
+ "https://rickandmortyapi.com/api/episode/17",
+ "https://rickandmortyapi.com/api/episode/18",
+ "https://rickandmortyapi.com/api/episode/19",
+ "https://rickandmortyapi.com/api/episode/20",
+ "https://rickandmortyapi.com/api/episode/21",
+ "https://rickandmortyapi.com/api/episode/22",
+ "https://rickandmortyapi.com/api/episode/23",
+ "https://rickandmortyapi.com/api/episode/24",
+ "https://rickandmortyapi.com/api/episode/25",
+ "https://rickandmortyapi.com/api/episode/26",
+ "https://rickandmortyapi.com/api/episode/27",
+ "https://rickandmortyapi.com/api/episode/28",
+ "https://rickandmortyapi.com/api/episode/29",
+ "https://rickandmortyapi.com/api/episode/30",
+ "https://rickandmortyapi.com/api/episode/31",
+ "https://rickandmortyapi.com/api/episode/32",
+ "https://rickandmortyapi.com/api/episode/33",
+ "https://rickandmortyapi.com/api/episode/34",
+ "https://rickandmortyapi.com/api/episode/35",
+ "https://rickandmortyapi.com/api/episode/36",
+ "https://rickandmortyapi.com/api/episode/37",
+ "https://rickandmortyapi.com/api/episode/38",
+ "https://rickandmortyapi.com/api/episode/39",
+ "https://rickandmortyapi.com/api/episode/40",
+ "https://rickandmortyapi.com/api/episode/41",
+ "https://rickandmortyapi.com/api/episode/42",
+ "https://rickandmortyapi.com/api/episode/43",
+ "https://rickandmortyapi.com/api/episode/44",
+ "https://rickandmortyapi.com/api/episode/45",
+ "https://rickandmortyapi.com/api/episode/46",
+ "https://rickandmortyapi.com/api/episode/47",
+ "https://rickandmortyapi.com/api/episode/48",
+ "https://rickandmortyapi.com/api/episode/49",
+ "https://rickandmortyapi.com/api/episode/50",
+ "https://rickandmortyapi.com/api/episode/51"
+ ],
+ "url": "https://rickandmortyapi.com/api/character/1",
+ "created": "2017-11-04T18:48:46.250Z"
+ },
+ {
+ "id": 2,
+ "name": "Morty Smith",
+ "status": "Alive",
+ "species": "Human",
+ "type": "",
+ "gender": "Male",
+ "origin": {
+ "name": "unknown",
+ "url": ""
+ },
+ "location": {
+ "name": "Citadel of Ricks",
+ "url": "https://rickandmortyapi.com/api/location/3"
+ },
+ "image": "https://rickandmortyapi.com/api/character/avatar/2.jpeg",
+ "episode": [
+ "https://rickandmortyapi.com/api/episode/1",
+ "https://rickandmortyapi.com/api/episode/2",
+ "https://rickandmortyapi.com/api/episode/3",
+ "https://rickandmortyapi.com/api/episode/4",
+ "https://rickandmortyapi.com/api/episode/5",
+ "https://rickandmortyapi.com/api/episode/6",
+ "https://rickandmortyapi.com/api/episode/7",
+ "https://rickandmortyapi.com/api/episode/8",
+ "https://rickandmortyapi.com/api/episode/9",
+ "https://rickandmortyapi.com/api/episode/10",
+ "https://rickandmortyapi.com/api/episode/11",
+ "https://rickandmortyapi.com/api/episode/12",
+ "https://rickandmortyapi.com/api/episode/13",
+ "https://rickandmortyapi.com/api/episode/14",
+ "https://rickandmortyapi.com/api/episode/15",
+ "https://rickandmortyapi.com/api/episode/16",
+ "https://rickandmortyapi.com/api/episode/17",
+ "https://rickandmortyapi.com/api/episode/18",
+ "https://rickandmortyapi.com/api/episode/19",
+ "https://rickandmortyapi.com/api/episode/20",
+ "https://rickandmortyapi.com/api/episode/21",
+ "https://rickandmortyapi.com/api/episode/22",
+ "https://rickandmortyapi.com/api/episode/23",
+ "https://rickandmortyapi.com/api/episode/24",
+ "https://rickandmortyapi.com/api/episode/25",
+ "https://rickandmortyapi.com/api/episode/26",
+ "https://rickandmortyapi.com/api/episode/27",
+ "https://rickandmortyapi.com/api/episode/28",
+ "https://rickandmortyapi.com/api/episode/29",
+ "https://rickandmortyapi.com/api/episode/30",
+ "https://rickandmortyapi.com/api/episode/31",
+ "https://rickandmortyapi.com/api/episode/32",
+ "https://rickandmortyapi.com/api/episode/33",
+ "https://rickandmortyapi.com/api/episode/34",
+ "https://rickandmortyapi.com/api/episode/35",
+ "https://rickandmortyapi.com/api/episode/36",
+ "https://rickandmortyapi.com/api/episode/37",
+ "https://rickandmortyapi.com/api/episode/38",
+ "https://rickandmortyapi.com/api/episode/39",
+ "https://rickandmortyapi.com/api/episode/40",
+ "https://rickandmortyapi.com/api/episode/41",
+ "https://rickandmortyapi.com/api/episode/42",
+ "https://rickandmortyapi.com/api/episode/43",
+ "https://rickandmortyapi.com/api/episode/44",
+ "https://rickandmortyapi.com/api/episode/45",
+ "https://rickandmortyapi.com/api/episode/46",
+ "https://rickandmortyapi.com/api/episode/47",
+ "https://rickandmortyapi.com/api/episode/48",
+ "https://rickandmortyapi.com/api/episode/49",
+ "https://rickandmortyapi.com/api/episode/50",
+ "https://rickandmortyapi.com/api/episode/51"
+ ],
+ "url": "https://rickandmortyapi.com/api/character/2",
+ "created": "2017-11-04T18:50:21.651Z"
+ },
+ {
+ "id": 3,
+ "name": "Summer Smith",
+ "status": "Alive",
+ "species": "Human",
+ "type": "",
+ "gender": "Female",
+ "origin": {
+ "name": "Earth (Replacement Dimension)",
+ "url": "https://rickandmortyapi.com/api/location/20"
+ },
+ "location": {
+ "name": "Earth (Replacement Dimension)",
+ "url": "https://rickandmortyapi.com/api/location/20"
+ },
+ "image": "https://rickandmortyapi.com/api/character/avatar/3.jpeg",
+ "episode": [
+ "https://rickandmortyapi.com/api/episode/6",
+ "https://rickandmortyapi.com/api/episode/7",
+ "https://rickandmortyapi.com/api/episode/8",
+ "https://rickandmortyapi.com/api/episode/9",
+ "https://rickandmortyapi.com/api/episode/10",
+ "https://rickandmortyapi.com/api/episode/11",
+ "https://rickandmortyapi.com/api/episode/12",
+ "https://rickandmortyapi.com/api/episode/14",
+ "https://rickandmortyapi.com/api/episode/15",
+ "https://rickandmortyapi.com/api/episode/16",
+ "https://rickandmortyapi.com/api/episode/17",
+ "https://rickandmortyapi.com/api/episode/18",
+ "https://rickandmortyapi.com/api/episode/19",
+ "https://rickandmortyapi.com/api/episode/20",
+ "https://rickandmortyapi.com/api/episode/21",
+ "https://rickandmortyapi.com/api/episode/22",
+ "https://rickandmortyapi.com/api/episode/23",
+ "https://rickandmortyapi.com/api/episode/24",
+ "https://rickandmortyapi.com/api/episode/25",
+ "https://rickandmortyapi.com/api/episode/26",
+ "https://rickandmortyapi.com/api/episode/27",
+ "https://rickandmortyapi.com/api/episode/29",
+ "https://rickandmortyapi.com/api/episode/30",
+ "https://rickandmortyapi.com/api/episode/31",
+ "https://rickandmortyapi.com/api/episode/32",
+ "https://rickandmortyapi.com/api/episode/33",
+ "https://rickandmortyapi.com/api/episode/34",
+ "https://rickandmortyapi.com/api/episode/35",
+ "https://rickandmortyapi.com/api/episode/36",
+ "https://rickandmortyapi.com/api/episode/38",
+ "https://rickandmortyapi.com/api/episode/39",
+ "https://rickandmortyapi.com/api/episode/40",
+ "https://rickandmortyapi.com/api/episode/41",
+ "https://rickandmortyapi.com/api/episode/42",
+ "https://rickandmortyapi.com/api/episode/43",
+ "https://rickandmortyapi.com/api/episode/44",
+ "https://rickandmortyapi.com/api/episode/45",
+ "https://rickandmortyapi.com/api/episode/46",
+ "https://rickandmortyapi.com/api/episode/47",
+ "https://rickandmortyapi.com/api/episode/48",
+ "https://rickandmortyapi.com/api/episode/49",
+ "https://rickandmortyapi.com/api/episode/51"
+ ],
+ "url": "https://rickandmortyapi.com/api/character/3",
+ "created": "2017-11-04T19:09:56.428Z"
+ },
+ {
+ "id": 4,
+ "name": "Beth Smith",
+ "status": "Alive",
+ "species": "Human",
+ "type": "",
+ "gender": "Female",
+ "origin": {
+ "name": "Earth (Replacement Dimension)",
+ "url": "https://rickandmortyapi.com/api/location/20"
+ },
+ "location": {
+ "name": "Earth (Replacement Dimension)",
+ "url": "https://rickandmortyapi.com/api/location/20"
+ },
+ "image": "https://rickandmortyapi.com/api/character/avatar/4.jpeg",
+ "episode": [
+ "https://rickandmortyapi.com/api/episode/6",
+ "https://rickandmortyapi.com/api/episode/7",
+ "https://rickandmortyapi.com/api/episode/8",
+ "https://rickandmortyapi.com/api/episode/9",
+ "https://rickandmortyapi.com/api/episode/10",
+ "https://rickandmortyapi.com/api/episode/11",
+ "https://rickandmortyapi.com/api/episode/12",
+ "https://rickandmortyapi.com/api/episode/14",
+ "https://rickandmortyapi.com/api/episode/15",
+ "https://rickandmortyapi.com/api/episode/16",
+ "https://rickandmortyapi.com/api/episode/18",
+ "https://rickandmortyapi.com/api/episode/19",
+ "https://rickandmortyapi.com/api/episode/20",
+ "https://rickandmortyapi.com/api/episode/21",
+ "https://rickandmortyapi.com/api/episode/22",
+ "https://rickandmortyapi.com/api/episode/23",
+ "https://rickandmortyapi.com/api/episode/24",
+ "https://rickandmortyapi.com/api/episode/25",
+ "https://rickandmortyapi.com/api/episode/26",
+ "https://rickandmortyapi.com/api/episode/27",
+ "https://rickandmortyapi.com/api/episode/28",
+ "https://rickandmortyapi.com/api/episode/29",
+ "https://rickandmortyapi.com/api/episode/30",
+ "https://rickandmortyapi.com/api/episode/31",
+ "https://rickandmortyapi.com/api/episode/32",
+ "https://rickandmortyapi.com/api/episode/33",
+ "https://rickandmortyapi.com/api/episode/34",
+ "https://rickandmortyapi.com/api/episode/35",
+ "https://rickandmortyapi.com/api/episode/36",
+ "https://rickandmortyapi.com/api/episode/38",
+ "https://rickandmortyapi.com/api/episode/39",
+ "https://rickandmortyapi.com/api/episode/40",
+ "https://rickandmortyapi.com/api/episode/41",
+ "https://rickandmortyapi.com/api/episode/42",
+ "https://rickandmortyapi.com/api/episode/43",
+ "https://rickandmortyapi.com/api/episode/44",
+ "https://rickandmortyapi.com/api/episode/45",
+ "https://rickandmortyapi.com/api/episode/46",
+ "https://rickandmortyapi.com/api/episode/47",
+ "https://rickandmortyapi.com/api/episode/48",
+ "https://rickandmortyapi.com/api/episode/49",
+ "https://rickandmortyapi.com/api/episode/51"
+ ],
+ "url": "https://rickandmortyapi.com/api/character/4",
+ "created": "2017-11-04T19:22:43.665Z"
+ },
+ {
+ "id": 5,
+ "name": "Jerry Smith",
+ "status": "Alive",
+ "species": "Human",
+ "type": "",
+ "gender": "Male",
+ "origin": {
+ "name": "Earth (Replacement Dimension)",
+ "url": "https://rickandmortyapi.com/api/location/20"
+ },
+ "location": {
+ "name": "Earth (Replacement Dimension)",
+ "url": "https://rickandmortyapi.com/api/location/20"
+ },
+ "image": "https://rickandmortyapi.com/api/character/avatar/5.jpeg",
+ "episode": [
+ "https://rickandmortyapi.com/api/episode/6",
+ "https://rickandmortyapi.com/api/episode/7",
+ "https://rickandmortyapi.com/api/episode/8",
+ "https://rickandmortyapi.com/api/episode/9",
+ "https://rickandmortyapi.com/api/episode/10",
+ "https://rickandmortyapi.com/api/episode/11",
+ "https://rickandmortyapi.com/api/episode/12",
+ "https://rickandmortyapi.com/api/episode/13",
+ "https://rickandmortyapi.com/api/episode/14",
+ "https://rickandmortyapi.com/api/episode/15",
+ "https://rickandmortyapi.com/api/episode/16",
+ "https://rickandmortyapi.com/api/episode/18",
+ "https://rickandmortyapi.com/api/episode/19",
+ "https://rickandmortyapi.com/api/episode/20",
+ "https://rickandmortyapi.com/api/episode/21",
+ "https://rickandmortyapi.com/api/episode/22",
+ "https://rickandmortyapi.com/api/episode/23",
+ "https://rickandmortyapi.com/api/episode/26",
+ "https://rickandmortyapi.com/api/episode/29",
+ "https://rickandmortyapi.com/api/episode/30",
+ "https://rickandmortyapi.com/api/episode/31",
+ "https://rickandmortyapi.com/api/episode/32",
+ "https://rickandmortyapi.com/api/episode/33",
+ "https://rickandmortyapi.com/api/episode/35",
+ "https://rickandmortyapi.com/api/episode/36",
+ "https://rickandmortyapi.com/api/episode/38",
+ "https://rickandmortyapi.com/api/episode/39",
+ "https://rickandmortyapi.com/api/episode/40",
+ "https://rickandmortyapi.com/api/episode/41",
+ "https://rickandmortyapi.com/api/episode/42",
+ "https://rickandmortyapi.com/api/episode/43",
+ "https://rickandmortyapi.com/api/episode/44",
+ "https://rickandmortyapi.com/api/episode/45",
+ "https://rickandmortyapi.com/api/episode/46",
+ "https://rickandmortyapi.com/api/episode/47",
+ "https://rickandmortyapi.com/api/episode/48",
+ "https://rickandmortyapi.com/api/episode/49",
+ "https://rickandmortyapi.com/api/episode/50",
+ "https://rickandmortyapi.com/api/episode/51"
+ ],
+ "url": "https://rickandmortyapi.com/api/character/5",
+ "created": "2017-11-04T19:26:56.301Z"
+ }])
+ );
+ })
+];
diff --git a/samples/endpoints/host/mocks/handlers.ts b/samples/endpoints/host/mocks/handlers.ts
new file mode 100644
index 000000000..9d1c5e9ee
--- /dev/null
+++ b/samples/endpoints/host/mocks/handlers.ts
@@ -0,0 +1,4 @@
+import type { RestHandler } from "msw";
+import { characterHandlers } from "./characterHandlers.ts";
+
+export const requestHandlers: RestHandler[] = characterHandlers;
diff --git a/samples/endpoints/host/nodemon.json b/samples/endpoints/host/nodemon.json
new file mode 100644
index 000000000..7a5919df8
--- /dev/null
+++ b/samples/endpoints/host/nodemon.json
@@ -0,0 +1,5 @@
+{
+ "watch": ["swc.dev.js", "webpack.dev.js"],
+ "exec": "webpack serve --config webpack.dev.js",
+ "verbose": true
+}
diff --git a/samples/endpoints/host/package.json b/samples/endpoints/host/package.json
new file mode 100644
index 000000000..667c20dcf
--- /dev/null
+++ b/samples/endpoints/host/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "@endpoints/host",
+ "author": "Workleap",
+ "version": "0.0.0",
+ "description": "Host application to showcase @squide.",
+ "private": true,
+ "license": "Apache-2.0",
+ "type": "module",
+ "scripts": {
+ "dev": "cross-env USE_MSW=true nodemon",
+ "build": "cross-env USE_MSW=true pnpm build:webpack && pnpm build:copy-redirects && pnpm build:copy-public-files",
+ "build:webpack": "webpack --config webpack.build.js",
+ "build:copy-redirects": "copyfiles _redirects dist",
+ "build:copy-public-files": "copyfiles -u 1 public/favicon.png public/mockServiceWorker.js dist",
+ "serve-build": "pnpm build && pnpm http-server dist -p 8080 -P http://localhost:8080? -c-1"
+ },
+ "devDependencies": {
+ "@squide/fakes": "workspace:*",
+ "@swc/core": "1.3.93",
+ "@swc/helpers": "0.5.3",
+ "@tanstack/react-query": "^5.0.0",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@types/webpack": "5.28.3",
+ "@workleap/browserslist-config": "2.0.0",
+ "@workleap/eslint-plugin": "3.0.0",
+ "@workleap/swc-configs": "2.1.2",
+ "@workleap/typescript-configs": "3.0.2",
+ "@workleap/webpack-configs": "1.1.0",
+ "browserslist": "4.22.1",
+ "copyfiles": "2.4.1",
+ "cross-env": "7.0.3",
+ "http-server": "14.1.1",
+ "msw": "1.3.2",
+ "nodemon": "3.0.1",
+ "typescript": "5.2.2",
+ "webpack": "5.89.0",
+ "webpack-cli": "5.1.4",
+ "webpack-dev-server": "4.15.1"
+ },
+ "dependencies": {
+ "@endpoints/local-module": "workspace:*",
+ "@endpoints/shared": "workspace:*",
+ "@endpoints/shell": "workspace:*",
+ "@squide/msw": "workspace:*",
+ "@squide/react-router": "workspace:*",
+ "@squide/webpack-module-federation": "workspace:*",
+ "axios": "1.5.1",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-error-boundary": "4.0.11",
+ "react-router-dom": "6.17.0"
+ }
+}
diff --git a/samples/endpoints/host/public/favicon.png b/samples/endpoints/host/public/favicon.png
new file mode 100644
index 000000000..47157f6b0
Binary files /dev/null and b/samples/endpoints/host/public/favicon.png differ
diff --git a/samples/endpoints/host/public/index.html b/samples/endpoints/host/public/index.html
new file mode 100644
index 000000000..98accb408
--- /dev/null
+++ b/samples/endpoints/host/public/index.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/samples/endpoints/host/public/mockServiceWorker.js b/samples/endpoints/host/public/mockServiceWorker.js
new file mode 100644
index 000000000..8ee70b3e4
--- /dev/null
+++ b/samples/endpoints/host/public/mockServiceWorker.js
@@ -0,0 +1,303 @@
+/* eslint-disable */
+/* tslint:disable */
+
+/**
+ * Mock Service Worker (1.2.2).
+ * @see https://github.com/mswjs/msw
+ * - Please do NOT modify this file.
+ * - Please do NOT serve this file on production.
+ */
+
+const INTEGRITY_CHECKSUM = '3d6b9f06410d179a7f7404d4bf4c3c70'
+const activeClientIds = new Set()
+
+self.addEventListener('install', function () {
+ self.skipWaiting()
+})
+
+self.addEventListener('activate', function (event) {
+ event.waitUntil(self.clients.claim())
+})
+
+self.addEventListener('message', async function (event) {
+ const clientId = event.source.id
+
+ if (!clientId || !self.clients) {
+ return
+ }
+
+ const client = await self.clients.get(clientId)
+
+ if (!client) {
+ return
+ }
+
+ const allClients = await self.clients.matchAll({
+ type: 'window',
+ })
+
+ switch (event.data) {
+ case 'KEEPALIVE_REQUEST': {
+ sendToClient(client, {
+ type: 'KEEPALIVE_RESPONSE',
+ })
+ break
+ }
+
+ case 'INTEGRITY_CHECK_REQUEST': {
+ sendToClient(client, {
+ type: 'INTEGRITY_CHECK_RESPONSE',
+ payload: INTEGRITY_CHECKSUM,
+ })
+ break
+ }
+
+ case 'MOCK_ACTIVATE': {
+ activeClientIds.add(clientId)
+
+ sendToClient(client, {
+ type: 'MOCKING_ENABLED',
+ payload: true,
+ })
+ break
+ }
+
+ case 'MOCK_DEACTIVATE': {
+ activeClientIds.delete(clientId)
+ break
+ }
+
+ case 'CLIENT_CLOSED': {
+ activeClientIds.delete(clientId)
+
+ const remainingClients = allClients.filter((client) => {
+ return client.id !== clientId
+ })
+
+ // Unregister itself when there are no more clients
+ if (remainingClients.length === 0) {
+ self.registration.unregister()
+ }
+
+ break
+ }
+ }
+})
+
+self.addEventListener('fetch', function (event) {
+ const { request } = event
+ const accept = request.headers.get('accept') || ''
+
+ // Bypass server-sent events.
+ if (accept.includes('text/event-stream')) {
+ return
+ }
+
+ // Bypass navigation requests.
+ if (request.mode === 'navigate') {
+ return
+ }
+
+ // Opening the DevTools triggers the "only-if-cached" request
+ // that cannot be handled by the worker. Bypass such requests.
+ if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
+ return
+ }
+
+ // Bypass all requests when there are no active clients.
+ // Prevents the self-unregistered worked from handling requests
+ // after it's been deleted (still remains active until the next reload).
+ if (activeClientIds.size === 0) {
+ return
+ }
+
+ // Generate unique request ID.
+ const requestId = Math.random().toString(16).slice(2)
+
+ event.respondWith(
+ handleRequest(event, requestId).catch((error) => {
+ if (error.name === 'NetworkError') {
+ console.warn(
+ '[MSW] Successfully emulated a network error for the "%s %s" request.',
+ request.method,
+ request.url,
+ )
+ return
+ }
+
+ // At this point, any exception indicates an issue with the original request/response.
+ console.error(
+ `\
+[MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`,
+ request.method,
+ request.url,
+ `${error.name}: ${error.message}`,
+ )
+ }),
+ )
+})
+
+async function handleRequest(event, requestId) {
+ const client = await resolveMainClient(event)
+ const response = await getResponse(event, client, requestId)
+
+ // Send back the response clone for the "response:*" life-cycle events.
+ // Ensure MSW is active and ready to handle the message, otherwise
+ // this message will pend indefinitely.
+ if (client && activeClientIds.has(client.id)) {
+ ;(async function () {
+ const clonedResponse = response.clone()
+ sendToClient(client, {
+ type: 'RESPONSE',
+ payload: {
+ requestId,
+ type: clonedResponse.type,
+ ok: clonedResponse.ok,
+ status: clonedResponse.status,
+ statusText: clonedResponse.statusText,
+ body:
+ clonedResponse.body === null ? null : await clonedResponse.text(),
+ headers: Object.fromEntries(clonedResponse.headers.entries()),
+ redirected: clonedResponse.redirected,
+ },
+ })
+ })()
+ }
+
+ return response
+}
+
+// Resolve the main client for the given event.
+// Client that issues a request doesn't necessarily equal the client
+// that registered the worker. It's with the latter the worker should
+// communicate with during the response resolving phase.
+async function resolveMainClient(event) {
+ const client = await self.clients.get(event.clientId)
+
+ if (client?.frameType === 'top-level') {
+ return client
+ }
+
+ const allClients = await self.clients.matchAll({
+ type: 'window',
+ })
+
+ return allClients
+ .filter((client) => {
+ // Get only those clients that are currently visible.
+ return client.visibilityState === 'visible'
+ })
+ .find((client) => {
+ // Find the client ID that's recorded in the
+ // set of clients that have registered the worker.
+ return activeClientIds.has(client.id)
+ })
+}
+
+async function getResponse(event, client, requestId) {
+ const { request } = event
+ const clonedRequest = request.clone()
+
+ function passthrough() {
+ // Clone the request because it might've been already used
+ // (i.e. its body has been read and sent to the client).
+ const headers = Object.fromEntries(clonedRequest.headers.entries())
+
+ // Remove MSW-specific request headers so the bypassed requests
+ // comply with the server's CORS preflight check.
+ // Operate with the headers as an object because request "Headers"
+ // are immutable.
+ delete headers['x-msw-bypass']
+
+ return fetch(clonedRequest, { headers })
+ }
+
+ // Bypass mocking when the client is not active.
+ if (!client) {
+ return passthrough()
+ }
+
+ // Bypass initial page load requests (i.e. static assets).
+ // The absence of the immediate/parent client in the map of the active clients
+ // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
+ // and is not ready to handle requests.
+ if (!activeClientIds.has(client.id)) {
+ return passthrough()
+ }
+
+ // Bypass requests with the explicit bypass header.
+ // Such requests can be issued by "ctx.fetch()".
+ if (request.headers.get('x-msw-bypass') === 'true') {
+ return passthrough()
+ }
+
+ // Notify the client that a request has been intercepted.
+ const clientMessage = await sendToClient(client, {
+ type: 'REQUEST',
+ payload: {
+ id: requestId,
+ url: request.url,
+ method: request.method,
+ headers: Object.fromEntries(request.headers.entries()),
+ cache: request.cache,
+ mode: request.mode,
+ credentials: request.credentials,
+ destination: request.destination,
+ integrity: request.integrity,
+ redirect: request.redirect,
+ referrer: request.referrer,
+ referrerPolicy: request.referrerPolicy,
+ body: await request.text(),
+ bodyUsed: request.bodyUsed,
+ keepalive: request.keepalive,
+ },
+ })
+
+ switch (clientMessage.type) {
+ case 'MOCK_RESPONSE': {
+ return respondWithMock(clientMessage.data)
+ }
+
+ case 'MOCK_NOT_FOUND': {
+ return passthrough()
+ }
+
+ case 'NETWORK_ERROR': {
+ const { name, message } = clientMessage.data
+ const networkError = new Error(message)
+ networkError.name = name
+
+ // Rejecting a "respondWith" promise emulates a network error.
+ throw networkError
+ }
+ }
+
+ return passthrough()
+}
+
+function sendToClient(client, message) {
+ return new Promise((resolve, reject) => {
+ const channel = new MessageChannel()
+
+ channel.port1.onmessage = (event) => {
+ if (event.data && event.data.error) {
+ return reject(event.data.error)
+ }
+
+ resolve(event.data)
+ }
+
+ client.postMessage(message, [channel.port2])
+ })
+}
+
+function sleep(timeMs) {
+ return new Promise((resolve) => {
+ setTimeout(resolve, timeMs)
+ })
+}
+
+async function respondWithMock(response) {
+ await sleep(response.delay)
+ return new Response(response.body, response)
+}
diff --git a/samples/endpoints/host/src/App.tsx b/samples/endpoints/host/src/App.tsx
new file mode 100644
index 000000000..bb4777f10
--- /dev/null
+++ b/samples/endpoints/host/src/App.tsx
@@ -0,0 +1,18 @@
+import { LoggerTelemetryService } from "@endpoints/shared";
+import { AppRouter } from "@endpoints/shell";
+import { useLogger } from "@squide/react-router";
+import { sessionManager } from "./session.ts";
+
+export function App() {
+ const logger = useLogger();
+
+ const telemetryService = new LoggerTelemetryService(logger);
+
+ return (
+
+ );
+}
diff --git a/samples/endpoints/host/src/HomePage.tsx b/samples/endpoints/host/src/HomePage.tsx
new file mode 100644
index 000000000..b1a6a5e04
--- /dev/null
+++ b/samples/endpoints/host/src/HomePage.tsx
@@ -0,0 +1,38 @@
+import { useSuspenseQuery } from "@tanstack/react-query";
+import axios from "axios";
+
+interface Character {
+ id: number;
+ name: string;
+ species: string;
+}
+
+export function HomePage() {
+ const { data: characters } = useSuspenseQuery({ queryKey: ["/api/character/1,2,3,4,5"], queryFn: () => {
+ return axios
+ .get("/api/character/1,2,3,4,5")
+ .then(({ data }) => {
+ return data;
+ });
+ } });
+
+ return (
+
+
Home
+
This page is served by @endpoints/host
+
+ {characters.map((x: Character) => {
+ return (
+
+ Id: {x.id}
+ -
+ Name: {x.name}
+ -
+ Species: {x.species}
+
+ );
+ })}
+
+
+ );
+}
diff --git a/samples/endpoints/host/src/bootstrap.tsx b/samples/endpoints/host/src/bootstrap.tsx
new file mode 100644
index 000000000..68fe3798b
--- /dev/null
+++ b/samples/endpoints/host/src/bootstrap.tsx
@@ -0,0 +1,54 @@
+import { registerLocalModule } from "@endpoints/local-module";
+import { isNetlify } from "@endpoints/shared";
+import { registerShell } from "@endpoints/shell";
+import { MswPlugin, setMswAsStarted } from "@squide/msw";
+import { ConsoleLogger, Runtime, RuntimeContext, registerLocalModules } from "@squide/react-router";
+import { registerRemoteModules, type RemoteDefinition } from "@squide/webpack-module-federation";
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import { App } from "./App.tsx";
+import { registerHost } from "./register.tsx";
+import { sessionAccessor, sessionManager } from "./session.ts";
+
+const Remotes: RemoteDefinition[] = [
+ {
+ name: "remote1",
+ url: isNetlify ? "https://squide-endpoints-remote-module.netlify.app" : "http://localhost:8081"
+ }
+];
+
+// Add a plugin to support Mock Service Worker for a federated application.
+// The plugin will help collect the request handlers from every module.
+const mswPlugin = new MswPlugin();
+
+const runtime = new Runtime({
+ loggers: [new ConsoleLogger()],
+ plugins: [mswPlugin],
+ sessionAccessor
+});
+
+registerLocalModules([registerShell(sessionManager, { host: "@endpoints/host" }), registerHost, registerLocalModule], runtime);
+
+registerRemoteModules(Remotes, runtime).then(() => {
+ if (process.env.USE_MSW) {
+ // Files including an import to the "msw" package are included dynamically to prevent adding
+ // MSW stuff to the bundled when it's not used.
+ import("../mocks/browser.ts").then(({ startMsw }) => {
+ // Will start MSW with the request handlers provided by every module.
+ startMsw(mswPlugin.requestHandlers);
+
+ // Indicate to resources that are dependent on MSW that the service has been started.
+ setMswAsStarted();
+ });
+ }
+});
+
+const root = createRoot(document.getElementById("root")!);
+
+root.render(
+
+
+
+
+
+);
diff --git a/samples/endpoints/host/src/index.ts b/samples/endpoints/host/src/index.ts
new file mode 100644
index 000000000..93cf609d8
--- /dev/null
+++ b/samples/endpoints/host/src/index.ts
@@ -0,0 +1,10 @@
+// Importing a bootstrap file is required when sharing dependencies between the host and the remotes.
+// Otherwise we get: Uncaught Error: Shared module is not available for eager consumption
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore doesn't support file extension.
+import("./bootstrap");
+
+// TS1208: 'index.ts' cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an
+// empty 'export {}' statement to make it a module.
+export { };
+
diff --git a/samples/endpoints/host/src/register.tsx b/samples/endpoints/host/src/register.tsx
new file mode 100644
index 000000000..b45901d30
--- /dev/null
+++ b/samples/endpoints/host/src/register.tsx
@@ -0,0 +1,60 @@
+import { getMswPlugin } from "@squide/msw";
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import type { ReactNode } from "react";
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ refetchOnWindowFocus: false,
+ retry: failureCount => {
+ return failureCount <= 2;
+ }
+ }
+ }
+});
+
+function Providers({ children }: { children: ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+
+function registerRoutes(runtime: Runtime) {
+ runtime.registerRoute({
+ index: true,
+ lazy: async () => {
+ const { HomePage } = await import("./HomePage.tsx");
+
+ return {
+ element:
+ };
+ }
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Home",
+ $priority: 999,
+ to: "/"
+ });
+}
+
+async function registerMsw(runtime: Runtime) {
+ if (process.env.USE_MSW) {
+ const mswPlugin = getMswPlugin(runtime);
+
+ // Files including an import to the "msw" package are included dynamically to prevent adding
+ // MSW stuff to the bundled when it's not used.
+ const requestHandlers = (await import("../mocks/handlers.ts")).requestHandlers;
+
+ mswPlugin.registerRequestHandlers(requestHandlers);
+ }
+}
+
+export const registerHost: ModuleRegisterFunction = runtime => {
+ registerRoutes(runtime);
+
+ return registerMsw(runtime);
+};
diff --git a/samples/endpoints/host/src/session.ts b/samples/endpoints/host/src/session.ts
new file mode 100644
index 000000000..1836d503c
--- /dev/null
+++ b/samples/endpoints/host/src/session.ts
@@ -0,0 +1,24 @@
+import type { Session, SessionManager } from "@endpoints/shared";
+import type { SessionAccessorFunction } from "@squide/react-router";
+
+export class InMemorySessionManager implements SessionManager {
+ #session?: Session;
+
+ setSession(session: Session) {
+ this.#session = session;
+ }
+
+ getSession() {
+ return this.#session;
+ }
+
+ clearSession() {
+ this.#session = undefined;
+ }
+}
+
+export const sessionManager = new InMemorySessionManager();
+
+export const sessionAccessor: SessionAccessorFunction = () => {
+ return sessionManager.getSession();
+};
diff --git a/samples/endpoints/host/swc.build.js b/samples/endpoints/host/swc.build.js
new file mode 100644
index 000000000..7e0820823
--- /dev/null
+++ b/samples/endpoints/host/swc.build.js
@@ -0,0 +1,7 @@
+// @ts-check
+
+import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs";
+
+const targets = browserslistToSwc();
+
+export const swcConfig = defineBuildConfig(targets);
diff --git a/samples/endpoints/host/swc.dev.js b/samples/endpoints/host/swc.dev.js
new file mode 100644
index 000000000..9d6fb9fa3
--- /dev/null
+++ b/samples/endpoints/host/swc.dev.js
@@ -0,0 +1,7 @@
+// @ts-check
+
+import { browserslistToSwc, defineDevConfig } from "@workleap/swc-configs";
+
+const targets = browserslistToSwc();
+
+export const swcConfig = defineDevConfig(targets);
diff --git a/samples/endpoints/host/tsconfig.json b/samples/endpoints/host/tsconfig.json
new file mode 100644
index 000000000..3f837ee64
--- /dev/null
+++ b/samples/endpoints/host/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "extends": "@workleap/typescript-configs/web-application.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/msw": ["../../../packages/msw/src/index.ts"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"],
+ "@endpoints/shell": ["../shell/src/index.ts"],
+ "@endpoints/shared": ["../shared/src/index.ts"],
+ "@endpoints/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"],
+ "@endpoints/local-module": ["../local-module/src/register.ts"]
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/samples/endpoints/host/webpack.build.js b/samples/endpoints/host/webpack.build.js
new file mode 100644
index 000000000..28b1cc447
--- /dev/null
+++ b/samples/endpoints/host/webpack.build.js
@@ -0,0 +1,21 @@
+// @ts-check
+
+import { defineBuildHostConfig } from "@squide/webpack-module-federation/defineConfig.js";
+import { swcConfig } from "./swc.build.js";
+
+// The trailing / is very important, otherwise paths will not be resolved correctly.
+const publicPath = process.env.NETLIFY === "true" ? "https://squide-endpoints-host.netlify.app/" : "http://localhost:8080/";
+
+export default defineBuildHostConfig(swcConfig, "host", publicPath, {
+ sharedDependencies: {
+ "@endpoints/shared": {
+ singleton: true,
+ eager: true
+ }
+ },
+ environmentVariables: {
+ "NETLIFY": process.env.NETLIFY === "true",
+ "USE_MSW": process.env.USE_MSW === "true"
+ }
+});
+
diff --git a/samples/endpoints/host/webpack.dev.js b/samples/endpoints/host/webpack.dev.js
new file mode 100644
index 000000000..2678e2d89
--- /dev/null
+++ b/samples/endpoints/host/webpack.dev.js
@@ -0,0 +1,18 @@
+// @ts-check
+
+import { defineDevHostConfig } from "@squide/webpack-module-federation/defineConfig.js";
+import { swcConfig } from "./swc.dev.js";
+
+export default defineDevHostConfig(swcConfig, "host", 8080, {
+ overlay: false,
+ sharedDependencies: {
+ "@endpoints/shared": {
+ singleton: true,
+ eager: true
+ }
+ },
+ environmentVariables: {
+ "NETLIFY": process.env.NETLIFY === "true",
+ "USE_MSW": process.env.USE_MSW === "true"
+ }
+});
diff --git a/samples/endpoints/local-module/.browserslistrc b/samples/endpoints/local-module/.browserslistrc
new file mode 100644
index 000000000..f8a8f866a
--- /dev/null
+++ b/samples/endpoints/local-module/.browserslistrc
@@ -0,0 +1 @@
+extends @workleap/browserslist-config
diff --git a/samples/endpoints/local-module/.eslintrc.json b/samples/endpoints/local-module/.eslintrc.json
new file mode 100644
index 000000000..bf0564209
--- /dev/null
+++ b/samples/endpoints/local-module/.eslintrc.json
@@ -0,0 +1,5 @@
+{
+ "$schema": "https://json.schemastore.org/eslintrc",
+ "root": true,
+ "extends": "plugin:@workleap/react-library"
+}
diff --git a/samples/endpoints/local-module/mocks/browser.ts b/samples/endpoints/local-module/mocks/browser.ts
new file mode 100644
index 000000000..337545e34
--- /dev/null
+++ b/samples/endpoints/local-module/mocks/browser.ts
@@ -0,0 +1,7 @@
+import { setupWorker, type RestHandler } from "msw";
+
+export function startMsw(requestHandlers: RestHandler[]) {
+ const worker = setupWorker(...requestHandlers);
+
+ worker.start();
+}
diff --git a/samples/endpoints/local-module/mocks/characterHandlers.ts b/samples/endpoints/local-module/mocks/characterHandlers.ts
new file mode 100644
index 000000000..e7dcb375f
--- /dev/null
+++ b/samples/endpoints/local-module/mocks/characterHandlers.ts
@@ -0,0 +1,60 @@
+/* eslint-disable max-len */
+
+import { rest, type RestHandler } from "msw";
+
+function simulateDelay(delay: number) {
+ return new Promise(resolve => {
+ setTimeout(() => {
+ resolve(undefined);
+ }, delay);
+ });
+}
+
+export const characterHandlers: RestHandler[] = [
+ rest.get("/api/character/1,2", async (req, res, ctx) => {
+ await simulateDelay(2000);
+
+ return res(
+ ctx.status(200),
+ ctx.json([{
+ "id": 1,
+ "name": "Rick Sanchez",
+ "status": "Alive",
+ "species": "Human",
+ "type": "",
+ "gender": "Male",
+ "origin": {
+ "name": "Earth (C-137)",
+ "url": "https://rickandmortyapi.com/api/location/1"
+ },
+ "location": {
+ "name": "Citadel of Ricks",
+ "url": "https://rickandmortyapi.com/api/location/3"
+ },
+ "image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg",
+ "episode": ["https://rickandmortyapi.com/api/episode/1", "https://rickandmortyapi.com/api/episode/2", "https://rickandmortyapi.com/api/episode/3", "https://rickandmortyapi.com/api/episode/4", "https://rickandmortyapi.com/api/episode/5", "https://rickandmortyapi.com/api/episode/6", "https://rickandmortyapi.com/api/episode/7", "https://rickandmortyapi.com/api/episode/8", "https://rickandmortyapi.com/api/episode/9", "https://rickandmortyapi.com/api/episode/10", "https://rickandmortyapi.com/api/episode/11", "https://rickandmortyapi.com/api/episode/12", "https://rickandmortyapi.com/api/episode/13", "https://rickandmortyapi.com/api/episode/14", "https://rickandmortyapi.com/api/episode/15", "https://rickandmortyapi.com/api/episode/16", "https://rickandmortyapi.com/api/episode/17", "https://rickandmortyapi.com/api/episode/18", "https://rickandmortyapi.com/api/episode/19", "https://rickandmortyapi.com/api/episode/20", "https://rickandmortyapi.com/api/episode/21", "https://rickandmortyapi.com/api/episode/22", "https://rickandmortyapi.com/api/episode/23", "https://rickandmortyapi.com/api/episode/24", "https://rickandmortyapi.com/api/episode/25", "https://rickandmortyapi.com/api/episode/26", "https://rickandmortyapi.com/api/episode/27", "https://rickandmortyapi.com/api/episode/28", "https://rickandmortyapi.com/api/episode/29", "https://rickandmortyapi.com/api/episode/30", "https://rickandmortyapi.com/api/episode/31", "https://rickandmortyapi.com/api/episode/32", "https://rickandmortyapi.com/api/episode/33", "https://rickandmortyapi.com/api/episode/34", "https://rickandmortyapi.com/api/episode/35", "https://rickandmortyapi.com/api/episode/36", "https://rickandmortyapi.com/api/episode/37", "https://rickandmortyapi.com/api/episode/38", "https://rickandmortyapi.com/api/episode/39", "https://rickandmortyapi.com/api/episode/40", "https://rickandmortyapi.com/api/episode/41", "https://rickandmortyapi.com/api/episode/42", "https://rickandmortyapi.com/api/episode/43", "https://rickandmortyapi.com/api/episode/44", "https://rickandmortyapi.com/api/episode/45", "https://rickandmortyapi.com/api/episode/46", "https://rickandmortyapi.com/api/episode/47", "https://rickandmortyapi.com/api/episode/48", "https://rickandmortyapi.com/api/episode/49", "https://rickandmortyapi.com/api/episode/50", "https://rickandmortyapi.com/api/episode/51"],
+ "url": "https://rickandmortyapi.com/api/character/1",
+ "created": "2017-11-04T18:48:46.250Z"
+ }, {
+ "id": 2,
+ "name": "Morty Smith",
+ "status": "Alive",
+ "species": "Human",
+ "type": "",
+ "gender": "Male",
+ "origin": {
+ "name": "unknown",
+ "url": ""
+ },
+ "location": {
+ "name": "Citadel of Ricks",
+ "url": "https://rickandmortyapi.com/api/location/3"
+ },
+ "image": "https://rickandmortyapi.com/api/character/avatar/2.jpeg",
+ "episode": ["https://rickandmortyapi.com/api/episode/1", "https://rickandmortyapi.com/api/episode/2", "https://rickandmortyapi.com/api/episode/3", "https://rickandmortyapi.com/api/episode/4", "https://rickandmortyapi.com/api/episode/5", "https://rickandmortyapi.com/api/episode/6", "https://rickandmortyapi.com/api/episode/7", "https://rickandmortyapi.com/api/episode/8", "https://rickandmortyapi.com/api/episode/9", "https://rickandmortyapi.com/api/episode/10", "https://rickandmortyapi.com/api/episode/11", "https://rickandmortyapi.com/api/episode/12", "https://rickandmortyapi.com/api/episode/13", "https://rickandmortyapi.com/api/episode/14", "https://rickandmortyapi.com/api/episode/15", "https://rickandmortyapi.com/api/episode/16", "https://rickandmortyapi.com/api/episode/17", "https://rickandmortyapi.com/api/episode/18", "https://rickandmortyapi.com/api/episode/19", "https://rickandmortyapi.com/api/episode/20", "https://rickandmortyapi.com/api/episode/21", "https://rickandmortyapi.com/api/episode/22", "https://rickandmortyapi.com/api/episode/23", "https://rickandmortyapi.com/api/episode/24", "https://rickandmortyapi.com/api/episode/25", "https://rickandmortyapi.com/api/episode/26", "https://rickandmortyapi.com/api/episode/27", "https://rickandmortyapi.com/api/episode/28", "https://rickandmortyapi.com/api/episode/29", "https://rickandmortyapi.com/api/episode/30", "https://rickandmortyapi.com/api/episode/31", "https://rickandmortyapi.com/api/episode/32", "https://rickandmortyapi.com/api/episode/33", "https://rickandmortyapi.com/api/episode/34", "https://rickandmortyapi.com/api/episode/35", "https://rickandmortyapi.com/api/episode/36", "https://rickandmortyapi.com/api/episode/37", "https://rickandmortyapi.com/api/episode/38", "https://rickandmortyapi.com/api/episode/39", "https://rickandmortyapi.com/api/episode/40", "https://rickandmortyapi.com/api/episode/41", "https://rickandmortyapi.com/api/episode/42", "https://rickandmortyapi.com/api/episode/43", "https://rickandmortyapi.com/api/episode/44", "https://rickandmortyapi.com/api/episode/45", "https://rickandmortyapi.com/api/episode/46", "https://rickandmortyapi.com/api/episode/47", "https://rickandmortyapi.com/api/episode/48", "https://rickandmortyapi.com/api/episode/49", "https://rickandmortyapi.com/api/episode/50", "https://rickandmortyapi.com/api/episode/51"],
+ "url": "https://rickandmortyapi.com/api/character/2",
+ "created": "2017-11-04T18:50:21.651Z"
+ }])
+ );
+ })
+];
diff --git a/samples/endpoints/local-module/mocks/handlers.ts b/samples/endpoints/local-module/mocks/handlers.ts
new file mode 100644
index 000000000..9d1c5e9ee
--- /dev/null
+++ b/samples/endpoints/local-module/mocks/handlers.ts
@@ -0,0 +1,4 @@
+import type { RestHandler } from "msw";
+import { characterHandlers } from "./characterHandlers.ts";
+
+export const requestHandlers: RestHandler[] = characterHandlers;
diff --git a/samples/endpoints/local-module/nodemon.isolated.json b/samples/endpoints/local-module/nodemon.isolated.json
new file mode 100644
index 000000000..f5a800db0
--- /dev/null
+++ b/samples/endpoints/local-module/nodemon.isolated.json
@@ -0,0 +1,5 @@
+{
+ "watch": ["swc.dev.js", "webpack.dev.js"],
+ "exec": "webpack serve --config webpack.config.js",
+ "verbose": true
+}
diff --git a/samples/endpoints/local-module/nodemon.json b/samples/endpoints/local-module/nodemon.json
new file mode 100644
index 000000000..79a8918cc
--- /dev/null
+++ b/samples/endpoints/local-module/nodemon.json
@@ -0,0 +1,5 @@
+{
+ "watch": ["tsup.dev.ts"],
+ "exec": "tsup --config ./tsup.dev.ts",
+ "verbose": true
+}
diff --git a/samples/endpoints/local-module/package.json b/samples/endpoints/local-module/package.json
new file mode 100644
index 000000000..7bfc2b9a3
--- /dev/null
+++ b/samples/endpoints/local-module/package.json
@@ -0,0 +1,71 @@
+{
+ "name": "@endpoints/local-module",
+ "author": "Workleap",
+ "version": "0.0.0",
+ "description": "Local module to showcase @squide.",
+ "private": true,
+ "license": "Apache-2.0",
+ "type": "module",
+ "exports": {
+ ".": {
+ "import": "./dist/register.js",
+ "types": "./dist/register.d.ts",
+ "default": "./dist/register.js"
+ }
+ },
+ "scripts": {
+ "dev": "cross-env USE_MSW=true nodemon",
+ "dev-isolated": "cross-env USE_MSW=true ISOLATED=true nodemon --config nodemon.isolated.json",
+ "build": "cross-env USE_MSW=true tsup --config ./tsup.build.ts",
+ "serve-build": "pnpm build"
+ },
+ "peerDependencies": {
+ "@endpoints/shared": "*",
+ "@endpoints/shell": "*",
+ "@squide/fakes": "*",
+ "@squide/msw": "*",
+ "@squide/react-router": "*",
+ "@tanstack/react-query": "rc",
+ "axios": "*",
+ "msw": "*",
+ "react": "*",
+ "react-dom": "*",
+ "react-router-dom": "*"
+ },
+ "devDependencies": {
+ "@swc/core": "1.3.93",
+ "@swc/helpers": "0.5.3",
+ "@tanstack/react-query-devtools": "^5.0.0",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@types/webpack": "5.28.3",
+ "@workleap/browserslist-config": "2.0.0",
+ "@workleap/eslint-plugin": "3.0.0",
+ "@workleap/swc-configs": "2.1.2",
+ "@workleap/tsup-configs": "3.0.1",
+ "@workleap/typescript-configs": "3.0.2",
+ "@workleap/webpack-configs": "1.1.0",
+ "browserslist": "4.22.1",
+ "cross-env": "7.0.3",
+ "nodemon": "3.0.1",
+ "tsup": "7.2.0",
+ "typescript": "5.2.2",
+ "webpack": "5.89.0",
+ "webpack-cli": "5.1.4",
+ "webpack-dev-server": "4.15.1"
+ },
+ "dependencies": {
+ "@endpoints/shared": "workspace:*",
+ "@endpoints/shell": "workspace:*",
+ "@squide/fakes": "workspace:*",
+ "@squide/msw": "workspace:*",
+ "@squide/react-router": "workspace:*",
+ "@tanstack/react-query": "^5.0.0",
+ "axios": "1.5.1",
+ "msw": "1.3.2",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-error-boundary": "4.0.11",
+ "react-router-dom": "6.17.0"
+ }
+}
diff --git a/samples/endpoints/local-module/public/favicon.png b/samples/endpoints/local-module/public/favicon.png
new file mode 100644
index 000000000..47157f6b0
Binary files /dev/null and b/samples/endpoints/local-module/public/favicon.png differ
diff --git a/samples/endpoints/local-module/public/index.html b/samples/endpoints/local-module/public/index.html
new file mode 100644
index 000000000..98accb408
--- /dev/null
+++ b/samples/endpoints/local-module/public/index.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/samples/endpoints/local-module/public/mockServiceWorker.js b/samples/endpoints/local-module/public/mockServiceWorker.js
new file mode 100644
index 000000000..8ee70b3e4
--- /dev/null
+++ b/samples/endpoints/local-module/public/mockServiceWorker.js
@@ -0,0 +1,303 @@
+/* eslint-disable */
+/* tslint:disable */
+
+/**
+ * Mock Service Worker (1.2.2).
+ * @see https://github.com/mswjs/msw
+ * - Please do NOT modify this file.
+ * - Please do NOT serve this file on production.
+ */
+
+const INTEGRITY_CHECKSUM = '3d6b9f06410d179a7f7404d4bf4c3c70'
+const activeClientIds = new Set()
+
+self.addEventListener('install', function () {
+ self.skipWaiting()
+})
+
+self.addEventListener('activate', function (event) {
+ event.waitUntil(self.clients.claim())
+})
+
+self.addEventListener('message', async function (event) {
+ const clientId = event.source.id
+
+ if (!clientId || !self.clients) {
+ return
+ }
+
+ const client = await self.clients.get(clientId)
+
+ if (!client) {
+ return
+ }
+
+ const allClients = await self.clients.matchAll({
+ type: 'window',
+ })
+
+ switch (event.data) {
+ case 'KEEPALIVE_REQUEST': {
+ sendToClient(client, {
+ type: 'KEEPALIVE_RESPONSE',
+ })
+ break
+ }
+
+ case 'INTEGRITY_CHECK_REQUEST': {
+ sendToClient(client, {
+ type: 'INTEGRITY_CHECK_RESPONSE',
+ payload: INTEGRITY_CHECKSUM,
+ })
+ break
+ }
+
+ case 'MOCK_ACTIVATE': {
+ activeClientIds.add(clientId)
+
+ sendToClient(client, {
+ type: 'MOCKING_ENABLED',
+ payload: true,
+ })
+ break
+ }
+
+ case 'MOCK_DEACTIVATE': {
+ activeClientIds.delete(clientId)
+ break
+ }
+
+ case 'CLIENT_CLOSED': {
+ activeClientIds.delete(clientId)
+
+ const remainingClients = allClients.filter((client) => {
+ return client.id !== clientId
+ })
+
+ // Unregister itself when there are no more clients
+ if (remainingClients.length === 0) {
+ self.registration.unregister()
+ }
+
+ break
+ }
+ }
+})
+
+self.addEventListener('fetch', function (event) {
+ const { request } = event
+ const accept = request.headers.get('accept') || ''
+
+ // Bypass server-sent events.
+ if (accept.includes('text/event-stream')) {
+ return
+ }
+
+ // Bypass navigation requests.
+ if (request.mode === 'navigate') {
+ return
+ }
+
+ // Opening the DevTools triggers the "only-if-cached" request
+ // that cannot be handled by the worker. Bypass such requests.
+ if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
+ return
+ }
+
+ // Bypass all requests when there are no active clients.
+ // Prevents the self-unregistered worked from handling requests
+ // after it's been deleted (still remains active until the next reload).
+ if (activeClientIds.size === 0) {
+ return
+ }
+
+ // Generate unique request ID.
+ const requestId = Math.random().toString(16).slice(2)
+
+ event.respondWith(
+ handleRequest(event, requestId).catch((error) => {
+ if (error.name === 'NetworkError') {
+ console.warn(
+ '[MSW] Successfully emulated a network error for the "%s %s" request.',
+ request.method,
+ request.url,
+ )
+ return
+ }
+
+ // At this point, any exception indicates an issue with the original request/response.
+ console.error(
+ `\
+[MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`,
+ request.method,
+ request.url,
+ `${error.name}: ${error.message}`,
+ )
+ }),
+ )
+})
+
+async function handleRequest(event, requestId) {
+ const client = await resolveMainClient(event)
+ const response = await getResponse(event, client, requestId)
+
+ // Send back the response clone for the "response:*" life-cycle events.
+ // Ensure MSW is active and ready to handle the message, otherwise
+ // this message will pend indefinitely.
+ if (client && activeClientIds.has(client.id)) {
+ ;(async function () {
+ const clonedResponse = response.clone()
+ sendToClient(client, {
+ type: 'RESPONSE',
+ payload: {
+ requestId,
+ type: clonedResponse.type,
+ ok: clonedResponse.ok,
+ status: clonedResponse.status,
+ statusText: clonedResponse.statusText,
+ body:
+ clonedResponse.body === null ? null : await clonedResponse.text(),
+ headers: Object.fromEntries(clonedResponse.headers.entries()),
+ redirected: clonedResponse.redirected,
+ },
+ })
+ })()
+ }
+
+ return response
+}
+
+// Resolve the main client for the given event.
+// Client that issues a request doesn't necessarily equal the client
+// that registered the worker. It's with the latter the worker should
+// communicate with during the response resolving phase.
+async function resolveMainClient(event) {
+ const client = await self.clients.get(event.clientId)
+
+ if (client?.frameType === 'top-level') {
+ return client
+ }
+
+ const allClients = await self.clients.matchAll({
+ type: 'window',
+ })
+
+ return allClients
+ .filter((client) => {
+ // Get only those clients that are currently visible.
+ return client.visibilityState === 'visible'
+ })
+ .find((client) => {
+ // Find the client ID that's recorded in the
+ // set of clients that have registered the worker.
+ return activeClientIds.has(client.id)
+ })
+}
+
+async function getResponse(event, client, requestId) {
+ const { request } = event
+ const clonedRequest = request.clone()
+
+ function passthrough() {
+ // Clone the request because it might've been already used
+ // (i.e. its body has been read and sent to the client).
+ const headers = Object.fromEntries(clonedRequest.headers.entries())
+
+ // Remove MSW-specific request headers so the bypassed requests
+ // comply with the server's CORS preflight check.
+ // Operate with the headers as an object because request "Headers"
+ // are immutable.
+ delete headers['x-msw-bypass']
+
+ return fetch(clonedRequest, { headers })
+ }
+
+ // Bypass mocking when the client is not active.
+ if (!client) {
+ return passthrough()
+ }
+
+ // Bypass initial page load requests (i.e. static assets).
+ // The absence of the immediate/parent client in the map of the active clients
+ // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
+ // and is not ready to handle requests.
+ if (!activeClientIds.has(client.id)) {
+ return passthrough()
+ }
+
+ // Bypass requests with the explicit bypass header.
+ // Such requests can be issued by "ctx.fetch()".
+ if (request.headers.get('x-msw-bypass') === 'true') {
+ return passthrough()
+ }
+
+ // Notify the client that a request has been intercepted.
+ const clientMessage = await sendToClient(client, {
+ type: 'REQUEST',
+ payload: {
+ id: requestId,
+ url: request.url,
+ method: request.method,
+ headers: Object.fromEntries(request.headers.entries()),
+ cache: request.cache,
+ mode: request.mode,
+ credentials: request.credentials,
+ destination: request.destination,
+ integrity: request.integrity,
+ redirect: request.redirect,
+ referrer: request.referrer,
+ referrerPolicy: request.referrerPolicy,
+ body: await request.text(),
+ bodyUsed: request.bodyUsed,
+ keepalive: request.keepalive,
+ },
+ })
+
+ switch (clientMessage.type) {
+ case 'MOCK_RESPONSE': {
+ return respondWithMock(clientMessage.data)
+ }
+
+ case 'MOCK_NOT_FOUND': {
+ return passthrough()
+ }
+
+ case 'NETWORK_ERROR': {
+ const { name, message } = clientMessage.data
+ const networkError = new Error(message)
+ networkError.name = name
+
+ // Rejecting a "respondWith" promise emulates a network error.
+ throw networkError
+ }
+ }
+
+ return passthrough()
+}
+
+function sendToClient(client, message) {
+ return new Promise((resolve, reject) => {
+ const channel = new MessageChannel()
+
+ channel.port1.onmessage = (event) => {
+ if (event.data && event.data.error) {
+ return reject(event.data.error)
+ }
+
+ resolve(event.data)
+ }
+
+ client.postMessage(message, [channel.port2])
+ })
+}
+
+function sleep(timeMs) {
+ return new Promise((resolve) => {
+ setTimeout(resolve, timeMs)
+ })
+}
+
+async function respondWithMock(response) {
+ await sleep(response.delay)
+ return new Response(response.body, response)
+}
diff --git a/samples/endpoints/local-module/src/CharactersTab.tsx b/samples/endpoints/local-module/src/CharactersTab.tsx
new file mode 100644
index 000000000..de9682f89
--- /dev/null
+++ b/samples/endpoints/local-module/src/CharactersTab.tsx
@@ -0,0 +1,38 @@
+import { useSuspenseQuery } from "@tanstack/react-query";
+import axios from "axios";
+
+interface Character {
+ id: number;
+ name: string;
+ species: string;
+}
+
+export function CharactersTab() {
+ const { data: characters } = useSuspenseQuery({ queryKey: ["/api/character/1,2"], queryFn: () => {
+ return axios
+ .get("/api/character/1,2")
+ .then(({ data }) => {
+ return data;
+ });
+ } });
+
+ return (
+
+
Characters
+
This tab is served by @endpoints/local-module
+
+ {characters.map((x: Character) => {
+ return (
+
+ Id: {x.id}
+ -
+ Name: {x.name}
+ -
+ Species: {x.species}
+
+ );
+ })}
+
+
+ );
+}
diff --git a/samples/endpoints/local-module/src/SubscriptionPage.tsx b/samples/endpoints/local-module/src/SubscriptionPage.tsx
new file mode 100644
index 000000000..324689ad3
--- /dev/null
+++ b/samples/endpoints/local-module/src/SubscriptionPage.tsx
@@ -0,0 +1,22 @@
+import { toSubscriptionStatusLabel, useSubscription } from "@endpoints/shared";
+
+export function SubscriptionPage() {
+ const subscription = useSubscription();
+
+ return (
+ <>
+ Subscription
+ This page is served by @endpoints/local-module
+
+ Company: {subscription?.company}
+
+
+ Contact: {subscription?.contact}
+
+
+ Status: {toSubscriptionStatusLabel(subscription?.status)}
+
+
+ >
+ );
+}
diff --git a/samples/endpoints/local-module/src/dev/App.tsx b/samples/endpoints/local-module/src/dev/App.tsx
new file mode 100644
index 000000000..bb4777f10
--- /dev/null
+++ b/samples/endpoints/local-module/src/dev/App.tsx
@@ -0,0 +1,18 @@
+import { LoggerTelemetryService } from "@endpoints/shared";
+import { AppRouter } from "@endpoints/shell";
+import { useLogger } from "@squide/react-router";
+import { sessionManager } from "./session.ts";
+
+export function App() {
+ const logger = useLogger();
+
+ const telemetryService = new LoggerTelemetryService(logger);
+
+ return (
+
+ );
+}
diff --git a/sample/local-module/src/dev/DevHome.tsx b/samples/endpoints/local-module/src/dev/DevHomePage.tsx
similarity index 78%
rename from sample/local-module/src/dev/DevHome.tsx
rename to samples/endpoints/local-module/src/dev/DevHomePage.tsx
index 8b9043ec5..f7e62419b 100644
--- a/sample/local-module/src/dev/DevHome.tsx
+++ b/samples/endpoints/local-module/src/dev/DevHomePage.tsx
@@ -1,4 +1,4 @@
-export default function DevHome() {
+export function DevHomePage() {
return (
Remote module development home page
diff --git a/samples/endpoints/local-module/src/dev/index.tsx b/samples/endpoints/local-module/src/dev/index.tsx
new file mode 100644
index 000000000..dfd929f43
--- /dev/null
+++ b/samples/endpoints/local-module/src/dev/index.tsx
@@ -0,0 +1,45 @@
+import { registerShell } from "@endpoints/shell";
+import { MswPlugin, setMswAsStarted } from "@squide/msw";
+import { ConsoleLogger, Runtime, RuntimeContext, registerLocalModules } from "@squide/react-router";
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import { registerLocalModule } from "../register.tsx";
+import { App } from "./App.tsx";
+import { registerDev } from "./register.tsx";
+import { sessionAccessor, sessionManager } from "./session.ts";
+
+const mswPlugin = new MswPlugin();
+
+// Create the shell runtime.
+// Services, loggers and sessionAccessor could be reuse through a shared packages or faked when in isolation.
+const runtime = new Runtime({
+ loggers: [new ConsoleLogger()],
+ plugins: [mswPlugin],
+ sessionAccessor
+});
+
+registerLocalModules([registerShell(sessionManager), registerDev, registerLocalModule], runtime);
+
+// Register MSW after the local modules has been registered since the request handlers
+// will be registered by the modules.
+if (process.env.USE_MSW) {
+ // Files including an import to the "msw" package are included dynamically to prevent adding
+ // MSW stuff to the bundled when it's not used.
+ import("../../mocks/browser.ts").then(({ startMsw }) => {
+ startMsw(mswPlugin.requestHandlers);
+
+ setMswAsStarted();
+ });
+}
+
+const root = createRoot(document.getElementById("root")!);
+
+root.render(
+
+
+
+
+
+);
+
+
diff --git a/samples/endpoints/local-module/src/dev/register.tsx b/samples/endpoints/local-module/src/dev/register.tsx
new file mode 100644
index 000000000..9628ce656
--- /dev/null
+++ b/samples/endpoints/local-module/src/dev/register.tsx
@@ -0,0 +1,9 @@
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { DevHomePage } from "./DevHomePage.tsx";
+
+export const registerDev: ModuleRegisterFunction
= runtime => {
+ runtime.registerRoute({
+ index: true,
+ element:
+ });
+};
diff --git a/samples/endpoints/local-module/src/dev/session.ts b/samples/endpoints/local-module/src/dev/session.ts
new file mode 100644
index 000000000..5417cd9d9
--- /dev/null
+++ b/samples/endpoints/local-module/src/dev/session.ts
@@ -0,0 +1,9 @@
+import type { Session } from "@endpoints/shared";
+import { LocalStorageSessionManager } from "@squide/fakes";
+import type { SessionAccessorFunction } from "@squide/react-router";
+
+export const sessionManager = new LocalStorageSessionManager();
+
+export const sessionAccessor: SessionAccessorFunction = () => {
+ return sessionManager.getSession();
+};
diff --git a/samples/endpoints/local-module/src/register.tsx b/samples/endpoints/local-module/src/register.tsx
new file mode 100644
index 000000000..8cecc8d9f
--- /dev/null
+++ b/samples/endpoints/local-module/src/register.tsx
@@ -0,0 +1,100 @@
+import { getMswPlugin } from "@squide/msw";
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
+import type { ReactNode } from "react";
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ refetchOnWindowFocus: false,
+ retry: failureCount => {
+ return failureCount <= 2;
+ }
+ }
+ }
+});
+
+function Providers({ children }: { children: ReactNode }) {
+ return (
+
+ {children}
+ {process.env.ISOLATED && (
+
+ )}
+
+ );
+}
+
+function registerRoutes(runtime: Runtime) {
+ runtime.registerRoute({
+ path: "/subscription",
+ lazy: async () => {
+ const { SubscriptionPage } = await import("./SubscriptionPage.tsx");
+
+ return {
+ element:
+ };
+ }
+ });
+
+ runtime.registerRoute({
+ path: "/federated-tabs",
+ lazy: async () => {
+ const { FederatedTabsLayout } = await import("@endpoints/shared/FederatedTabsLayout.tsx");
+
+ return {
+ element:
+ };
+ }
+ });
+
+ runtime.registerRoute({
+ index: true,
+ lazy: async () => {
+ const { CharactersTab } = await import("./CharactersTab.tsx");
+
+ return {
+ element:
+ };
+ }
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Subscription",
+ to: "/subscription"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Tabs",
+ $priority: 100,
+ to: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Characters",
+ to: "/federated-tabs"
+ }, {
+ menuId: "/federated-tabs"
+ });
+}
+
+async function registerMsw(runtime: Runtime) {
+ if (process.env.USE_MSW) {
+ const mswPlugin = getMswPlugin(runtime);
+
+ // Files including an import to the "msw" package are included dynamically to prevent adding
+ // MSW stuff to the bundled when it's not used.
+ const requestHandlers = (await import("../mocks/handlers.ts")).requestHandlers;
+
+ mswPlugin.registerRequestHandlers(requestHandlers);
+ }
+}
+
+export const registerLocalModule: ModuleRegisterFunction = runtime => {
+ registerRoutes(runtime);
+
+ return registerMsw(runtime);
+};
diff --git a/samples/endpoints/local-module/swc.config.js b/samples/endpoints/local-module/swc.config.js
new file mode 100644
index 000000000..9d6fb9fa3
--- /dev/null
+++ b/samples/endpoints/local-module/swc.config.js
@@ -0,0 +1,7 @@
+// @ts-check
+
+import { browserslistToSwc, defineDevConfig } from "@workleap/swc-configs";
+
+const targets = browserslistToSwc();
+
+export const swcConfig = defineDevConfig(targets);
diff --git a/samples/endpoints/local-module/tsconfig.json b/samples/endpoints/local-module/tsconfig.json
new file mode 100644
index 000000000..ddec9262d
--- /dev/null
+++ b/samples/endpoints/local-module/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "@workleap/typescript-configs/library.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/msw": ["../../../packages/msw/src/index.ts"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"],
+ "@endpoints/shell": ["../shell/src/index.ts"],
+ "@endpoints/shared": ["../shared/src/index.ts"],
+ "@endpoints/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"]
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/samples/endpoints/local-module/tsup.build.ts b/samples/endpoints/local-module/tsup.build.ts
new file mode 100644
index 000000000..1b2c65a89
--- /dev/null
+++ b/samples/endpoints/local-module/tsup.build.ts
@@ -0,0 +1,3 @@
+import { defineBuildConfig } from "@workleap/tsup-configs";
+
+export default defineBuildConfig();
diff --git a/samples/endpoints/local-module/tsup.dev.ts b/samples/endpoints/local-module/tsup.dev.ts
new file mode 100644
index 000000000..8aa2904c8
--- /dev/null
+++ b/samples/endpoints/local-module/tsup.dev.ts
@@ -0,0 +1,3 @@
+import { defineDevConfig } from "@workleap/tsup-configs";
+
+export default defineDevConfig();
diff --git a/samples/endpoints/local-module/webpack.config.js b/samples/endpoints/local-module/webpack.config.js
new file mode 100644
index 000000000..f93dd6fec
--- /dev/null
+++ b/samples/endpoints/local-module/webpack.config.js
@@ -0,0 +1,16 @@
+// @ts-check
+
+import { defineDevConfig } from "@workleap/webpack-configs";
+import path from "node:path";
+import { swcConfig } from "./swc.config.js";
+
+export default defineDevConfig(swcConfig, {
+ cache: false,
+ entry: path.resolve("./src/dev/index.tsx"),
+ overlay: false,
+ environmentVariables: {
+ "ISOLATED": process.env.ISOLATED === "true",
+ "USE_MSW": process.env.USE_MSW === "true"
+ }
+});
+
diff --git a/samples/endpoints/remote-module/.browserslistrc b/samples/endpoints/remote-module/.browserslistrc
new file mode 100644
index 000000000..f8a8f866a
--- /dev/null
+++ b/samples/endpoints/remote-module/.browserslistrc
@@ -0,0 +1 @@
+extends @workleap/browserslist-config
diff --git a/samples/endpoints/remote-module/.eslintrc.json b/samples/endpoints/remote-module/.eslintrc.json
new file mode 100644
index 000000000..ab20e5046
--- /dev/null
+++ b/samples/endpoints/remote-module/.eslintrc.json
@@ -0,0 +1,5 @@
+{
+ "$schema": "https://json.schemastore.org/eslintrc",
+ "root": true,
+ "extends": "plugin:@workleap/web-application"
+}
diff --git a/samples/endpoints/remote-module/mocks/browser.ts b/samples/endpoints/remote-module/mocks/browser.ts
new file mode 100644
index 000000000..337545e34
--- /dev/null
+++ b/samples/endpoints/remote-module/mocks/browser.ts
@@ -0,0 +1,7 @@
+import { setupWorker, type RestHandler } from "msw";
+
+export function startMsw(requestHandlers: RestHandler[]) {
+ const worker = setupWorker(...requestHandlers);
+
+ worker.start();
+}
diff --git a/samples/endpoints/remote-module/mocks/episodeHandlers.ts b/samples/endpoints/remote-module/mocks/episodeHandlers.ts
new file mode 100644
index 000000000..9d0f2f7cf
--- /dev/null
+++ b/samples/endpoints/remote-module/mocks/episodeHandlers.ts
@@ -0,0 +1,72 @@
+/* eslint-disable max-len */
+
+import { rest, type RestHandler } from "msw";
+
+export const episodeHandlers: RestHandler[] = [
+ rest.get("/api/episode/1,2,3,4,5,6,7", async (req, res, ctx) => {
+ return res(
+ ctx.status(200),
+ ctx.json([{
+ "id": 1,
+ "name": "Pilot",
+ "air_date": "December 2, 2013",
+ "episode": "S01E01",
+ "characters": ["https://rickandmortyapi.com/api/character/1", "https://rickandmortyapi.com/api/character/2", "https://rickandmortyapi.com/api/character/35", "https://rickandmortyapi.com/api/character/38", "https://rickandmortyapi.com/api/character/62", "https://rickandmortyapi.com/api/character/92", "https://rickandmortyapi.com/api/character/127", "https://rickandmortyapi.com/api/character/144", "https://rickandmortyapi.com/api/character/158", "https://rickandmortyapi.com/api/character/175", "https://rickandmortyapi.com/api/character/179", "https://rickandmortyapi.com/api/character/181", "https://rickandmortyapi.com/api/character/239", "https://rickandmortyapi.com/api/character/249", "https://rickandmortyapi.com/api/character/271", "https://rickandmortyapi.com/api/character/338", "https://rickandmortyapi.com/api/character/394", "https://rickandmortyapi.com/api/character/395", "https://rickandmortyapi.com/api/character/435"],
+ "url": "https://rickandmortyapi.com/api/episode/1",
+ "created": "2017-11-10T12:56:33.798Z"
+ }, {
+ "id": 2,
+ "name": "Lawnmower Dog",
+ "air_date": "December 9, 2013",
+ "episode": "S01E02",
+ "characters": ["https://rickandmortyapi.com/api/character/1", "https://rickandmortyapi.com/api/character/2", "https://rickandmortyapi.com/api/character/38", "https://rickandmortyapi.com/api/character/46", "https://rickandmortyapi.com/api/character/63", "https://rickandmortyapi.com/api/character/80", "https://rickandmortyapi.com/api/character/175", "https://rickandmortyapi.com/api/character/221", "https://rickandmortyapi.com/api/character/239", "https://rickandmortyapi.com/api/character/246", "https://rickandmortyapi.com/api/character/304", "https://rickandmortyapi.com/api/character/305", "https://rickandmortyapi.com/api/character/306", "https://rickandmortyapi.com/api/character/329", "https://rickandmortyapi.com/api/character/338", "https://rickandmortyapi.com/api/character/396", "https://rickandmortyapi.com/api/character/397", "https://rickandmortyapi.com/api/character/398", "https://rickandmortyapi.com/api/character/405"],
+ "url": "https://rickandmortyapi.com/api/episode/2",
+ "created": "2017-11-10T12:56:33.916Z"
+ }, {
+ "id": 3,
+ "name": "Anatomy Park",
+ "air_date": "December 16, 2013",
+ "episode": "S01E03",
+ "characters": ["https://rickandmortyapi.com/api/character/1", "https://rickandmortyapi.com/api/character/2", "https://rickandmortyapi.com/api/character/12", "https://rickandmortyapi.com/api/character/17", "https://rickandmortyapi.com/api/character/38", "https://rickandmortyapi.com/api/character/45", "https://rickandmortyapi.com/api/character/96", "https://rickandmortyapi.com/api/character/97", "https://rickandmortyapi.com/api/character/98", "https://rickandmortyapi.com/api/character/99", "https://rickandmortyapi.com/api/character/100", "https://rickandmortyapi.com/api/character/101", "https://rickandmortyapi.com/api/character/108", "https://rickandmortyapi.com/api/character/112", "https://rickandmortyapi.com/api/character/114", "https://rickandmortyapi.com/api/character/169", "https://rickandmortyapi.com/api/character/175", "https://rickandmortyapi.com/api/character/186", "https://rickandmortyapi.com/api/character/201", "https://rickandmortyapi.com/api/character/268", "https://rickandmortyapi.com/api/character/300", "https://rickandmortyapi.com/api/character/302", "https://rickandmortyapi.com/api/character/338", "https://rickandmortyapi.com/api/character/356"],
+ "url": "https://rickandmortyapi.com/api/episode/3",
+ "created": "2017-11-10T12:56:34.022Z"
+ }, {
+ "id": 4,
+ "name": "M. Night Shaym-Aliens!",
+ "air_date": "January 13, 2014",
+ "episode": "S01E04",
+ "characters": ["https://rickandmortyapi.com/api/character/1", "https://rickandmortyapi.com/api/character/2", "https://rickandmortyapi.com/api/character/38", "https://rickandmortyapi.com/api/character/87", "https://rickandmortyapi.com/api/character/175", "https://rickandmortyapi.com/api/character/179", "https://rickandmortyapi.com/api/character/181", "https://rickandmortyapi.com/api/character/191", "https://rickandmortyapi.com/api/character/239", "https://rickandmortyapi.com/api/character/241", "https://rickandmortyapi.com/api/character/270", "https://rickandmortyapi.com/api/character/337", "https://rickandmortyapi.com/api/character/338"],
+ "url": "https://rickandmortyapi.com/api/episode/4",
+ "created": "2017-11-10T12:56:34.129Z"
+ }, {
+ "id": 5,
+ "name": "Meeseeks and Destroy",
+ "air_date": "January 20, 2014",
+ "episode": "S01E05",
+ "characters": ["https://rickandmortyapi.com/api/character/1", "https://rickandmortyapi.com/api/character/2", "https://rickandmortyapi.com/api/character/38", "https://rickandmortyapi.com/api/character/41", "https://rickandmortyapi.com/api/character/89", "https://rickandmortyapi.com/api/character/116", "https://rickandmortyapi.com/api/character/117", "https://rickandmortyapi.com/api/character/120", "https://rickandmortyapi.com/api/character/175", "https://rickandmortyapi.com/api/character/193", "https://rickandmortyapi.com/api/character/238", "https://rickandmortyapi.com/api/character/242", "https://rickandmortyapi.com/api/character/271", "https://rickandmortyapi.com/api/character/303", "https://rickandmortyapi.com/api/character/326", "https://rickandmortyapi.com/api/character/333", "https://rickandmortyapi.com/api/character/338", "https://rickandmortyapi.com/api/character/343", "https://rickandmortyapi.com/api/character/399", "https://rickandmortyapi.com/api/character/400"],
+ "url": "https://rickandmortyapi.com/api/episode/5",
+ "created": "2017-11-10T12:56:34.236Z"
+ }, {
+ "id": 6,
+ "name": "Rick Potion #9",
+ "air_date": "January 27, 2014",
+ "episode": "S01E06",
+ "characters": ["https://rickandmortyapi.com/api/character/1", "https://rickandmortyapi.com/api/character/2", "https://rickandmortyapi.com/api/character/3", "https://rickandmortyapi.com/api/character/4", "https://rickandmortyapi.com/api/character/5", "https://rickandmortyapi.com/api/character/38", "https://rickandmortyapi.com/api/character/58", "https://rickandmortyapi.com/api/character/82", "https://rickandmortyapi.com/api/character/83", "https://rickandmortyapi.com/api/character/92", "https://rickandmortyapi.com/api/character/155", "https://rickandmortyapi.com/api/character/175", "https://rickandmortyapi.com/api/character/179", "https://rickandmortyapi.com/api/character/181", "https://rickandmortyapi.com/api/character/216", "https://rickandmortyapi.com/api/character/234", "https://rickandmortyapi.com/api/character/239", "https://rickandmortyapi.com/api/character/249", "https://rickandmortyapi.com/api/character/251", "https://rickandmortyapi.com/api/character/271", "https://rickandmortyapi.com/api/character/293", "https://rickandmortyapi.com/api/character/338", "https://rickandmortyapi.com/api/character/343", "https://rickandmortyapi.com/api/character/394"],
+ "url": "https://rickandmortyapi.com/api/episode/6",
+ "created": "2017-11-10T12:56:34.339Z"
+ }, {
+ "id": 7,
+ "name": "Raising Gazorpazorp",
+ "air_date": "March 10, 2014",
+ "episode": "S01E07",
+ "characters": ["https://rickandmortyapi.com/api/character/1", "https://rickandmortyapi.com/api/character/2", "https://rickandmortyapi.com/api/character/3", "https://rickandmortyapi.com/api/character/4", "https://rickandmortyapi.com/api/character/5", "https://rickandmortyapi.com/api/character/59", "https://rickandmortyapi.com/api/character/151", "https://rickandmortyapi.com/api/character/168", "https://rickandmortyapi.com/api/character/211", "https://rickandmortyapi.com/api/character/230", "https://rickandmortyapi.com/api/character/258", "https://rickandmortyapi.com/api/character/329", "https://rickandmortyapi.com/api/character/376", "https://rickandmortyapi.com/api/character/401"],
+ "url": "https://rickandmortyapi.com/api/episode/7",
+ "created": "2017-11-10T12:56:34.441Z"
+ }])
+ );
+ })
+];
+
+/*
+
+*/
diff --git a/samples/endpoints/remote-module/mocks/handlers.ts b/samples/endpoints/remote-module/mocks/handlers.ts
new file mode 100644
index 000000000..4cfecd283
--- /dev/null
+++ b/samples/endpoints/remote-module/mocks/handlers.ts
@@ -0,0 +1,6 @@
+import type { RestHandler } from "msw";
+import { episodeHandlers } from "./episodeHandlers.ts";
+import { locationHandlers } from "./locationHandlers.ts";
+
+export const requestHandlers: RestHandler[] = [...episodeHandlers, ...locationHandlers];
+
diff --git a/samples/endpoints/remote-module/mocks/locationHandlers.ts b/samples/endpoints/remote-module/mocks/locationHandlers.ts
new file mode 100644
index 000000000..d978c88a7
--- /dev/null
+++ b/samples/endpoints/remote-module/mocks/locationHandlers.ts
@@ -0,0 +1,42 @@
+/* eslint-disable max-len */
+
+import { rest, type RestHandler } from "msw";
+
+export const locationHandlers: RestHandler[] = [
+ rest.get("/api/location/1,2,3", async (req, res, ctx) => {
+ return res(
+ ctx.status(200),
+ ctx.json([{
+ "id": 1,
+ "name": "Earth (C-137)",
+ "type": "Planet",
+ "dimension": "Dimension C-137",
+ "residents": ["https://rickandmortyapi.com/api/character/38", "https://rickandmortyapi.com/api/character/45", "https://rickandmortyapi.com/api/character/71", "https://rickandmortyapi.com/api/character/82", "https://rickandmortyapi.com/api/character/83", "https://rickandmortyapi.com/api/character/92", "https://rickandmortyapi.com/api/character/112", "https://rickandmortyapi.com/api/character/114", "https://rickandmortyapi.com/api/character/116", "https://rickandmortyapi.com/api/character/117", "https://rickandmortyapi.com/api/character/120", "https://rickandmortyapi.com/api/character/127", "https://rickandmortyapi.com/api/character/155", "https://rickandmortyapi.com/api/character/169", "https://rickandmortyapi.com/api/character/175", "https://rickandmortyapi.com/api/character/179", "https://rickandmortyapi.com/api/character/186", "https://rickandmortyapi.com/api/character/201", "https://rickandmortyapi.com/api/character/216", "https://rickandmortyapi.com/api/character/239", "https://rickandmortyapi.com/api/character/271", "https://rickandmortyapi.com/api/character/302", "https://rickandmortyapi.com/api/character/303", "https://rickandmortyapi.com/api/character/338", "https://rickandmortyapi.com/api/character/343", "https://rickandmortyapi.com/api/character/356", "https://rickandmortyapi.com/api/character/394"],
+ "url": "https://rickandmortyapi.com/api/location/1",
+ "created": "2017-11-10T12:42:04.162Z"
+ }, {
+ "id": 2,
+ "name": "Abadango",
+ "type": "Cluster",
+ "dimension": "unknown",
+ "residents": ["https://rickandmortyapi.com/api/character/6"],
+ "url": "https://rickandmortyapi.com/api/location/2",
+ "created": "2017-11-10T13:06:38.182Z"
+ }, {
+ "id": 3,
+ "name": "Citadel of Ricks",
+ "type": "Space station",
+ "dimension": "unknown",
+ "residents": ["https://rickandmortyapi.com/api/character/8", "https://rickandmortyapi.com/api/character/14", "https://rickandmortyapi.com/api/character/15", "https://rickandmortyapi.com/api/character/18", "https://rickandmortyapi.com/api/character/21", "https://rickandmortyapi.com/api/character/22", "https://rickandmortyapi.com/api/character/27", "https://rickandmortyapi.com/api/character/42", "https://rickandmortyapi.com/api/character/43", "https://rickandmortyapi.com/api/character/44", "https://rickandmortyapi.com/api/character/48", "https://rickandmortyapi.com/api/character/53", "https://rickandmortyapi.com/api/character/56", "https://rickandmortyapi.com/api/character/61", "https://rickandmortyapi.com/api/character/69", "https://rickandmortyapi.com/api/character/72", "https://rickandmortyapi.com/api/character/73", "https://rickandmortyapi.com/api/character/74", "https://rickandmortyapi.com/api/character/77", "https://rickandmortyapi.com/api/character/78", "https://rickandmortyapi.com/api/character/85", "https://rickandmortyapi.com/api/character/86", "https://rickandmortyapi.com/api/character/95", "https://rickandmortyapi.com/api/character/118", "https://rickandmortyapi.com/api/character/119", "https://rickandmortyapi.com/api/character/123", "https://rickandmortyapi.com/api/character/135", "https://rickandmortyapi.com/api/character/143", "https://rickandmortyapi.com/api/character/152", "https://rickandmortyapi.com/api/character/164", "https://rickandmortyapi.com/api/character/165", "https://rickandmortyapi.com/api/character/187", "https://rickandmortyapi.com/api/character/200", "https://rickandmortyapi.com/api/character/206", "https://rickandmortyapi.com/api/character/209", "https://rickandmortyapi.com/api/character/220", "https://rickandmortyapi.com/api/character/229", "https://rickandmortyapi.com/api/character/231", "https://rickandmortyapi.com/api/character/235", "https://rickandmortyapi.com/api/character/267", "https://rickandmortyapi.com/api/character/278", "https://rickandmortyapi.com/api/character/281", "https://rickandmortyapi.com/api/character/283", "https://rickandmortyapi.com/api/character/284", "https://rickandmortyapi.com/api/character/285", "https://rickandmortyapi.com/api/character/286", "https://rickandmortyapi.com/api/character/287", "https://rickandmortyapi.com/api/character/288", "https://rickandmortyapi.com/api/character/289", "https://rickandmortyapi.com/api/character/291", "https://rickandmortyapi.com/api/character/295", "https://rickandmortyapi.com/api/character/298", "https://rickandmortyapi.com/api/character/299", "https://rickandmortyapi.com/api/character/322", "https://rickandmortyapi.com/api/character/325", "https://rickandmortyapi.com/api/character/328", "https://rickandmortyapi.com/api/character/330", "https://rickandmortyapi.com/api/character/345", "https://rickandmortyapi.com/api/character/359", "https://rickandmortyapi.com/api/character/366", "https://rickandmortyapi.com/api/character/378", "https://rickandmortyapi.com/api/character/385", "https://rickandmortyapi.com/api/character/392", "https://rickandmortyapi.com/api/character/461", "https://rickandmortyapi.com/api/character/462", "https://rickandmortyapi.com/api/character/463", "https://rickandmortyapi.com/api/character/464", "https://rickandmortyapi.com/api/character/465", "https://rickandmortyapi.com/api/character/466", "https://rickandmortyapi.com/api/character/472", "https://rickandmortyapi.com/api/character/473", "https://rickandmortyapi.com/api/character/474", "https://rickandmortyapi.com/api/character/475", "https://rickandmortyapi.com/api/character/476", "https://rickandmortyapi.com/api/character/477", "https://rickandmortyapi.com/api/character/478", "https://rickandmortyapi.com/api/character/479", "https://rickandmortyapi.com/api/character/480", "https://rickandmortyapi.com/api/character/481", "https://rickandmortyapi.com/api/character/482", "https://rickandmortyapi.com/api/character/483", "https://rickandmortyapi.com/api/character/484", "https://rickandmortyapi.com/api/character/485", "https://rickandmortyapi.com/api/character/486", "https://rickandmortyapi.com/api/character/487", "https://rickandmortyapi.com/api/character/488", "https://rickandmortyapi.com/api/character/489", "https://rickandmortyapi.com/api/character/2", "https://rickandmortyapi.com/api/character/1", "https://rickandmortyapi.com/api/character/801", "https://rickandmortyapi.com/api/character/802", "https://rickandmortyapi.com/api/character/803", "https://rickandmortyapi.com/api/character/804", "https://rickandmortyapi.com/api/character/805", "https://rickandmortyapi.com/api/character/806", "https://rickandmortyapi.com/api/character/810", "https://rickandmortyapi.com/api/character/811", "https://rickandmortyapi.com/api/character/812", "https://rickandmortyapi.com/api/character/819", "https://rickandmortyapi.com/api/character/820", "https://rickandmortyapi.com/api/character/818"],
+ "url": "https://rickandmortyapi.com/api/location/3",
+ "created": "2017-11-10T13:08:13.191Z"
+ }])
+ );
+ }),
+
+ rest.get("/api/location/failing", async (req, res, ctx) => {
+ return res(
+ ctx.status(500)
+ );
+ })
+];
diff --git a/samples/endpoints/remote-module/nodemon.json b/samples/endpoints/remote-module/nodemon.json
new file mode 100644
index 000000000..7a5919df8
--- /dev/null
+++ b/samples/endpoints/remote-module/nodemon.json
@@ -0,0 +1,5 @@
+{
+ "watch": ["swc.dev.js", "webpack.dev.js"],
+ "exec": "webpack serve --config webpack.dev.js",
+ "verbose": true
+}
diff --git a/samples/endpoints/remote-module/package.json b/samples/endpoints/remote-module/package.json
new file mode 100644
index 000000000..cc85563ee
--- /dev/null
+++ b/samples/endpoints/remote-module/package.json
@@ -0,0 +1,51 @@
+{
+ "name": "@endpoints/remote-module",
+ "author": "Workleap",
+ "version": "0.0.0",
+ "description": "Remote module to showcase @squide.",
+ "private": true,
+ "license": "Apache-2.0",
+ "type": "module",
+ "scripts": {
+ "dev": "cross-env USE_MSW=true nodemon",
+ "dev-isolated": "cross-env USE_MSW=true ISOLATED=true pnpm dev",
+ "build": "cross-env USE_MSW=true webpack --config webpack.build.js",
+ "serve-build": "pnpm build && pnpm http-server dist -p 8081 -P http://localhost:8081? -c-1"
+ },
+ "devDependencies": {
+ "@swc/core": "1.3.93",
+ "@swc/helpers": "0.5.3",
+ "@tanstack/react-query-devtools": "^5.0.0",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@types/webpack": "5.28.3",
+ "@workleap/browserslist-config": "2.0.0",
+ "@workleap/eslint-plugin": "3.0.0",
+ "@workleap/swc-configs": "2.1.2",
+ "@workleap/typescript-configs": "3.0.2",
+ "@workleap/webpack-configs": "1.1.0",
+ "browserslist": "4.22.1",
+ "cross-env": "7.0.3",
+ "http-server": "14.1.1",
+ "nodemon": "3.0.1",
+ "typescript": "5.2.2",
+ "webpack": "5.89.0",
+ "webpack-cli": "5.1.4",
+ "webpack-dev-server": "4.15.1"
+ },
+ "dependencies": {
+ "@endpoints/shared": "workspace:*",
+ "@endpoints/shell": "workspace:*",
+ "@squide/fakes": "workspace:*",
+ "@squide/msw": "workspace:*",
+ "@squide/react-router": "workspace:*",
+ "@squide/webpack-module-federation": "workspace:*",
+ "@tanstack/react-query": "^5.0.0",
+ "axios": "1.5.1",
+ "msw": "1.3.2",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-error-boundary": "4.0.11",
+ "react-router-dom": "6.17.0"
+ }
+}
diff --git a/samples/endpoints/remote-module/public/favicon.png b/samples/endpoints/remote-module/public/favicon.png
new file mode 100644
index 000000000..47157f6b0
Binary files /dev/null and b/samples/endpoints/remote-module/public/favicon.png differ
diff --git a/samples/endpoints/remote-module/public/index.html b/samples/endpoints/remote-module/public/index.html
new file mode 100644
index 000000000..98accb408
--- /dev/null
+++ b/samples/endpoints/remote-module/public/index.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/samples/endpoints/remote-module/public/mockServiceWorker.js b/samples/endpoints/remote-module/public/mockServiceWorker.js
new file mode 100644
index 000000000..8ee70b3e4
--- /dev/null
+++ b/samples/endpoints/remote-module/public/mockServiceWorker.js
@@ -0,0 +1,303 @@
+/* eslint-disable */
+/* tslint:disable */
+
+/**
+ * Mock Service Worker (1.2.2).
+ * @see https://github.com/mswjs/msw
+ * - Please do NOT modify this file.
+ * - Please do NOT serve this file on production.
+ */
+
+const INTEGRITY_CHECKSUM = '3d6b9f06410d179a7f7404d4bf4c3c70'
+const activeClientIds = new Set()
+
+self.addEventListener('install', function () {
+ self.skipWaiting()
+})
+
+self.addEventListener('activate', function (event) {
+ event.waitUntil(self.clients.claim())
+})
+
+self.addEventListener('message', async function (event) {
+ const clientId = event.source.id
+
+ if (!clientId || !self.clients) {
+ return
+ }
+
+ const client = await self.clients.get(clientId)
+
+ if (!client) {
+ return
+ }
+
+ const allClients = await self.clients.matchAll({
+ type: 'window',
+ })
+
+ switch (event.data) {
+ case 'KEEPALIVE_REQUEST': {
+ sendToClient(client, {
+ type: 'KEEPALIVE_RESPONSE',
+ })
+ break
+ }
+
+ case 'INTEGRITY_CHECK_REQUEST': {
+ sendToClient(client, {
+ type: 'INTEGRITY_CHECK_RESPONSE',
+ payload: INTEGRITY_CHECKSUM,
+ })
+ break
+ }
+
+ case 'MOCK_ACTIVATE': {
+ activeClientIds.add(clientId)
+
+ sendToClient(client, {
+ type: 'MOCKING_ENABLED',
+ payload: true,
+ })
+ break
+ }
+
+ case 'MOCK_DEACTIVATE': {
+ activeClientIds.delete(clientId)
+ break
+ }
+
+ case 'CLIENT_CLOSED': {
+ activeClientIds.delete(clientId)
+
+ const remainingClients = allClients.filter((client) => {
+ return client.id !== clientId
+ })
+
+ // Unregister itself when there are no more clients
+ if (remainingClients.length === 0) {
+ self.registration.unregister()
+ }
+
+ break
+ }
+ }
+})
+
+self.addEventListener('fetch', function (event) {
+ const { request } = event
+ const accept = request.headers.get('accept') || ''
+
+ // Bypass server-sent events.
+ if (accept.includes('text/event-stream')) {
+ return
+ }
+
+ // Bypass navigation requests.
+ if (request.mode === 'navigate') {
+ return
+ }
+
+ // Opening the DevTools triggers the "only-if-cached" request
+ // that cannot be handled by the worker. Bypass such requests.
+ if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
+ return
+ }
+
+ // Bypass all requests when there are no active clients.
+ // Prevents the self-unregistered worked from handling requests
+ // after it's been deleted (still remains active until the next reload).
+ if (activeClientIds.size === 0) {
+ return
+ }
+
+ // Generate unique request ID.
+ const requestId = Math.random().toString(16).slice(2)
+
+ event.respondWith(
+ handleRequest(event, requestId).catch((error) => {
+ if (error.name === 'NetworkError') {
+ console.warn(
+ '[MSW] Successfully emulated a network error for the "%s %s" request.',
+ request.method,
+ request.url,
+ )
+ return
+ }
+
+ // At this point, any exception indicates an issue with the original request/response.
+ console.error(
+ `\
+[MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`,
+ request.method,
+ request.url,
+ `${error.name}: ${error.message}`,
+ )
+ }),
+ )
+})
+
+async function handleRequest(event, requestId) {
+ const client = await resolveMainClient(event)
+ const response = await getResponse(event, client, requestId)
+
+ // Send back the response clone for the "response:*" life-cycle events.
+ // Ensure MSW is active and ready to handle the message, otherwise
+ // this message will pend indefinitely.
+ if (client && activeClientIds.has(client.id)) {
+ ;(async function () {
+ const clonedResponse = response.clone()
+ sendToClient(client, {
+ type: 'RESPONSE',
+ payload: {
+ requestId,
+ type: clonedResponse.type,
+ ok: clonedResponse.ok,
+ status: clonedResponse.status,
+ statusText: clonedResponse.statusText,
+ body:
+ clonedResponse.body === null ? null : await clonedResponse.text(),
+ headers: Object.fromEntries(clonedResponse.headers.entries()),
+ redirected: clonedResponse.redirected,
+ },
+ })
+ })()
+ }
+
+ return response
+}
+
+// Resolve the main client for the given event.
+// Client that issues a request doesn't necessarily equal the client
+// that registered the worker. It's with the latter the worker should
+// communicate with during the response resolving phase.
+async function resolveMainClient(event) {
+ const client = await self.clients.get(event.clientId)
+
+ if (client?.frameType === 'top-level') {
+ return client
+ }
+
+ const allClients = await self.clients.matchAll({
+ type: 'window',
+ })
+
+ return allClients
+ .filter((client) => {
+ // Get only those clients that are currently visible.
+ return client.visibilityState === 'visible'
+ })
+ .find((client) => {
+ // Find the client ID that's recorded in the
+ // set of clients that have registered the worker.
+ return activeClientIds.has(client.id)
+ })
+}
+
+async function getResponse(event, client, requestId) {
+ const { request } = event
+ const clonedRequest = request.clone()
+
+ function passthrough() {
+ // Clone the request because it might've been already used
+ // (i.e. its body has been read and sent to the client).
+ const headers = Object.fromEntries(clonedRequest.headers.entries())
+
+ // Remove MSW-specific request headers so the bypassed requests
+ // comply with the server's CORS preflight check.
+ // Operate with the headers as an object because request "Headers"
+ // are immutable.
+ delete headers['x-msw-bypass']
+
+ return fetch(clonedRequest, { headers })
+ }
+
+ // Bypass mocking when the client is not active.
+ if (!client) {
+ return passthrough()
+ }
+
+ // Bypass initial page load requests (i.e. static assets).
+ // The absence of the immediate/parent client in the map of the active clients
+ // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
+ // and is not ready to handle requests.
+ if (!activeClientIds.has(client.id)) {
+ return passthrough()
+ }
+
+ // Bypass requests with the explicit bypass header.
+ // Such requests can be issued by "ctx.fetch()".
+ if (request.headers.get('x-msw-bypass') === 'true') {
+ return passthrough()
+ }
+
+ // Notify the client that a request has been intercepted.
+ const clientMessage = await sendToClient(client, {
+ type: 'REQUEST',
+ payload: {
+ id: requestId,
+ url: request.url,
+ method: request.method,
+ headers: Object.fromEntries(request.headers.entries()),
+ cache: request.cache,
+ mode: request.mode,
+ credentials: request.credentials,
+ destination: request.destination,
+ integrity: request.integrity,
+ redirect: request.redirect,
+ referrer: request.referrer,
+ referrerPolicy: request.referrerPolicy,
+ body: await request.text(),
+ bodyUsed: request.bodyUsed,
+ keepalive: request.keepalive,
+ },
+ })
+
+ switch (clientMessage.type) {
+ case 'MOCK_RESPONSE': {
+ return respondWithMock(clientMessage.data)
+ }
+
+ case 'MOCK_NOT_FOUND': {
+ return passthrough()
+ }
+
+ case 'NETWORK_ERROR': {
+ const { name, message } = clientMessage.data
+ const networkError = new Error(message)
+ networkError.name = name
+
+ // Rejecting a "respondWith" promise emulates a network error.
+ throw networkError
+ }
+ }
+
+ return passthrough()
+}
+
+function sendToClient(client, message) {
+ return new Promise((resolve, reject) => {
+ const channel = new MessageChannel()
+
+ channel.port1.onmessage = (event) => {
+ if (event.data && event.data.error) {
+ return reject(event.data.error)
+ }
+
+ resolve(event.data)
+ }
+
+ client.postMessage(message, [channel.port2])
+ })
+}
+
+function sleep(timeMs) {
+ return new Promise((resolve) => {
+ setTimeout(resolve, timeMs)
+ })
+}
+
+async function respondWithMock(response) {
+ await sleep(response.delay)
+ return new Response(response.body, response)
+}
diff --git a/samples/endpoints/remote-module/src/EpisodesTab.tsx b/samples/endpoints/remote-module/src/EpisodesTab.tsx
new file mode 100644
index 000000000..60885b7c9
--- /dev/null
+++ b/samples/endpoints/remote-module/src/EpisodesTab.tsx
@@ -0,0 +1,38 @@
+import { useSuspenseQuery } from "@tanstack/react-query";
+import axios from "axios";
+
+interface Episode {
+ id: number;
+ name: string;
+ episode: string;
+}
+
+export function EpisodesTab() {
+ const { data: episodes } = useSuspenseQuery({ queryKey: ["/api/episode/1,2,3,4,5,6,7"], queryFn: () => {
+ return axios
+ .get("/api/episode/1,2,3,4,5,6,7")
+ .then(({ data }) => {
+ return data;
+ });
+ } });
+
+ return (
+
+
Episodes
+
This tab is served by @endpoints/remote-module
+
+ {episodes.map((x: Episode) => {
+ return (
+
+ Id: {x.id}
+ -
+ Name: {x.name}
+ -
+ Episode: {x.episode}
+
+ );
+ })}
+
+
+ );
+}
diff --git a/samples/endpoints/remote-module/src/FailingTab.tsx b/samples/endpoints/remote-module/src/FailingTab.tsx
new file mode 100644
index 000000000..82afb5b40
--- /dev/null
+++ b/samples/endpoints/remote-module/src/FailingTab.tsx
@@ -0,0 +1,19 @@
+import { useSuspenseQuery } from "@tanstack/react-query";
+import axios from "axios";
+
+export function FailingTab() {
+ useSuspenseQuery({ queryKey: ["/api/location/failing"], queryFn: () => {
+ return axios
+ .get("/api/location/failing")
+ .then(({ data }) => {
+ return data;
+ });
+ } });
+
+ return (
+ <>
+ Expected to fail!
+ Something went wront because the API call should have failed and you shouldn't see this!
+ >
+ );
+}
diff --git a/samples/endpoints/remote-module/src/LocationsTab.tsx b/samples/endpoints/remote-module/src/LocationsTab.tsx
new file mode 100644
index 000000000..01d16acda
--- /dev/null
+++ b/samples/endpoints/remote-module/src/LocationsTab.tsx
@@ -0,0 +1,38 @@
+import { useSuspenseQuery } from "@tanstack/react-query";
+import axios from "axios";
+
+interface Location {
+ id: number;
+ name: string;
+ type: string;
+}
+
+export function LocationsTab() {
+ const { data: locations } = useSuspenseQuery({ queryKey: ["/api/location/1,2,3"], queryFn: () => {
+ return axios
+ .get("/api/location/1,2,3")
+ .then(({ data }) => {
+ return data;
+ });
+ } });
+
+ return (
+
+
Locations
+
This tab is served by @endpoints/remote-module
+
+ {locations.map((x: Location) => {
+ return (
+
+ Id: {x.id}
+ -
+ Name: {x.name}
+ -
+ Type: {x.type}
+
+ );
+ })}
+
+
+ );
+}
diff --git a/samples/endpoints/remote-module/src/Providers.tsx b/samples/endpoints/remote-module/src/Providers.tsx
new file mode 100644
index 000000000..358cc6560
--- /dev/null
+++ b/samples/endpoints/remote-module/src/Providers.tsx
@@ -0,0 +1,25 @@
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
+import type { ReactNode } from "react";
+
+export const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ refetchOnWindowFocus: false,
+ retry: failureCount => {
+ return failureCount <= 2;
+ }
+ }
+ }
+});
+
+export function Providers({ children }: { children: ReactNode }) {
+ return (
+
+ {children}
+ {process.env.ISOLATED && (
+
+ )}
+
+ );
+}
diff --git a/samples/endpoints/remote-module/src/dev/App.tsx b/samples/endpoints/remote-module/src/dev/App.tsx
new file mode 100644
index 000000000..87b79ab65
--- /dev/null
+++ b/samples/endpoints/remote-module/src/dev/App.tsx
@@ -0,0 +1,19 @@
+import { LoggerTelemetryService } from "@endpoints/shared";
+import { AppRouter } from "@endpoints/shell";
+import { useLogger } from "@squide/react-router";
+import { sessionManager } from "./session.ts";
+
+export function App() {
+ const logger = useLogger();
+
+ const telemetryService = new LoggerTelemetryService(logger);
+
+ return (
+
+ );
+}
+
diff --git a/samples/endpoints/remote-module/src/dev/DevHomePage.tsx b/samples/endpoints/remote-module/src/dev/DevHomePage.tsx
new file mode 100644
index 000000000..f7e62419b
--- /dev/null
+++ b/samples/endpoints/remote-module/src/dev/DevHomePage.tsx
@@ -0,0 +1,8 @@
+export function DevHomePage() {
+ return (
+
+
Remote module development home page
+
Hey!
+
+ );
+}
diff --git a/samples/endpoints/remote-module/src/dev/index.tsx b/samples/endpoints/remote-module/src/dev/index.tsx
new file mode 100644
index 000000000..36cfde3f9
--- /dev/null
+++ b/samples/endpoints/remote-module/src/dev/index.tsx
@@ -0,0 +1,47 @@
+import { registerShell } from "@endpoints/shell";
+import { MswPlugin, setMswAsStarted } from "@squide/msw";
+import { ConsoleLogger, Runtime, RuntimeContext, registerLocalModules } from "@squide/react-router";
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import { register as registerModule } from "../register.tsx";
+import { App } from "./App.tsx";
+import { registerDev } from "./register.tsx";
+import { sessionAccessor, sessionManager } from "./session.ts";
+
+const mswPlugin = new MswPlugin();
+
+// Create the shell runtime.
+// Services, loggers and sessionAccessor could be reuse through a shared packages or faked when in isolation.
+const runtime = new Runtime({
+ loggers: [new ConsoleLogger()],
+ plugins: [mswPlugin],
+ sessionAccessor
+});
+
+// Registering the remote module as a static module because the "register" function
+// is local when developing in isolation.
+registerLocalModules([registerShell(sessionManager), registerDev, registerModule], runtime);
+
+// Register MSW after the local modules has been registered since the request handlers
+// will be registered by the modules.
+if (process.env.USE_MSW) {
+ // Files including an import to the "msw" package are included dynamically to prevent adding
+ // MSW stuff to the bundled when it's not used.
+ import("../../mocks/browser.ts").then(({ startMsw }) => {
+ startMsw(mswPlugin.requestHandlers);
+
+ setMswAsStarted();
+ });
+}
+
+const root = createRoot(document.getElementById("root")!);
+
+root.render(
+
+
+
+
+
+);
+
+
diff --git a/samples/endpoints/remote-module/src/dev/register.tsx b/samples/endpoints/remote-module/src/dev/register.tsx
new file mode 100644
index 000000000..5567785bb
--- /dev/null
+++ b/samples/endpoints/remote-module/src/dev/register.tsx
@@ -0,0 +1,26 @@
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { Providers } from "../Providers.tsx";
+import { DevHomePage } from "./DevHomePage.tsx";
+
+export const registerDev: ModuleRegisterFunction = runtime => {
+ runtime.registerRoute({
+ index: true,
+ element:
+ });
+
+ runtime.registerRoute({
+ path: "/federated-tabs",
+ lazy: async () => {
+ const { FederatedTabsLayout } = await import("@endpoints/shared/FederatedTabsLayout.tsx");
+
+ return {
+ element:
+ };
+ }
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Tabs",
+ to: "/federated-tabs"
+ });
+};
diff --git a/samples/endpoints/remote-module/src/dev/session.ts b/samples/endpoints/remote-module/src/dev/session.ts
new file mode 100644
index 000000000..5417cd9d9
--- /dev/null
+++ b/samples/endpoints/remote-module/src/dev/session.ts
@@ -0,0 +1,9 @@
+import type { Session } from "@endpoints/shared";
+import { LocalStorageSessionManager } from "@squide/fakes";
+import type { SessionAccessorFunction } from "@squide/react-router";
+
+export const sessionManager = new LocalStorageSessionManager();
+
+export const sessionAccessor: SessionAccessorFunction = () => {
+ return sessionManager.getSession();
+};
diff --git a/samples/endpoints/remote-module/src/register.tsx b/samples/endpoints/remote-module/src/register.tsx
new file mode 100644
index 000000000..36467f5ea
--- /dev/null
+++ b/samples/endpoints/remote-module/src/register.tsx
@@ -0,0 +1,83 @@
+import { getMswPlugin } from "@squide/msw";
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { Providers } from "./Providers.tsx";
+
+function registerRoutes(runtime: Runtime) {
+ runtime.registerRoute({
+ path: "/federated-tabs/episodes",
+ lazy: async () => {
+ const { EpisodesTab } = await import("./EpisodesTab.tsx");
+
+ return {
+ element:
+ };
+ }
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerRoute({
+ path: "/federated-tabs/locations",
+ lazy: async () => {
+ const { LocationsTab } = await import("./LocationsTab.tsx");
+
+ return {
+ element:
+ };
+ }
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerRoute({
+ path: "/federated-tabs/failing",
+ lazy: async () => {
+ const { FailingTab } = await import("./FailingTab.tsx");
+
+ return {
+ element:
+ };
+ }
+ }, {
+ parentPath: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Episodes",
+ to: "/federated-tabs/episodes"
+ }, {
+ menuId: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Locations",
+ to: "/federated-tabs/locations"
+ }, {
+ menuId: "/federated-tabs"
+ });
+
+ runtime.registerNavigationItem({
+ $label: "Failing",
+ to: "/federated-tabs/failing"
+ }, {
+ menuId: "/federated-tabs"
+ });
+}
+
+async function registerMsw(runtime: Runtime) {
+ if (process.env.USE_MSW) {
+ const mswPlugin = getMswPlugin(runtime);
+
+ // Files including an import to the "msw" package are included dynamically to prevent adding
+ // MSW stuff to the bundled when it's not used.
+ const requestHandlers = (await import("../mocks/handlers.ts")).requestHandlers;
+
+ mswPlugin.registerRequestHandlers(requestHandlers);
+ }
+}
+
+export const register: ModuleRegisterFunction = async runtime => {
+ registerRoutes(runtime);
+
+ return registerMsw(runtime);
+};
diff --git a/samples/endpoints/remote-module/swc.build.js b/samples/endpoints/remote-module/swc.build.js
new file mode 100644
index 000000000..7e0820823
--- /dev/null
+++ b/samples/endpoints/remote-module/swc.build.js
@@ -0,0 +1,7 @@
+// @ts-check
+
+import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs";
+
+const targets = browserslistToSwc();
+
+export const swcConfig = defineBuildConfig(targets);
diff --git a/samples/endpoints/remote-module/swc.dev.js b/samples/endpoints/remote-module/swc.dev.js
new file mode 100644
index 000000000..9d6fb9fa3
--- /dev/null
+++ b/samples/endpoints/remote-module/swc.dev.js
@@ -0,0 +1,7 @@
+// @ts-check
+
+import { browserslistToSwc, defineDevConfig } from "@workleap/swc-configs";
+
+const targets = browserslistToSwc();
+
+export const swcConfig = defineDevConfig(targets);
diff --git a/samples/endpoints/remote-module/tsconfig.json b/samples/endpoints/remote-module/tsconfig.json
new file mode 100644
index 000000000..f5dc566b5
--- /dev/null
+++ b/samples/endpoints/remote-module/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "@workleap/typescript-configs/web-application.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/msw": ["../../../packages/msw/src/index.ts"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"],
+ "@endpoints/shell": ["../shell/src/index.ts"],
+ "@endpoints/shared": ["../shared/src/index.ts"],
+ "@endpoints/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"]
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/samples/endpoints/remote-module/webpack.build.js b/samples/endpoints/remote-module/webpack.build.js
new file mode 100644
index 000000000..b3043d1b9
--- /dev/null
+++ b/samples/endpoints/remote-module/webpack.build.js
@@ -0,0 +1,19 @@
+// @ts-check
+
+import { defineBuildRemoteModuleConfig } from "@squide/webpack-module-federation/defineConfig.js";
+import { swcConfig } from "./swc.build.js";
+
+// The trailing / is very important, otherwise paths will not be resolved correctly.
+const publicPath = process.env.NETLIFY === "true" ? "https://squide-endpoints-remote-module.netlify.app/" : "http://localhost:8081/";
+
+export default defineBuildRemoteModuleConfig(swcConfig, "remote1", publicPath, {
+ sharedDependencies: {
+ "@endpoints/shared": {
+ singleton: true
+ }
+ },
+ environmentVariables: {
+ "NETLIFY": process.env.NETLIFY === "true",
+ "USE_MSW": process.env.USE_MSW === "true"
+ }
+});
diff --git a/samples/endpoints/remote-module/webpack.dev.js b/samples/endpoints/remote-module/webpack.dev.js
new file mode 100644
index 000000000..8e9a76c0d
--- /dev/null
+++ b/samples/endpoints/remote-module/webpack.dev.js
@@ -0,0 +1,36 @@
+// @ts-check
+
+import { defineDevRemoteModuleConfig } from "@squide/webpack-module-federation/defineConfig.js";
+import { defineDevConfig } from "@workleap/webpack-configs";
+import path from "node:path";
+import { swcConfig } from "./swc.dev.js";
+
+let config;
+
+if (!process.env.ISOLATED) {
+ config = defineDevRemoteModuleConfig(swcConfig, "remote1", 8081, {
+ sharedDependencies: {
+ "@endpoints/shared": {
+ singleton: true
+ }
+ },
+ environmentVariables: {
+ "NETLIFY": process.env.NETLIFY === "true",
+ "ISOLATED": process.env.ISOLATED === "true",
+ "USE_MSW": process.env.USE_MSW === "true"
+ }
+ });
+} else {
+ config = defineDevConfig(swcConfig, {
+ cache: false,
+ entry: path.resolve("./src/dev/index.tsx"),
+ overlay: false,
+ environmentVariables: {
+ "ISOLATED": process.env.ISOLATED === "true",
+ "USE_MSW": process.env.USE_MSW === "true"
+ }
+ });
+}
+
+export default config;
+
diff --git a/samples/endpoints/shared/.eslintrc.json b/samples/endpoints/shared/.eslintrc.json
new file mode 100644
index 000000000..bf0564209
--- /dev/null
+++ b/samples/endpoints/shared/.eslintrc.json
@@ -0,0 +1,5 @@
+{
+ "$schema": "https://json.schemastore.org/eslintrc",
+ "root": true,
+ "extends": "plugin:@workleap/react-library"
+}
diff --git a/samples/endpoints/shared/nodemon.json b/samples/endpoints/shared/nodemon.json
new file mode 100644
index 000000000..79a8918cc
--- /dev/null
+++ b/samples/endpoints/shared/nodemon.json
@@ -0,0 +1,5 @@
+{
+ "watch": ["tsup.dev.ts"],
+ "exec": "tsup --config ./tsup.dev.ts",
+ "verbose": true
+}
diff --git a/samples/endpoints/shared/package.json b/samples/endpoints/shared/package.json
new file mode 100644
index 000000000..41d6eabb6
--- /dev/null
+++ b/samples/endpoints/shared/package.json
@@ -0,0 +1,52 @@
+{
+ "name": "@endpoints/shared",
+ "author": "Workleap",
+ "version": "0.0.0",
+ "description": "Shared package to showcase @squide.",
+ "private": true,
+ "license": "Apache-2.0",
+ "type": "module",
+ "exports": {
+ ".": {
+ "import": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "default": "./dist/index.js"
+ },
+ "./FederatedTabsLayout.tsx": {
+ "import": "./dist/FederatedTabsLayout.js",
+ "types": "./dist/FederatedTabsLayout.d.ts",
+ "default": "./dist/FederatedTabsLayout.js"
+ }
+ },
+ "scripts": {
+ "dev": "nodemon",
+ "dev-msw": "pnpm nodemon",
+ "build": "tsup --config ./tsup.build.ts",
+ "serve-build": "pnpm build"
+ },
+ "peerDependencies": {
+ "@squide/react-router": "*",
+ "@tanstack/react-query": "*",
+ "react": "*",
+ "react-dom": "*",
+ "react-error-boundary": "*",
+ "react-router-dom": "*"
+ },
+ "devDependencies": {
+ "@remix-run/router": "1.10.0",
+ "@squide/react-router": "workspace:*",
+ "@tanstack/react-query": "5.0.0",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@workleap/eslint-plugin": "3.0.0",
+ "@workleap/tsup-configs": "3.0.1",
+ "@workleap/typescript-configs": "3.0.2",
+ "nodemon": "3.0.1",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-error-boundary": "4.0.11",
+ "react-router-dom": "6.17.0",
+ "tsup": "7.2.0",
+ "typescript": "5.2.2"
+ }
+}
diff --git a/samples/endpoints/shared/src/FederatedTabsLayout.tsx b/samples/endpoints/shared/src/FederatedTabsLayout.tsx
new file mode 100644
index 000000000..1319a7e39
--- /dev/null
+++ b/samples/endpoints/shared/src/FederatedTabsLayout.tsx
@@ -0,0 +1,78 @@
+import { useNavigationItems, useRenderedNavigationItems, type NavigationLinkRenderProps, type RenderItemFunction, type RenderSectionFunction } from "@squide/react-router";
+import { QueryErrorResetBoundary } from "@tanstack/react-query";
+import { Suspense, useCallback, type MouseEvent } from "react";
+import { ErrorBoundary, type FallbackProps } from "react-error-boundary";
+import { Link, Outlet, useNavigate } from "react-router-dom";
+
+export interface FederatedTabsLayoutProps {
+ host?: string;
+}
+
+const renderItem: RenderItemFunction = (item, index, level) => {
+ const { label, linkProps } = item as NavigationLinkRenderProps;
+
+ return (
+
+
+ {label}
+
+
+ );
+};
+
+const renderSection: RenderSectionFunction = elements => {
+ return (
+
+ );
+};
+
+function TabsError({ resetErrorBoundary }: FallbackProps) {
+ const navigate = useNavigate();
+
+ const handleReset = useCallback((event: MouseEvent) => {
+ event.preventDefault();
+
+ resetErrorBoundary();
+ navigate("/federated-tabs");
+ }, [resetErrorBoundary, navigate]);
+
+ return (
+
+
+ An error occured while rendering the tab.
+
+
Reset
+
+ );
+}
+
+export function FederatedTabsLayout({ host }: FederatedTabsLayoutProps) {
+ const navigationItems = useNavigationItems("/federated-tabs");
+ const renderedTabs = useRenderedNavigationItems(navigationItems, renderItem, renderSection);
+
+ return (
+ <>
+ Tabs
+ {host && This layout is served by {host}
}
+ {renderedTabs}
+
+
+ {({ reset }) => (
+
+ Loading...
}>
+
+
+
+ )}
+
+
+ >
+ );
+}
+
+
diff --git a/samples/endpoints/shared/src/index.ts b/samples/endpoints/shared/src/index.ts
new file mode 100644
index 000000000..0490fb04b
--- /dev/null
+++ b/samples/endpoints/shared/src/index.ts
@@ -0,0 +1,5 @@
+export * from "./isNetlify.ts";
+export * from "./session.ts";
+export * from "./subscription.ts";
+export * from "./telemetryService.ts";
+
diff --git a/samples/endpoints/shared/src/isNetlify.ts b/samples/endpoints/shared/src/isNetlify.ts
new file mode 100644
index 000000000..60dddc162
--- /dev/null
+++ b/samples/endpoints/shared/src/isNetlify.ts
@@ -0,0 +1,3 @@
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+export const isNetlify = process.env.NETLIFY === true;
diff --git a/samples/endpoints/shared/src/session.ts b/samples/endpoints/shared/src/session.ts
new file mode 100644
index 000000000..0f33aff7d
--- /dev/null
+++ b/samples/endpoints/shared/src/session.ts
@@ -0,0 +1,12 @@
+export interface Session {
+ user: {
+ id: number;
+ name: string;
+ };
+}
+
+export interface SessionManager {
+ setSession: (session: Session) => void;
+ getSession: () => Session | undefined;
+ clearSession: () => void;
+}
diff --git a/samples/endpoints/shared/src/subscription.ts b/samples/endpoints/shared/src/subscription.ts
new file mode 100644
index 000000000..ea301e22e
--- /dev/null
+++ b/samples/endpoints/shared/src/subscription.ts
@@ -0,0 +1,32 @@
+import { createContext, useContext } from "react";
+
+export type SubscriptionStatus = "unknown" | "trial" | "paid" | "not-paid";
+
+export interface Subscription {
+ company: string;
+ contact: string;
+ status: SubscriptionStatus;
+}
+
+export const SubscriptionContext = createContext(undefined);
+
+export function useSubscription() {
+ return useContext(SubscriptionContext);
+}
+
+export function toSubscriptionStatusLabel(status?: SubscriptionStatus) {
+ if (!status) {
+ return "-";
+ }
+
+ switch (status) {
+ case "unknown":
+ return "-";
+ case "trial":
+ return "Trial";
+ case "paid":
+ return "Paid";
+ case "not-paid":
+ return "Not paid";
+ }
+}
diff --git a/samples/endpoints/shared/src/telemetryService.ts b/samples/endpoints/shared/src/telemetryService.ts
new file mode 100644
index 000000000..eb26fdf1f
--- /dev/null
+++ b/samples/endpoints/shared/src/telemetryService.ts
@@ -0,0 +1,24 @@
+import type { Logger } from "@squide/react-router";
+import { createContext, useContext } from "react";
+
+export interface TelemetryService {
+ track: (value: string) => void;
+}
+
+export class LoggerTelemetryService implements TelemetryService {
+ #logger: Logger;
+
+ constructor(logger: Logger) {
+ this.#logger = logger;
+ }
+
+ track(value: string) {
+ this.#logger.information(`[telemetry] ${value}`);
+ }
+}
+
+export const TelemetryServiceContext = createContext(undefined);
+
+export function useTelemetryService() {
+ return useContext(TelemetryServiceContext);
+}
diff --git a/samples/endpoints/shared/tsconfig.json b/samples/endpoints/shared/tsconfig.json
new file mode 100644
index 000000000..f1ddba989
--- /dev/null
+++ b/samples/endpoints/shared/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@workleap/typescript-configs/library.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/msw": ["../../../packages/msw/src/index.ts"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"],
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/samples/endpoints/shared/tsup.build.ts b/samples/endpoints/shared/tsup.build.ts
new file mode 100644
index 000000000..1b2c65a89
--- /dev/null
+++ b/samples/endpoints/shared/tsup.build.ts
@@ -0,0 +1,3 @@
+import { defineBuildConfig } from "@workleap/tsup-configs";
+
+export default defineBuildConfig();
diff --git a/samples/endpoints/shared/tsup.dev.ts b/samples/endpoints/shared/tsup.dev.ts
new file mode 100644
index 000000000..8aa2904c8
--- /dev/null
+++ b/samples/endpoints/shared/tsup.dev.ts
@@ -0,0 +1,3 @@
+import { defineDevConfig } from "@workleap/tsup-configs";
+
+export default defineDevConfig();
diff --git a/samples/endpoints/shell/.eslintrc.json b/samples/endpoints/shell/.eslintrc.json
new file mode 100644
index 000000000..bf0564209
--- /dev/null
+++ b/samples/endpoints/shell/.eslintrc.json
@@ -0,0 +1,5 @@
+{
+ "$schema": "https://json.schemastore.org/eslintrc",
+ "root": true,
+ "extends": "plugin:@workleap/react-library"
+}
diff --git a/samples/endpoints/shell/mocks/authenticationHandlers.ts b/samples/endpoints/shell/mocks/authenticationHandlers.ts
new file mode 100644
index 000000000..d252781cf
--- /dev/null
+++ b/samples/endpoints/shell/mocks/authenticationHandlers.ts
@@ -0,0 +1,58 @@
+import { rest, type RestHandler } from "msw";
+import { sessionManager } from "./session.ts";
+
+function simulateDelay(delay: number) {
+ return new Promise(resolve => {
+ setTimeout(() => {
+ resolve(undefined);
+ }, delay);
+ });
+}
+
+export const authenticationHandlers: RestHandler[] = [
+ rest.post("/api/login", async (req, res, ctx) => {
+ const { username, password } = await req.json();
+
+ if (username !== "temp" || password !== "temp") {
+ return res(
+ ctx.status(401)
+ );
+ }
+
+ await simulateDelay(1000);
+
+ sessionManager.setSession({
+ userId: Math.random(),
+ username
+ });
+
+ return res(
+ ctx.status(200)
+ );
+ }),
+
+ rest.post("/api/logout", async (req, res, ctx) => {
+ sessionManager.clearSession();
+
+ return res(
+ ctx.status(200)
+ );
+ }),
+
+ rest.get("/api/session", async (req, res, ctx) => {
+ const session = sessionManager.getSession();
+
+ if (!session) {
+ return res(
+ ctx.status(401)
+ );
+ }
+
+ await simulateDelay(500);
+
+ return res(
+ ctx.status(200),
+ ctx.json(session)
+ );
+ })
+];
diff --git a/samples/endpoints/shell/mocks/session.ts b/samples/endpoints/shell/mocks/session.ts
new file mode 100644
index 000000000..41352d673
--- /dev/null
+++ b/samples/endpoints/shell/mocks/session.ts
@@ -0,0 +1,8 @@
+import { LocalStorageSessionManager } from "@squide/fakes";
+
+export interface Session {
+ userId: number;
+ username: string;
+}
+
+export const sessionManager = new LocalStorageSessionManager({ key: "squide-sample-msw-session" });
diff --git a/samples/endpoints/shell/mocks/subscriptionHandlers.ts b/samples/endpoints/shell/mocks/subscriptionHandlers.ts
new file mode 100644
index 000000000..7a62e38d2
--- /dev/null
+++ b/samples/endpoints/shell/mocks/subscriptionHandlers.ts
@@ -0,0 +1,21 @@
+import { rest, type RestHandler } from "msw";
+import { sessionManager } from "./session.ts";
+
+export const subscriptionHandlers: RestHandler[] = [
+ rest.get("/api/subscription", async (req, res, ctx) => {
+ if (!sessionManager.getSession()) {
+ return res(
+ ctx.status(401)
+ );
+ }
+
+ return res(
+ ctx.status(200),
+ ctx.json({
+ company: "Workleap",
+ contact: "John Doe",
+ status: "paid"
+ })
+ );
+ })
+];
diff --git a/samples/endpoints/shell/nodemon.json b/samples/endpoints/shell/nodemon.json
new file mode 100644
index 000000000..79a8918cc
--- /dev/null
+++ b/samples/endpoints/shell/nodemon.json
@@ -0,0 +1,5 @@
+{
+ "watch": ["tsup.dev.ts"],
+ "exec": "tsup --config ./tsup.dev.ts",
+ "verbose": true
+}
diff --git a/samples/endpoints/shell/package.json b/samples/endpoints/shell/package.json
new file mode 100644
index 000000000..3edb35872
--- /dev/null
+++ b/samples/endpoints/shell/package.json
@@ -0,0 +1,56 @@
+{
+ "name": "@endpoints/shell",
+ "author": "Workleap",
+ "version": "0.0.0",
+ "description": "Application shell package to showcase @squide.",
+ "private": true,
+ "license": "Apache-2.0",
+ "type": "module",
+ "exports": {
+ ".": {
+ "import": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "default": "./dist/index.js"
+ }
+ },
+ "scripts": {
+ "dev": "nodemon",
+ "dev-msw": "pnpm nodemon",
+ "build": "tsup --config ./tsup.build.ts",
+ "serve-build": "pnpm build"
+ },
+ "peerDependencies": {
+ "@endpoints/shared": "*",
+ "@squide/fakes": "*",
+ "@squide/msw": "*",
+ "@squide/react-router": "*",
+ "@squide/webpack-module-federation": "*",
+ "axios": "*",
+ "msw": "*",
+ "react": "*",
+ "react-dom": "*",
+ "react-router-dom": "*"
+ },
+ "devDependencies": {
+ "@endpoints/shared": "workspace:*",
+ "@remix-run/router": "1.10.0",
+ "@squide/fakes": "workspace:*",
+ "@squide/msw": "workspace:*",
+ "@squide/react-router": "workspace:*",
+ "@squide/webpack-module-federation": "workspace:*",
+ "@types/react": "18.2.28",
+ "@types/react-dom": "18.2.13",
+ "@workleap/eslint-plugin": "3.0.0",
+ "@workleap/tsup-configs": "3.0.1",
+ "@workleap/typescript-configs": "3.0.2",
+ "axios": "1.5.1",
+ "msw": "1.3.2",
+ "nodemon": "3.0.1",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-error-boundary": "4.0.11",
+ "react-router-dom": "6.17.0",
+ "tsup": "7.2.0",
+ "typescript": "5.2.2"
+ }
+}
diff --git a/samples/endpoints/shell/src/AppRouter.tsx b/samples/endpoints/shell/src/AppRouter.tsx
new file mode 100644
index 000000000..46bd54d2a
--- /dev/null
+++ b/samples/endpoints/shell/src/AppRouter.tsx
@@ -0,0 +1,130 @@
+import { SubscriptionContext, TelemetryServiceContext, useTelemetryService, type Session, type SessionManager, type Subscription, type TelemetryService } from "@endpoints/shared";
+import { useIsMswStarted } from "@squide/msw";
+import { useIsRouteMatchProtected, useLogger, useRoutes } from "@squide/react-router";
+import { useAreModulesReady } from "@squide/webpack-module-federation";
+import axios from "axios";
+import { useEffect, useMemo, useState } from "react";
+import { Outlet, RouterProvider, createBrowserRouter, useLocation } from "react-router-dom";
+
+export function RootRoute() {
+ const location = useLocation();
+ const telemetryService = useTelemetryService();
+
+ useEffect(() => {
+ telemetryService?.track(`Navigated to the "${location.pathname}" page.`);
+ }, [location, telemetryService]);
+
+ return (
+
+ );
+}
+
+export interface AppRouterProps {
+ waitForMsw: boolean;
+ sessionManager: SessionManager;
+ telemetryService: TelemetryService;
+}
+
+export function AppRouter({ waitForMsw, sessionManager, telemetryService }: AppRouterProps) {
+ const [isReady, setIsReady] = useState(false);
+
+ // Could be done with a ref (https://react.dev/reference/react/useRef) to save a re-render but for this sample
+ // it seemed unnecessary. If your application loads a lot of data at bootstrapping, it should be considered.
+ const [subscription, setSubscription] = useState();
+
+ const logger = useLogger();
+ const routes = useRoutes();
+
+ // Re-render the app once all the remotes are registered, otherwise the remotes routes won't be added to the router.
+ const areModulesReady = useAreModulesReady();
+
+ // Re-render the app once MSW is started, otherwise, the API calls for module routes will return a 404 status.
+ const isMswStarted = useIsMswStarted(waitForMsw);
+
+ // Ideally "useLocation" would be used so the component re-renderer everytime the location change but it doesn't
+ // seem feasible (at least not easily) as public and private routes go through this component.
+ // Anyhow, since all the Workleap apps will authenticate through a third party authentication provider, it
+ // doesn't seems like a big deal as the application will be reloaded anyway after the user logged in on the third party.
+ const isActiveRouteProtected = useIsRouteMatchProtected(window.location);
+
+ useEffect(() => {
+ if (areModulesReady && !isMswStarted) {
+ logger.debug("[shell] Modules are ready, waiting for MSW to start.");
+ }
+
+ if (!areModulesReady && isMswStarted) {
+ logger.debug("[shell] MSW is started, waiting for the modules to be ready.");
+ }
+
+ if (areModulesReady && isMswStarted) {
+ if (isActiveRouteProtected) {
+ logger.debug(`[shell] Fetching session data as "${window.location}" is a protected route.`);
+
+ const sessionPromise = axios.get("/api/session")
+ .then(({ data }) => {
+ const session: Session = {
+ user: {
+ id: data.userId,
+ name: data.username
+ }
+ };
+
+ logger.debug("[shell] %cSession is ready%c:", "color: white; background-color: green;", "", session);
+
+ sessionManager.setSession(session);
+ });
+
+ const subscriptionPromise = axios.get("/api/subscription")
+ .then(({ data }) => {
+ const _subscription: Subscription = {
+ company: data.company,
+ contact: data.contact,
+ status: data.status
+ };
+
+ logger.debug("[shell] %cSubscription is ready%c:", "color: white; background-color: green;", "", _subscription);
+
+ setSubscription(_subscription);
+ });
+
+ Promise.all([sessionPromise, subscriptionPromise])
+ .catch((error: unknown) => {
+ if (axios.isAxiosError(error) && error.response?.status === 401) {
+ // The authentication boundary will redirect to the login page.
+ return;
+ }
+
+ throw error;
+ })
+ .finally(() => {
+ setIsReady(true);
+ });
+ } else {
+ logger.debug(`[shell] Passing through as "${window.location}" is a public route.`);
+
+ setIsReady(true);
+ }
+ }
+ }, [areModulesReady, isMswStarted, isActiveRouteProtected, logger, sessionManager]);
+
+ const router = useMemo(() => {
+ return createBrowserRouter([
+ {
+ element: ,
+ children: routes
+ }
+ ]);
+ }, [routes]);
+
+ if (!isReady) {
+ return Loading...
;
+ }
+
+ return (
+
+
+
+
+
+ );
+}
diff --git a/samples/endpoints/shell/src/AuthenticatedLayout.tsx b/samples/endpoints/shell/src/AuthenticatedLayout.tsx
new file mode 100644
index 000000000..2c158a657
--- /dev/null
+++ b/samples/endpoints/shell/src/AuthenticatedLayout.tsx
@@ -0,0 +1,95 @@
+import { toSubscriptionStatusLabel, useSubscription, type Session, type SessionManager } from "@endpoints/shared";
+import { isNavigationLink, useLogger, useNavigationItems, useRenderedNavigationItems, useSession, type NavigationLinkRenderProps, type NavigationSectionRenderProps, type RenderItemFunction, type RenderSectionFunction } from "@squide/react-router";
+import axios from "axios";
+import { Suspense, useCallback, type MouseEvent, type ReactNode } from "react";
+import { Link, Outlet, useNavigate } from "react-router-dom";
+
+type RenderLinkItemFunction = (item: NavigationLinkRenderProps, index: number, level: number) => ReactNode;
+
+type RenderSectionItemFunction = (item: NavigationSectionRenderProps, index: number, level: number) => ReactNode;
+
+const renderLinkItem: RenderLinkItemFunction = ({ label, linkProps, additionalProps: { highlight, ...additionalProps } }, index, level) => {
+ return (
+
+
+ {label}
+
+
+ );
+};
+
+const renderSectionItem: RenderSectionItemFunction = ({ label, section }, index, level) => {
+ return (
+
+ {label}
+
+ ({section})
+
+
+ );
+};
+
+const renderItem: RenderItemFunction = (item, index, level) => {
+ return isNavigationLink(item) ? renderLinkItem(item, index, level) : renderSectionItem(item, index, level);
+};
+
+const renderSection: RenderSectionFunction = (elements, index, level) => {
+ return (
+
+ );
+};
+
+export interface AuthenticatedLayoutProps {
+ sessionManager: SessionManager;
+}
+
+export function AuthenticatedLayout({ sessionManager }: AuthenticatedLayoutProps) {
+ const logger = useLogger();
+ const session = useSession() as Session;
+ const subscription = useSubscription();
+
+ const navigate = useNavigate();
+
+ const handleDisconnect = useCallback(async (event: MouseEvent) => {
+ event.preventDefault();
+
+ await axios.post("/api/logout")
+ .then(() => {
+ sessionManager.clearSession();
+
+ logger.debug("[shell] The user session has been cleared.");
+
+ navigate("/logout");
+ })
+ .catch(() => {
+ throw new Error("An unknown error happened while disconnecting the user.");
+ });
+ }, [logger, navigate, sessionManager]);
+
+ const navigationItems = useNavigationItems();
+ const renderedNavigationItems = useRenderedNavigationItems(navigationItems, renderItem, renderSection);
+
+ return (
+ <>
+
+
+ {renderedNavigationItems}
+
+
+ {/* Must check for a null session because when the disconnect button is clicked, it will clear the session and rerender this layout. */}
+ (Subscription: {toSubscriptionStatusLabel(subscription?.status)} - User: {session?.user?.name} )
+
+
+ Disconnect
+
+
+ Loading...}>
+
+
+ >
+ );
+}
+
+export const Component = AuthenticatedLayout;
diff --git a/samples/endpoints/shell/src/AuthenticationBoundary.tsx b/samples/endpoints/shell/src/AuthenticationBoundary.tsx
new file mode 100644
index 000000000..aec77b69a
--- /dev/null
+++ b/samples/endpoints/shell/src/AuthenticationBoundary.tsx
@@ -0,0 +1,17 @@
+import { useIsAuthenticated, useLogger } from "@squide/react-router";
+import { Navigate, Outlet } from "react-router-dom";
+
+export function AuthenticationBoundary() {
+ const logger = useLogger();
+ const isAuthenticated = useIsAuthenticated();
+
+ if (isAuthenticated) {
+ return ;
+ }
+
+ logger.debug("[shell] The user is not authenticated, redirecting to the login page.");
+
+ return ;
+}
+
+export const Component = AuthenticationBoundary;
diff --git a/samples/endpoints/shell/src/LoginPage.tsx b/samples/endpoints/shell/src/LoginPage.tsx
new file mode 100644
index 000000000..30626ba72
--- /dev/null
+++ b/samples/endpoints/shell/src/LoginPage.tsx
@@ -0,0 +1,87 @@
+import { useIsAuthenticated } from "@squide/react-router";
+import axios from "axios";
+import { useCallback, useState, type ChangeEvent, type MouseEvent } from "react";
+import { Navigate } from "react-router-dom";
+
+export interface LoginPageProps {
+ host?: string;
+}
+
+export function LoginPage({ host }: LoginPageProps) {
+ const [username, setUserName] = useState("");
+ const [password, setPassword] = useState("");
+ const [errorMessage, setErrorMessage] = useState();
+ const [isBusy, setIsBusy] = useState(false);
+
+ const handleClick = useCallback((event: MouseEvent) => {
+ event.preventDefault();
+
+ setIsBusy(true);
+ setErrorMessage(undefined);
+
+ axios.post("/api/login", { username, password })
+ .then(() => {
+ setIsBusy(false);
+
+ // Reloading the whole application so the "App.tsx" component is re-rendered. Ideally, "useNavigate" would be
+ // used so "App.tsx" component would re-renderer everytime the location change but it doesn't
+ // seem feasible (at least not easily) as public and private routes go through the "App.tsx" component.
+ // Anyhow, since all the Workleap apps will authenticate through a third party authentication provider, it
+ // doesn't seems like a big deal as the application will be reloaded anyway after the user logged in on the third party.
+ // application will be reloaded anyway after the login on the third party.
+ window.location.href = "/";
+ })
+ .catch((error: unknown) => {
+ setIsBusy(false);
+
+ if (axios.isAxiosError(error) && error.response?.status === 401) {
+ setErrorMessage("Invalid credentials, please try again.");
+ } else {
+ throw error;
+ }
+ });
+ }, [username, password]);
+
+ const handleUserNameChange = useCallback((event: ChangeEvent) => {
+ setUserName(event.target.value);
+ }, []);
+
+ const handlePasswordChange = useCallback((event: ChangeEvent) => {
+ setPassword(event.target.value);
+ }, []);
+
+ const isAuthenticated = useIsAuthenticated();
+
+ if (isAuthenticated) {
+ return ;
+ }
+
+ return (
+ <>
+ Login
+ {host && This page is served by {host}
}
+
+ >
+ );
+}
+
+export const Component = LoginPage;
diff --git a/samples/endpoints/shell/src/LogoutPage.tsx b/samples/endpoints/shell/src/LogoutPage.tsx
new file mode 100644
index 000000000..d5768df8c
--- /dev/null
+++ b/samples/endpoints/shell/src/LogoutPage.tsx
@@ -0,0 +1,18 @@
+import { Link } from "react-router-dom";
+
+export interface LogoutPageProps {
+ host?: string;
+}
+
+export function LogoutPage({ host }: LogoutPageProps) {
+ return (
+ <>
+ Logged out
+ {host && This page is served by {host}
}
+ You are logged out from the application!
+ Log in again
+ >
+ );
+}
+
+export const Component = LogoutPage;
diff --git a/samples/endpoints/shell/src/ModuleErrorBoundary.tsx b/samples/endpoints/shell/src/ModuleErrorBoundary.tsx
new file mode 100644
index 000000000..e7f4676e6
--- /dev/null
+++ b/samples/endpoints/shell/src/ModuleErrorBoundary.tsx
@@ -0,0 +1,39 @@
+import { useLogger } from "@squide/react-router";
+import { useCallback, useEffect } from "react";
+import { isRouteErrorResponse, useLocation, useRouteError } from "react-router-dom";
+
+function getErrorMessage(error: unknown) {
+ if (isRouteErrorResponse(error)) {
+ return `${error.status} ${error.statusText}`;
+ }
+
+ return error instanceof Error
+ ? error.message
+ : JSON.stringify(error);
+}
+
+export function ModuleErrorBoundary() {
+ const error = useRouteError();
+ const location = useLocation();
+ const logger = useLogger();
+
+ const handleReloadButtonClick = useCallback(() => {
+ window.location.reload();
+ }, []);
+
+ useEffect(() => {
+ logger.error(`[shell] An unmanaged error occurred while rendering the route with path ${location.pathname}`, error);
+ }, [location.pathname, error, logger]);
+
+ return (
+
+
Unmanaged error
+
An unmanaged error occurred inside a module. Still, other parts of the application are fully functional!
+
π {getErrorMessage(error)}
+
+
Reload
+
+ );
+}
+
+export const ErrorBoundary = ModuleErrorBoundary;
diff --git a/samples/endpoints/shell/src/NoMatchPage.tsx b/samples/endpoints/shell/src/NoMatchPage.tsx
new file mode 100644
index 000000000..b512a8d2b
--- /dev/null
+++ b/samples/endpoints/shell/src/NoMatchPage.tsx
@@ -0,0 +1,19 @@
+import { Link } from "react-router-dom";
+
+export interface NoMatchPageProps {
+ path: string;
+ host?: string;
+}
+
+export function NoMatchPage({ path, host }: NoMatchPageProps) {
+ return (
+ <>
+ 404
+ {host && This page is served by {host}
}
+ We can't find the path "{path}".
+ Go back home
+ >
+ );
+}
+
+export const Component = NoMatchPage;
diff --git a/samples/endpoints/shell/src/RootErrorBoundary.tsx b/samples/endpoints/shell/src/RootErrorBoundary.tsx
new file mode 100644
index 000000000..c3c995fd8
--- /dev/null
+++ b/samples/endpoints/shell/src/RootErrorBoundary.tsx
@@ -0,0 +1,35 @@
+import { useLogger } from "@squide/react-router";
+import { useCallback } from "react";
+import { isRouteErrorResponse, useLocation, useRouteError } from "react-router-dom";
+
+function getErrorMessage(error: unknown) {
+ if (isRouteErrorResponse(error)) {
+ return `${error.status} ${error.statusText}`;
+ }
+
+ return error instanceof Error
+ ? error.message
+ : JSON.stringify(error);
+}
+
+export function RootErrorBoundary() {
+ const error = useRouteError();
+ const location = useLocation();
+ const logger = useLogger();
+
+ const handleReloadButtonClick = useCallback(() => {
+ window.location.reload();
+ }, []);
+
+ logger.error(`[shell] An unmanaged error occurred while rendering the route with path ${location.pathname}`, error);
+
+ return (
+
+
Unmanaged error
+
An unmanaged error occurred and the application is broken, try refreshing your browser.
+
π {getErrorMessage(error)}
+
+
Reload
+
+ );
+}
diff --git a/sample/remote-module/src/CustomLayout.tsx b/samples/endpoints/shell/src/RootLayout.tsx
similarity index 77%
rename from sample/remote-module/src/CustomLayout.tsx
rename to samples/endpoints/shell/src/RootLayout.tsx
index 584535d99..a818a4409 100644
--- a/sample/remote-module/src/CustomLayout.tsx
+++ b/samples/endpoints/shell/src/RootLayout.tsx
@@ -1,6 +1,6 @@
import { Outlet } from "react-router-dom";
-export default function CustomLayout() {
+export function RootLayout() {
return (
diff --git a/samples/endpoints/shell/src/index.ts b/samples/endpoints/shell/src/index.ts
new file mode 100644
index 000000000..5e03e14a7
--- /dev/null
+++ b/samples/endpoints/shell/src/index.ts
@@ -0,0 +1,3 @@
+export * from "./AppRouter.tsx";
+export * from "./register.tsx";
+
diff --git a/samples/endpoints/shell/src/register.tsx b/samples/endpoints/shell/src/register.tsx
new file mode 100644
index 000000000..f0dcc5522
--- /dev/null
+++ b/samples/endpoints/shell/src/register.tsx
@@ -0,0 +1,119 @@
+import type { SessionManager } from "@endpoints/shared";
+import { getMswPlugin } from "@squide/msw";
+import type { ModuleRegisterFunction, Runtime } from "@squide/react-router";
+import { ManagedRoutes } from "@squide/react-router";
+import { authenticationHandlers } from "../mocks/authenticationHandlers.ts";
+import { subscriptionHandlers } from "../mocks/subscriptionHandlers.ts";
+import { RootErrorBoundary } from "./RootErrorBoundary.tsx";
+import { RootLayout } from "./RootLayout.tsx";
+
+export interface RegisterShellOptions {
+ // This is only for demo purposed, do not copy this.
+ host?: string;
+}
+
+function registerRoutes(runtime: Runtime, sessionManager: SessionManager, host?: string) {
+ runtime.registerRoute({
+ // Pathless route to declare a root layout and a root error boundary.
+ $visibility: "public",
+ element:
,
+ children: [
+ {
+ // Public pages like the login and logout pages will be rendered under this pathless route.
+ $visibility: "public",
+ $name: "root-error-boundary",
+ errorElement:
,
+ children: [
+ {
+ // Pathless route to declare an authenticated boundary.
+ lazy: () => import("./AuthenticationBoundary.tsx"),
+ children: [
+ {
+ // Pathless route to declare an authenticated layout.
+ lazy: async () => {
+ const { AuthenticatedLayout } = await import("./AuthenticatedLayout.tsx");
+
+ return {
+ element:
+ };
+ },
+ children: [
+ {
+ // Pathless route to declare an error boundary inside the layout instead of outside.
+ // It's quite useful to prevent losing the layout when an unmanaged error occurs.
+ lazy: () => import("./ModuleErrorBoundary.tsx"),
+ children: [
+ ManagedRoutes
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }, {
+ hoist: true
+ });
+
+ runtime.registerRoute({
+ $visibility: "public",
+ path: "/login",
+ lazy: async () => {
+ const { LoginPage } = await import("./LoginPage.tsx");
+
+ return {
+ element:
+ };
+ }
+ }, {
+ parentName: "root-error-boundary"
+ });
+
+ runtime.registerRoute({
+ $visibility: "public",
+ path: "/logout",
+ lazy: async () => {
+ const { LogoutPage } = await import("./LogoutPage.tsx");
+
+ return {
+ element:
+ };
+ }
+ }, {
+ parentName: "root-error-boundary"
+ });
+
+ runtime.registerRoute({
+ $visibility: "public",
+ path: "*",
+ lazy: async () => {
+ const { NoMatchPage } = await import("./NoMatchPage.tsx");
+
+ return {
+ element:
+ };
+ }
+ }, {
+ parentName: "root-error-boundary"
+ });
+}
+
+function registerMsw(runtime: Runtime) {
+ const mswPlugin = getMswPlugin(runtime);
+
+ mswPlugin.registerRequestHandlers([
+ ...authenticationHandlers,
+ ...subscriptionHandlers
+ ]);
+}
+
+export function registerShell(sessionManager: SessionManager, { host }: RegisterShellOptions = {}) {
+ const register: ModuleRegisterFunction
= runtime => {
+ registerRoutes(runtime, sessionManager, host);
+ registerMsw(runtime);
+ };
+
+ return register;
+}
diff --git a/samples/endpoints/shell/tsconfig.json b/samples/endpoints/shell/tsconfig.json
new file mode 100644
index 000000000..42197450d
--- /dev/null
+++ b/samples/endpoints/shell/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "extends": "@workleap/typescript-configs/library.json",
+ "compilerOptions": {
+ "paths": {
+ "@squide/core": ["../../../packages/core/src/index.ts"],
+ "@squide/react-router": ["../../../packages/react-router/src/index.ts"],
+ "@squide/webpack-module-federation": ["../../../packages/webpack-module-federation/src/index.ts"],
+ "@squide/webpack-module-federation/defineConfig.js": ["../../../packages/webpack-module-federation/src/defineConfig.js"],
+ "@squide/msw": ["../../../packages/msw/src/index.ts"],
+ "@squide/fakes": ["../../../packages/fakes/src/index.ts"],
+ "@endpoints/shared": ["../shared/src/index.ts"],
+ "@endpoints/shared/FederatedTabsLayout.tsx": ["../shared/src/FederatedTabsLayout.tsx"]
+ }
+ },
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/samples/endpoints/shell/tsup.build.ts b/samples/endpoints/shell/tsup.build.ts
new file mode 100644
index 000000000..1b2c65a89
--- /dev/null
+++ b/samples/endpoints/shell/tsup.build.ts
@@ -0,0 +1,3 @@
+import { defineBuildConfig } from "@workleap/tsup-configs";
+
+export default defineBuildConfig();
diff --git a/samples/endpoints/shell/tsup.dev.ts b/samples/endpoints/shell/tsup.dev.ts
new file mode 100644
index 000000000..8aa2904c8
--- /dev/null
+++ b/samples/endpoints/shell/tsup.dev.ts
@@ -0,0 +1,3 @@
+import { defineDevConfig } from "@workleap/tsup-configs";
+
+export default defineDevConfig();