+
diff --git a/docs/auth/index.md b/docs/auth/index.md
index 5702e96cee..fa185c0c23 100644
--- a/docs/auth/index.md
+++ b/docs/auth/index.md
@@ -150,6 +150,31 @@ const app = createApp({
});
```
+If the provider in auth backend expects additional headers such as `x-provider-token`, there is now a way to configure that in `ProxiedSignInPage` using the optional `headers` prop.
+
+Example:
+
+```tsx
+
+```
+
+Headers can also be returned in an async manner:
+
+```tsx
+
{
+ const someValue = await someFn();
+ return { 'x-some-key': someValue };
+ }}
+/>
+```
+
A downside of this method is that it can be cumbersome to set up for local development.
As a workaround for this, it's possible to dynamically select the sign-in page based on
what environment the app is running in, and then use a different sign-in method for local
diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md
index 55843f3b24..41d72b2be2 100644
--- a/docs/features/kubernetes/configuration.md
+++ b/docs/features/kubernetes/configuration.md
@@ -31,6 +31,7 @@ kubernetes:
dashboardUrl: http://127.0.0.1:64713 # url copied from running the command: minikube service kubernetes-dashboard -n kubernetes-dashboard
dashboardApp: standard
caData: ${K8S_CONFIG_CA_DATA}
+ caFile: '' # local path to CA file
customResources:
- group: 'argoproj.io'
apiVersion: 'v1alpha1'
@@ -248,8 +249,8 @@ kubernetes:
##### `clusters.\*.caData` (optional)
Base64-encoded certificate authority bundle in PEM format. The Kubernetes client
-will verify that TLS certificate presented by the API server is signed by this
-CA.
+will verify that the TLS certificate presented by the API server is signed by
+this CA.
This value could be obtained via inspecting the kubeconfig file (usually
at `~/.kube/config`) under `clusters[*].cluster.certificate-authority-data`. For
@@ -265,6 +266,14 @@ See also
https://cloud.google.com/kubernetes-engine/docs/how-to/api-server-authentication#environments-without-gcloud
for complete docs about GKE without `gcloud`.
+##### `clusters.\*.caFile` (optional)
+
+Filesystem path (on the host where the Backstage process is running) to a
+certificate authority bundle in PEM format. The Kubernetes client will verify
+that the TLS certificate presented by the API server is signed by this CA. Note
+that only clusters defined in the app-config via the [`config`](#config)
+cluster locator method can be configured in this way.
+
##### `clusters.\*.customResources` (optional)
Configures which [custom resources][3] to look for when returning an entity's
diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md
index 5cc2ab5f06..7267e9fd5b 100644
--- a/docs/features/search/how-to-guides.md
+++ b/docs/features/search/how-to-guides.md
@@ -1,8 +1,8 @@
---
id: how-to-guides
-title: Search "HOW TO" guides
-sidebar_label: "HOW TO" guides
-description: Search "HOW TO" guides
+title: Search How-To guides
+sidebar_label: How-To guides
+description: Search How To guides
---
## How to implement your own Search API
diff --git a/docs/features/search/search-engines.md b/docs/features/search/search-engines.md
index 35e17205ac..ccd8268dbe 100644
--- a/docs/features/search/search-engines.md
+++ b/docs/features/search/search-engines.md
@@ -117,7 +117,8 @@ within your instance. The configuration options are documented in the
The underlying functionality uses either the official ElasticSearch client
version 7.x (meaning that ElasticSearch version 7 is the only one confirmed to
-be supported), or the OpenSearch client, when the `aws` provider is configured.
+be supported), or the OpenSearch client, when the `aws` or `opensearch `provider
+is configured.
Should you need to create your own bespoke search experiences that require more
than just a query translator (such as faceted search or Relay pagination), you
@@ -200,6 +201,20 @@ search:
password: changeme
```
+### OpenSearch
+
+OpenSearch can be self hosted for example with the [official docker image](https://hub.docker.com/r/opensearchproject/opensearch). The configuration requires only the node and authentication.
+
+```yaml
+search:
+ elasticsearch:
+ provider: opensearch
+ node: http://0.0.0.0:9200
+ auth:
+ username: opensearch
+ password: changeme
+```
+
### Others
Other ElasticSearch instances can be connected to by using standard
diff --git a/docs/features/techdocs/configuration.md b/docs/features/techdocs/configuration.md
index 4e806296e5..097d31f760 100644
--- a/docs/features/techdocs/configuration.md
+++ b/docs/features/techdocs/configuration.md
@@ -106,8 +106,20 @@ techdocs:
# If not set, the default location will be the root of the storage bucket
bucketRootPath: '/'
- # (Optional) An API key is required to write to a storage bucket.
- # If not set, environment variables or aws config file will be used to authenticate.
+ # (Optional) The AWS account ID where the storage bucket is located.
+ # Credentials for the account ID must be configured in the 'aws' app config section.
+ # See the integration-aws-node package for details on how to configure credentials in
+ # the 'aws' app config section.
+ # https://www.npmjs.com/package/@backstage/integration-aws-node
+ # If account ID is not set and no credentials are set, environment variables or aws config file will be used to authenticate.
+ # https://www.npmjs.com/package/@aws-sdk/credential-provider-node
+ # https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html
+ accountId: ${TECHDOCS_AWSS3_ACCOUNT_ID}
+
+ # (Optional) AWS credentials to use to write to the storage bucket.
+ # This configuration section is now deprecated.
+ # Configuring the account ID is now preferred, with credentials in the 'aws' app config section.
+ # If credentials are not set and no account ID is set, environment variables or aws config file will be used to authenticate.
# https://www.npmjs.com/package/@aws-sdk/credential-provider-node
# https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html
credentials:
diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md
index 70ea27821b..cfca7c6a7f 100644
--- a/docs/features/techdocs/how-to-guides.md
+++ b/docs/features/techdocs/how-to-guides.md
@@ -1,8 +1,8 @@
---
id: how-to-guides
-title: TechDocs "HOW TO" guides
-sidebar_label: "HOW TO" guides
-description: TechDocs "HOW TO" guides related to TechDocs
+title: TechDocs How-To guides
+sidebar_label: How-To guides
+description: TechDocs How-To guides related to TechDocs
---
## How to migrate from TechDocs Basic to Recommended deployment approach?
diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md
index 3ea57edc6b..f38a806413 100644
--- a/docs/features/techdocs/using-cloud-storage.md
+++ b/docs/features/techdocs/using-cloud-storage.md
@@ -244,10 +244,13 @@ techdocs:
type: 'awsS3'
awsS3:
bucketName: 'name-of-techdocs-storage-bucket'
+ accountId: '123456789012'
region: ${AWS_REGION}
- credentials:
- accessKeyId: ${AWS_ACCESS_KEY_ID}
- secretAccessKey: ${AWS_SECRET_ACCESS_KEY}
+aws:
+ accounts:
+ - accountId: '123456789012'
+ accessKeyId: ${AWS_ACCESS_KEY_ID}
+ secretAccessKey: ${AWS_SECRET_ACCESS_KEY}
```
Refer to the
diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md
index fc5b02e6f4..0441d3f589 100644
--- a/docs/getting-started/configuration.md
+++ b/docs/getting-started/configuration.md
@@ -79,7 +79,7 @@ backend:
database:
- client: better-sqlite3
- connection: ':memory:'
-+ # config options: https://node-postgres.com/api/client
++ # config options: https://node-postgres.com/apis/client
+ client: pg
+ connection:
+ host: ${POSTGRES_HOST}
diff --git a/docs/getting-started/homepage.md b/docs/getting-started/homepage.md
index 2d34998013..7db41d7768 100644
--- a/docs/getting-started/homepage.md
+++ b/docs/getting-started/homepage.md
@@ -84,8 +84,8 @@ Let's update the route for "Home" in the Backstage sidebar to point to the new h
-
-
+
+
Before
diff --git a/docs/overview/logos.md b/docs/overview/logos.md
index 9421b7f31e..ac54640e33 100644
--- a/docs/overview/logos.md
+++ b/docs/overview/logos.md
@@ -21,7 +21,7 @@ The assets below are all in `.svg` format. Other formats are available in the
-
+
## Backstage icon
@@ -37,6 +37,6 @@ The assets below are all in `.svg` format. Other formats are available in the
-
+
diff --git a/docs/overview/versioning-policy.md b/docs/overview/versioning-policy.md
index 10ffc82188..ad5421585e 100644
--- a/docs/overview/versioning-policy.md
+++ b/docs/overview/versioning-policy.md
@@ -1,7 +1,7 @@
---
id: versioning-policy
title: Release & Versioning Policy
-description:
+description: The process and policy for releasing and versioning Backstage
---
The Backstage project is comprised of a set of software components that together
diff --git a/docs/releases/v1.2.0-changelog.md b/docs/releases/v1.2.0-changelog.md
index 30c780e7ae..977f8a25b7 100644
--- a/docs/releases/v1.2.0-changelog.md
+++ b/docs/releases/v1.2.0-changelog.md
@@ -722,7 +722,7 @@
### Patch Changes
-- ac19f82936: Added ARIA landmark to Page component and added ARIA landmark to DesktopSidebar and Sidebar components
+- ac19f82936: Added ARIA landmark `` to Page component and added ARIA landmark `` to DesktopSidebar and Sidebar components
- 55f68c386a: Enabled select component to be enabled by keyboard
- c0055ece91: Announce external links to screen readers
- e210c0cab8: Add ability to customize `Read More` destination with `readMoreUrl` prop for `MissingAnnotationEmptyState` component.
@@ -733,7 +733,7 @@
- e462112be5: Updated dependency `rc-progress` to `3.3.2`.
- 2bcb0a0e2b: Sidebar NAV now includes aria-label. Component AboutField now uses h2 variant instead of subtitle2 (font properties unchanged)
- c7f32b53a4: Fixed multiple scrolls appearing on Page when added InfoCard with external bottom link
-- 3603014e0e: Add ARIA landmark( ), & label and a heading to OAuthRequestDialog. Removed nested interactive control (button).
+- 3603014e0e: Add ARIA landmark( ``), & label and a heading to OAuthRequestDialog. Removed nested interactive control (button).
- 2025d7c123: Properly highlight `SidebarSubmenuItem` dropdown items on hover, use ellipsis styling on long labels in `SidebarSubmenu`, allow `icon` and `to` properties to be optional on `SidebarSubmenuItem`, and fix `SidebarPage` padding to be responsive to pinned state
- 2295b4ab2b: Add controls to Storybook stories
- 521293b22e: Added a chevron Indicator when the sidebar is collapsed and has a sub-menu
diff --git a/docs/releases/v1.2.0-next.1-changelog.md b/docs/releases/v1.2.0-next.1-changelog.md
index d7b843be48..5881f7caff 100644
--- a/docs/releases/v1.2.0-next.1-changelog.md
+++ b/docs/releases/v1.2.0-next.1-changelog.md
@@ -169,7 +169,7 @@
### Patch Changes
-- ac19f82936: Added ARIA landmark to Page component and added ARIA landmark to DesktopSidebar and Sidebar components
+- ac19f82936: Added ARIA landmark `` to Page component and added ARIA landmark `` to DesktopSidebar and Sidebar components
- c0055ece91: Announce external links to screen readers
- cfc0f2e5bd: Added optional anchorOrigin alignment prop to AlertDisplay
- f4380eb602: Add an aria-label to the support button to improve accessibility for screen readers
diff --git a/docs/releases/v1.2.0-next.3-changelog.md b/docs/releases/v1.2.0-next.3-changelog.md
index 4efce476d4..81c16c74ea 100644
--- a/docs/releases/v1.2.0-next.3-changelog.md
+++ b/docs/releases/v1.2.0-next.3-changelog.md
@@ -5,7 +5,7 @@
### Patch Changes
- 52c02ac02b: Don't set the background color on an Avatar component that has a picture.
-- 3603014e0e: Add ARIA landmark( ), & label and a heading to OAuthRequestDialog. Removed nested interactive control (button).
+- 3603014e0e: Add ARIA landmark( ``), & label and a heading to OAuthRequestDialog. Removed nested interactive control (button).
- 2025d7c123: Properly highlight `SidebarSubmenuItem` dropdown items on hover, use ellipsis styling on long labels in `SidebarSubmenu`, allow `icon` and `to` properties to be optional on `SidebarSubmenuItem`, and fix `SidebarPage` padding to be responsive to pinned state
## @backstage/plugin-home@0.4.21-next.3
diff --git a/docs/releases/v1.9.0-next.4-changelog.md b/docs/releases/v1.9.0-next.4-changelog.md
new file mode 100644
index 0000000000..9d72c29eb3
--- /dev/null
+++ b/docs/releases/v1.9.0-next.4-changelog.md
@@ -0,0 +1,2212 @@
+# Release v1.9.0-next.4
+
+## @backstage/cli@0.22.0-next.4
+
+### Minor Changes
+
+- 736f893f72: The Jest configuration that was previously enabled with `BACKSTAGE_NEXT_TESTS` is now enabled by default. To revert to the old configuration you can now instead set `BACKSTAGE_OLD_TESTS`.
+
+ This new configuration uses the `babel` coverage provider rather than `v8`. It used to be that `v8` worked better when using Sucrase for transpilation, but now that we have switched to SWC, `babel` seems to work better. In addition, the new configuration also enables source maps by default, as they no longer have a negative impact on code coverage accuracy, and it also enables a modified Jest runtime with additional caching of script objects.
+
+### Patch Changes
+
+- dd721148b5: Updated Jest coverage configuration to only apply either in the root project or package configuration, depending on whether repo or package tests are run.
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- c27eabef6b: Adds new web-library package option when generating a new plugin
+- 309f2daca4: Updated dependency `esbuild` to `^0.16.0`.
+- d9d9a7a134: Removed all copyright notices from package templates.
+- Updated dependencies
+ - @backstage/cli-common@0.1.11-next.0
+ - @backstage/config@1.0.5-next.1
+ - @backstage/config-loader@1.1.7-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/release-manifests@0.0.8-next.0
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/core-app-api@1.3.0-next.4
+
+### Minor Changes
+
+- e0d9c9559a: Added a new `AppRouter` component and `app.createRoot()` method that replaces `app.getRouter()` and `app.getProvider()`, which are now deprecated. The new `AppRouter` component is a drop-in replacement for the old router component, while the new `app.createRoot()` method is used instead of the old provider component.
+
+ An old app setup might look like this:
+
+ ```tsx
+ const app = createApp(/* ... */);
+
+ const AppProvider = app.getProvider();
+ const AppRouter = app.getRouter();
+
+ const routes = ...;
+
+ const App = () => (
+
+
+
+
+ {routes}
+
+
+ );
+
+ export default App;
+ ```
+
+ With these new APIs, the setup now looks like this:
+
+ ```tsx
+ import { AppRouter } from '@backstage/core-app-api';
+
+ const app = createApp(/* ... */);
+
+ const routes = ...;
+
+ export default app.createRoot(
+ <>
+
+
+
+ {routes}
+
+ >,
+ );
+ ```
+
+ Note that `app.createRoot()` accepts a React element, rather than a component.
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- Updated dependencies
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/types@1.0.2-next.1
+ - @backstage/version-bridge@1.0.3-next.0
+
+## @backstage/integration-aws-node@0.1.0-next.0
+
+### Minor Changes
+
+- 13278732f6: New package for AWS integration node library
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+
+## @backstage/plugin-scaffolder@1.9.0-next.4
+
+### Minor Changes
+
+- 34a48cdc4f: The `RepoUrlPicker` field extension now has an `allowedProjects` option for narrowing the selection of Bitbucket URLs.
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- db6310b6a0: Show input type array correctly on installed actions page.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/plugin-permission-react@0.4.8-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-scaffolder-common@1.2.3-next.1
+
+## @backstage/plugin-scaffolder-backend@1.9.0-next.3
+
+### Minor Changes
+
+- 0053d07bee: Update the `github:publish` action to allow passing wether to dismiss stale reviews on the protected default branch.
+
+### Patch Changes
+
+- 935b66a646: Change step output template examples to use square bracket syntax.
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- 309f2daca4: Updated dependency `esbuild` to `^0.16.0`.
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+ - @backstage/plugin-scaffolder-common@1.2.3-next.1
+
+## @backstage/plugin-search-backend-module-elasticsearch@1.1.0-next.3
+
+### Minor Changes
+
+- d09485ea79: Added support for self hosted OpenSearch via new provider
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-search-backend-node@1.1.0-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-techdocs-backend@1.5.0-next.3
+
+### Minor Changes
+
+- dfbdae092e: Added a new optional `accountId` to the configuration options of the AWS S3 publisher. Configuring this option will source credentials for the `accountId` in the `aws` app config section. See for more details.
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/plugin-techdocs-node@1.4.3-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/app-defaults@1.0.9-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-app-api@1.3.0-next.4
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-permission-react@0.4.8-next.3
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/backend-app-api@0.2.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/plugin-permission-node@0.7.2-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/errors@1.1.4-next.1
+
+## @backstage/backend-common@0.17.0-next.3
+
+### Patch Changes
+
+- 840f2113c6: Fix `GitlabUrlReader.readTree` bug when there were no matching commits
+- Updated dependencies
+ - @backstage/cli-common@0.1.11-next.0
+ - @backstage/config@1.0.5-next.1
+ - @backstage/config-loader@1.1.7-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/backend-defaults@0.1.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-app-api@0.2.4-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+
+## @backstage/backend-plugin-api@0.2.0-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+
+## @backstage/backend-tasks@0.4.0-next.3
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/backend-test-utils@0.1.31-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.22.0-next.4
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-app-api@0.2.4-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/config@1.0.5-next.1
+
+## @backstage/core-components@0.12.1-next.4
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- a5a2d12298: Added option to pass additional headers to ` `, which are passed along with the request to the underlying provider
+- Updated dependencies
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/version-bridge@1.0.3-next.0
+
+## @backstage/create-app@0.4.35-next.4
+
+### Patch Changes
+
+- 935b66a646: Change step output template examples to use square bracket syntax.
+
+- dfb269fab2: Updated the template to have the `'/test'` proxy endpoint in `app-config.yaml` be commented out by default.
+
+- d9b3753f87: Updated the app template to use the new `AppRouter` component instead of `app.getRouter()`, as well as `app.createRoot()` instead of `app.getProvider()`.
+
+ To apply this change to an existing app, make the following change to `packages/app/src/App.tsx`:
+
+ ```diff
+ -import { FlatRoutes } from '@backstage/core-app-api';
+ +import { AppRouter, FlatRoutes } from '@backstage/core-app-api';
+
+ ...
+
+ -const AppProvider = app.getProvider();
+ -const AppRouter = app.getRouter();
+
+ ...
+
+ -const App = () => (
+ +export default app.createRoot(
+ -
+ + <>
+
+
+
+ {routes}
+
+ -
+ + >,
+ );
+ ```
+
+ The final export step should end up looking something like this:
+
+ ```tsx
+ export default app.createRoot(
+ <>
+
+
+
+ {routes}
+
+ >,
+ );
+ ```
+
+ Note that `app.createRoot()` accepts a React element, rather than a component.
+
+- 71e75c0b70: Removed the `react-router` dependency from the app package, using only `react-router-dom` instead.
+
+ This change is just a bit of cleanup and is optional. If you want to apply it to your app, remove the `react-router` dependency from `packages/app/package.json`, and replace any imports from `react-router` with `react-router-dom` instead.
+
+- Updated dependencies
+ - @backstage/cli-common@0.1.11-next.0
+
+## @backstage/dev-utils@1.0.9-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-app-api@1.3.0-next.4
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/app-defaults@1.0.9-next.4
+ - @backstage/test-utils@1.2.3-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+
+## @backstage/integration-react@1.1.7-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/repo-tools@0.1.0-next.2
+
+### Patch Changes
+
+- a8611bcac4: Add new command options to the `api-report`
+
+ - added `--allow-warnings`, `-a` to continue processing packages if selected packages have warnings
+ - added `--allow-all-warnings` to continue processing packages any packages have warnings
+ - added `--omit-messages`, `-o` to pass some warnings messages code to be omitted from the api-report.md files
+ - The `paths` argument for this command now takes as default the value on `workspaces.packages` inside the root package.json
+ - change the path resolution to use the `@backstage/cli-common` packages instead
+
+- Updated dependencies
+ - @backstage/cli-common@0.1.11-next.0
+ - @backstage/errors@1.1.4-next.1
+
+## @techdocs/cli@1.2.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/plugin-techdocs-node@1.4.3-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/cli-common@0.1.11-next.0
+ - @backstage/config@1.0.5-next.1
+
+## @backstage/test-utils@1.2.3-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-app-api@1.3.0-next.4
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-permission-react@0.4.8-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-adr@0.2.4-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/plugin-search-react@1.3.0-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-adr-common@0.2.4-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-adr-backend@0.2.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-adr-common@0.2.4-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-adr-common@0.2.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-airbrake@0.3.12-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/dev-utils@1.0.9-next.4
+ - @backstage/test-utils@1.2.3-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-airbrake-backend@0.2.12-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+
+## @backstage/plugin-allure@0.1.28-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-analytics-module-ga@0.1.23-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-apache-airflow@0.2.5-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+
+## @backstage/plugin-api-docs@0.8.12-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog@1.7.0-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-apollo-explorer@0.1.5-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-app-backend@0.3.39-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/config-loader@1.1.7-next.2
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-auth-backend@0.17.2-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+
+## @backstage/plugin-auth-node@0.2.8-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+
+## @backstage/plugin-azure-devops@0.2.3-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-azure-devops-common@0.3.0
+
+## @backstage/plugin-azure-devops-backend@0.3.18-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-azure-devops-common@0.3.0
+
+## @backstage/plugin-azure-sites@0.1.1-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-azure-sites-common@0.1.0
+
+## @backstage/plugin-azure-sites-backend@0.1.1-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-azure-sites-common@0.1.0
+
+## @backstage/plugin-badges@0.2.36-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-badges-backend@0.1.33-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+
+## @backstage/plugin-bazaar@0.2.1-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.22.0-next.4
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog@1.7.0-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+
+## @backstage/plugin-bazaar-backend@0.2.2-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-test-utils@0.1.31-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+
+## @backstage/plugin-bitrise@0.1.39-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-catalog@1.7.0-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/plugin-search-react@1.3.0-next.4
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-catalog-backend@1.6.0-next.3
+
+### Patch Changes
+
+- ba13ff663c: Added a new `catalog.rules[].location` configuration that makes it possible to configure catalog rules to only apply to specific locations, either via exact match or a glob pattern.
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- 71147d5c16: Internal code reorganization.
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-permission-node@0.7.2-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+ - @backstage/plugin-scaffolder-common@1.2.3-next.1
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-catalog-backend-module-aws@0.1.12-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
+## @backstage/plugin-catalog-backend-module-azure@0.1.10-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
+## @backstage/plugin-catalog-backend-module-bitbucket@0.2.6-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-bitbucket-cloud-common@0.2.2-next.1
+
+## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.6-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-bitbucket-cloud-common@0.2.2-next.1
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+ - @backstage/plugin-events-node@0.2.0-next.3
+
+## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
+## @backstage/plugin-catalog-backend-module-gerrit@0.1.7-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
+## @backstage/plugin-catalog-backend-module-github@0.2.2-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+ - @backstage/plugin-events-node@0.2.0-next.3
+
+## @backstage/plugin-catalog-backend-module-gitlab@0.1.10-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
+## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.1.0-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/backend-test-utils@0.1.31-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
+## @backstage/plugin-catalog-backend-module-ldap@0.5.6-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-catalog-backend-module-msgraph@0.4.5-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
+## @backstage/plugin-catalog-backend-module-openapi@0.1.5-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
+## @backstage/plugin-catalog-common@1.0.9-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-catalog-graph@0.2.24-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-catalog-import@0.9.2-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+
+## @backstage/plugin-catalog-node@1.3.0-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+
+## @backstage/plugin-catalog-react@1.2.2-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-permission-react@0.4.8-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+ - @backstage/version-bridge@1.0.3-next.0
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+
+## @backstage/plugin-cicd-statistics@0.1.14-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+
+## @backstage/plugin-cicd-statistics-module-gitlab@0.1.8-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/plugin-cicd-statistics@0.1.14-next.4
+
+## @backstage/plugin-circleci@0.3.12-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-cloudbuild@0.3.12-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-code-climate@0.1.12-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-code-coverage@0.2.5-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-code-coverage-backend@0.2.5-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+
+## @backstage/plugin-codescene@0.1.7-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-config-schema@0.1.35-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-cost-insights@0.12.1-next.4
+
+### Patch Changes
+
+- 593c22253a: Added Y axis for metric data, with relevant formatting and data domain
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/test-utils@1.2.3-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-cost-insights-common@0.1.1
+
+## @backstage/plugin-dynatrace@1.0.2-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-events-backend@0.2.0-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-events-node@0.2.0-next.3
+
+## @backstage/plugin-events-backend-module-aws-sqs@0.1.1-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-events-node@0.2.0-next.3
+
+## @backstage/plugin-events-backend-module-azure@0.1.1-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/plugin-events-node@0.2.0-next.3
+
+## @backstage/plugin-events-backend-module-bitbucket-cloud@0.1.1-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/plugin-events-node@0.2.0-next.3
+
+## @backstage/plugin-events-backend-module-gerrit@0.1.1-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/plugin-events-node@0.2.0-next.3
+
+## @backstage/plugin-events-backend-module-github@0.1.1-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-events-node@0.2.0-next.3
+
+## @backstage/plugin-events-backend-module-gitlab@0.1.1-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-events-node@0.2.0-next.3
+
+## @backstage/plugin-events-backend-test-utils@0.1.1-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-events-node@0.2.0-next.3
+
+## @backstage/plugin-events-node@0.2.0-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-plugin-api@0.2.0-next.3
+
+## @backstage/plugin-explore@0.3.43-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/plugin-search-react@1.3.0-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-explore-common@0.0.1-next.0
+ - @backstage/plugin-explore-react@0.0.24-next.2
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-explore-backend@0.0.1-next.2
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-explore-common@0.0.1-next.0
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-firehydrant@0.1.29-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-fossa@0.2.44-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-gcalendar@0.3.8-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-gcp-projects@0.3.31-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-git-release-manager@0.3.25-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-github-actions@0.5.12-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-github-deployments@0.1.43-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-github-issues@0.2.1-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-github-pull-requests-board@0.1.6-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-gitops-profiles@0.3.30-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-gocd@0.1.18-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-graphiql@0.2.44-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-graphql-backend@0.1.29-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-catalog-graphql@0.3.16-next.1
+
+## @backstage/plugin-home@0.4.28-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/plugin-stack-overflow@0.1.8-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-ilert@0.2.1-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-jenkins@0.7.11-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-jenkins-common@0.1.11-next.3
+
+## @backstage/plugin-jenkins-backend@0.1.29-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+ - @backstage/plugin-jenkins-common@0.1.11-next.3
+
+## @backstage/plugin-jenkins-common@0.1.11-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+
+## @backstage/plugin-kafka@0.3.12-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-kafka-backend@0.2.32-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+
+## @backstage/plugin-kubernetes@0.7.5-next.4
+
+### Patch Changes
+
+- 365f887717: Removed rendering for ErrorEmptyState in ErrorReporting component, so nothing is rendered when there are no errors. Also removed Divider on Kubernetes page.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-kubernetes-common@0.4.5-next.1
+
+## @backstage/plugin-kubernetes-backend@0.8.1-next.4
+
+### Patch Changes
+
+- 22e20b3a59: Clusters declared in the app-config can now have their CA configured via a local filesystem path using the `caFile` property.
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-test-utils@0.1.31-next.4
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+ - @backstage/plugin-kubernetes-common@0.4.5-next.1
+
+## @backstage/plugin-lighthouse@0.3.12-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-newrelic@0.3.30-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-newrelic-dashboard@0.2.5-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+
+## @backstage/plugin-org@0.6.2-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-org-react@0.1.1-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-pagerduty@0.5.5-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-periskop@0.1.10-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-periskop-backend@0.1.10-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+
+## @backstage/plugin-permission-backend@0.5.14-next.3
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-permission-node@0.7.2-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+
+## @backstage/plugin-permission-common@0.7.2-next.2
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- Updated dependencies
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-permission-node@0.7.2-next.3
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+
+## @backstage/plugin-permission-react@0.4.8-next.3
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+
+## @backstage/plugin-playlist@0.1.3-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/plugin-permission-react@0.4.8-next.3
+ - @backstage/plugin-search-react@1.3.0-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-playlist-common@0.1.3-next.2
+
+## @backstage/plugin-playlist-backend@0.2.2-next.4
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-permission-node@0.7.2-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-test-utils@0.1.31-next.4
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+ - @backstage/plugin-playlist-common@0.1.3-next.2
+
+## @backstage/plugin-playlist-common@0.1.3-next.2
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+
+## @backstage/plugin-proxy-backend@0.2.33-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+
+## @backstage/plugin-rollbar@0.4.12-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-rollbar-backend@0.1.36-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+
+## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.14-next.3
+
+### Patch Changes
+
+- 935b66a646: Change step output template examples to use square bracket syntax.
+- Updated dependencies
+ - @backstage/plugin-scaffolder-backend@1.9.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-scaffolder-backend-module-rails@0.4.7-next.3
+
+### Patch Changes
+
+- 935b66a646: Change step output template examples to use square bracket syntax.
+- Updated dependencies
+ - @backstage/plugin-scaffolder-backend@1.9.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.12-next.3
+
+### Patch Changes
+
+- 935b66a646: Change step output template examples to use square bracket syntax.
+- Updated dependencies
+ - @backstage/plugin-scaffolder-backend@1.9.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-search@1.0.5-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/plugin-search-react@1.3.0-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+ - @backstage/version-bridge@1.0.3-next.0
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-search-backend@1.2.0-next.3
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-permission-node@0.7.2-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+ - @backstage/plugin-search-backend-node@1.1.0-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-search-backend-module-pg@0.4.3-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-search-backend-node@1.1.0-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-search-backend-node@1.1.0-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-search-common@1.2.0-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-search-react@1.3.0-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+ - @backstage/version-bridge@1.0.3-next.0
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-sentry@0.4.5-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-shortcuts@0.3.4-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-sonarqube@0.5.1-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-sonarqube-backend@0.1.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+
+## @backstage/plugin-splunk-on-call@0.4.1-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-stack-overflow@0.1.8-next.4
+
+### Patch Changes
+
+- c981e83612: The ` ` component is now able to highlight the result title and/or text when provided. To take advantage of this, pass in the `highlight` prop, similar to how it is done on other result list item components.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-home@0.4.28-next.4
+ - @backstage/plugin-search-react@1.3.0-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-stack-overflow-backend@0.1.8-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.22.0-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-tech-insights@0.3.4-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-tech-insights-common@0.2.9-next.1
+
+## @backstage/plugin-tech-insights-backend@0.5.5-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-tech-insights-common@0.2.9-next.1
+ - @backstage/plugin-tech-insights-node@0.3.7-next.3
+
+## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.23-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-tech-insights-common@0.2.9-next.1
+ - @backstage/plugin-tech-insights-node@0.3.7-next.3
+
+## @backstage/plugin-tech-insights-node@0.3.7-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-tech-insights-common@0.2.9-next.1
+
+## @backstage/plugin-tech-radar@0.5.19-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-techdocs@1.4.1-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/plugin-search-react@1.3.0-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-search-common@1.2.0-next.3
+ - @backstage/plugin-techdocs-react@1.0.7-next.4
+
+## @backstage/plugin-techdocs-addons-test-utils@1.0.7-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-app-api@1.3.0-next.4
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/test-utils@1.2.3-next.4
+ - @backstage/plugin-catalog@1.7.0-next.4
+ - @backstage/plugin-search-react@1.3.0-next.4
+ - @backstage/plugin-techdocs@1.4.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-techdocs-react@1.0.7-next.4
+
+## @backstage/plugin-techdocs-module-addons-contrib@1.0.7-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-techdocs-react@1.0.7-next.4
+
+## @backstage/plugin-techdocs-node@1.4.3-next.3
+
+### Patch Changes
+
+- e40790d0c2: Add support for specifying an S3 bucket's account ID and retrieving the credentials from the `aws` app config section. This is now the preferred way to configure AWS credentials for Techdocs.
+- Updated dependencies
+ - @backstage/integration-aws-node@0.1.0-next.0
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-search-common@1.2.0-next.3
+
+## @backstage/plugin-techdocs-react@1.0.7-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/version-bridge@1.0.3-next.0
+
+## @backstage/plugin-todo@0.2.14-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-todo-backend@0.1.36-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+
+## @backstage/plugin-user-settings@0.6.0-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-app-api@1.3.0-next.4
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+
+## @backstage/plugin-user-settings-backend@0.1.3-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+
+## @backstage/plugin-vault@0.1.6-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## @backstage/plugin-vault-backend@0.2.5-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-test-utils@0.1.31-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+
+## @backstage/plugin-xcmetrics@0.2.32-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
+## example-app@0.2.78-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-cost-insights@0.12.1-next.4
+ - @backstage/plugin-kubernetes@0.7.5-next.4
+ - @backstage/cli@0.22.0-next.4
+ - @backstage/core-app-api@1.3.0-next.4
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-scaffolder@1.9.0-next.4
+ - @backstage/app-defaults@1.0.9-next.4
+ - @backstage/plugin-airbrake@0.3.12-next.4
+ - @backstage/plugin-api-docs@0.8.12-next.4
+ - @backstage/plugin-azure-devops@0.2.3-next.4
+ - @backstage/plugin-badges@0.2.36-next.4
+ - @backstage/plugin-catalog-graph@0.2.24-next.4
+ - @backstage/plugin-catalog-import@0.9.2-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/plugin-circleci@0.3.12-next.4
+ - @backstage/plugin-cloudbuild@0.3.12-next.4
+ - @backstage/plugin-code-coverage@0.2.5-next.4
+ - @backstage/plugin-explore@0.3.43-next.4
+ - @backstage/plugin-github-actions@0.5.12-next.4
+ - @backstage/plugin-home@0.4.28-next.4
+ - @backstage/plugin-jenkins@0.7.11-next.4
+ - @backstage/plugin-kafka@0.3.12-next.4
+ - @backstage/plugin-org@0.6.2-next.4
+ - @backstage/plugin-permission-react@0.4.8-next.3
+ - @backstage/plugin-playlist@0.1.3-next.4
+ - @backstage/plugin-rollbar@0.4.12-next.4
+ - @backstage/plugin-search@1.0.5-next.4
+ - @backstage/plugin-search-react@1.3.0-next.4
+ - @backstage/plugin-sentry@0.4.5-next.4
+ - @backstage/plugin-shortcuts@0.3.4-next.4
+ - @backstage/plugin-techdocs@1.4.1-next.4
+ - @backstage/plugin-todo@0.2.14-next.4
+ - @backstage/plugin-user-settings@0.6.0-next.4
+ - @backstage/plugin-stack-overflow@0.1.8-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-apache-airflow@0.2.5-next.4
+ - @backstage/plugin-azure-sites@0.1.1-next.4
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-dynatrace@1.0.2-next.4
+ - @backstage/plugin-gcalendar@0.3.8-next.4
+ - @backstage/plugin-gcp-projects@0.3.31-next.4
+ - @backstage/plugin-gocd@0.1.18-next.4
+ - @backstage/plugin-graphiql@0.2.44-next.4
+ - @backstage/plugin-lighthouse@0.3.12-next.4
+ - @backstage/plugin-newrelic@0.3.30-next.4
+ - @backstage/plugin-newrelic-dashboard@0.2.5-next.4
+ - @backstage/plugin-pagerduty@0.5.5-next.4
+ - @backstage/plugin-search-common@1.2.0-next.3
+ - @backstage/plugin-tech-insights@0.3.4-next.4
+ - @backstage/plugin-tech-radar@0.5.19-next.4
+ - @backstage/plugin-techdocs-module-addons-contrib@1.0.7-next.4
+ - @backstage/plugin-techdocs-react@1.0.7-next.4
+ - @internal/plugin-catalog-customized@0.0.5-next.4
+
+## example-backend@0.2.78-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/plugin-scaffolder-backend-module-rails@0.4.7-next.3
+ - @backstage/plugin-scaffolder-backend@1.9.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/plugin-permission-backend@0.5.14-next.3
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-permission-node@0.7.2-next.3
+ - @backstage/plugin-playlist-backend@0.2.2-next.4
+ - @backstage/plugin-search-backend@1.2.0-next.3
+ - @backstage/plugin-kubernetes-backend@0.8.1-next.4
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/plugin-search-backend-module-elasticsearch@1.1.0-next.3
+ - @backstage/plugin-techdocs-backend@1.5.0-next.3
+ - example-app@0.2.78-next.4
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-app-backend@0.3.39-next.3
+ - @backstage/plugin-auth-backend@0.17.2-next.3
+ - @backstage/plugin-auth-node@0.2.8-next.3
+ - @backstage/plugin-azure-devops-backend@0.3.18-next.3
+ - @backstage/plugin-azure-sites-backend@0.1.1-next.3
+ - @backstage/plugin-badges-backend@0.1.33-next.3
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+ - @backstage/plugin-code-coverage-backend@0.2.5-next.3
+ - @backstage/plugin-events-backend@0.2.0-next.3
+ - @backstage/plugin-events-node@0.2.0-next.3
+ - @backstage/plugin-explore-backend@0.0.1-next.2
+ - @backstage/plugin-graphql-backend@0.1.29-next.3
+ - @backstage/plugin-jenkins-backend@0.1.29-next.3
+ - @backstage/plugin-kafka-backend@0.2.32-next.3
+ - @backstage/plugin-proxy-backend@0.2.33-next.3
+ - @backstage/plugin-rollbar-backend@0.1.36-next.3
+ - @backstage/plugin-search-backend-module-pg@0.4.3-next.3
+ - @backstage/plugin-search-backend-node@1.1.0-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+ - @backstage/plugin-tech-insights-backend@0.5.5-next.3
+ - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.23-next.3
+ - @backstage/plugin-tech-insights-node@0.3.7-next.3
+ - @backstage/plugin-todo-backend@0.1.36-next.3
+
+## example-backend-next@0.0.6-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/plugin-scaffolder-backend@1.9.0-next.3
+ - @backstage/backend-defaults@0.1.4-next.3
+ - @backstage/plugin-app-backend@0.3.39-next.3
+
+## techdocs-cli-embedded-app@0.2.77-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.22.0-next.4
+ - @backstage/core-app-api@1.3.0-next.4
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/app-defaults@1.0.9-next.4
+ - @backstage/test-utils@1.2.3-next.4
+ - @backstage/plugin-catalog@1.7.0-next.4
+ - @backstage/plugin-techdocs@1.4.1-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-techdocs-react@1.0.7-next.4
+
+## @internal/plugin-catalog-customized@0.0.5-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog@1.7.0-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+
+## @internal/plugin-todo-list@1.0.8-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
+## @internal/plugin-todo-list-backend@1.0.8-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+
+## @internal/plugin-todo-list-common@1.0.7-next.2
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
diff --git a/microsite-next/.gitignore b/microsite-next/.gitignore
new file mode 100644
index 0000000000..497e1057c6
--- /dev/null
+++ b/microsite-next/.gitignore
@@ -0,0 +1,5 @@
+
+# Build output
+build
+i18n
+.docusaurus
diff --git a/microsite-next/.prettierignore b/microsite-next/.prettierignore
new file mode 100644
index 0000000000..b52c4a85c3
--- /dev/null
+++ b/microsite-next/.prettierignore
@@ -0,0 +1 @@
+.docusaurus
diff --git a/microsite-next/docusaurus.config.js b/microsite-next/docusaurus.config.js
new file mode 100644
index 0000000000..2b37ae20b2
--- /dev/null
+++ b/microsite-next/docusaurus.config.js
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+ title: 'Backstage Software Catalog and Developer Platform',
+ tagline: 'An open platform for building developer portals',
+ url: 'https://backstage.io',
+ baseUrl: '/',
+ organizationName: 'Spotify',
+ projectName: 'backstage',
+ scripts: [
+ 'https://buttons.github.io/buttons.js',
+ 'https://unpkg.com/medium-zoom@1.0.6/dist/medium-zoom.min.js',
+ '/js/medium-zoom.js',
+ '/js/dismissable-banner.js',
+ '/js/scroll-nav-to-view-in-docs.js',
+ ],
+ stylesheets: [
+ 'https://fonts.googleapis.com/css?family=IBM+Plex+Mono:500,700&display=swap',
+ ],
+ favicon: 'img/favicon.ico',
+ customFields: {
+ fossWebsite: 'https://spotify.github.io/',
+ repoUrl: 'https://github.com/backstage/backstage',
+ },
+ onBrokenLinks: 'log',
+ onBrokenMarkdownLinks: 'log',
+ presets: [
+ [
+ '@docusaurus/preset-classic',
+ {
+ docs: {
+ showLastUpdateAuthor: true,
+ showLastUpdateTime: true,
+ editUrl: 'https://github.com/backstage/backstage/edit/master/docs/',
+ path: '../docs',
+ sidebarPath: 'sidebars.json',
+ },
+ blog: {
+ path: '../microsite/blog',
+ },
+ theme: {
+ customCss: 'src/css/customTheme.css',
+ },
+ gtag: {
+ trackingID: 'G-KSEVGGNCJW',
+ },
+ },
+ ],
+ ],
+ plugins: [],
+ themeConfig: {
+ navbar: {
+ title: 'Backstage Software Catalog and Developer Platform',
+ items: [
+ {
+ href: 'https://github.com/backstage/backstage',
+ label: 'GitHub',
+ position: 'left',
+ },
+ {
+ to: 'docs/overview/what-is-backstage',
+ label: 'Docs',
+ position: 'left',
+ },
+ {
+ to: '/plugins',
+ label: 'Plugins',
+ position: 'left',
+ },
+ {
+ to: '/blog',
+ label: 'Blog',
+ position: 'left',
+ },
+ {
+ to: 'docs/releases/v1.8.0',
+ label: 'Releases',
+ position: 'left',
+ },
+ {
+ to: '/demos',
+ label: 'Demos',
+ position: 'left',
+ },
+ {
+ to: '/community',
+ label: 'Community',
+ position: 'left',
+ },
+ ],
+ },
+ image: 'img/sharing-opengraph.png',
+ footer: {
+ links: [
+ {
+ items: [
+ {
+ html: ' ',
+ },
+ ],
+ },
+ {
+ title: 'Docs',
+ items: [
+ {
+ label: 'What is Backstage?',
+ to: 'docs/overview/what-is-backstage',
+ },
+ {
+ label: 'Getting started',
+ to: 'docs/getting-started/',
+ },
+ {
+ label: 'Software Catalog',
+ to: 'docs/features/software-catalog/software-catalog-overview',
+ },
+ {
+ label: 'Create a Plugin',
+ to: 'docs/plugins/create-a-plugin',
+ },
+ {
+ label: 'Designing for Backstage',
+ to: 'docs/dls/design',
+ },
+ ],
+ },
+ {
+ title: 'Community',
+ items: [
+ {
+ label: 'Support chatroom',
+ to: 'https://discord.gg/MUpMjP2',
+ },
+ {
+ label: 'Contributing',
+ to: 'https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md',
+ },
+ {
+ label: 'Adopting',
+ to: 'https://backstage.spotify.com',
+ },
+ {
+ label: 'Subscribe to our newsletter',
+ to: 'https://mailchi.mp/spotify/backstage-community',
+ },
+ {
+ label: 'CNCF Incubation',
+ to: 'https://www.cncf.io/projects/',
+ },
+ ],
+ },
+ {
+ title: 'More',
+ items: [
+ {
+ label: 'Open Source @ Spotify',
+ to: 'https://spotify.github.io/',
+ },
+ {
+ label: 'Spotify Engineering Blog',
+ to: 'https://engineering.atspotify.com/',
+ },
+ {
+ label: 'Spotify for Developers',
+ to: 'https://developer.spotify.com/',
+ },
+ {
+ label: 'Github',
+ to: 'https://github.com/backstage/',
+ },
+ ],
+ },
+ ],
+ copyright:
+ 'Made with ❤️ at Spotify
Copyright © 2022 Backstage Project Authors. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page: https://www.linuxfoundation.org/trademark-usage
',
+ },
+ algolia: {
+ appId: 'AZYC4ZFNTN',
+ apiKey: '7dbd2089b0d445ee0d87db71abfc794f',
+ indexName: 'backstage',
+ searchParameters: {},
+ },
+ },
+};
diff --git a/microsite-next/package.json b/microsite-next/package.json
new file mode 100644
index 0000000000..1b33d2896f
--- /dev/null
+++ b/microsite-next/package.json
@@ -0,0 +1,33 @@
+{
+ "version": "0.0.0",
+ "name": "backstage-microsite",
+ "license": "Apache-2.0",
+ "private": true,
+ "scripts": {
+ "examples": "docusaurus-examples",
+ "start": "docusaurus start",
+ "build": "docusaurus build",
+ "prettier:check": "prettier --check .",
+ "publish-gh-pages": "docusaurus-publish",
+ "write-translations": "docusaurus-write-translations",
+ "version": "docusaurus-version",
+ "rename-version": "docusaurus-rename-version",
+ "verify:sidebars": "node ./scripts/verify-sidebars",
+ "swizzle": "docusaurus swizzle",
+ "deploy": "docusaurus deploy",
+ "docusaurus": "docusaurus"
+ },
+ "devDependencies": {
+ "@spotify/prettier-config": "^14.0.0",
+ "js-yaml": "^4.1.0",
+ "prettier": "^2.6.2"
+ },
+ "prettier": "@spotify/prettier-config",
+ "dependencies": {
+ "@docusaurus/core": "2.2.0",
+ "@docusaurus/preset-classic": "2.2.0",
+ "clsx": "^1.1.1",
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2"
+ }
+}
diff --git a/microsite-next/sidebars.json b/microsite-next/sidebars.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/microsite-next/sidebars.json
@@ -0,0 +1 @@
+{}
diff --git a/microsite-next/src/css/customTheme.css b/microsite-next/src/css/customTheme.css
new file mode 100644
index 0000000000..3b71d51d62
--- /dev/null
+++ b/microsite-next/src/css/customTheme.css
@@ -0,0 +1,47 @@
+:root {
+ --ifm-color-primary-lightest: #66d2bf;
+ --ifm-color-primary-lighter: #4acab3;
+ --ifm-color-primary-light: #40c8af;
+ --ifm-color-primary: #36baa2;
+ --ifm-color-primary-dark: #31a792;
+ --ifm-color-primary-darker: #2e9e8a;
+ --ifm-color-primary-darkest: #268271;
+}
+
+.footerLogo {
+ background-image: url(/img/logo.svg);
+ background-repeat: no-repeat;
+ height: 40px;
+ width: 180px;
+ margin-top: 0px;
+}
+
+.copyright {
+ font-size: 10pt;
+}
+
+/* logo.md */
+.logoWhite {
+ background-color: white;
+}
+
+/* Utility API Styling */
+.textGreen {
+ color: #82b366;
+}
+.textBlue {
+ color: #6c8ebf;
+}
+.textPurple {
+ color: #9673a6;
+}
+.textYellow {
+ color: #d6b656;
+}
+.textRed {
+ color: #b85450;
+}
+.textAlignCenter {
+ text-align: center;
+}
+/* End of Utility API Styling */
diff --git a/microsite-next/src/pages/index.tsx b/microsite-next/src/pages/index.tsx
new file mode 100644
index 0000000000..3bbf03b0e2
--- /dev/null
+++ b/microsite-next/src/pages/index.tsx
@@ -0,0 +1,11 @@
+import Layout from '@theme/Layout';
+import React from 'react';
+
+function Index() {
+ return (
+
+ HELLO
+
+ );
+}
+export default Index;
diff --git a/microsite-next/static b/microsite-next/static
new file mode 120000
index 0000000000..d9a02b18c2
--- /dev/null
+++ b/microsite-next/static
@@ -0,0 +1 @@
+../microsite/static
\ No newline at end of file
diff --git a/microsite-next/yarn.lock b/microsite-next/yarn.lock
new file mode 100644
index 0000000000..fa35b93945
--- /dev/null
+++ b/microsite-next/yarn.lock
@@ -0,0 +1,10804 @@
+# This file is generated by running "yarn install" inside your project.
+# Manual changes might be lost - proceed with caution!
+
+__metadata:
+ version: 6
+ cacheKey: 8
+
+"@algolia/autocomplete-core@npm:1.7.2":
+ version: 1.7.2
+ resolution: "@algolia/autocomplete-core@npm:1.7.2"
+ dependencies:
+ "@algolia/autocomplete-shared": 1.7.2
+ checksum: 7d3e879ac74f2d3fd6f80a01d6c05bd22264c428030396234112be7628a80d3a7c250613b2d4102f8ef63115be7b96d8d0231bdf8a02aa9b58873500aa61ffcc
+ languageName: node
+ linkType: hard
+
+"@algolia/autocomplete-preset-algolia@npm:1.7.2":
+ version: 1.7.2
+ resolution: "@algolia/autocomplete-preset-algolia@npm:1.7.2"
+ dependencies:
+ "@algolia/autocomplete-shared": 1.7.2
+ peerDependencies:
+ "@algolia/client-search": ">= 4.9.1 < 6"
+ algoliasearch: ">= 4.9.1 < 6"
+ checksum: 7120ce1d312dbe6d898a0cecd9b28e45f9162a2fd9208a4c4e2efa77027455ee083c11cb782196374da717e990d6ca362c286ace475db97916e52bd277061d77
+ languageName: node
+ linkType: hard
+
+"@algolia/autocomplete-shared@npm:1.7.2":
+ version: 1.7.2
+ resolution: "@algolia/autocomplete-shared@npm:1.7.2"
+ checksum: 8336cd1e79e56e3901196862ae17896c6e9542e269a05860ab72d869e35f17ab0f40ecbe35d1e34617cc70749d3f8323d09b347c443a7b7b2b126dddb44779aa
+ languageName: node
+ linkType: hard
+
+"@algolia/cache-browser-local-storage@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/cache-browser-local-storage@npm:4.14.2"
+ dependencies:
+ "@algolia/cache-common": 4.14.2
+ checksum: e7d5f43ff01df5f21a2b5304b5d8f8ae25f2c6093e83e79556cb78ae07f342111ba77eba633b837b5b74a17293ea6a208acb1ade71782baafa9c2da7d58ee45c
+ languageName: node
+ linkType: hard
+
+"@algolia/cache-common@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/cache-common@npm:4.14.2"
+ checksum: 4fd04c714aee19f6eaaac4ae7e00e914a44473af9a84cf3c4260e436c6ea20f5590e05e9006d963372d84ce57268776811fcb929d79e0415b59d74779bd31ee7
+ languageName: node
+ linkType: hard
+
+"@algolia/cache-in-memory@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/cache-in-memory@npm:4.14.2"
+ dependencies:
+ "@algolia/cache-common": 4.14.2
+ checksum: d6981f812a368a38db21e52c98ec81a5c0eda5d896377f7bdcc04a0be1673ac9e184836d7973065fab84dc947a63fe959586468fc14b9a87e32f916959df6222
+ languageName: node
+ linkType: hard
+
+"@algolia/client-account@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/client-account@npm:4.14.2"
+ dependencies:
+ "@algolia/client-common": 4.14.2
+ "@algolia/client-search": 4.14.2
+ "@algolia/transporter": 4.14.2
+ checksum: 2e9eed5a4b8434775af87899bda8140d51eb2dd0cf08fc49370a4dc9541c220db9b241976dad14ae5d07a25f7ddafd9759a2eb462788f21a20f14e04968f98a4
+ languageName: node
+ linkType: hard
+
+"@algolia/client-analytics@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/client-analytics@npm:4.14.2"
+ dependencies:
+ "@algolia/client-common": 4.14.2
+ "@algolia/client-search": 4.14.2
+ "@algolia/requester-common": 4.14.2
+ "@algolia/transporter": 4.14.2
+ checksum: 61874e026c9d08dd628da443b5b34d1a3bb707a0283e727d94ee6d61057631039c5cf6303e6234cc6fbe84ff71c2758f952b664277715ca5761819aec73e7aad
+ languageName: node
+ linkType: hard
+
+"@algolia/client-common@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/client-common@npm:4.14.2"
+ dependencies:
+ "@algolia/requester-common": 4.14.2
+ "@algolia/transporter": 4.14.2
+ checksum: da2be279ac51e1b43c02c6d2bbf0d9cc8b1cb3250ad10a803fca609bcfb8164a8adc21281b599fd8aa322c04deea77d2f07adcae1a363952559472e781e26c71
+ languageName: node
+ linkType: hard
+
+"@algolia/client-personalization@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/client-personalization@npm:4.14.2"
+ dependencies:
+ "@algolia/client-common": 4.14.2
+ "@algolia/requester-common": 4.14.2
+ "@algolia/transporter": 4.14.2
+ checksum: 0dd25c84a40fe9853d14fadc3c8893e84bee370b5a3eb6730afe816afe1f92b970096d2dfb68073f606fa074fdeb66c3a73811d9a9a9774af5311f34d939fd72
+ languageName: node
+ linkType: hard
+
+"@algolia/client-search@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/client-search@npm:4.14.2"
+ dependencies:
+ "@algolia/client-common": 4.14.2
+ "@algolia/requester-common": 4.14.2
+ "@algolia/transporter": 4.14.2
+ checksum: 2695bc9e8c98badb601b915dbb075dd92996af350b0e4915a7a3b7825bd45f20815534debcfcb51bb7f682ba5d09f3c41918edb36e0a7f7bb154d3b205825f65
+ languageName: node
+ linkType: hard
+
+"@algolia/events@npm:^4.0.1":
+ version: 4.0.1
+ resolution: "@algolia/events@npm:4.0.1"
+ checksum: 4f63943f4554cfcfed91d8b8c009a49dca192b81056d8c75e532796f64828cd69899852013e81ff3fff07030df8782b9b95c19a3da0845786bdfe22af42442c2
+ languageName: node
+ linkType: hard
+
+"@algolia/logger-common@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/logger-common@npm:4.14.2"
+ checksum: a4000a98831d64c8d826ccece9f5f3a77bc000d93d74a7c6b51f186d3dfd96c0bb00934f70c69da8f3c4dfb9f30ce55ab59aca9ba79c3cc3e924597838a94429
+ languageName: node
+ linkType: hard
+
+"@algolia/logger-console@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/logger-console@npm:4.14.2"
+ dependencies:
+ "@algolia/logger-common": 4.14.2
+ checksum: 96c6209c7ef72cbc170b180f5b84c6523a5b6f4dea978c982577d2417eb19eb9c9ea3bc73089ced692a05bec141d66fd6d5401458d0aa162dbcace5017dbd127
+ languageName: node
+ linkType: hard
+
+"@algolia/requester-browser-xhr@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/requester-browser-xhr@npm:4.14.2"
+ dependencies:
+ "@algolia/requester-common": 4.14.2
+ checksum: 7d8666e21cd0d15dc2e25f6917464c2f98cf73e0d2fced94cc6a3c4e97a990b8b93d9531bbf6f3b1ff2342b9ce9760d1dcb64dbbf61a5f2c31fe4f42541deef2
+ languageName: node
+ linkType: hard
+
+"@algolia/requester-common@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/requester-common@npm:4.14.2"
+ checksum: 7de4148a55db56fe2bf18c1359cccbc2f41031fe2bfbc945d75f143b854638c51e7ec2ef9c6dc69b38d5edb87cd096ce5d7087680da32825562db79026ea39cc
+ languageName: node
+ linkType: hard
+
+"@algolia/requester-node-http@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/requester-node-http@npm:4.14.2"
+ dependencies:
+ "@algolia/requester-common": 4.14.2
+ checksum: 5f5fe8b040f73bd95c6bdb5b97396e078b629b2b4cd93fea671d545be375c79501c65296c34824f0ff8368b5b51edc7a6ad9e694b04223c1416dcda869c6f566
+ languageName: node
+ linkType: hard
+
+"@algolia/transporter@npm:4.14.2":
+ version: 4.14.2
+ resolution: "@algolia/transporter@npm:4.14.2"
+ dependencies:
+ "@algolia/cache-common": 4.14.2
+ "@algolia/logger-common": 4.14.2
+ "@algolia/requester-common": 4.14.2
+ checksum: 72c72013f3edb4d4484e7a43fb3c2555646ab04f422249514ed0309e20f41f5563f4c4dcf5623ca64c293624ecc74f87acaf2d9820e8c829cb5de067bdfe0257
+ languageName: node
+ linkType: hard
+
+"@ampproject/remapping@npm:^2.1.0":
+ version: 2.2.0
+ resolution: "@ampproject/remapping@npm:2.2.0"
+ dependencies:
+ "@jridgewell/gen-mapping": ^0.1.0
+ "@jridgewell/trace-mapping": ^0.3.9
+ checksum: d74d170d06468913921d72430259424b7e4c826b5a7d39ff839a29d547efb97dc577caa8ba3fb5cf023624e9af9d09651afc3d4112a45e2050328abc9b3a2292
+ languageName: node
+ linkType: hard
+
+"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.18.6, @babel/code-frame@npm:^7.8.3":
+ version: 7.18.6
+ resolution: "@babel/code-frame@npm:7.18.6"
+ dependencies:
+ "@babel/highlight": ^7.18.6
+ checksum: 195e2be3172d7684bf95cff69ae3b7a15a9841ea9d27d3c843662d50cdd7d6470fd9c8e64be84d031117e4a4083486effba39f9aef6bbb2c89f7f21bcfba33ba
+ languageName: node
+ linkType: hard
+
+"@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.20.0, @babel/compat-data@npm:^7.20.1":
+ version: 7.20.5
+ resolution: "@babel/compat-data@npm:7.20.5"
+ checksum: 523790c43ef6388fae91d1ca9acf1ab0e1b22208dcd39c0e5e7a6adf0b48a133f1831be8d5931a72ecd48860f3e3fb777cb89840794abd8647a5c8e5cfab484e
+ languageName: node
+ linkType: hard
+
+"@babel/core@npm:7.12.9":
+ version: 7.12.9
+ resolution: "@babel/core@npm:7.12.9"
+ dependencies:
+ "@babel/code-frame": ^7.10.4
+ "@babel/generator": ^7.12.5
+ "@babel/helper-module-transforms": ^7.12.1
+ "@babel/helpers": ^7.12.5
+ "@babel/parser": ^7.12.7
+ "@babel/template": ^7.12.7
+ "@babel/traverse": ^7.12.9
+ "@babel/types": ^7.12.7
+ convert-source-map: ^1.7.0
+ debug: ^4.1.0
+ gensync: ^1.0.0-beta.1
+ json5: ^2.1.2
+ lodash: ^4.17.19
+ resolve: ^1.3.2
+ semver: ^5.4.1
+ source-map: ^0.5.0
+ checksum: 4d34eca4688214a4eb6bd5dde906b69a7824f17b931f52cd03628a8ac94d8fbe15565aebffdde106e974c8738cd64ac62c6a6060baa7139a06db1f18c4ff872d
+ languageName: node
+ linkType: hard
+
+"@babel/core@npm:^7.18.6, @babel/core@npm:^7.19.6":
+ version: 7.20.5
+ resolution: "@babel/core@npm:7.20.5"
+ dependencies:
+ "@ampproject/remapping": ^2.1.0
+ "@babel/code-frame": ^7.18.6
+ "@babel/generator": ^7.20.5
+ "@babel/helper-compilation-targets": ^7.20.0
+ "@babel/helper-module-transforms": ^7.20.2
+ "@babel/helpers": ^7.20.5
+ "@babel/parser": ^7.20.5
+ "@babel/template": ^7.18.10
+ "@babel/traverse": ^7.20.5
+ "@babel/types": ^7.20.5
+ convert-source-map: ^1.7.0
+ debug: ^4.1.0
+ gensync: ^1.0.0-beta.2
+ json5: ^2.2.1
+ semver: ^6.3.0
+ checksum: 9547f1e6364bc58c3621e3b17ec17f0d034ff159e5a520091d9381608d40af3be4042dd27c20ad7d3e938422d75850ac56a3758d6801d65df701557af4bd244b
+ languageName: node
+ linkType: hard
+
+"@babel/generator@npm:^7.12.5, @babel/generator@npm:^7.18.7, @babel/generator@npm:^7.20.5":
+ version: 7.20.5
+ resolution: "@babel/generator@npm:7.20.5"
+ dependencies:
+ "@babel/types": ^7.20.5
+ "@jridgewell/gen-mapping": ^0.3.2
+ jsesc: ^2.5.1
+ checksum: 31c10d1e122f08cf755a24bd6f5d197f47eceba03f1133759687d00ab72d210e60ba4011da42f368b6e9fa85cbfda7dc4adb9889c2c20cc5c34bb2d57c1deab7
+ languageName: node
+ linkType: hard
+
+"@babel/helper-annotate-as-pure@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/helper-annotate-as-pure@npm:7.18.6"
+ dependencies:
+ "@babel/types": ^7.18.6
+ checksum: 88ccd15ced475ef2243fdd3b2916a29ea54c5db3cd0cfabf9d1d29ff6e63b7f7cd1c27264137d7a40ac2e978b9b9a542c332e78f40eb72abe737a7400788fc1b
+ languageName: node
+ linkType: hard
+
+"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.18.6":
+ version: 7.18.9
+ resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.18.9"
+ dependencies:
+ "@babel/helper-explode-assignable-expression": ^7.18.6
+ "@babel/types": ^7.18.9
+ checksum: b4bc214cb56329daff6cc18a7f7a26aeafb55a1242e5362f3d47fe3808421f8c7cd91fff95d6b9b7ccb67e14e5a67d944e49dbe026942bfcbfda19b1c72a8e72
+ languageName: node
+ linkType: hard
+
+"@babel/helper-compilation-targets@npm:^7.17.7, @babel/helper-compilation-targets@npm:^7.18.9, @babel/helper-compilation-targets@npm:^7.20.0":
+ version: 7.20.0
+ resolution: "@babel/helper-compilation-targets@npm:7.20.0"
+ dependencies:
+ "@babel/compat-data": ^7.20.0
+ "@babel/helper-validator-option": ^7.18.6
+ browserslist: ^4.21.3
+ semver: ^6.3.0
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: bc183f2109648849c8fde0b3c5cf08adf2f7ad6dc617b546fd20f34c8ef574ee5ee293c8d1bd0ed0221212e8f5907cdc2c42097870f1dcc769a654107d82c95b
+ languageName: node
+ linkType: hard
+
+"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.20.2, @babel/helper-create-class-features-plugin@npm:^7.20.5":
+ version: 7.20.5
+ resolution: "@babel/helper-create-class-features-plugin@npm:7.20.5"
+ dependencies:
+ "@babel/helper-annotate-as-pure": ^7.18.6
+ "@babel/helper-environment-visitor": ^7.18.9
+ "@babel/helper-function-name": ^7.19.0
+ "@babel/helper-member-expression-to-functions": ^7.18.9
+ "@babel/helper-optimise-call-expression": ^7.18.6
+ "@babel/helper-replace-supers": ^7.19.1
+ "@babel/helper-split-export-declaration": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 51b0662cc44ae5fe3691ed552f97312006709ec3f5321a5e5b5a139a5743eaaf65987f30ee7c171af80ab77460fb57c1970b0b1583dd70d90b58e4433b117a1b
+ languageName: node
+ linkType: hard
+
+"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.20.5":
+ version: 7.20.5
+ resolution: "@babel/helper-create-regexp-features-plugin@npm:7.20.5"
+ dependencies:
+ "@babel/helper-annotate-as-pure": ^7.18.6
+ regexpu-core: ^5.2.1
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 7f29c3cb7447cca047b0d394f8ab98e4923d00e86a7afa56e5df9770c48ec107891505d2d1f06b720ecc94ed24bf58d90986cc35fe4a43b549eb7b7a5077b693
+ languageName: node
+ linkType: hard
+
+"@babel/helper-define-polyfill-provider@npm:^0.3.3":
+ version: 0.3.3
+ resolution: "@babel/helper-define-polyfill-provider@npm:0.3.3"
+ dependencies:
+ "@babel/helper-compilation-targets": ^7.17.7
+ "@babel/helper-plugin-utils": ^7.16.7
+ debug: ^4.1.1
+ lodash.debounce: ^4.0.8
+ resolve: ^1.14.2
+ semver: ^6.1.2
+ peerDependencies:
+ "@babel/core": ^7.4.0-0
+ checksum: 8e3fe75513302e34f6d92bd67b53890e8545e6c5bca8fe757b9979f09d68d7e259f6daea90dc9e01e332c4f8781bda31c5fe551c82a277f9bc0bec007aed497c
+ languageName: node
+ linkType: hard
+
+"@babel/helper-environment-visitor@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/helper-environment-visitor@npm:7.18.9"
+ checksum: b25101f6162ddca2d12da73942c08ad203d7668e06663df685634a8fde54a98bc015f6f62938e8554457a592a024108d45b8f3e651fd6dcdb877275b73cc4420
+ languageName: node
+ linkType: hard
+
+"@babel/helper-explode-assignable-expression@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/helper-explode-assignable-expression@npm:7.18.6"
+ dependencies:
+ "@babel/types": ^7.18.6
+ checksum: 225cfcc3376a8799023d15dc95000609e9d4e7547b29528c7f7111a0e05493ffb12c15d70d379a0bb32d42752f340233c4115bded6d299bc0c3ab7a12be3d30f
+ languageName: node
+ linkType: hard
+
+"@babel/helper-function-name@npm:^7.18.9, @babel/helper-function-name@npm:^7.19.0":
+ version: 7.19.0
+ resolution: "@babel/helper-function-name@npm:7.19.0"
+ dependencies:
+ "@babel/template": ^7.18.10
+ "@babel/types": ^7.19.0
+ checksum: eac1f5db428ba546270c2b8d750c24eb528b8fcfe50c81de2e0bdebf0e20f24bec688d4331533b782e4a907fad435244621ca2193cfcf80a86731299840e0f6e
+ languageName: node
+ linkType: hard
+
+"@babel/helper-hoist-variables@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/helper-hoist-variables@npm:7.18.6"
+ dependencies:
+ "@babel/types": ^7.18.6
+ checksum: fd9c35bb435fda802bf9ff7b6f2df06308a21277c6dec2120a35b09f9de68f68a33972e2c15505c1a1a04b36ec64c9ace97d4a9e26d6097b76b4396b7c5fa20f
+ languageName: node
+ linkType: hard
+
+"@babel/helper-member-expression-to-functions@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/helper-member-expression-to-functions@npm:7.18.9"
+ dependencies:
+ "@babel/types": ^7.18.9
+ checksum: fcf8184e3b55051c4286b2cbedf0eccc781d0f3c9b5cbaba582eca19bf0e8d87806cdb7efc8554fcb969ceaf2b187d5ea748d40022d06ec7739fbb18c1b19a7a
+ languageName: node
+ linkType: hard
+
+"@babel/helper-module-imports@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/helper-module-imports@npm:7.18.6"
+ dependencies:
+ "@babel/types": ^7.18.6
+ checksum: f393f8a3b3304b1b7a288a38c10989de754f01d29caf62ce7c4e5835daf0a27b81f3ac687d9d2780d39685aae7b55267324b512150e7b2be967b0c493b6a1def
+ languageName: node
+ linkType: hard
+
+"@babel/helper-module-transforms@npm:^7.12.1, @babel/helper-module-transforms@npm:^7.18.6, @babel/helper-module-transforms@npm:^7.19.6, @babel/helper-module-transforms@npm:^7.20.2":
+ version: 7.20.2
+ resolution: "@babel/helper-module-transforms@npm:7.20.2"
+ dependencies:
+ "@babel/helper-environment-visitor": ^7.18.9
+ "@babel/helper-module-imports": ^7.18.6
+ "@babel/helper-simple-access": ^7.20.2
+ "@babel/helper-split-export-declaration": ^7.18.6
+ "@babel/helper-validator-identifier": ^7.19.1
+ "@babel/template": ^7.18.10
+ "@babel/traverse": ^7.20.1
+ "@babel/types": ^7.20.2
+ checksum: 33a60ca115f6fce2c9d98e2a2e5649498aa7b23e2ae3c18745d7a021487708fc311458c33542f299387a0da168afccba94116e077f2cce49ae9e5ab83399e8a2
+ languageName: node
+ linkType: hard
+
+"@babel/helper-optimise-call-expression@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/helper-optimise-call-expression@npm:7.18.6"
+ dependencies:
+ "@babel/types": ^7.18.6
+ checksum: e518fe8418571405e21644cfb39cf694f30b6c47b10b006609a92469ae8b8775cbff56f0b19732343e2ea910641091c5a2dc73b56ceba04e116a33b0f8bd2fbd
+ languageName: node
+ linkType: hard
+
+"@babel/helper-plugin-utils@npm:7.10.4":
+ version: 7.10.4
+ resolution: "@babel/helper-plugin-utils@npm:7.10.4"
+ checksum: 639ed8fc462b97a83226cee6bb081b1d77e7f73e8b033d2592ed107ee41d96601e321e5ea53a33e47469c7f1146b250a3dcda5ab873c7de162ab62120c341a41
+ languageName: node
+ linkType: hard
+
+"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.16.7, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.18.9, @babel/helper-plugin-utils@npm:^7.19.0, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3":
+ version: 7.20.2
+ resolution: "@babel/helper-plugin-utils@npm:7.20.2"
+ checksum: f6cae53b7fdb1bf3abd50fa61b10b4470985b400cc794d92635da1e7077bb19729f626adc0741b69403d9b6e411cddddb9c0157a709cc7c4eeb41e663be5d74b
+ languageName: node
+ linkType: hard
+
+"@babel/helper-remap-async-to-generator@npm:^7.18.6, @babel/helper-remap-async-to-generator@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/helper-remap-async-to-generator@npm:7.18.9"
+ dependencies:
+ "@babel/helper-annotate-as-pure": ^7.18.6
+ "@babel/helper-environment-visitor": ^7.18.9
+ "@babel/helper-wrap-function": ^7.18.9
+ "@babel/types": ^7.18.9
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 4be6076192308671b046245899b703ba090dbe7ad03e0bea897bb2944ae5b88e5e85853c9d1f83f643474b54c578d8ac0800b80341a86e8538264a725fbbefec
+ languageName: node
+ linkType: hard
+
+"@babel/helper-replace-supers@npm:^7.18.6, @babel/helper-replace-supers@npm:^7.19.1":
+ version: 7.19.1
+ resolution: "@babel/helper-replace-supers@npm:7.19.1"
+ dependencies:
+ "@babel/helper-environment-visitor": ^7.18.9
+ "@babel/helper-member-expression-to-functions": ^7.18.9
+ "@babel/helper-optimise-call-expression": ^7.18.6
+ "@babel/traverse": ^7.19.1
+ "@babel/types": ^7.19.0
+ checksum: a0e4bf79ebe7d2bb5947169e47a0b4439c73fb0ec57d446cf3ea81b736721129ec373c3f94d2ebd2716b26dd65f8e6c083dac898170d42905e7ba815a2f52c25
+ languageName: node
+ linkType: hard
+
+"@babel/helper-simple-access@npm:^7.19.4, @babel/helper-simple-access@npm:^7.20.2":
+ version: 7.20.2
+ resolution: "@babel/helper-simple-access@npm:7.20.2"
+ dependencies:
+ "@babel/types": ^7.20.2
+ checksum: ad1e96ee2e5f654ffee2369a586e5e8d2722bf2d8b028a121b4c33ebae47253f64d420157b9f0a8927aea3a9e0f18c0103e74fdd531815cf3650a0a4adca11a1
+ languageName: node
+ linkType: hard
+
+"@babel/helper-skip-transparent-expression-wrappers@npm:^7.18.9":
+ version: 7.20.0
+ resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.20.0"
+ dependencies:
+ "@babel/types": ^7.20.0
+ checksum: 34da8c832d1c8a546e45d5c1d59755459ffe43629436707079989599b91e8c19e50e73af7a4bd09c95402d389266731b0d9c5f69e372d8ebd3a709c05c80d7dd
+ languageName: node
+ linkType: hard
+
+"@babel/helper-split-export-declaration@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/helper-split-export-declaration@npm:7.18.6"
+ dependencies:
+ "@babel/types": ^7.18.6
+ checksum: c6d3dede53878f6be1d869e03e9ffbbb36f4897c7cc1527dc96c56d127d834ffe4520a6f7e467f5b6f3c2843ea0e81a7819d66ae02f707f6ac057f3d57943a2b
+ languageName: node
+ linkType: hard
+
+"@babel/helper-string-parser@npm:^7.19.4":
+ version: 7.19.4
+ resolution: "@babel/helper-string-parser@npm:7.19.4"
+ checksum: b2f8a3920b30dfac81ec282ac4ad9598ea170648f8254b10f475abe6d944808fb006aab325d3eb5a8ad3bea8dfa888cfa6ef471050dae5748497c110ec060943
+ languageName: node
+ linkType: hard
+
+"@babel/helper-validator-identifier@npm:^7.18.6, @babel/helper-validator-identifier@npm:^7.19.1":
+ version: 7.19.1
+ resolution: "@babel/helper-validator-identifier@npm:7.19.1"
+ checksum: 0eca5e86a729162af569b46c6c41a63e18b43dbe09fda1d2a3c8924f7d617116af39cac5e4cd5d431bb760b4dca3c0970e0c444789b1db42bcf1fa41fbad0a3a
+ languageName: node
+ linkType: hard
+
+"@babel/helper-validator-option@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/helper-validator-option@npm:7.18.6"
+ checksum: f9cc6eb7cc5d759c5abf006402180f8d5e4251e9198197428a97e05d65eb2f8ae5a0ce73b1dfd2d35af41d0eb780627a64edf98a4e71f064eeeacef8de58f2cf
+ languageName: node
+ linkType: hard
+
+"@babel/helper-wrap-function@npm:^7.18.9":
+ version: 7.20.5
+ resolution: "@babel/helper-wrap-function@npm:7.20.5"
+ dependencies:
+ "@babel/helper-function-name": ^7.19.0
+ "@babel/template": ^7.18.10
+ "@babel/traverse": ^7.20.5
+ "@babel/types": ^7.20.5
+ checksum: 11a6fc28334368a193a9cb3ad16f29cd7603bab958433efc82ebe59fa6556c227faa24f07ce43983f7a85df826f71d441638442c4315e90a554fe0a70ca5005b
+ languageName: node
+ linkType: hard
+
+"@babel/helpers@npm:^7.12.5, @babel/helpers@npm:^7.20.5":
+ version: 7.20.6
+ resolution: "@babel/helpers@npm:7.20.6"
+ dependencies:
+ "@babel/template": ^7.18.10
+ "@babel/traverse": ^7.20.5
+ "@babel/types": ^7.20.5
+ checksum: f03ec6eb2bf8dc7cdfe2569ee421fd9ba6c7bac6c862d90b608ccdd80281ebe858bc56ca175fc92b3ac50f63126b66bbd5ec86f9f361729289a20054518f1ac5
+ languageName: node
+ linkType: hard
+
+"@babel/highlight@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/highlight@npm:7.18.6"
+ dependencies:
+ "@babel/helper-validator-identifier": ^7.18.6
+ chalk: ^2.0.0
+ js-tokens: ^4.0.0
+ checksum: 92d8ee61549de5ff5120e945e774728e5ccd57fd3b2ed6eace020ec744823d4a98e242be1453d21764a30a14769ecd62170fba28539b211799bbaf232bbb2789
+ languageName: node
+ linkType: hard
+
+"@babel/parser@npm:^7.12.7, @babel/parser@npm:^7.18.10, @babel/parser@npm:^7.18.8, @babel/parser@npm:^7.20.5":
+ version: 7.20.5
+ resolution: "@babel/parser@npm:7.20.5"
+ bin:
+ parser: ./bin/babel-parser.js
+ checksum: e8d514ce0aa74d56725bd102919a49fa367afef9cd8208cf52f670f54b061c4672f51b4b7980058ab1f5fe73615fe4dc90720ab47bbcebae07ad08d667eda318
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 845bd280c55a6a91d232cfa54eaf9708ec71e594676fe705794f494bb8b711d833b752b59d1a5c154695225880c23dbc9cab0e53af16fd57807976cd3ff41b8d
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.18.9"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.9
+ "@babel/helper-skip-transparent-expression-wrappers": ^7.18.9
+ "@babel/plugin-proposal-optional-chaining": ^7.18.9
+ peerDependencies:
+ "@babel/core": ^7.13.0
+ checksum: 93abb5cb179a13db171bfc2cdf79489598f43c50cc174f97a2b7bb1d44d24ade7109665a20cf4e317ad6c1c730f036f06478f7c7e789b4240be1abdb60d6452f
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-async-generator-functions@npm:^7.20.1":
+ version: 7.20.1
+ resolution: "@babel/plugin-proposal-async-generator-functions@npm:7.20.1"
+ dependencies:
+ "@babel/helper-environment-visitor": ^7.18.9
+ "@babel/helper-plugin-utils": ^7.19.0
+ "@babel/helper-remap-async-to-generator": ^7.18.9
+ "@babel/plugin-syntax-async-generators": ^7.8.4
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 518483a68c5618932109913eb7316ed5e656c575cbd9d22667bc0451e35a1be45f8eaeb8e2065834b36c8a93c4840f78cebf8f1d067b07c422f7be16d58eca60
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-class-properties@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-proposal-class-properties@npm:7.18.6"
+ dependencies:
+ "@babel/helper-create-class-features-plugin": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 49a78a2773ec0db56e915d9797e44fd079ab8a9b2e1716e0df07c92532f2c65d76aeda9543883916b8e0ff13606afeffa67c5b93d05b607bc87653ad18a91422
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-class-static-block@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-proposal-class-static-block@npm:7.18.6"
+ dependencies:
+ "@babel/helper-create-class-features-plugin": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.18.6
+ "@babel/plugin-syntax-class-static-block": ^7.14.5
+ peerDependencies:
+ "@babel/core": ^7.12.0
+ checksum: b8d7ae99ed5ad784f39e7820e3ac03841f91d6ed60ab4a98c61d6112253da36013e12807bae4ffed0ef3cb318e47debac112ed614e03b403fb8b075b09a828ee
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-dynamic-import@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-proposal-dynamic-import@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ "@babel/plugin-syntax-dynamic-import": ^7.8.3
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 96b1c8a8ad8171d39e9ab106be33bde37ae09b22fb2c449afee9a5edf3c537933d79d963dcdc2694d10677cb96da739cdf1b53454e6a5deab9801f28a818bb2f
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-export-namespace-from@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/plugin-proposal-export-namespace-from@npm:7.18.9"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.9
+ "@babel/plugin-syntax-export-namespace-from": ^7.8.3
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 84ff22bacc5d30918a849bfb7e0e90ae4c5b8d8b65f2ac881803d1cf9068dffbe53bd657b0e4bc4c20b4db301b1c85f1e74183cf29a0dd31e964bd4e97c363ef
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-json-strings@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-proposal-json-strings@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ "@babel/plugin-syntax-json-strings": ^7.8.3
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 25ba0e6b9d6115174f51f7c6787e96214c90dd4026e266976b248a2ed417fe50fddae72843ffb3cbe324014a18632ce5648dfac77f089da858022b49fd608cb3
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-logical-assignment-operators@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/plugin-proposal-logical-assignment-operators@npm:7.18.9"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.9
+ "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: dd87fa4a48c6408c5e85dbd6405a65cc8fe909e3090030df46df90df64cdf3e74007381a58ed87608778ee597eff7395d215274009bb3f5d8964b2db5557754f
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-nullish-coalescing-operator@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-proposal-nullish-coalescing-operator@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 949c9ddcdecdaec766ee610ef98f965f928ccc0361dd87cf9f88cf4896a6ccd62fce063d4494778e50da99dea63d270a1be574a62d6ab81cbe9d85884bf55a7d
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-numeric-separator@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-proposal-numeric-separator@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ "@babel/plugin-syntax-numeric-separator": ^7.10.4
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: f370ea584c55bf4040e1f78c80b4eeb1ce2e6aaa74f87d1a48266493c33931d0b6222d8cee3a082383d6bb648ab8d6b7147a06f974d3296ef3bc39c7851683ec
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-object-rest-spread@npm:7.12.1":
+ version: 7.12.1
+ resolution: "@babel/plugin-proposal-object-rest-spread@npm:7.12.1"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.10.4
+ "@babel/plugin-syntax-object-rest-spread": ^7.8.0
+ "@babel/plugin-transform-parameters": ^7.12.1
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 221a41630c9a7162bf0416c71695b3f7f38482078a1d0d3af7abdc4f07ea1c9feed890399158d56c1d0278c971fe6f565ce822e9351e4481f7d98e9ff735dced
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-object-rest-spread@npm:^7.20.2":
+ version: 7.20.2
+ resolution: "@babel/plugin-proposal-object-rest-spread@npm:7.20.2"
+ dependencies:
+ "@babel/compat-data": ^7.20.1
+ "@babel/helper-compilation-targets": ^7.20.0
+ "@babel/helper-plugin-utils": ^7.20.2
+ "@babel/plugin-syntax-object-rest-spread": ^7.8.3
+ "@babel/plugin-transform-parameters": ^7.20.1
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 9764d1a4735fcd384fdb9b6c6ccb20d1bea2f88f648640d26ce5d9cd5880ce1e389d2f852d7bea7e86ff343726225dc16e1deb92c7b3dc5c5721ed905a602318
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-optional-catch-binding@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-proposal-optional-catch-binding@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ "@babel/plugin-syntax-optional-catch-binding": ^7.8.3
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 7b5b39fb5d8d6d14faad6cb68ece5eeb2fd550fb66b5af7d7582402f974f5bc3684641f7c192a5a57e0f59acfae4aada6786be1eba030881ddc590666eff4d1e
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-optional-chaining@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/plugin-proposal-optional-chaining@npm:7.18.9"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.9
+ "@babel/helper-skip-transparent-expression-wrappers": ^7.18.9
+ "@babel/plugin-syntax-optional-chaining": ^7.8.3
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: f2db40e26172f07c50b635cb61e1f36165de3ba868fcf608d967642f0d044b7c6beb0e7ecf17cbd421144b99e1eae7ad6031ded92925343bb0ed1d08707b514f
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-private-methods@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-proposal-private-methods@npm:7.18.6"
+ dependencies:
+ "@babel/helper-create-class-features-plugin": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 22d8502ee96bca99ad2c8393e8493e2b8d4507576dd054490fd8201a36824373440106f5b098b6d821b026c7e72b0424ff4aeca69ed5f42e48f029d3a156d5ad
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-private-property-in-object@npm:^7.18.6":
+ version: 7.20.5
+ resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.20.5"
+ dependencies:
+ "@babel/helper-annotate-as-pure": ^7.18.6
+ "@babel/helper-create-class-features-plugin": ^7.20.5
+ "@babel/helper-plugin-utils": ^7.20.2
+ "@babel/plugin-syntax-private-property-in-object": ^7.14.5
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 513b5e0e2c1b2846be5336cf680e932ae17924ef885aa1429e1a4f7924724bdd99b15f28d67187d0a006d5f18a0c4b61d96c3ecb4902fed3c8fe2f0abfc9753a
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-unicode-property-regex@npm:^7.18.6, @babel/plugin-proposal-unicode-property-regex@npm:^7.4.4":
+ version: 7.18.6
+ resolution: "@babel/plugin-proposal-unicode-property-regex@npm:7.18.6"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: a8575ecb7ff24bf6c6e94808d5c84bb5a0c6dd7892b54f09f4646711ba0ee1e1668032b3c43e3e1dfec2c5716c302e851ac756c1645e15882d73df6ad21ae951
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-async-generators@npm:^7.8.4":
+ version: 7.8.4
+ resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.8.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 7ed1c1d9b9e5b64ef028ea5e755c0be2d4e5e4e3d6cf7df757b9a8c4cfa4193d268176d0f1f7fbecdda6fe722885c7fda681f480f3741d8a2d26854736f05367
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-class-properties@npm:^7.12.13":
+ version: 7.12.13
+ resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.12.13
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 24f34b196d6342f28d4bad303612d7ff566ab0a013ce89e775d98d6f832969462e7235f3e7eaf17678a533d4be0ba45d3ae34ab4e5a9dcbda5d98d49e5efa2fc
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-class-static-block@npm:^7.14.5":
+ version: 7.14.5
+ resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.14.5
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 3e80814b5b6d4fe17826093918680a351c2d34398a914ce6e55d8083d72a9bdde4fbaf6a2dcea0e23a03de26dc2917ae3efd603d27099e2b98380345703bf948
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-dynamic-import@npm:^7.8.3":
+ version: 7.8.3
+ resolution: "@babel/plugin-syntax-dynamic-import@npm:7.8.3"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.8.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: ce307af83cf433d4ec42932329fad25fa73138ab39c7436882ea28742e1c0066626d224e0ad2988724c82644e41601cef607b36194f695cb78a1fcdc959637bd
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-export-namespace-from@npm:^7.8.3":
+ version: 7.8.3
+ resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.8.3
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 85740478be5b0de185228e7814451d74ab8ce0a26fcca7613955262a26e99e8e15e9da58f60c754b84515d4c679b590dbd3f2148f0f58025f4ae706f1c5a5d4a
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-import-assertions@npm:^7.20.0":
+ version: 7.20.0
+ resolution: "@babel/plugin-syntax-import-assertions@npm:7.20.0"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.19.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 6a86220e0aae40164cd3ffaf80e7c076a1be02a8f3480455dddbae05fda8140f429290027604df7a11b3f3f124866e8a6d69dbfa1dda61ee7377b920ad144d5b
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-json-strings@npm:^7.8.3":
+ version: 7.8.3
+ resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.8.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: bf5aea1f3188c9a507e16efe030efb996853ca3cadd6512c51db7233cc58f3ac89ff8c6bdfb01d30843b161cfe7d321e1bf28da82f7ab8d7e6bc5464666f354a
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-jsx@npm:7.12.1":
+ version: 7.12.1
+ resolution: "@babel/plugin-syntax-jsx@npm:7.12.1"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.10.4
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: d4b9b589c484b2e0856799770f060dff34c67b24d7f4526f66309a0e0e9cf388a5c1f2c0da329d1973cc87d1b2cede8f3dc8facfac59e785d6393a003bcdd0f9
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-jsx@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-syntax-jsx@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 6d37ea972970195f1ffe1a54745ce2ae456e0ac6145fae9aa1480f297248b262ea6ebb93010eddb86ebfacb94f57c05a1fc5d232b9a67325b09060299d515c67
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4":
+ version: 7.10.4
+ resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.10.4
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: aff33577037e34e515911255cdbb1fd39efee33658aa00b8a5fd3a4b903585112d037cce1cc9e4632f0487dc554486106b79ccd5ea63a2e00df4363f6d4ff886
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3":
+ version: 7.8.3
+ resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.8.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 87aca4918916020d1fedba54c0e232de408df2644a425d153be368313fdde40d96088feed6c4e5ab72aac89be5d07fef2ddf329a15109c5eb65df006bf2580d1
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-numeric-separator@npm:^7.10.4":
+ version: 7.10.4
+ resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.10.4
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 01ec5547bd0497f76cc903ff4d6b02abc8c05f301c88d2622b6d834e33a5651aa7c7a3d80d8d57656a4588f7276eba357f6b7e006482f5b564b7a6488de493a1
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-object-rest-spread@npm:7.8.3, @babel/plugin-syntax-object-rest-spread@npm:^7.8.0, @babel/plugin-syntax-object-rest-spread@npm:^7.8.3":
+ version: 7.8.3
+ resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.8.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: fddcf581a57f77e80eb6b981b10658421bc321ba5f0a5b754118c6a92a5448f12a0c336f77b8abf734841e102e5126d69110a306eadb03ca3e1547cab31f5cbf
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3":
+ version: 7.8.3
+ resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.8.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 910d90e72bc90ea1ce698e89c1027fed8845212d5ab588e35ef91f13b93143845f94e2539d831dc8d8ededc14ec02f04f7bd6a8179edd43a326c784e7ed7f0b9
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-optional-chaining@npm:^7.8.3":
+ version: 7.8.3
+ resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.8.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: eef94d53a1453361553c1f98b68d17782861a04a392840341bc91780838dd4e695209c783631cf0de14c635758beafb6a3a65399846ffa4386bff90639347f30
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5":
+ version: 7.14.5
+ resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.14.5
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: b317174783e6e96029b743ccff2a67d63d38756876e7e5d0ba53a322e38d9ca452c13354a57de1ad476b4c066dbae699e0ca157441da611117a47af88985ecda
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-top-level-await@npm:^7.14.5":
+ version: 7.14.5
+ resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.14.5
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: bbd1a56b095be7820029b209677b194db9b1d26691fe999856462e66b25b281f031f3dfd91b1619e9dcf95bebe336211833b854d0fb8780d618e35667c2d0d7e
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-typescript@npm:^7.20.0":
+ version: 7.20.0
+ resolution: "@babel/plugin-syntax-typescript@npm:7.20.0"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.19.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 6189c0b5c32ba3c9a80a42338bd50719d783b20ef29b853d4f03929e971913d3cefd80184e924ae98ad6db09080be8fe6f1ffde9a6db8972523234f0274d36f7
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-arrow-functions@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-arrow-functions@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 900f5c695755062b91eec74da6f9092f40b8fada099058b92576f1e23c55e9813ec437051893a9b3c05cefe39e8ac06303d4a91b384e1c03dd8dc1581ea11602
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-async-to-generator@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-async-to-generator@npm:7.18.6"
+ dependencies:
+ "@babel/helper-module-imports": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.18.6
+ "@babel/helper-remap-async-to-generator": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: c2cca47468cf1aeefdc7ec35d670e195c86cee4de28a1970648c46a88ce6bd1806ef0bab27251b9e7fb791bb28a64dcd543770efd899f28ee5f7854e64e873d3
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-block-scoped-functions@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 0a0df61f94601e3666bf39f2cc26f5f7b22a94450fb93081edbed967bd752ce3f81d1227fefd3799f5ee2722171b5e28db61379234d1bb85b6ec689589f99d7e
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-block-scoping@npm:^7.20.2":
+ version: 7.20.5
+ resolution: "@babel/plugin-transform-block-scoping@npm:7.20.5"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.20.2
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 03606bc6710c15cd4e4d1163e1cbab08799f852a5dd55a1f7e115032e9406ac9430ddc0cb6d09a51a4095446985640411f60683c6fcea9bc1a7b202462022e1c
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-classes@npm:^7.20.2":
+ version: 7.20.2
+ resolution: "@babel/plugin-transform-classes@npm:7.20.2"
+ dependencies:
+ "@babel/helper-annotate-as-pure": ^7.18.6
+ "@babel/helper-compilation-targets": ^7.20.0
+ "@babel/helper-environment-visitor": ^7.18.9
+ "@babel/helper-function-name": ^7.19.0
+ "@babel/helper-optimise-call-expression": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.20.2
+ "@babel/helper-replace-supers": ^7.19.1
+ "@babel/helper-split-export-declaration": ^7.18.6
+ globals: ^11.1.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 57f3467a8eb7853cdb61cda963cfb6c6568ad276d77c9de2ff5a2194650010217aa318ef3733975537c6fb906b73a019afb6ea650b01852e7d2e1fab4034361b
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-computed-properties@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/plugin-transform-computed-properties@npm:7.18.9"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.9
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: a6bfbea207827d77592628973c0e8cc3319db636506bdc6e81e21582de2e767890e6975b382d0511e9ec3773b9f43691185df90832883bbf9251f688d27fbc1d
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-destructuring@npm:^7.20.2":
+ version: 7.20.2
+ resolution: "@babel/plugin-transform-destructuring@npm:7.20.2"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.20.2
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 09033e09b28ca1b0d46a8d82f5a677b1d718a739b3c199886908c3ef1af23369317d0c429b21507d480ee82721c15892a9893be18e50ad6fc219e69312f4b097
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-dotall-regex@npm:^7.18.6, @babel/plugin-transform-dotall-regex@npm:^7.4.4":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-dotall-regex@npm:7.18.6"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: cbe5d7063eb8f8cca24cd4827bc97f5641166509e58781a5f8aa47fb3d2d786ce4506a30fca2e01f61f18792783a5cb5d96bf5434c3dd1ad0de8c9cc625a53da
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-duplicate-keys@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/plugin-transform-duplicate-keys@npm:7.18.9"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.9
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 220bf4a9fec5c4d4a7b1de38810350260e8ea08481bf78332a464a21256a95f0df8cd56025f346238f09b04f8e86d4158fafc9f4af57abaef31637e3b58bd4fe
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-exponentiation-operator@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.18.6"
+ dependencies:
+ "@babel/helper-builder-binary-assignment-operator-visitor": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 7f70222f6829c82a36005508d34ddbe6fd0974ae190683a8670dd6ff08669aaf51fef2209d7403f9bd543cb2d12b18458016c99a6ed0332ccedb3ea127b01229
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-for-of@npm:^7.18.8":
+ version: 7.18.8
+ resolution: "@babel/plugin-transform-for-of@npm:7.18.8"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: ca64c623cf0c7a80ab6f07ebd3e6e4ade95e2ae806696f70b43eafe6394fa8ce21f2b1ffdd15df2067f7363d2ecfe26472a97c6c774403d2163fa05f50c98f17
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-function-name@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/plugin-transform-function-name@npm:7.18.9"
+ dependencies:
+ "@babel/helper-compilation-targets": ^7.18.9
+ "@babel/helper-function-name": ^7.18.9
+ "@babel/helper-plugin-utils": ^7.18.9
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 62dd9c6cdc9714704efe15545e782ee52d74dc73916bf954b4d3bee088fb0ec9e3c8f52e751252433656c09f744b27b757fc06ed99bcde28e8a21600a1d8e597
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-literals@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/plugin-transform-literals@npm:7.18.9"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.9
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 3458dd2f1a47ac51d9d607aa18f3d321cbfa8560a985199185bed5a906bb0c61ba85575d386460bac9aed43fdd98940041fae5a67dff286f6f967707cff489f8
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-member-expression-literals@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-member-expression-literals@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 35a3d04f6693bc6b298c05453d85ee6e41cc806538acb6928427e0e97ae06059f97d2f07d21495fcf5f70d3c13a242e2ecbd09d5c1fcb1b1a73ff528dcb0b695
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-modules-amd@npm:^7.19.6":
+ version: 7.19.6
+ resolution: "@babel/plugin-transform-modules-amd@npm:7.19.6"
+ dependencies:
+ "@babel/helper-module-transforms": ^7.19.6
+ "@babel/helper-plugin-utils": ^7.19.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 4236aad970025bc10c772c1589b1e2eab8b7681933bb5ffa6e395d4c1a52532b28c47c553e3011b4272ea81e5ab39fe969eb5349584e8390e59771055c467d42
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-modules-commonjs@npm:^7.19.6":
+ version: 7.19.6
+ resolution: "@babel/plugin-transform-modules-commonjs@npm:7.19.6"
+ dependencies:
+ "@babel/helper-module-transforms": ^7.19.6
+ "@babel/helper-plugin-utils": ^7.19.0
+ "@babel/helper-simple-access": ^7.19.4
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 85d46945ab5ba3fff89e962d560a5d40253f228b9659a697683db3de07c0236e8cd60e5eb41958007359951a42bc268bf32350fcdb5b4a86f58dff1e032c096e
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-modules-systemjs@npm:^7.19.6":
+ version: 7.19.6
+ resolution: "@babel/plugin-transform-modules-systemjs@npm:7.19.6"
+ dependencies:
+ "@babel/helper-hoist-variables": ^7.18.6
+ "@babel/helper-module-transforms": ^7.19.6
+ "@babel/helper-plugin-utils": ^7.19.0
+ "@babel/helper-validator-identifier": ^7.19.1
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 8526431cc81ea3eb232ad50862d0ed1cbb422b5251d14a8d6610d0ca0617f6e75f35179e98eb1235d0cccb980120350b9f112594e5646dd45378d41eaaf87342
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-modules-umd@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-modules-umd@npm:7.18.6"
+ dependencies:
+ "@babel/helper-module-transforms": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: c3b6796c6f4579f1ba5ab0cdcc73910c1e9c8e1e773c507c8bb4da33072b3ae5df73c6d68f9126dab6e99c24ea8571e1563f8710d7c421fac1cde1e434c20153
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.19.1":
+ version: 7.20.5
+ resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.20.5"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": ^7.20.5
+ "@babel/helper-plugin-utils": ^7.20.2
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 528c95fb1087e212f17e1c6456df041b28a83c772b9c93d2e407c9d03b72182b0d9d126770c1d6e0b23aab052599ceaf25ed6a2c0627f4249be34a83f6fae853
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-new-target@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-new-target@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: bd780e14f46af55d0ae8503b3cb81ca86dcc73ed782f177e74f498fff934754f9e9911df1f8f3bd123777eed7c1c1af4d66abab87c8daae5403e7719a6b845d1
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-object-super@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-object-super@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ "@babel/helper-replace-supers": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 0fcb04e15deea96ae047c21cb403607d49f06b23b4589055993365ebd7a7d7541334f06bf9642e90075e66efce6ebaf1eb0ef066fbbab802d21d714f1aac3aef
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-parameters@npm:^7.12.1, @babel/plugin-transform-parameters@npm:^7.20.1":
+ version: 7.20.5
+ resolution: "@babel/plugin-transform-parameters@npm:7.20.5"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.20.2
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: fa588b0d8551e3e0cfde5fcb9d63a7acd38da199bee1851dd7e2abb34b3d754684defb1209a5669ecf0076d3d17ddc375b3f107da770b550a30402e4b9d7aa2f
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-property-literals@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-property-literals@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 1c16e64de554703f4b547541de2edda6c01346dd3031d4d29e881aa7733785cd26d53611a4ccf5353f4d3e69097bb0111c0a93ace9e683edd94fea28c4484144
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-react-constant-elements@npm:^7.18.12":
+ version: 7.20.2
+ resolution: "@babel/plugin-transform-react-constant-elements@npm:7.20.2"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.20.2
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 7b041b726e7c14b8c26a0dd240defac5f93a1f449371c6bdc5e6b46d581211300cc1a79da4140bdf20347f49e175dcb4f469812399206864024d1fdc81171193
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-react-display-name@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-react-display-name@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 51c087ab9e41ef71a29335587da28417536c6f816c292e092ffc0e0985d2f032656801d4dd502213ce32481f4ba6c69402993ffa67f0818a07606ff811e4be49
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-react-jsx-development@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-react-jsx-development@npm:7.18.6"
+ dependencies:
+ "@babel/plugin-transform-react-jsx": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: ec9fa65db66f938b75c45e99584367779ac3e0af8afc589187262e1337c7c4205ea312877813ae4df9fb93d766627b8968d74ac2ba702e4883b1dbbe4953ecee
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-react-jsx@npm:^7.18.6":
+ version: 7.19.0
+ resolution: "@babel/plugin-transform-react-jsx@npm:7.19.0"
+ dependencies:
+ "@babel/helper-annotate-as-pure": ^7.18.6
+ "@babel/helper-module-imports": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.19.0
+ "@babel/plugin-syntax-jsx": ^7.18.6
+ "@babel/types": ^7.19.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: d7d6f0b8f24b1f6b7cf8062c4e91c59af82489a993e51859bd49c2d62a2d2b77fd40b02a9a1d0e6d874cf4ce56a05fa3564b964587d00c94ebc62593524052ec
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-react-pure-annotations@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.18.6"
+ dependencies:
+ "@babel/helper-annotate-as-pure": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 97c4873d409088f437f9084d084615948198dd87fc6723ada0e7e29c5a03623c2f3e03df3f52e7e7d4d23be32a08ea00818bff302812e48713c706713bd06219
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-regenerator@npm:^7.18.6":
+ version: 7.20.5
+ resolution: "@babel/plugin-transform-regenerator@npm:7.20.5"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.20.2
+ regenerator-transform: ^0.15.1
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 13164861e71fb23d84c6270ef5330b03c54d5d661c2c7468f28e21c4f8598558ca0c8c3cb1d996219352946e849d270a61372bc93c8fbe9676e78e3ffd0dea07
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-reserved-words@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-reserved-words@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 0738cdc30abdae07c8ec4b233b30c31f68b3ff0eaa40eddb45ae607c066127f5fa99ddad3c0177d8e2832e3a7d3ad115775c62b431ebd6189c40a951b867a80c
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-runtime@npm:^7.18.6":
+ version: 7.19.6
+ resolution: "@babel/plugin-transform-runtime@npm:7.19.6"
+ dependencies:
+ "@babel/helper-module-imports": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.19.0
+ babel-plugin-polyfill-corejs2: ^0.3.3
+ babel-plugin-polyfill-corejs3: ^0.6.0
+ babel-plugin-polyfill-regenerator: ^0.4.1
+ semver: ^6.3.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: ef93efbcbb00dcf4da6dcc55bda698a2a57fca3fb05a6a13e932ecfdb7c1c5d2f0b5b245c1c4faca0318853937caba0d82442f58b7653249f64275d08052fbd8
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-shorthand-properties@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-shorthand-properties@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: b8e4e8acc2700d1e0d7d5dbfd4fdfb935651913de6be36e6afb7e739d8f9ca539a5150075a0f9b79c88be25ddf45abb912fe7abf525f0b80f5b9d9860de685d7
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-spread@npm:^7.19.0":
+ version: 7.19.0
+ resolution: "@babel/plugin-transform-spread@npm:7.19.0"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.19.0
+ "@babel/helper-skip-transparent-expression-wrappers": ^7.18.9
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: e73a4deb095999185e70b524d0ff4e35df50fcda58299e700a6149a15bbc1a9b369ef1cef384e15a54b3c3ce316cc0f054dbf249dcd0d1ca59f4281dd4df9718
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-sticky-regex@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-sticky-regex@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 68ea18884ae9723443ffa975eb736c8c0d751265859cd3955691253f7fee37d7a0f7efea96c8a062876af49a257a18ea0ed5fea0d95a7b3611ce40f7ee23aee3
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-template-literals@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/plugin-transform-template-literals@npm:7.18.9"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.9
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 3d2fcd79b7c345917f69b92a85bdc3ddd68ce2c87dc70c7d61a8373546ccd1f5cb8adc8540b49dfba08e1b82bb7b3bbe23a19efdb2b9c994db2db42906ca9fb2
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-typeof-symbol@npm:^7.18.9":
+ version: 7.18.9
+ resolution: "@babel/plugin-transform-typeof-symbol@npm:7.18.9"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.9
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: e754e0d8b8a028c52e10c148088606e3f7a9942c57bd648fc0438e5b4868db73c386a5ed47ab6d6f0594aae29ee5ffc2ffc0f7ebee7fae560a066d6dea811cd4
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-typescript@npm:^7.18.6":
+ version: 7.20.2
+ resolution: "@babel/plugin-transform-typescript@npm:7.20.2"
+ dependencies:
+ "@babel/helper-create-class-features-plugin": ^7.20.2
+ "@babel/helper-plugin-utils": ^7.20.2
+ "@babel/plugin-syntax-typescript": ^7.20.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 14434eb77cb3c8c4187a055eabdd5ff8b3e90a37ac95ecc7c9007ea8fc5660e0652c445646a2a25836a02d91944e0dc1e8b58ef55b063a901e54a24fdb4168af
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-unicode-escapes@npm:^7.18.10":
+ version: 7.18.10
+ resolution: "@babel/plugin-transform-unicode-escapes@npm:7.18.10"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.9
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: f5baca55cb3c11bc08ec589f5f522d85c1ab509b4d11492437e45027d64ae0b22f0907bd1381e8d7f2a436384bb1f9ad89d19277314242c5c2671a0f91d0f9cd
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-unicode-regex@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/plugin-transform-unicode-regex@npm:7.18.6"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": ^7.18.6
+ "@babel/helper-plugin-utils": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: d9e18d57536a2d317fb0b7c04f8f55347f3cfacb75e636b4c6fa2080ab13a3542771b5120e726b598b815891fc606d1472ac02b749c69fd527b03847f22dc25e
+ languageName: node
+ linkType: hard
+
+"@babel/preset-env@npm:^7.18.6, @babel/preset-env@npm:^7.19.4":
+ version: 7.20.2
+ resolution: "@babel/preset-env@npm:7.20.2"
+ dependencies:
+ "@babel/compat-data": ^7.20.1
+ "@babel/helper-compilation-targets": ^7.20.0
+ "@babel/helper-plugin-utils": ^7.20.2
+ "@babel/helper-validator-option": ^7.18.6
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.18.6
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.18.9
+ "@babel/plugin-proposal-async-generator-functions": ^7.20.1
+ "@babel/plugin-proposal-class-properties": ^7.18.6
+ "@babel/plugin-proposal-class-static-block": ^7.18.6
+ "@babel/plugin-proposal-dynamic-import": ^7.18.6
+ "@babel/plugin-proposal-export-namespace-from": ^7.18.9
+ "@babel/plugin-proposal-json-strings": ^7.18.6
+ "@babel/plugin-proposal-logical-assignment-operators": ^7.18.9
+ "@babel/plugin-proposal-nullish-coalescing-operator": ^7.18.6
+ "@babel/plugin-proposal-numeric-separator": ^7.18.6
+ "@babel/plugin-proposal-object-rest-spread": ^7.20.2
+ "@babel/plugin-proposal-optional-catch-binding": ^7.18.6
+ "@babel/plugin-proposal-optional-chaining": ^7.18.9
+ "@babel/plugin-proposal-private-methods": ^7.18.6
+ "@babel/plugin-proposal-private-property-in-object": ^7.18.6
+ "@babel/plugin-proposal-unicode-property-regex": ^7.18.6
+ "@babel/plugin-syntax-async-generators": ^7.8.4
+ "@babel/plugin-syntax-class-properties": ^7.12.13
+ "@babel/plugin-syntax-class-static-block": ^7.14.5
+ "@babel/plugin-syntax-dynamic-import": ^7.8.3
+ "@babel/plugin-syntax-export-namespace-from": ^7.8.3
+ "@babel/plugin-syntax-import-assertions": ^7.20.0
+ "@babel/plugin-syntax-json-strings": ^7.8.3
+ "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4
+ "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3
+ "@babel/plugin-syntax-numeric-separator": ^7.10.4
+ "@babel/plugin-syntax-object-rest-spread": ^7.8.3
+ "@babel/plugin-syntax-optional-catch-binding": ^7.8.3
+ "@babel/plugin-syntax-optional-chaining": ^7.8.3
+ "@babel/plugin-syntax-private-property-in-object": ^7.14.5
+ "@babel/plugin-syntax-top-level-await": ^7.14.5
+ "@babel/plugin-transform-arrow-functions": ^7.18.6
+ "@babel/plugin-transform-async-to-generator": ^7.18.6
+ "@babel/plugin-transform-block-scoped-functions": ^7.18.6
+ "@babel/plugin-transform-block-scoping": ^7.20.2
+ "@babel/plugin-transform-classes": ^7.20.2
+ "@babel/plugin-transform-computed-properties": ^7.18.9
+ "@babel/plugin-transform-destructuring": ^7.20.2
+ "@babel/plugin-transform-dotall-regex": ^7.18.6
+ "@babel/plugin-transform-duplicate-keys": ^7.18.9
+ "@babel/plugin-transform-exponentiation-operator": ^7.18.6
+ "@babel/plugin-transform-for-of": ^7.18.8
+ "@babel/plugin-transform-function-name": ^7.18.9
+ "@babel/plugin-transform-literals": ^7.18.9
+ "@babel/plugin-transform-member-expression-literals": ^7.18.6
+ "@babel/plugin-transform-modules-amd": ^7.19.6
+ "@babel/plugin-transform-modules-commonjs": ^7.19.6
+ "@babel/plugin-transform-modules-systemjs": ^7.19.6
+ "@babel/plugin-transform-modules-umd": ^7.18.6
+ "@babel/plugin-transform-named-capturing-groups-regex": ^7.19.1
+ "@babel/plugin-transform-new-target": ^7.18.6
+ "@babel/plugin-transform-object-super": ^7.18.6
+ "@babel/plugin-transform-parameters": ^7.20.1
+ "@babel/plugin-transform-property-literals": ^7.18.6
+ "@babel/plugin-transform-regenerator": ^7.18.6
+ "@babel/plugin-transform-reserved-words": ^7.18.6
+ "@babel/plugin-transform-shorthand-properties": ^7.18.6
+ "@babel/plugin-transform-spread": ^7.19.0
+ "@babel/plugin-transform-sticky-regex": ^7.18.6
+ "@babel/plugin-transform-template-literals": ^7.18.9
+ "@babel/plugin-transform-typeof-symbol": ^7.18.9
+ "@babel/plugin-transform-unicode-escapes": ^7.18.10
+ "@babel/plugin-transform-unicode-regex": ^7.18.6
+ "@babel/preset-modules": ^0.1.5
+ "@babel/types": ^7.20.2
+ babel-plugin-polyfill-corejs2: ^0.3.3
+ babel-plugin-polyfill-corejs3: ^0.6.0
+ babel-plugin-polyfill-regenerator: ^0.4.1
+ core-js-compat: ^3.25.1
+ semver: ^6.3.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: ece2d7e9c7789db6116e962b8e1a55eb55c110c44c217f0c8f6ffea4ca234954e66557f7bd019b7affadf7fbb3a53ccc807e93fc935aacd48146234b73b6947e
+ languageName: node
+ linkType: hard
+
+"@babel/preset-modules@npm:^0.1.5":
+ version: 0.1.5
+ resolution: "@babel/preset-modules@npm:0.1.5"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.0.0
+ "@babel/plugin-proposal-unicode-property-regex": ^7.4.4
+ "@babel/plugin-transform-dotall-regex": ^7.4.4
+ "@babel/types": ^7.4.4
+ esutils: ^2.0.2
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 8430e0e9e9d520b53e22e8c4c6a5a080a12b63af6eabe559c2310b187bd62ae113f3da82ba33e9d1d0f3230930ca702843aae9dd226dec51f7d7114dc1f51c10
+ languageName: node
+ linkType: hard
+
+"@babel/preset-react@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/preset-react@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ "@babel/helper-validator-option": ^7.18.6
+ "@babel/plugin-transform-react-display-name": ^7.18.6
+ "@babel/plugin-transform-react-jsx": ^7.18.6
+ "@babel/plugin-transform-react-jsx-development": ^7.18.6
+ "@babel/plugin-transform-react-pure-annotations": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 540d9cf0a0cc0bb07e6879994e6fb7152f87dafbac880b56b65e2f528134c7ba33e0cd140b58700c77b2ebf4c81fa6468fed0ba391462d75efc7f8c1699bb4c3
+ languageName: node
+ linkType: hard
+
+"@babel/preset-typescript@npm:^7.18.6":
+ version: 7.18.6
+ resolution: "@babel/preset-typescript@npm:7.18.6"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.18.6
+ "@babel/helper-validator-option": ^7.18.6
+ "@babel/plugin-transform-typescript": ^7.18.6
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 7fe0da5103eb72d3cf39cf3e138a794c8cdd19c0b38e3e101507eef519c46a87a0d6d0e8bc9e28a13ea2364001ebe7430b9d75758aab4c3c3a8db9a487b9dc7c
+ languageName: node
+ linkType: hard
+
+"@babel/runtime-corejs3@npm:^7.18.6":
+ version: 7.20.6
+ resolution: "@babel/runtime-corejs3@npm:7.20.6"
+ dependencies:
+ core-js-pure: ^3.25.1
+ regenerator-runtime: ^0.13.11
+ checksum: d533d432216509426c4f9dad56db2fe453112b7d738433111944372fba4abd0b07bee3261f19a218530b435de46592121b2a6a57b98c0c7c3452d552ba009c3e
+ languageName: node
+ linkType: hard
+
+"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.10.3, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.8.4":
+ version: 7.20.6
+ resolution: "@babel/runtime@npm:7.20.6"
+ dependencies:
+ regenerator-runtime: ^0.13.11
+ checksum: 42a8504db21031b1859fbc0f52d698a3d2f5ada9519eb76c6f96a7e657d8d555732a18fe71ef428a67cc9fc81ca0d3562fb7afdc70549c5fec343190cbaa9b03
+ languageName: node
+ linkType: hard
+
+"@babel/template@npm:^7.12.7, @babel/template@npm:^7.18.10":
+ version: 7.18.10
+ resolution: "@babel/template@npm:7.18.10"
+ dependencies:
+ "@babel/code-frame": ^7.18.6
+ "@babel/parser": ^7.18.10
+ "@babel/types": ^7.18.10
+ checksum: 93a6aa094af5f355a72bd55f67fa1828a046c70e46f01b1606e6118fa1802b6df535ca06be83cc5a5e834022be95c7b714f0a268b5f20af984465a71e28f1473
+ languageName: node
+ linkType: hard
+
+"@babel/traverse@npm:^7.12.9, @babel/traverse@npm:^7.18.8, @babel/traverse@npm:^7.19.1, @babel/traverse@npm:^7.20.1, @babel/traverse@npm:^7.20.5":
+ version: 7.20.5
+ resolution: "@babel/traverse@npm:7.20.5"
+ dependencies:
+ "@babel/code-frame": ^7.18.6
+ "@babel/generator": ^7.20.5
+ "@babel/helper-environment-visitor": ^7.18.9
+ "@babel/helper-function-name": ^7.19.0
+ "@babel/helper-hoist-variables": ^7.18.6
+ "@babel/helper-split-export-declaration": ^7.18.6
+ "@babel/parser": ^7.20.5
+ "@babel/types": ^7.20.5
+ debug: ^4.1.0
+ globals: ^11.1.0
+ checksum: c7fed468614aab1cf762dda5df26e2cfcd2b1b448c9d3321ac44786c4ee773fb0e10357e6593c3c6a648ae2e0be6d90462d855998dc10e3abae84de99291e008
+ languageName: node
+ linkType: hard
+
+"@babel/types@npm:^7.12.7, @babel/types@npm:^7.18.10, @babel/types@npm:^7.18.6, @babel/types@npm:^7.18.9, @babel/types@npm:^7.19.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.2, @babel/types@npm:^7.20.5, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3":
+ version: 7.20.5
+ resolution: "@babel/types@npm:7.20.5"
+ dependencies:
+ "@babel/helper-string-parser": ^7.19.4
+ "@babel/helper-validator-identifier": ^7.19.1
+ to-fast-properties: ^2.0.0
+ checksum: 773f0a1ad9f6ca5c5beaf751d1d8d81b9130de87689d1321fc911d73c3b1167326d66f0ae086a27fb5bfc8b4ee3ffebf1339be50d3b4d8015719692468c31f2d
+ languageName: node
+ linkType: hard
+
+"@colors/colors@npm:1.5.0":
+ version: 1.5.0
+ resolution: "@colors/colors@npm:1.5.0"
+ checksum: d64d5260bed1d5012ae3fc617d38d1afc0329fec05342f4e6b838f46998855ba56e0a73833f4a80fa8378c84810da254f76a8a19c39d038260dc06dc4e007425
+ languageName: node
+ linkType: hard
+
+"@docsearch/css@npm:3.3.0":
+ version: 3.3.0
+ resolution: "@docsearch/css@npm:3.3.0"
+ checksum: 1cbf381fe0b454f933e736d04fe8a2d9f86c375022ef738b44d67a0b4c187b0d8fcb945a1ba5a404059e50e3968d9fe769de22779d071f6189f07c161239892c
+ languageName: node
+ linkType: hard
+
+"@docsearch/react@npm:^3.1.1":
+ version: 3.3.0
+ resolution: "@docsearch/react@npm:3.3.0"
+ dependencies:
+ "@algolia/autocomplete-core": 1.7.2
+ "@algolia/autocomplete-preset-algolia": 1.7.2
+ "@docsearch/css": 3.3.0
+ algoliasearch: ^4.0.0
+ peerDependencies:
+ "@types/react": ">= 16.8.0 < 19.0.0"
+ react: ">= 16.8.0 < 19.0.0"
+ react-dom: ">= 16.8.0 < 19.0.0"
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ checksum: 2bc4aa649fad3ff74e61537e674e658903c01509b2835827943f23895b40b7697476399179d43bc721f7e72044c797d4d793fcdaa394ff4f9fca1389a197a78c
+ languageName: node
+ linkType: hard
+
+"@docusaurus/core@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/core@npm:2.2.0"
+ dependencies:
+ "@babel/core": ^7.18.6
+ "@babel/generator": ^7.18.7
+ "@babel/plugin-syntax-dynamic-import": ^7.8.3
+ "@babel/plugin-transform-runtime": ^7.18.6
+ "@babel/preset-env": ^7.18.6
+ "@babel/preset-react": ^7.18.6
+ "@babel/preset-typescript": ^7.18.6
+ "@babel/runtime": ^7.18.6
+ "@babel/runtime-corejs3": ^7.18.6
+ "@babel/traverse": ^7.18.8
+ "@docusaurus/cssnano-preset": 2.2.0
+ "@docusaurus/logger": 2.2.0
+ "@docusaurus/mdx-loader": 2.2.0
+ "@docusaurus/react-loadable": 5.5.2
+ "@docusaurus/utils": 2.2.0
+ "@docusaurus/utils-common": 2.2.0
+ "@docusaurus/utils-validation": 2.2.0
+ "@slorber/static-site-generator-webpack-plugin": ^4.0.7
+ "@svgr/webpack": ^6.2.1
+ autoprefixer: ^10.4.7
+ babel-loader: ^8.2.5
+ babel-plugin-dynamic-import-node: ^2.3.3
+ boxen: ^6.2.1
+ chalk: ^4.1.2
+ chokidar: ^3.5.3
+ clean-css: ^5.3.0
+ cli-table3: ^0.6.2
+ combine-promises: ^1.1.0
+ commander: ^5.1.0
+ copy-webpack-plugin: ^11.0.0
+ core-js: ^3.23.3
+ css-loader: ^6.7.1
+ css-minimizer-webpack-plugin: ^4.0.0
+ cssnano: ^5.1.12
+ del: ^6.1.1
+ detect-port: ^1.3.0
+ escape-html: ^1.0.3
+ eta: ^1.12.3
+ file-loader: ^6.2.0
+ fs-extra: ^10.1.0
+ html-minifier-terser: ^6.1.0
+ html-tags: ^3.2.0
+ html-webpack-plugin: ^5.5.0
+ import-fresh: ^3.3.0
+ leven: ^3.1.0
+ lodash: ^4.17.21
+ mini-css-extract-plugin: ^2.6.1
+ postcss: ^8.4.14
+ postcss-loader: ^7.0.0
+ prompts: ^2.4.2
+ react-dev-utils: ^12.0.1
+ react-helmet-async: ^1.3.0
+ react-loadable: "npm:@docusaurus/react-loadable@5.5.2"
+ react-loadable-ssr-addon-v5-slorber: ^1.0.1
+ react-router: ^5.3.3
+ react-router-config: ^5.1.1
+ react-router-dom: ^5.3.3
+ rtl-detect: ^1.0.4
+ semver: ^7.3.7
+ serve-handler: ^6.1.3
+ shelljs: ^0.8.5
+ terser-webpack-plugin: ^5.3.3
+ tslib: ^2.4.0
+ update-notifier: ^5.1.0
+ url-loader: ^4.1.1
+ wait-on: ^6.0.1
+ webpack: ^5.73.0
+ webpack-bundle-analyzer: ^4.5.0
+ webpack-dev-server: ^4.9.3
+ webpack-merge: ^5.8.0
+ webpackbar: ^5.0.2
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ bin:
+ docusaurus: bin/docusaurus.mjs
+ checksum: ff47e6cf85b0f7dc0a9e5b9b0d26e33a6f7385f067566ff4f9b026d044839e4dfb4c3bc9476cfab7a7e95a0065478a534cda403dac3bb7bac9987406f1978a11
+ languageName: node
+ linkType: hard
+
+"@docusaurus/cssnano-preset@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/cssnano-preset@npm:2.2.0"
+ dependencies:
+ cssnano-preset-advanced: ^5.3.8
+ postcss: ^8.4.14
+ postcss-sort-media-queries: ^4.2.1
+ tslib: ^2.4.0
+ checksum: eff9707414867bf844ef5d84bde1c843593b9b7f542dd1a0a7acc88798b0c5ddb721124229912c234bd88b93cb18d8d69c6115cbf706c2a790497f7d9dd23757
+ languageName: node
+ linkType: hard
+
+"@docusaurus/logger@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/logger@npm:2.2.0"
+ dependencies:
+ chalk: ^4.1.2
+ tslib: ^2.4.0
+ checksum: b3ce6e18721a34793a892221485c941d5f7112ae96d569f7918d12c1f50bde9c99bc4195f4d225e874b2bd5800a35413bfeaf78b63c6fbae5f3015d44d118eee
+ languageName: node
+ linkType: hard
+
+"@docusaurus/mdx-loader@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/mdx-loader@npm:2.2.0"
+ dependencies:
+ "@babel/parser": ^7.18.8
+ "@babel/traverse": ^7.18.8
+ "@docusaurus/logger": 2.2.0
+ "@docusaurus/utils": 2.2.0
+ "@mdx-js/mdx": ^1.6.22
+ escape-html: ^1.0.3
+ file-loader: ^6.2.0
+ fs-extra: ^10.1.0
+ image-size: ^1.0.1
+ mdast-util-to-string: ^2.0.0
+ remark-emoji: ^2.2.0
+ stringify-object: ^3.3.0
+ tslib: ^2.4.0
+ unified: ^9.2.2
+ unist-util-visit: ^2.0.3
+ url-loader: ^4.1.1
+ webpack: ^5.73.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: fee586498f43c46581062e681424c4637e75d505d813d8bf25f5315c912560f6600cd925bc5b07a93d5d5966741439578e7e72f30030b4c58a5cfdf72e0d8928
+ languageName: node
+ linkType: hard
+
+"@docusaurus/module-type-aliases@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/module-type-aliases@npm:2.2.0"
+ dependencies:
+ "@docusaurus/react-loadable": 5.5.2
+ "@docusaurus/types": 2.2.0
+ "@types/history": ^4.7.11
+ "@types/react": "*"
+ "@types/react-router-config": "*"
+ "@types/react-router-dom": "*"
+ react-helmet-async: "*"
+ react-loadable: "npm:@docusaurus/react-loadable@5.5.2"
+ peerDependencies:
+ react: "*"
+ react-dom: "*"
+ checksum: ebcb9dff2f88b5962cd34aaa78b1a48531da4776229ef507665e3f053cccb185aadcc16c3703f21031e14ccb6c8312662a6eec1a2a06bc0a423221ad200e1e9e
+ languageName: node
+ linkType: hard
+
+"@docusaurus/plugin-content-blog@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/plugin-content-blog@npm:2.2.0"
+ dependencies:
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/logger": 2.2.0
+ "@docusaurus/mdx-loader": 2.2.0
+ "@docusaurus/types": 2.2.0
+ "@docusaurus/utils": 2.2.0
+ "@docusaurus/utils-common": 2.2.0
+ "@docusaurus/utils-validation": 2.2.0
+ cheerio: ^1.0.0-rc.12
+ feed: ^4.2.2
+ fs-extra: ^10.1.0
+ lodash: ^4.17.21
+ reading-time: ^1.5.0
+ tslib: ^2.4.0
+ unist-util-visit: ^2.0.3
+ utility-types: ^3.10.0
+ webpack: ^5.73.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: 6d51e3b17b6fdeb4e04ddebe4d4ba8c7cc830bdc066c2b7898e4dee185e408f0d28ea873d18b5ee4406a568a9b05f70d17c986a9ed16b16b1450d34ca190fd06
+ languageName: node
+ linkType: hard
+
+"@docusaurus/plugin-content-docs@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/plugin-content-docs@npm:2.2.0"
+ dependencies:
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/logger": 2.2.0
+ "@docusaurus/mdx-loader": 2.2.0
+ "@docusaurus/module-type-aliases": 2.2.0
+ "@docusaurus/types": 2.2.0
+ "@docusaurus/utils": 2.2.0
+ "@docusaurus/utils-validation": 2.2.0
+ "@types/react-router-config": ^5.0.6
+ combine-promises: ^1.1.0
+ fs-extra: ^10.1.0
+ import-fresh: ^3.3.0
+ js-yaml: ^4.1.0
+ lodash: ^4.17.21
+ tslib: ^2.4.0
+ utility-types: ^3.10.0
+ webpack: ^5.73.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: 3a262b49dd6f9d59f4e10dd25185bb4280dbf77b62e28a1dd658d5db0861ae8c82dd025f24212f0d8fec0a46a37f6ef0f2cde25ac736d445247e8727177da660
+ languageName: node
+ linkType: hard
+
+"@docusaurus/plugin-content-pages@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/plugin-content-pages@npm:2.2.0"
+ dependencies:
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/mdx-loader": 2.2.0
+ "@docusaurus/types": 2.2.0
+ "@docusaurus/utils": 2.2.0
+ "@docusaurus/utils-validation": 2.2.0
+ fs-extra: ^10.1.0
+ tslib: ^2.4.0
+ webpack: ^5.73.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: 1e22fb8deb9b8f612ebe1ea6f8b1ce76acfc6eb8cbc0d5fc9b99b99d64e2f356d0fb136247e9f72cd84b2788eaf953a640d23ff7e2a5d650de6ec06468181a94
+ languageName: node
+ linkType: hard
+
+"@docusaurus/plugin-debug@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/plugin-debug@npm:2.2.0"
+ dependencies:
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/types": 2.2.0
+ "@docusaurus/utils": 2.2.0
+ fs-extra: ^10.1.0
+ react-json-view: ^1.21.3
+ tslib: ^2.4.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: edf2a416b790591c66ffa8ca1fd4ed15ab2d2dc15cd67c5253714502a6828739a7a47996c3664731c6b24da1da5862ddfef60defb84bd3b8273313267db0cb54
+ languageName: node
+ linkType: hard
+
+"@docusaurus/plugin-google-analytics@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/plugin-google-analytics@npm:2.2.0"
+ dependencies:
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/types": 2.2.0
+ "@docusaurus/utils-validation": 2.2.0
+ tslib: ^2.4.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: 44ad3a6c1b661516cb87553103565af64a6f145d823b16882d5c7d23b99e091b7c4ba8323c5f6fe756e70fbb0f9f31d56c74512dc17da6d3c16dfabd17d719ac
+ languageName: node
+ linkType: hard
+
+"@docusaurus/plugin-google-gtag@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/plugin-google-gtag@npm:2.2.0"
+ dependencies:
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/types": 2.2.0
+ "@docusaurus/utils-validation": 2.2.0
+ tslib: ^2.4.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: 4e7d6fcc3f30f1d54933fdeb59d3065989596e91940304965635867808d89c7b864a394f5fab2bcde98037539bf6840efc692e856fb7a4ae32ce8b5f8a4e191a
+ languageName: node
+ linkType: hard
+
+"@docusaurus/plugin-sitemap@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/plugin-sitemap@npm:2.2.0"
+ dependencies:
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/logger": 2.2.0
+ "@docusaurus/types": 2.2.0
+ "@docusaurus/utils": 2.2.0
+ "@docusaurus/utils-common": 2.2.0
+ "@docusaurus/utils-validation": 2.2.0
+ fs-extra: ^10.1.0
+ sitemap: ^7.1.1
+ tslib: ^2.4.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: 8ae78093d17a96fc2c6f3829d425731dae3af19b0eec29c61a6465342462a8c24da4c5a10f1a1b1813630d2408f2e11fa17af652b74b4e8fda975d4a00bf1389
+ languageName: node
+ linkType: hard
+
+"@docusaurus/preset-classic@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/preset-classic@npm:2.2.0"
+ dependencies:
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/plugin-content-blog": 2.2.0
+ "@docusaurus/plugin-content-docs": 2.2.0
+ "@docusaurus/plugin-content-pages": 2.2.0
+ "@docusaurus/plugin-debug": 2.2.0
+ "@docusaurus/plugin-google-analytics": 2.2.0
+ "@docusaurus/plugin-google-gtag": 2.2.0
+ "@docusaurus/plugin-sitemap": 2.2.0
+ "@docusaurus/theme-classic": 2.2.0
+ "@docusaurus/theme-common": 2.2.0
+ "@docusaurus/theme-search-algolia": 2.2.0
+ "@docusaurus/types": 2.2.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: 70214f17766097a2e9c4b21a343bf323f7ed3d2e23c6169577cd14333a074fa15aabff6532c1774ec17c54f50c1616dbd8625c41a115d2fe799b2b7fa830c2c9
+ languageName: node
+ linkType: hard
+
+"@docusaurus/react-loadable@npm:5.5.2, react-loadable@npm:@docusaurus/react-loadable@5.5.2":
+ version: 5.5.2
+ resolution: "@docusaurus/react-loadable@npm:5.5.2"
+ dependencies:
+ "@types/react": "*"
+ prop-types: ^15.6.2
+ peerDependencies:
+ react: "*"
+ checksum: 930fb9e2936412a12461f210acdc154a433283921ca43ac3fc3b84cb6c12eb738b3a3719373022bf68004efeb1a928dbe36c467d7a1f86454ed6241576d936e7
+ languageName: node
+ linkType: hard
+
+"@docusaurus/theme-classic@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/theme-classic@npm:2.2.0"
+ dependencies:
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/mdx-loader": 2.2.0
+ "@docusaurus/module-type-aliases": 2.2.0
+ "@docusaurus/plugin-content-blog": 2.2.0
+ "@docusaurus/plugin-content-docs": 2.2.0
+ "@docusaurus/plugin-content-pages": 2.2.0
+ "@docusaurus/theme-common": 2.2.0
+ "@docusaurus/theme-translations": 2.2.0
+ "@docusaurus/types": 2.2.0
+ "@docusaurus/utils": 2.2.0
+ "@docusaurus/utils-common": 2.2.0
+ "@docusaurus/utils-validation": 2.2.0
+ "@mdx-js/react": ^1.6.22
+ clsx: ^1.2.1
+ copy-text-to-clipboard: ^3.0.1
+ infima: 0.2.0-alpha.42
+ lodash: ^4.17.21
+ nprogress: ^0.2.0
+ postcss: ^8.4.14
+ prism-react-renderer: ^1.3.5
+ prismjs: ^1.28.0
+ react-router-dom: ^5.3.3
+ rtlcss: ^3.5.0
+ tslib: ^2.4.0
+ utility-types: ^3.10.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: ccfb0bef12178d0fbe3329a3238cd6bf7223ee03d890594676c06490eabfd59908bb1872c1a007f605db4edf402bc49cdf14aa7116550e95844d5135a92c2969
+ languageName: node
+ linkType: hard
+
+"@docusaurus/theme-common@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/theme-common@npm:2.2.0"
+ dependencies:
+ "@docusaurus/mdx-loader": 2.2.0
+ "@docusaurus/module-type-aliases": 2.2.0
+ "@docusaurus/plugin-content-blog": 2.2.0
+ "@docusaurus/plugin-content-docs": 2.2.0
+ "@docusaurus/plugin-content-pages": 2.2.0
+ "@docusaurus/utils": 2.2.0
+ "@types/history": ^4.7.11
+ "@types/react": "*"
+ "@types/react-router-config": "*"
+ clsx: ^1.2.1
+ parse-numeric-range: ^1.3.0
+ prism-react-renderer: ^1.3.5
+ tslib: ^2.4.0
+ utility-types: ^3.10.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: 23cbba8e7e24494c6d106ce3d0b90ef461580bfacef9f27dfbc4f0b33fcb349394faf2bedf0a44db8c455535e50e828e82270c8f159c3d8d60f0e0980170be4e
+ languageName: node
+ linkType: hard
+
+"@docusaurus/theme-search-algolia@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/theme-search-algolia@npm:2.2.0"
+ dependencies:
+ "@docsearch/react": ^3.1.1
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/logger": 2.2.0
+ "@docusaurus/plugin-content-docs": 2.2.0
+ "@docusaurus/theme-common": 2.2.0
+ "@docusaurus/theme-translations": 2.2.0
+ "@docusaurus/utils": 2.2.0
+ "@docusaurus/utils-validation": 2.2.0
+ algoliasearch: ^4.13.1
+ algoliasearch-helper: ^3.10.0
+ clsx: ^1.2.1
+ eta: ^1.12.3
+ fs-extra: ^10.1.0
+ lodash: ^4.17.21
+ tslib: ^2.4.0
+ utility-types: ^3.10.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: 42b6cb0322d6c772b7796ea6e9693d596554ebd087792ad71238cebedf3b632bfa8005138d521bce1ff118f49aea7d72e5dc97a03f236b4728a2dc7576870071
+ languageName: node
+ linkType: hard
+
+"@docusaurus/theme-translations@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/theme-translations@npm:2.2.0"
+ dependencies:
+ fs-extra: ^10.1.0
+ tslib: ^2.4.0
+ checksum: 7fe7d104fd094f2af2321986a86edef1eb8ab25415ea94ab1b242d08aec7627b3d5790001631621cd80c57c710714308aad5adfbf570cb74e0f01fda93b610be
+ languageName: node
+ linkType: hard
+
+"@docusaurus/types@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/types@npm:2.2.0"
+ dependencies:
+ "@types/history": ^4.7.11
+ "@types/react": "*"
+ commander: ^5.1.0
+ joi: ^17.6.0
+ react-helmet-async: ^1.3.0
+ utility-types: ^3.10.0
+ webpack: ^5.73.0
+ webpack-merge: ^5.8.0
+ peerDependencies:
+ react: ^16.8.4 || ^17.0.0
+ react-dom: ^16.8.4 || ^17.0.0
+ checksum: 5166ca49bb9333e4d733e4bf8d49d65e11ea6b39e4d8eecc24e1de24d61d2459c52dd8bd27362b66b03e41df96acf1a449145211b3bf0c5a59a987c77102e8f1
+ languageName: node
+ linkType: hard
+
+"@docusaurus/utils-common@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/utils-common@npm:2.2.0"
+ dependencies:
+ tslib: ^2.4.0
+ peerDependencies:
+ "@docusaurus/types": "*"
+ peerDependenciesMeta:
+ "@docusaurus/types":
+ optional: true
+ checksum: 05d23a2f82a1bc119e3ad6b37481c9bc984f62efd3a79046567216784b78fb20fe7452252d610bb4c063e4ded8a7ab7efa1dc9f9f228357c20b9f4729c7a0576
+ languageName: node
+ linkType: hard
+
+"@docusaurus/utils-validation@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/utils-validation@npm:2.2.0"
+ dependencies:
+ "@docusaurus/logger": 2.2.0
+ "@docusaurus/utils": 2.2.0
+ joi: ^17.6.0
+ js-yaml: ^4.1.0
+ tslib: ^2.4.0
+ checksum: a30e47cf84628950176cc02a121f31b200b46cdccf02e80d76f24b51b9d33fccee35c43047f507b8fb48deb38f863580ecbcdc1393718c6f3a14fcd40d5d1ab6
+ languageName: node
+ linkType: hard
+
+"@docusaurus/utils@npm:2.2.0":
+ version: 2.2.0
+ resolution: "@docusaurus/utils@npm:2.2.0"
+ dependencies:
+ "@docusaurus/logger": 2.2.0
+ "@svgr/webpack": ^6.2.1
+ file-loader: ^6.2.0
+ fs-extra: ^10.1.0
+ github-slugger: ^1.4.0
+ globby: ^11.1.0
+ gray-matter: ^4.0.3
+ js-yaml: ^4.1.0
+ lodash: ^4.17.21
+ micromatch: ^4.0.5
+ resolve-pathname: ^3.0.0
+ shelljs: ^0.8.5
+ tslib: ^2.4.0
+ url-loader: ^4.1.1
+ webpack: ^5.73.0
+ peerDependencies:
+ "@docusaurus/types": "*"
+ peerDependenciesMeta:
+ "@docusaurus/types":
+ optional: true
+ checksum: d027a6d2417e043ac463402aadca22f1101f942daaf02330d9bb4743dcbe3bd2fd46d27dedf316fcf2b6698713fede974ba59eb5d4bc92c8959e23bc25e7a03a
+ languageName: node
+ linkType: hard
+
+"@gar/promisify@npm:^1.1.3":
+ version: 1.1.3
+ resolution: "@gar/promisify@npm:1.1.3"
+ checksum: 4059f790e2d07bf3c3ff3e0fec0daa8144fe35c1f6e0111c9921bd32106adaa97a4ab096ad7dab1e28ee6a9060083c4d1a4ada42a7f5f3f7a96b8812e2b757c1
+ languageName: node
+ linkType: hard
+
+"@hapi/hoek@npm:^9.0.0":
+ version: 9.3.0
+ resolution: "@hapi/hoek@npm:9.3.0"
+ checksum: 4771c7a776242c3c022b168046af4e324d116a9d2e1d60631ee64f474c6e38d1bb07092d898bf95c7bc5d334c5582798a1456321b2e53ca817d4e7c88bc25b43
+ languageName: node
+ linkType: hard
+
+"@hapi/topo@npm:^5.0.0":
+ version: 5.1.0
+ resolution: "@hapi/topo@npm:5.1.0"
+ dependencies:
+ "@hapi/hoek": ^9.0.0
+ checksum: 604dfd5dde76d5c334bd03f9001fce69c7ce529883acf92da96f4fe7e51221bf5e5110e964caca287a6a616ba027c071748ab636ff178ad750547fba611d6014
+ languageName: node
+ linkType: hard
+
+"@jest/schemas@npm:^29.0.0":
+ version: 29.0.0
+ resolution: "@jest/schemas@npm:29.0.0"
+ dependencies:
+ "@sinclair/typebox": ^0.24.1
+ checksum: 41355c78f09eb1097e57a3c5d0ca11c9099e235e01ea5fa4e3953562a79a6a9296c1d300f1ba50ca75236048829e056b00685cd2f1ff8285e56fd2ce01249acb
+ languageName: node
+ linkType: hard
+
+"@jest/types@npm:^29.3.1":
+ version: 29.3.1
+ resolution: "@jest/types@npm:29.3.1"
+ dependencies:
+ "@jest/schemas": ^29.0.0
+ "@types/istanbul-lib-coverage": ^2.0.0
+ "@types/istanbul-reports": ^3.0.0
+ "@types/node": "*"
+ "@types/yargs": ^17.0.8
+ chalk: ^4.0.0
+ checksum: 6f9faf27507b845ff3839c1adc6dbd038d7046d03d37e84c9fc956f60718711a801a5094c7eeee6b39ccf42c0ab61347fdc0fa49ab493ae5a8efd2fd41228ee8
+ languageName: node
+ linkType: hard
+
+"@jridgewell/gen-mapping@npm:^0.1.0":
+ version: 0.1.1
+ resolution: "@jridgewell/gen-mapping@npm:0.1.1"
+ dependencies:
+ "@jridgewell/set-array": ^1.0.0
+ "@jridgewell/sourcemap-codec": ^1.4.10
+ checksum: 3bcc21fe786de6ffbf35c399a174faab05eb23ce6a03e8769569de28abbf4facc2db36a9ddb0150545ae23a8d35a7cf7237b2aa9e9356a7c626fb4698287d5cc
+ languageName: node
+ linkType: hard
+
+"@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.2":
+ version: 0.3.2
+ resolution: "@jridgewell/gen-mapping@npm:0.3.2"
+ dependencies:
+ "@jridgewell/set-array": ^1.0.1
+ "@jridgewell/sourcemap-codec": ^1.4.10
+ "@jridgewell/trace-mapping": ^0.3.9
+ checksum: 1832707a1c476afebe4d0fbbd4b9434fdb51a4c3e009ab1e9938648e21b7a97049fa6009393bdf05cab7504108413441df26d8a3c12193996e65493a4efb6882
+ languageName: node
+ linkType: hard
+
+"@jridgewell/resolve-uri@npm:3.1.0":
+ version: 3.1.0
+ resolution: "@jridgewell/resolve-uri@npm:3.1.0"
+ checksum: b5ceaaf9a110fcb2780d1d8f8d4a0bfd216702f31c988d8042e5f8fbe353c55d9b0f55a1733afdc64806f8e79c485d2464680ac48a0d9fcadb9548ee6b81d267
+ languageName: node
+ linkType: hard
+
+"@jridgewell/set-array@npm:^1.0.0, @jridgewell/set-array@npm:^1.0.1":
+ version: 1.1.2
+ resolution: "@jridgewell/set-array@npm:1.1.2"
+ checksum: 69a84d5980385f396ff60a175f7177af0b8da4ddb81824cb7016a9ef914eee9806c72b6b65942003c63f7983d4f39a5c6c27185bbca88eb4690b62075602e28e
+ languageName: node
+ linkType: hard
+
+"@jridgewell/source-map@npm:^0.3.2":
+ version: 0.3.2
+ resolution: "@jridgewell/source-map@npm:0.3.2"
+ dependencies:
+ "@jridgewell/gen-mapping": ^0.3.0
+ "@jridgewell/trace-mapping": ^0.3.9
+ checksum: 1b83f0eb944e77b70559a394d5d3b3f98a81fcc186946aceb3ef42d036762b52ef71493c6c0a3b7c1d2f08785f53ba2df1277fe629a06e6109588ff4cdcf7482
+ languageName: node
+ linkType: hard
+
+"@jridgewell/sourcemap-codec@npm:1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.10":
+ version: 1.4.14
+ resolution: "@jridgewell/sourcemap-codec@npm:1.4.14"
+ checksum: 61100637b6d173d3ba786a5dff019e1a74b1f394f323c1fee337ff390239f053b87266c7a948777f4b1ee68c01a8ad0ab61e5ff4abb5a012a0b091bec391ab97
+ languageName: node
+ linkType: hard
+
+"@jridgewell/trace-mapping@npm:^0.3.14, @jridgewell/trace-mapping@npm:^0.3.9":
+ version: 0.3.17
+ resolution: "@jridgewell/trace-mapping@npm:0.3.17"
+ dependencies:
+ "@jridgewell/resolve-uri": 3.1.0
+ "@jridgewell/sourcemap-codec": 1.4.14
+ checksum: 9d703b859cff5cd83b7308fd457a431387db5db96bd781a63bf48e183418dd9d3d44e76b9e4ae13237f6abeeb25d739ec9215c1d5bfdd08f66f750a50074a339
+ languageName: node
+ linkType: hard
+
+"@leichtgewicht/ip-codec@npm:^2.0.1":
+ version: 2.0.4
+ resolution: "@leichtgewicht/ip-codec@npm:2.0.4"
+ checksum: 468de1f04d33de6d300892683d7c8aecbf96d1e2c5fe084f95f816e50a054d45b7c1ebfb141a1447d844b86a948733f6eebd92234da8581c84a1ad4de2946a2d
+ languageName: node
+ linkType: hard
+
+"@mdx-js/mdx@npm:^1.6.22":
+ version: 1.6.22
+ resolution: "@mdx-js/mdx@npm:1.6.22"
+ dependencies:
+ "@babel/core": 7.12.9
+ "@babel/plugin-syntax-jsx": 7.12.1
+ "@babel/plugin-syntax-object-rest-spread": 7.8.3
+ "@mdx-js/util": 1.6.22
+ babel-plugin-apply-mdx-type-prop: 1.6.22
+ babel-plugin-extract-import-names: 1.6.22
+ camelcase-css: 2.0.1
+ detab: 2.0.4
+ hast-util-raw: 6.0.1
+ lodash.uniq: 4.5.0
+ mdast-util-to-hast: 10.0.1
+ remark-footnotes: 2.0.0
+ remark-mdx: 1.6.22
+ remark-parse: 8.0.3
+ remark-squeeze-paragraphs: 4.0.0
+ style-to-object: 0.3.0
+ unified: 9.2.0
+ unist-builder: 2.0.3
+ unist-util-visit: 2.0.3
+ checksum: 0839b4a3899416326ea6578fe9e470af319da559bc6d3669c60942e456b49a98eebeb3358c623007b4786a2175a450d2c51cd59df64639013c5a3d22366931a6
+ languageName: node
+ linkType: hard
+
+"@mdx-js/react@npm:^1.6.22":
+ version: 1.6.22
+ resolution: "@mdx-js/react@npm:1.6.22"
+ peerDependencies:
+ react: ^16.13.1 || ^17.0.0
+ checksum: bc84bd514bc127f898819a0c6f1a6915d9541011bd8aefa1fcc1c9bea8939f31051409e546bdec92babfa5b56092a16d05ef6d318304ac029299df5181dc94c8
+ languageName: node
+ linkType: hard
+
+"@mdx-js/util@npm:1.6.22":
+ version: 1.6.22
+ resolution: "@mdx-js/util@npm:1.6.22"
+ checksum: 4b393907e39a1a75214f0314bf72a0adfa5e5adffd050dd5efe9c055b8549481a3cfc9f308c16dfb33311daf3ff63added7d5fd1fe52db614c004f886e0e559a
+ languageName: node
+ linkType: hard
+
+"@nodelib/fs.scandir@npm:2.1.5":
+ version: 2.1.5
+ resolution: "@nodelib/fs.scandir@npm:2.1.5"
+ dependencies:
+ "@nodelib/fs.stat": 2.0.5
+ run-parallel: ^1.1.9
+ checksum: a970d595bd23c66c880e0ef1817791432dbb7acbb8d44b7e7d0e7a22f4521260d4a83f7f9fd61d44fda4610105577f8f58a60718105fb38352baed612fd79e59
+ languageName: node
+ linkType: hard
+
+"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2":
+ version: 2.0.5
+ resolution: "@nodelib/fs.stat@npm:2.0.5"
+ checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0
+ languageName: node
+ linkType: hard
+
+"@nodelib/fs.walk@npm:^1.2.3":
+ version: 1.2.8
+ resolution: "@nodelib/fs.walk@npm:1.2.8"
+ dependencies:
+ "@nodelib/fs.scandir": 2.1.5
+ fastq: ^1.6.0
+ checksum: 190c643f156d8f8f277bf2a6078af1ffde1fd43f498f187c2db24d35b4b4b5785c02c7dc52e356497b9a1b65b13edc996de08de0b961c32844364da02986dc53
+ languageName: node
+ linkType: hard
+
+"@npmcli/fs@npm:^2.1.0":
+ version: 2.1.2
+ resolution: "@npmcli/fs@npm:2.1.2"
+ dependencies:
+ "@gar/promisify": ^1.1.3
+ semver: ^7.3.5
+ checksum: 405074965e72d4c9d728931b64d2d38e6ea12066d4fad651ac253d175e413c06fe4350970c783db0d749181da8fe49c42d3880bd1cbc12cd68e3a7964d820225
+ languageName: node
+ linkType: hard
+
+"@npmcli/move-file@npm:^2.0.0":
+ version: 2.0.1
+ resolution: "@npmcli/move-file@npm:2.0.1"
+ dependencies:
+ mkdirp: ^1.0.4
+ rimraf: ^3.0.2
+ checksum: 52dc02259d98da517fae4cb3a0a3850227bdae4939dda1980b788a7670636ca2b4a01b58df03dd5f65c1e3cb70c50fa8ce5762b582b3f499ec30ee5ce1fd9380
+ languageName: node
+ linkType: hard
+
+"@polka/url@npm:^1.0.0-next.20":
+ version: 1.0.0-next.21
+ resolution: "@polka/url@npm:1.0.0-next.21"
+ checksum: c7654046d38984257dd639eab3dc770d1b0340916097b2fac03ce5d23506ada684e05574a69b255c32ea6a144a957c8cd84264159b545fca031c772289d88788
+ languageName: node
+ linkType: hard
+
+"@sideway/address@npm:^4.1.3":
+ version: 4.1.4
+ resolution: "@sideway/address@npm:4.1.4"
+ dependencies:
+ "@hapi/hoek": ^9.0.0
+ checksum: b9fca2a93ac2c975ba12e0a6d97853832fb1f4fb02393015e012b47fa916a75ca95102d77214b2a29a2784740df2407951af8c5dde054824c65577fd293c4cdb
+ languageName: node
+ linkType: hard
+
+"@sideway/formula@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "@sideway/formula@npm:3.0.0"
+ checksum: 8ae26a0ed6bc84f7310be6aae6eb9d81e97f382619fc69025d346871a707eaab0fa38b8c857e3f0c35a19923de129f42d35c50b8010c928d64aab41578580ec4
+ languageName: node
+ linkType: hard
+
+"@sideway/pinpoint@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "@sideway/pinpoint@npm:2.0.0"
+ checksum: 0f4491e5897fcf5bf02c46f5c359c56a314e90ba243f42f0c100437935daa2488f20482f0f77186bd6bf43345095a95d8143ecf8b1f4d876a7bc0806aba9c3d2
+ languageName: node
+ linkType: hard
+
+"@sinclair/typebox@npm:^0.24.1":
+ version: 0.24.51
+ resolution: "@sinclair/typebox@npm:0.24.51"
+ checksum: fd0d855e748ef767eb19da1a60ed0ab928e91e0f358c1dd198d600762c0015440b15755e96d1176e2a0db7e09c6a64ed487828ee10dd0c3e22f61eb09c478cd0
+ languageName: node
+ linkType: hard
+
+"@sindresorhus/is@npm:^0.14.0":
+ version: 0.14.0
+ resolution: "@sindresorhus/is@npm:0.14.0"
+ checksum: 971e0441dd44ba3909b467219a5e242da0fc584048db5324cfb8048148fa8dcc9d44d71e3948972c4f6121d24e5da402ef191420d1266a95f713bb6d6e59c98a
+ languageName: node
+ linkType: hard
+
+"@slorber/static-site-generator-webpack-plugin@npm:^4.0.7":
+ version: 4.0.7
+ resolution: "@slorber/static-site-generator-webpack-plugin@npm:4.0.7"
+ dependencies:
+ eval: ^0.1.8
+ p-map: ^4.0.0
+ webpack-sources: ^3.2.2
+ checksum: a1e1d8b22dd51059524993f3fdd6861db10eb950debc389e5dd650702287fa2004eace03e6bc8f25b977bd7bc01d76a50aa271cbb73c58a8ec558945d728f307
+ languageName: node
+ linkType: hard
+
+"@spotify/prettier-config@npm:^14.0.0":
+ version: 14.1.3
+ resolution: "@spotify/prettier-config@npm:14.1.3"
+ peerDependencies:
+ prettier: 2.x
+ checksum: 0c64ec0de9be5ae24a9b2a8f5c3af6c02306a47f54fffbd014852b00245fc939f3131eeeac8e906dfbb6aa86a5c0213b7f35623badad072979068f8cd69c316f
+ languageName: node
+ linkType: hard
+
+"@svgr/babel-plugin-add-jsx-attribute@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:6.5.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: cab83832830a57735329ed68f67c03b57ca21fa037b0134847b0c5c0ef4beca89956d7dacfbf7b2a10fd901e7009e877512086db2ee918b8c69aee7742ae32c0
+ languageName: node
+ linkType: hard
+
+"@svgr/babel-plugin-remove-jsx-attribute@npm:*":
+ version: 6.5.0
+ resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:6.5.0"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 7a4dfc1345f5855b010684e9c5301731842bf91d72b82ce5cc4c82c80b94de1036e447a8a00fb306a6dd575cb4c640d8ce3cfee6607ddbb804796a77284c7f22
+ languageName: node
+ linkType: hard
+
+"@svgr/babel-plugin-remove-jsx-empty-expression@npm:*":
+ version: 6.5.0
+ resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:6.5.0"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 3e173f720d530f9f71f8506f3eb78583eec3d87d66e385efe1ef3b3ebfc4e3680ec30f36414726de6a163e99ca69f54886022967e49476dea522267e1986936e
+ languageName: node
+ linkType: hard
+
+"@svgr/babel-plugin-replace-jsx-attribute-value@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:6.5.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: b7d2125758e766e1ebd14b92216b800bdc976959bc696dbfa1e28682919147c1df4bb8b1b5fd037d7a83026e27e681fea3b8d3741af8d3cf4c9dfa3d412125df
+ languageName: node
+ linkType: hard
+
+"@svgr/babel-plugin-svg-dynamic-title@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:6.5.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 0fd42ebf127ae9163ef341e84972daa99bdcb9e6ed3f83aabd95ee173fddc43e40e02fa847fbc0a1058cf5549f72b7960a2c5e22c3e4ac18f7e3ac81277852ae
+ languageName: node
+ linkType: hard
+
+"@svgr/babel-plugin-svg-em-dimensions@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:6.5.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: c1550ee9f548526fa66fd171e3ffb5696bfc4e4cd108a631d39db492c7410dc10bba4eb5a190e9df824bf806130ccc586ae7d2e43c547e6a4f93bbb29a18f344
+ languageName: node
+ linkType: hard
+
+"@svgr/babel-plugin-transform-react-native-svg@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:6.5.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 4c924af22b948b812629e80efb90ad1ec8faae26a232d8ca8a06b46b53e966a2c415a57806a3ff0ea806a622612e546422719b69ec6839717a7755dac19171d9
+ languageName: node
+ linkType: hard
+
+"@svgr/babel-plugin-transform-svg-component@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/babel-plugin-transform-svg-component@npm:6.5.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: e496bb5ee871feb6bcab250b6e067322da7dd5c9c2b530b41e5586fe090f86611339b49d0a909c334d9b24cbca0fa755c949a2526c6ad03c6b5885666874cf5f
+ languageName: node
+ linkType: hard
+
+"@svgr/babel-preset@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/babel-preset@npm:6.5.1"
+ dependencies:
+ "@svgr/babel-plugin-add-jsx-attribute": ^6.5.1
+ "@svgr/babel-plugin-remove-jsx-attribute": "*"
+ "@svgr/babel-plugin-remove-jsx-empty-expression": "*"
+ "@svgr/babel-plugin-replace-jsx-attribute-value": ^6.5.1
+ "@svgr/babel-plugin-svg-dynamic-title": ^6.5.1
+ "@svgr/babel-plugin-svg-em-dimensions": ^6.5.1
+ "@svgr/babel-plugin-transform-react-native-svg": ^6.5.1
+ "@svgr/babel-plugin-transform-svg-component": ^6.5.1
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 9f124be39a8e64f909162f925b3a63ddaa5a342a5e24fc0b7f7d9d4d7f7e3b916596c754fb557dc259928399cad5366a27cb231627a0d2dcc4b13ac521cf05af
+ languageName: node
+ linkType: hard
+
+"@svgr/core@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/core@npm:6.5.1"
+ dependencies:
+ "@babel/core": ^7.19.6
+ "@svgr/babel-preset": ^6.5.1
+ "@svgr/plugin-jsx": ^6.5.1
+ camelcase: ^6.2.0
+ cosmiconfig: ^7.0.1
+ checksum: fd6d6d5da5aeb956703310480b626c1fb3e3973ad9fe8025efc1dcf3d895f857b70d100c63cf32cebb20eb83c9607bafa464c9436e18fe6fe4fafdc73ed6b1a5
+ languageName: node
+ linkType: hard
+
+"@svgr/hast-util-to-babel-ast@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/hast-util-to-babel-ast@npm:6.5.1"
+ dependencies:
+ "@babel/types": ^7.20.0
+ entities: ^4.4.0
+ checksum: 37923cce1b3f4e2039077b0c570b6edbabe37d1cf1a6ee35e71e0fe00f9cffac450eec45e9720b1010418131a999cb0047331ba1b6d1d2c69af1b92ac785aacf
+ languageName: node
+ linkType: hard
+
+"@svgr/plugin-jsx@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/plugin-jsx@npm:6.5.1"
+ dependencies:
+ "@babel/core": ^7.19.6
+ "@svgr/babel-preset": ^6.5.1
+ "@svgr/hast-util-to-babel-ast": ^6.5.1
+ svg-parser: ^2.0.4
+ peerDependencies:
+ "@svgr/core": ^6.0.0
+ checksum: 42f22847a6bdf930514d7bedd3c5e1fd8d53eb3594779f9db16cb94c762425907c375cd8ec789114e100a4d38068aca6c7ab5efea4c612fba63f0630c44cc859
+ languageName: node
+ linkType: hard
+
+"@svgr/plugin-svgo@npm:^6.5.1":
+ version: 6.5.1
+ resolution: "@svgr/plugin-svgo@npm:6.5.1"
+ dependencies:
+ cosmiconfig: ^7.0.1
+ deepmerge: ^4.2.2
+ svgo: ^2.8.0
+ peerDependencies:
+ "@svgr/core": "*"
+ checksum: cd2833530ac0485221adc2146fd992ab20d79f4b12eebcd45fa859721dd779483158e11dfd9a534858fe468416b9412416e25cbe07ac7932c44ed5fa2021c72e
+ languageName: node
+ linkType: hard
+
+"@svgr/webpack@npm:^6.2.1":
+ version: 6.5.1
+ resolution: "@svgr/webpack@npm:6.5.1"
+ dependencies:
+ "@babel/core": ^7.19.6
+ "@babel/plugin-transform-react-constant-elements": ^7.18.12
+ "@babel/preset-env": ^7.19.4
+ "@babel/preset-react": ^7.18.6
+ "@babel/preset-typescript": ^7.18.6
+ "@svgr/core": ^6.5.1
+ "@svgr/plugin-jsx": ^6.5.1
+ "@svgr/plugin-svgo": ^6.5.1
+ checksum: d10582eb4fa82a5b6d314cb49f2c640af4fd3a60f5b76095d2b14e383ef6a43a6f4674b68774a21787dbde69dec0a251cfcfc3f9a96c82754ba5d5c6daf785f0
+ languageName: node
+ linkType: hard
+
+"@szmarczak/http-timer@npm:^1.1.2":
+ version: 1.1.2
+ resolution: "@szmarczak/http-timer@npm:1.1.2"
+ dependencies:
+ defer-to-connect: ^1.0.1
+ checksum: 4d9158061c5f397c57b4988cde33a163244e4f02df16364f103971957a32886beb104d6180902cbe8b38cb940e234d9f98a4e486200deca621923f62f50a06fe
+ languageName: node
+ linkType: hard
+
+"@tootallnate/once@npm:2":
+ version: 2.0.0
+ resolution: "@tootallnate/once@npm:2.0.0"
+ checksum: ad87447820dd3f24825d2d947ebc03072b20a42bfc96cbafec16bff8bbda6c1a81fcb0be56d5b21968560c5359a0af4038a68ba150c3e1694fe4c109a063bed8
+ languageName: node
+ linkType: hard
+
+"@trysound/sax@npm:0.2.0":
+ version: 0.2.0
+ resolution: "@trysound/sax@npm:0.2.0"
+ checksum: 11226c39b52b391719a2a92e10183e4260d9651f86edced166da1d95f39a0a1eaa470e44d14ac685ccd6d3df7e2002433782872c0feeb260d61e80f21250e65c
+ languageName: node
+ linkType: hard
+
+"@types/body-parser@npm:*":
+ version: 1.19.2
+ resolution: "@types/body-parser@npm:1.19.2"
+ dependencies:
+ "@types/connect": "*"
+ "@types/node": "*"
+ checksum: e17840c7d747a549f00aebe72c89313d09fbc4b632b949b2470c5cb3b1cb73863901ae84d9335b567a79ec5efcfb8a28ff8e3f36bc8748a9686756b6d5681f40
+ languageName: node
+ linkType: hard
+
+"@types/bonjour@npm:^3.5.9":
+ version: 3.5.10
+ resolution: "@types/bonjour@npm:3.5.10"
+ dependencies:
+ "@types/node": "*"
+ checksum: bfcadb042a41b124c4e3de4925e3be6d35b78f93f27c4535d5ff86980dc0f8bc407ed99b9b54528952dc62834d5a779392f7a12c2947dd19330eb05a6bcae15a
+ languageName: node
+ linkType: hard
+
+"@types/connect-history-api-fallback@npm:^1.3.5":
+ version: 1.3.5
+ resolution: "@types/connect-history-api-fallback@npm:1.3.5"
+ dependencies:
+ "@types/express-serve-static-core": "*"
+ "@types/node": "*"
+ checksum: 464d06e5ab00f113fa89978633d5eb00d225aeb4ebbadc07f6f3bc337aa7cbfcd74957b2a539d6d47f2e128e956a17819973ec7ae62ade2e16e367a6c38b8d3a
+ languageName: node
+ linkType: hard
+
+"@types/connect@npm:*":
+ version: 3.4.35
+ resolution: "@types/connect@npm:3.4.35"
+ dependencies:
+ "@types/node": "*"
+ checksum: fe81351470f2d3165e8b12ce33542eef89ea893e36dd62e8f7d72566dfb7e448376ae962f9f3ea888547ce8b55a40020ca0e01d637fab5d99567673084542641
+ languageName: node
+ linkType: hard
+
+"@types/eslint-scope@npm:^3.7.3":
+ version: 3.7.4
+ resolution: "@types/eslint-scope@npm:3.7.4"
+ dependencies:
+ "@types/eslint": "*"
+ "@types/estree": "*"
+ checksum: ea6a9363e92f301cd3888194469f9ec9d0021fe0a397a97a6dd689e7545c75de0bd2153dfb13d3ab532853a278b6572c6f678ce846980669e41029d205653460
+ languageName: node
+ linkType: hard
+
+"@types/eslint@npm:*":
+ version: 8.4.10
+ resolution: "@types/eslint@npm:8.4.10"
+ dependencies:
+ "@types/estree": "*"
+ "@types/json-schema": "*"
+ checksum: 21e009ed9ed9bc8920fdafc6e11ff321c4538b4cc18a56fdd59dc5184ea7bbf363c71638c9bdb59fc1254dddcdd567485136ed68b0ee4750948d4e32cb79c689
+ languageName: node
+ linkType: hard
+
+"@types/estree@npm:*":
+ version: 1.0.0
+ resolution: "@types/estree@npm:1.0.0"
+ checksum: 910d97fb7092c6738d30a7430ae4786a38542023c6302b95d46f49420b797f21619cdde11fa92b338366268795884111c2eb10356e4bd2c8ad5b92941e9e6443
+ languageName: node
+ linkType: hard
+
+"@types/estree@npm:^0.0.51":
+ version: 0.0.51
+ resolution: "@types/estree@npm:0.0.51"
+ checksum: e56a3bcf759fd9185e992e7fdb3c6a5f81e8ff120e871641607581fb3728d16c811702a7d40fa5f869b7f7b4437ab6a87eb8d98ffafeee51e85bbe955932a189
+ languageName: node
+ linkType: hard
+
+"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.18":
+ version: 4.17.31
+ resolution: "@types/express-serve-static-core@npm:4.17.31"
+ dependencies:
+ "@types/node": "*"
+ "@types/qs": "*"
+ "@types/range-parser": "*"
+ checksum: 009bfbe1070837454a1056aa710d0390ee5fb8c05dfe5a1691cc3e2ca88dc256f80e1ca27cb51a978681631d2f6431bfc9ec352ea46dd0c6eb183d0170bde5df
+ languageName: node
+ linkType: hard
+
+"@types/express@npm:*, @types/express@npm:^4.17.13":
+ version: 4.17.14
+ resolution: "@types/express@npm:4.17.14"
+ dependencies:
+ "@types/body-parser": "*"
+ "@types/express-serve-static-core": ^4.17.18
+ "@types/qs": "*"
+ "@types/serve-static": "*"
+ checksum: 15c1af46d02de834e4a225eccaa9d85c0370fdbb3ed4e1bc2d323d24872309961542b993ae236335aeb3e278630224a6ea002078d39e651d78a3b0356b1eaa79
+ languageName: node
+ linkType: hard
+
+"@types/hast@npm:^2.0.0":
+ version: 2.3.4
+ resolution: "@types/hast@npm:2.3.4"
+ dependencies:
+ "@types/unist": "*"
+ checksum: fff47998f4c11e21a7454b58673f70478740ecdafd95aaf50b70a3daa7da9cdc57315545bf9c039613732c40b7b0e9e49d11d03fe9a4304721cdc3b29a88141e
+ languageName: node
+ linkType: hard
+
+"@types/history@npm:^4.7.11":
+ version: 4.7.11
+ resolution: "@types/history@npm:4.7.11"
+ checksum: c92e2ba407dcab0581a9afdf98f533aa41b61a71133420a6d92b1ca9839f741ab1f9395b17454ba5b88cb86020b70b22d74a1950ccfbdfd9beeaa5459fdc3464
+ languageName: node
+ linkType: hard
+
+"@types/html-minifier-terser@npm:^6.0.0":
+ version: 6.1.0
+ resolution: "@types/html-minifier-terser@npm:6.1.0"
+ checksum: eb843f6a8d662d44fb18ec61041117734c6aae77aa38df1be3b4712e8e50ffaa35f1e1c92fdd0fde14a5675fecf457abcd0d15a01fae7506c91926176967f452
+ languageName: node
+ linkType: hard
+
+"@types/http-proxy@npm:^1.17.8":
+ version: 1.17.9
+ resolution: "@types/http-proxy@npm:1.17.9"
+ dependencies:
+ "@types/node": "*"
+ checksum: 7a6746d00729b2a9fe9f9dd3453430b099931df879ec8f7a7b5f07b1795f6d99b0512640c45a67390b1e4bacb9401e36824952aeeaf089feba8627a063cf8e00
+ languageName: node
+ linkType: hard
+
+"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0":
+ version: 2.0.4
+ resolution: "@types/istanbul-lib-coverage@npm:2.0.4"
+ checksum: a25d7589ee65c94d31464c16b72a9dc81dfa0bea9d3e105ae03882d616e2a0712a9c101a599ec482d297c3591e16336962878cb3eb1a0a62d5b76d277a890ce7
+ languageName: node
+ linkType: hard
+
+"@types/istanbul-lib-report@npm:*":
+ version: 3.0.0
+ resolution: "@types/istanbul-lib-report@npm:3.0.0"
+ dependencies:
+ "@types/istanbul-lib-coverage": "*"
+ checksum: 656398b62dc288e1b5226f8880af98087233cdb90100655c989a09f3052b5775bf98ba58a16c5ae642fb66c61aba402e07a9f2bff1d1569e3b306026c59f3f36
+ languageName: node
+ linkType: hard
+
+"@types/istanbul-reports@npm:^3.0.0":
+ version: 3.0.1
+ resolution: "@types/istanbul-reports@npm:3.0.1"
+ dependencies:
+ "@types/istanbul-lib-report": "*"
+ checksum: f1ad54bc68f37f60b30c7915886b92f86b847033e597f9b34f2415acdbe5ed742fa559a0a40050d74cdba3b6a63c342cac1f3a64dba5b68b66a6941f4abd7903
+ languageName: node
+ linkType: hard
+
+"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9":
+ version: 7.0.11
+ resolution: "@types/json-schema@npm:7.0.11"
+ checksum: 527bddfe62db9012fccd7627794bd4c71beb77601861055d87e3ee464f2217c85fca7a4b56ae677478367bbd248dbde13553312b7d4dbc702a2f2bbf60c4018d
+ languageName: node
+ linkType: hard
+
+"@types/keyv@npm:^3.1.1":
+ version: 3.1.4
+ resolution: "@types/keyv@npm:3.1.4"
+ dependencies:
+ "@types/node": "*"
+ checksum: e009a2bfb50e90ca9b7c6e8f648f8464067271fd99116f881073fa6fa76dc8d0133181dd65e6614d5fb1220d671d67b0124aef7d97dc02d7e342ab143a47779d
+ languageName: node
+ linkType: hard
+
+"@types/mdast@npm:^3.0.0":
+ version: 3.0.10
+ resolution: "@types/mdast@npm:3.0.10"
+ dependencies:
+ "@types/unist": "*"
+ checksum: 3f587bfc0a9a2403ecadc220e61031b01734fedaf82e27eb4d5ba039c0eb54db8c85681ccc070ab4df3f7ec711b736a82b990e69caa14c74bf7ac0ccf2ac7313
+ languageName: node
+ linkType: hard
+
+"@types/mime@npm:*":
+ version: 3.0.1
+ resolution: "@types/mime@npm:3.0.1"
+ checksum: 4040fac73fd0cea2460e29b348c1a6173da747f3a87da0dbce80dd7a9355a3d0e51d6d9a401654f3e5550620e3718b5a899b2ec1debf18424e298a2c605346e7
+ languageName: node
+ linkType: hard
+
+"@types/node@npm:*":
+ version: 18.11.13
+ resolution: "@types/node@npm:18.11.13"
+ checksum: b0c1aa3bd2f5df8240e61096a49d6d4be600109b824d23408ec4ba1ec057dc0c60588e09f73b8a60455ad26d367e9c5562fad8403099f885cbc7b4cace83ec4c
+ languageName: node
+ linkType: hard
+
+"@types/node@npm:^17.0.5":
+ version: 17.0.45
+ resolution: "@types/node@npm:17.0.45"
+ checksum: aa04366b9103b7d6cfd6b2ef64182e0eaa7d4462c3f817618486ea0422984c51fc69fd0d436eae6c9e696ddfdbec9ccaa27a917f7c2e8c75c5d57827fe3d95e8
+ languageName: node
+ linkType: hard
+
+"@types/parse-json@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "@types/parse-json@npm:4.0.0"
+ checksum: fd6bce2b674b6efc3db4c7c3d336bd70c90838e8439de639b909ce22f3720d21344f52427f1d9e57b265fcb7f6c018699b99e5e0c208a1a4823014269a6bf35b
+ languageName: node
+ linkType: hard
+
+"@types/parse5@npm:^5.0.0":
+ version: 5.0.3
+ resolution: "@types/parse5@npm:5.0.3"
+ checksum: d6b7495cb1850f9f2e9c5e103ede9f2d30a5320669707b105c403868adc9e4bf8d3a7ff314cc23f67826bbbbbc0e6147346ce9062ab429f099dba7a01f463919
+ languageName: node
+ linkType: hard
+
+"@types/prop-types@npm:*":
+ version: 15.7.5
+ resolution: "@types/prop-types@npm:15.7.5"
+ checksum: 5b43b8b15415e1f298243165f1d44390403bb2bd42e662bca3b5b5633fdd39c938e91b7fce3a9483699db0f7a715d08cef220c121f723a634972fdf596aec980
+ languageName: node
+ linkType: hard
+
+"@types/qs@npm:*":
+ version: 6.9.7
+ resolution: "@types/qs@npm:6.9.7"
+ checksum: 7fd6f9c25053e9b5bb6bc9f9f76c1d89e6c04f7707a7ba0e44cc01f17ef5284adb82f230f542c2d5557d69407c9a40f0f3515e8319afd14e1e16b5543ac6cdba
+ languageName: node
+ linkType: hard
+
+"@types/range-parser@npm:*":
+ version: 1.2.4
+ resolution: "@types/range-parser@npm:1.2.4"
+ checksum: b7c0dfd5080a989d6c8bb0b6750fc0933d9acabeb476da6fe71d8bdf1ab65e37c136169d84148034802f48378ab94e3c37bb4ef7656b2bec2cb9c0f8d4146a95
+ languageName: node
+ linkType: hard
+
+"@types/react-router-config@npm:*, @types/react-router-config@npm:^5.0.6":
+ version: 5.0.6
+ resolution: "@types/react-router-config@npm:5.0.6"
+ dependencies:
+ "@types/history": ^4.7.11
+ "@types/react": "*"
+ "@types/react-router": "*"
+ checksum: e32a7b19d14c1c07e2c06630207bc4ecf86a01585b832bf3c0756c9eaca312b5839bc8d50e8d744738ea50e7bbde0be3b1fd14a6a9398159d36bce33aff7f280
+ languageName: node
+ linkType: hard
+
+"@types/react-router-dom@npm:*":
+ version: 5.3.3
+ resolution: "@types/react-router-dom@npm:5.3.3"
+ dependencies:
+ "@types/history": ^4.7.11
+ "@types/react": "*"
+ "@types/react-router": "*"
+ checksum: 28c4ea48909803c414bf5a08502acbb8ba414669b4b43bb51297c05fe5addc4df0b8fd00e0a9d1e3535ec4073ef38aaafac2c4a2b95b787167d113bc059beff3
+ languageName: node
+ linkType: hard
+
+"@types/react-router@npm:*":
+ version: 5.1.19
+ resolution: "@types/react-router@npm:5.1.19"
+ dependencies:
+ "@types/history": ^4.7.11
+ "@types/react": "*"
+ checksum: 3536c3dec7af1f12fed2bea246eb143bd893ee66d4e58c1d3fe734cbd67d8a0aedac0bba9255c58fc69dbd32ae17ad280d6866916aee32653a705178e4a544dc
+ languageName: node
+ linkType: hard
+
+"@types/react@npm:*":
+ version: 18.0.26
+ resolution: "@types/react@npm:18.0.26"
+ dependencies:
+ "@types/prop-types": "*"
+ "@types/scheduler": "*"
+ csstype: ^3.0.2
+ checksum: b62f0ea3cdfa68e106391728325057ad36f1bde7ba2dfae029472c47e01e482bc77c6ba4f1dad59f3f04ee81cb597618ff7c30a33c157c0a20462b6dd6aa2d4d
+ languageName: node
+ linkType: hard
+
+"@types/responselike@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "@types/responselike@npm:1.0.0"
+ dependencies:
+ "@types/node": "*"
+ checksum: e99fc7cc6265407987b30deda54c1c24bb1478803faf6037557a774b2f034c5b097ffd65847daa87e82a61a250d919f35c3588654b0fdaa816906650f596d1b0
+ languageName: node
+ linkType: hard
+
+"@types/retry@npm:0.12.0":
+ version: 0.12.0
+ resolution: "@types/retry@npm:0.12.0"
+ checksum: 61a072c7639f6e8126588bf1eb1ce8835f2cb9c2aba795c4491cf6310e013267b0c8488039857c261c387e9728c1b43205099223f160bb6a76b4374f741b5603
+ languageName: node
+ linkType: hard
+
+"@types/sax@npm:^1.2.1":
+ version: 1.2.4
+ resolution: "@types/sax@npm:1.2.4"
+ dependencies:
+ "@types/node": "*"
+ checksum: 2aa50cbf1d1f0cf8541ef1787f94c7442e58e63900afd3b45c354e4140ed5efc5cf26fca8eb9df9970a74c7ea582293ae2083271bd046dedf4c3cc2689a40892
+ languageName: node
+ linkType: hard
+
+"@types/scheduler@npm:*":
+ version: 0.16.2
+ resolution: "@types/scheduler@npm:0.16.2"
+ checksum: b6b4dcfeae6deba2e06a70941860fb1435730576d3689225a421280b7742318d1548b3d22c1f66ab68e414f346a9542f29240bc955b6332c5b11e561077583bc
+ languageName: node
+ linkType: hard
+
+"@types/serve-index@npm:^1.9.1":
+ version: 1.9.1
+ resolution: "@types/serve-index@npm:1.9.1"
+ dependencies:
+ "@types/express": "*"
+ checksum: 026f3995fb500f6df7c3fe5009e53bad6d739e20b84089f58ebfafb2f404bbbb6162bbe33f72d2f2af32d5b8d3799c8e179793f90d9ed5871fb8591190bb6056
+ languageName: node
+ linkType: hard
+
+"@types/serve-static@npm:*, @types/serve-static@npm:^1.13.10":
+ version: 1.15.0
+ resolution: "@types/serve-static@npm:1.15.0"
+ dependencies:
+ "@types/mime": "*"
+ "@types/node": "*"
+ checksum: b6ac93d471fb0f53ddcac1f9b67572a09cd62806f7db5855244b28f6f421139626f24799392566e97d1ffc61b12f9de7f30380c39fcae3c8a161fe161d44edf2
+ languageName: node
+ linkType: hard
+
+"@types/sockjs@npm:^0.3.33":
+ version: 0.3.33
+ resolution: "@types/sockjs@npm:0.3.33"
+ dependencies:
+ "@types/node": "*"
+ checksum: b9bbb2b5c5ead2fb884bb019f61a014e37410bddd295de28184e1b2e71ee6b04120c5ba7b9954617f0bdf962c13d06249ce65004490889c747c80d3f628ea842
+ languageName: node
+ linkType: hard
+
+"@types/unist@npm:*, @types/unist@npm:^2.0.0, @types/unist@npm:^2.0.2, @types/unist@npm:^2.0.3":
+ version: 2.0.6
+ resolution: "@types/unist@npm:2.0.6"
+ checksum: 25cb860ff10dde48b54622d58b23e66214211a61c84c0f15f88d38b61aa1b53d4d46e42b557924a93178c501c166aa37e28d7f6d994aba13d24685326272d5db
+ languageName: node
+ linkType: hard
+
+"@types/ws@npm:^8.5.1":
+ version: 8.5.3
+ resolution: "@types/ws@npm:8.5.3"
+ dependencies:
+ "@types/node": "*"
+ checksum: 0ce46f850d41383fcdc2149bcacc86d7232fa7a233f903d2246dff86e31701a02f8566f40af5f8b56d1834779255c04ec6ec78660fe0f9b2a69cf3d71937e4ae
+ languageName: node
+ linkType: hard
+
+"@types/yargs-parser@npm:*":
+ version: 21.0.0
+ resolution: "@types/yargs-parser@npm:21.0.0"
+ checksum: b2f4c8d12ac18a567440379909127cf2cec393daffb73f246d0a25df36ea983b93b7e9e824251f959e9f928cbc7c1aab6728d0a0ff15d6145f66cec2be67d9a2
+ languageName: node
+ linkType: hard
+
+"@types/yargs@npm:^17.0.8":
+ version: 17.0.17
+ resolution: "@types/yargs@npm:17.0.17"
+ dependencies:
+ "@types/yargs-parser": "*"
+ checksum: 4f1b5149e794c8960652b4339dc96655e53b48fdbe1b847fcb0db95e72e760724a4c5c616a7fccb3c0ae8beb0e57e06e37391d492e916e3ff179aafeb890e426
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/ast@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/ast@npm:1.11.1"
+ dependencies:
+ "@webassemblyjs/helper-numbers": 1.11.1
+ "@webassemblyjs/helper-wasm-bytecode": 1.11.1
+ checksum: 1eee1534adebeece635362f8e834ae03e389281972611408d64be7895fc49f48f98fddbbb5339bf8a72cb101bcb066e8bca3ca1bf1ef47dadf89def0395a8d87
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/floating-point-hex-parser@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.11.1"
+ checksum: b8efc6fa08e4787b7f8e682182d84dfdf8da9d9c77cae5d293818bc4a55c1f419a87fa265ab85252b3e6c1fd323d799efea68d825d341a7c365c64bc14750e97
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/helper-api-error@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/helper-api-error@npm:1.11.1"
+ checksum: 0792813f0ed4a0e5ee0750e8b5d0c631f08e927f4bdfdd9fe9105dc410c786850b8c61bff7f9f515fdfb149903bec3c976a1310573a4c6866a94d49bc7271959
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/helper-buffer@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/helper-buffer@npm:1.11.1"
+ checksum: a337ee44b45590c3a30db5a8b7b68a717526cf967ada9f10253995294dbd70a58b2da2165222e0b9830cd4fc6e4c833bf441a721128d1fe2e9a7ab26b36003ce
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/helper-numbers@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/helper-numbers@npm:1.11.1"
+ dependencies:
+ "@webassemblyjs/floating-point-hex-parser": 1.11.1
+ "@webassemblyjs/helper-api-error": 1.11.1
+ "@xtuc/long": 4.2.2
+ checksum: 44d2905dac2f14d1e9b5765cf1063a0fa3d57295c6d8930f6c59a36462afecc6e763e8a110b97b342a0f13376166c5d41aa928e6ced92e2f06b071fd0db59d3a
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/helper-wasm-bytecode@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.11.1"
+ checksum: eac400113127832c88f5826bcc3ad1c0db9b3dbd4c51a723cfdb16af6bfcbceb608170fdaac0ab7731a7e18b291be7af68a47fcdb41cfe0260c10857e7413d97
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/helper-wasm-section@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/helper-wasm-section@npm:1.11.1"
+ dependencies:
+ "@webassemblyjs/ast": 1.11.1
+ "@webassemblyjs/helper-buffer": 1.11.1
+ "@webassemblyjs/helper-wasm-bytecode": 1.11.1
+ "@webassemblyjs/wasm-gen": 1.11.1
+ checksum: 617696cfe8ecaf0532763162aaf748eb69096fb27950219bb87686c6b2e66e11cd0614d95d319d0ab1904bc14ebe4e29068b12c3e7c5e020281379741fe4bedf
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/ieee754@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/ieee754@npm:1.11.1"
+ dependencies:
+ "@xtuc/ieee754": ^1.2.0
+ checksum: 23a0ac02a50f244471631802798a816524df17e56b1ef929f0c73e3cde70eaf105a24130105c60aff9d64a24ce3b640dad443d6f86e5967f922943a7115022ec
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/leb128@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/leb128@npm:1.11.1"
+ dependencies:
+ "@xtuc/long": 4.2.2
+ checksum: 33ccc4ade2f24de07bf31690844d0b1ad224304ee2062b0e464a610b0209c79e0b3009ac190efe0e6bd568b0d1578d7c3047fc1f9d0197c92fc061f56224ff4a
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/utf8@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/utf8@npm:1.11.1"
+ checksum: 972c5cfc769d7af79313a6bfb96517253a270a4bf0c33ba486aa43cac43917184fb35e51dfc9e6b5601548cd5931479a42e42c89a13bb591ffabebf30c8a6a0b
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/wasm-edit@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/wasm-edit@npm:1.11.1"
+ dependencies:
+ "@webassemblyjs/ast": 1.11.1
+ "@webassemblyjs/helper-buffer": 1.11.1
+ "@webassemblyjs/helper-wasm-bytecode": 1.11.1
+ "@webassemblyjs/helper-wasm-section": 1.11.1
+ "@webassemblyjs/wasm-gen": 1.11.1
+ "@webassemblyjs/wasm-opt": 1.11.1
+ "@webassemblyjs/wasm-parser": 1.11.1
+ "@webassemblyjs/wast-printer": 1.11.1
+ checksum: 6d7d9efaec1227e7ef7585a5d7ff0be5f329f7c1c6b6c0e906b18ed2e9a28792a5635e450aca2d136770d0207225f204eff70a4b8fd879d3ac79e1dcc26dbeb9
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/wasm-gen@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/wasm-gen@npm:1.11.1"
+ dependencies:
+ "@webassemblyjs/ast": 1.11.1
+ "@webassemblyjs/helper-wasm-bytecode": 1.11.1
+ "@webassemblyjs/ieee754": 1.11.1
+ "@webassemblyjs/leb128": 1.11.1
+ "@webassemblyjs/utf8": 1.11.1
+ checksum: 1f6921e640293bf99fb16b21e09acb59b340a79f986c8f979853a0ae9f0b58557534b81e02ea2b4ef11e929d946708533fd0693c7f3712924128fdafd6465f5b
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/wasm-opt@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/wasm-opt@npm:1.11.1"
+ dependencies:
+ "@webassemblyjs/ast": 1.11.1
+ "@webassemblyjs/helper-buffer": 1.11.1
+ "@webassemblyjs/wasm-gen": 1.11.1
+ "@webassemblyjs/wasm-parser": 1.11.1
+ checksum: 21586883a20009e2b20feb67bdc451bbc6942252e038aae4c3a08e6f67b6bae0f5f88f20bfc7bd0452db5000bacaf5ab42b98cf9aa034a6c70e9fc616142e1db
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/wasm-parser@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/wasm-parser@npm:1.11.1"
+ dependencies:
+ "@webassemblyjs/ast": 1.11.1
+ "@webassemblyjs/helper-api-error": 1.11.1
+ "@webassemblyjs/helper-wasm-bytecode": 1.11.1
+ "@webassemblyjs/ieee754": 1.11.1
+ "@webassemblyjs/leb128": 1.11.1
+ "@webassemblyjs/utf8": 1.11.1
+ checksum: 1521644065c360e7b27fad9f4bb2df1802d134dd62937fa1f601a1975cde56bc31a57b6e26408b9ee0228626ff3ba1131ae6f74ffb7d718415b6528c5a6dbfc2
+ languageName: node
+ linkType: hard
+
+"@webassemblyjs/wast-printer@npm:1.11.1":
+ version: 1.11.1
+ resolution: "@webassemblyjs/wast-printer@npm:1.11.1"
+ dependencies:
+ "@webassemblyjs/ast": 1.11.1
+ "@xtuc/long": 4.2.2
+ checksum: f15ae4c2441b979a3b4fce78f3d83472fb22350c6dc3fd34bfe7c3da108e0b2360718734d961bba20e7716cb8578e964b870da55b035e209e50ec9db0378a3f7
+ languageName: node
+ linkType: hard
+
+"@xtuc/ieee754@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "@xtuc/ieee754@npm:1.2.0"
+ checksum: ac56d4ca6e17790f1b1677f978c0c6808b1900a5b138885d3da21732f62e30e8f0d9120fcf8f6edfff5100ca902b46f8dd7c1e3f903728634523981e80e2885a
+ languageName: node
+ linkType: hard
+
+"@xtuc/long@npm:4.2.2":
+ version: 4.2.2
+ resolution: "@xtuc/long@npm:4.2.2"
+ checksum: 8ed0d477ce3bc9c6fe2bf6a6a2cc316bb9c4127c5a7827bae947fa8ec34c7092395c5a283cc300c05b5fa01cbbfa1f938f410a7bf75db7c7846fea41949989ec
+ languageName: node
+ linkType: hard
+
+"abbrev@npm:^1.0.0":
+ version: 1.1.1
+ resolution: "abbrev@npm:1.1.1"
+ checksum: a4a97ec07d7ea112c517036882b2ac22f3109b7b19077dc656316d07d308438aac28e4d9746dc4d84bf6b1e75b4a7b0a5f3cb30592419f128ca9a8cee3bcfa17
+ languageName: node
+ linkType: hard
+
+"accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8":
+ version: 1.3.8
+ resolution: "accepts@npm:1.3.8"
+ dependencies:
+ mime-types: ~2.1.34
+ negotiator: 0.6.3
+ checksum: 50c43d32e7b50285ebe84b613ee4a3aa426715a7d131b65b786e2ead0fd76b6b60091b9916d3478a75f11f162628a2139991b6c03ab3f1d9ab7c86075dc8eab4
+ languageName: node
+ linkType: hard
+
+"acorn-import-assertions@npm:^1.7.6":
+ version: 1.8.0
+ resolution: "acorn-import-assertions@npm:1.8.0"
+ peerDependencies:
+ acorn: ^8
+ checksum: 5c4cf7c850102ba7ae0eeae0deb40fb3158c8ca5ff15c0bca43b5c47e307a1de3d8ef761788f881343680ea374631ae9e9615ba8876fee5268dbe068c98bcba6
+ languageName: node
+ linkType: hard
+
+"acorn-walk@npm:^8.0.0":
+ version: 8.2.0
+ resolution: "acorn-walk@npm:8.2.0"
+ checksum: 1715e76c01dd7b2d4ca472f9c58968516a4899378a63ad5b6c2d668bba8da21a71976c14ec5f5b75f887b6317c4ae0b897ab141c831d741dc76024d8745f1ad1
+ languageName: node
+ linkType: hard
+
+"acorn@npm:^8.0.4, acorn@npm:^8.5.0, acorn@npm:^8.7.1":
+ version: 8.8.1
+ resolution: "acorn@npm:8.8.1"
+ bin:
+ acorn: bin/acorn
+ checksum: 4079b67283b94935157698831967642f24a075c52ce3feaaaafe095776dfbe15d86a1b33b1e53860fc0d062ed6c83f4284a5c87c85b9ad51853a01173da6097f
+ languageName: node
+ linkType: hard
+
+"address@npm:^1.0.1, address@npm:^1.1.2":
+ version: 1.2.1
+ resolution: "address@npm:1.2.1"
+ checksum: e4c0f961464ccad09c3f7ed3a8d12f609354a87dd1ad379e43661e9684446fbf158be3edeef85e1590dfc6c88c0897c5908bc18f232eb86e43993a2ada5820fa
+ languageName: node
+ linkType: hard
+
+"agent-base@npm:6, agent-base@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "agent-base@npm:6.0.2"
+ dependencies:
+ debug: 4
+ checksum: f52b6872cc96fd5f622071b71ef200e01c7c4c454ee68bc9accca90c98cfb39f2810e3e9aa330435835eedc8c23f4f8a15267f67c6e245d2b33757575bdac49d
+ languageName: node
+ linkType: hard
+
+"agentkeepalive@npm:^4.2.1":
+ version: 4.2.1
+ resolution: "agentkeepalive@npm:4.2.1"
+ dependencies:
+ debug: ^4.1.0
+ depd: ^1.1.2
+ humanize-ms: ^1.2.1
+ checksum: 39cb49ed8cf217fd6da058a92828a0a84e0b74c35550f82ee0a10e1ee403c4b78ade7948be2279b188b7a7303f5d396ea2738b134731e464bf28de00a4f72a18
+ languageName: node
+ linkType: hard
+
+"aggregate-error@npm:^3.0.0":
+ version: 3.1.0
+ resolution: "aggregate-error@npm:3.1.0"
+ dependencies:
+ clean-stack: ^2.0.0
+ indent-string: ^4.0.0
+ checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79
+ languageName: node
+ linkType: hard
+
+"ajv-formats@npm:^2.1.1":
+ version: 2.1.1
+ resolution: "ajv-formats@npm:2.1.1"
+ dependencies:
+ ajv: ^8.0.0
+ peerDependencies:
+ ajv: ^8.0.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+ checksum: 4a287d937f1ebaad4683249a4c40c0fa3beed30d9ddc0adba04859026a622da0d317851316ea64b3680dc60f5c3c708105ddd5d5db8fe595d9d0207fd19f90b7
+ languageName: node
+ linkType: hard
+
+"ajv-keywords@npm:^3.4.1, ajv-keywords@npm:^3.5.2":
+ version: 3.5.2
+ resolution: "ajv-keywords@npm:3.5.2"
+ peerDependencies:
+ ajv: ^6.9.1
+ checksum: 7dc5e5931677a680589050f79dcbe1fefbb8fea38a955af03724229139175b433c63c68f7ae5f86cf8f65d55eb7c25f75a046723e2e58296707617ca690feae9
+ languageName: node
+ linkType: hard
+
+"ajv-keywords@npm:^5.0.0":
+ version: 5.1.0
+ resolution: "ajv-keywords@npm:5.1.0"
+ dependencies:
+ fast-deep-equal: ^3.1.3
+ peerDependencies:
+ ajv: ^8.8.2
+ checksum: c35193940b853119242c6757787f09ecf89a2c19bcd36d03ed1a615e710d19d450cb448bfda407b939aba54b002368c8bff30529cc50a0536a8e10bcce300421
+ languageName: node
+ linkType: hard
+
+"ajv@npm:^6.12.2, ajv@npm:^6.12.4, ajv@npm:^6.12.5":
+ version: 6.12.6
+ resolution: "ajv@npm:6.12.6"
+ dependencies:
+ fast-deep-equal: ^3.1.1
+ fast-json-stable-stringify: ^2.0.0
+ json-schema-traverse: ^0.4.1
+ uri-js: ^4.2.2
+ checksum: 874972efe5c4202ab0a68379481fbd3d1b5d0a7bd6d3cc21d40d3536ebff3352a2a1fabb632d4fd2cc7fe4cbdcd5ed6782084c9bbf7f32a1536d18f9da5007d4
+ languageName: node
+ linkType: hard
+
+"ajv@npm:^8.0.0, ajv@npm:^8.8.0":
+ version: 8.11.2
+ resolution: "ajv@npm:8.11.2"
+ dependencies:
+ fast-deep-equal: ^3.1.1
+ json-schema-traverse: ^1.0.0
+ require-from-string: ^2.0.2
+ uri-js: ^4.2.2
+ checksum: 53435bf79ee7d1eabba8085962dba4c08d08593334b304db7772887f0b7beebc1b3d957432f7437ed4b60e53b5d966a57b439869890209c50fed610459999e3e
+ languageName: node
+ linkType: hard
+
+"algoliasearch-helper@npm:^3.10.0":
+ version: 3.11.1
+ resolution: "algoliasearch-helper@npm:3.11.1"
+ dependencies:
+ "@algolia/events": ^4.0.1
+ peerDependencies:
+ algoliasearch: ">= 3.1 < 6"
+ checksum: 207616ca4549e2d06a278357ce478951a37c606f40f5b39b8e2d13bba143023a10814f065cd89629e5f2c121935d61a97d96bfb687ae7a98ef25b63da37fcf70
+ languageName: node
+ linkType: hard
+
+"algoliasearch@npm:^4.0.0, algoliasearch@npm:^4.13.1":
+ version: 4.14.2
+ resolution: "algoliasearch@npm:4.14.2"
+ dependencies:
+ "@algolia/cache-browser-local-storage": 4.14.2
+ "@algolia/cache-common": 4.14.2
+ "@algolia/cache-in-memory": 4.14.2
+ "@algolia/client-account": 4.14.2
+ "@algolia/client-analytics": 4.14.2
+ "@algolia/client-common": 4.14.2
+ "@algolia/client-personalization": 4.14.2
+ "@algolia/client-search": 4.14.2
+ "@algolia/logger-common": 4.14.2
+ "@algolia/logger-console": 4.14.2
+ "@algolia/requester-browser-xhr": 4.14.2
+ "@algolia/requester-common": 4.14.2
+ "@algolia/requester-node-http": 4.14.2
+ "@algolia/transporter": 4.14.2
+ checksum: 4365a0d0f066f3ad6798e4dd0d7487cba1cf4546dac27e66cb84865f91955d6537dc5bad4e71d4bf22a68c0b721b1e6f20109203566ca1a252fe2713d713c0fd
+ languageName: node
+ linkType: hard
+
+"ansi-align@npm:^3.0.0, ansi-align@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "ansi-align@npm:3.0.1"
+ dependencies:
+ string-width: ^4.1.0
+ checksum: 6abfa08f2141d231c257162b15292467081fa49a208593e055c866aa0455b57f3a86b5a678c190c618faa79b4c59e254493099cb700dd9cf2293c6be2c8f5d8d
+ languageName: node
+ linkType: hard
+
+"ansi-html-community@npm:^0.0.8":
+ version: 0.0.8
+ resolution: "ansi-html-community@npm:0.0.8"
+ bin:
+ ansi-html: bin/ansi-html
+ checksum: 04c568e8348a636963f915e48eaa3e01218322e1169acafdd79c384f22e5558c003f79bbc480c1563865497482817c7eed025f0653ebc17642fededa5cb42089
+ languageName: node
+ linkType: hard
+
+"ansi-regex@npm:^5.0.1":
+ version: 5.0.1
+ resolution: "ansi-regex@npm:5.0.1"
+ checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b
+ languageName: node
+ linkType: hard
+
+"ansi-regex@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "ansi-regex@npm:6.0.1"
+ checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169
+ languageName: node
+ linkType: hard
+
+"ansi-styles@npm:^3.2.1":
+ version: 3.2.1
+ resolution: "ansi-styles@npm:3.2.1"
+ dependencies:
+ color-convert: ^1.9.0
+ checksum: d85ade01c10e5dd77b6c89f34ed7531da5830d2cb5882c645f330079975b716438cd7ebb81d0d6e6b4f9c577f19ae41ab55f07f19786b02f9dfd9e0377395665
+ languageName: node
+ linkType: hard
+
+"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0":
+ version: 4.3.0
+ resolution: "ansi-styles@npm:4.3.0"
+ dependencies:
+ color-convert: ^2.0.1
+ checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4
+ languageName: node
+ linkType: hard
+
+"ansi-styles@npm:^6.1.0":
+ version: 6.2.1
+ resolution: "ansi-styles@npm:6.2.1"
+ checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9
+ languageName: node
+ linkType: hard
+
+"anymatch@npm:~3.1.2":
+ version: 3.1.3
+ resolution: "anymatch@npm:3.1.3"
+ dependencies:
+ normalize-path: ^3.0.0
+ picomatch: ^2.0.4
+ checksum: 3e044fd6d1d26545f235a9fe4d7a534e2029d8e59fa7fd9f2a6eb21230f6b5380ea1eaf55136e60cbf8e613544b3b766e7a6fa2102e2a3a117505466e3025dc2
+ languageName: node
+ linkType: hard
+
+"aproba@npm:^1.0.3 || ^2.0.0":
+ version: 2.0.0
+ resolution: "aproba@npm:2.0.0"
+ checksum: 5615cadcfb45289eea63f8afd064ab656006361020e1735112e346593856f87435e02d8dcc7ff0d11928bc7d425f27bc7c2a84f6c0b35ab0ff659c814c138a24
+ languageName: node
+ linkType: hard
+
+"are-we-there-yet@npm:^3.0.0":
+ version: 3.0.1
+ resolution: "are-we-there-yet@npm:3.0.1"
+ dependencies:
+ delegates: ^1.0.0
+ readable-stream: ^3.6.0
+ checksum: 52590c24860fa7173bedeb69a4c05fb573473e860197f618b9a28432ee4379049336727ae3a1f9c4cb083114601c1140cee578376164d0e651217a9843f9fe83
+ languageName: node
+ linkType: hard
+
+"arg@npm:^5.0.0":
+ version: 5.0.2
+ resolution: "arg@npm:5.0.2"
+ checksum: 6c69ada1a9943d332d9e5382393e897c500908d91d5cb735a01120d5f71daf1b339b7b8980cbeaba8fd1afc68e658a739746179e4315a26e8a28951ff9930078
+ languageName: node
+ linkType: hard
+
+"argparse@npm:^1.0.7":
+ version: 1.0.10
+ resolution: "argparse@npm:1.0.10"
+ dependencies:
+ sprintf-js: ~1.0.2
+ checksum: 7ca6e45583a28de7258e39e13d81e925cfa25d7d4aacbf806a382d3c02fcb13403a07fb8aeef949f10a7cfe4a62da0e2e807b348a5980554cc28ee573ef95945
+ languageName: node
+ linkType: hard
+
+"argparse@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "argparse@npm:2.0.1"
+ checksum: 83644b56493e89a254bae05702abf3a1101b4fa4d0ca31df1c9985275a5a5bd47b3c27b7fa0b71098d41114d8ca000e6ed90cad764b306f8a503665e4d517ced
+ languageName: node
+ linkType: hard
+
+"array-flatten@npm:1.1.1":
+ version: 1.1.1
+ resolution: "array-flatten@npm:1.1.1"
+ checksum: a9925bf3512d9dce202112965de90c222cd59a4fbfce68a0951d25d965cf44642931f40aac72309c41f12df19afa010ecadceb07cfff9ccc1621e99d89ab5f3b
+ languageName: node
+ linkType: hard
+
+"array-flatten@npm:^2.1.2":
+ version: 2.1.2
+ resolution: "array-flatten@npm:2.1.2"
+ checksum: e8988aac1fbfcdaae343d08c9a06a6fddd2c6141721eeeea45c3cf523bf4431d29a46602929455ed548c7a3e0769928cdc630405427297e7081bd118fdec9262
+ languageName: node
+ linkType: hard
+
+"array-union@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "array-union@npm:2.1.0"
+ checksum: 5bee12395cba82da674931df6d0fea23c4aa4660cb3b338ced9f828782a65caa232573e6bf3968f23e0c5eb301764a382cef2f128b170a9dc59de0e36c39f98d
+ languageName: node
+ linkType: hard
+
+"asap@npm:~2.0.3":
+ version: 2.0.6
+ resolution: "asap@npm:2.0.6"
+ checksum: b296c92c4b969e973260e47523207cd5769abd27c245a68c26dc7a0fe8053c55bb04360237cb51cab1df52be939da77150ace99ad331fb7fb13b3423ed73ff3d
+ languageName: node
+ linkType: hard
+
+"at-least-node@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "at-least-node@npm:1.0.0"
+ checksum: 463e2f8e43384f1afb54bc68485c436d7622acec08b6fad269b421cb1d29cebb5af751426793d0961ed243146fe4dc983402f6d5a51b720b277818dbf6f2e49e
+ languageName: node
+ linkType: hard
+
+"autoprefixer@npm:^10.4.12, autoprefixer@npm:^10.4.7":
+ version: 10.4.13
+ resolution: "autoprefixer@npm:10.4.13"
+ dependencies:
+ browserslist: ^4.21.4
+ caniuse-lite: ^1.0.30001426
+ fraction.js: ^4.2.0
+ normalize-range: ^0.1.2
+ picocolors: ^1.0.0
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.1.0
+ bin:
+ autoprefixer: bin/autoprefixer
+ checksum: dcb1cb7ae96a3363d65d82e52f9a0a7d8c982256f6fd032d7e1ec311f099c23acfebfd517ff8e96bf93f716a66c4ea2b80c60aa19efd2f474ce434bd75ef7b79
+ languageName: node
+ linkType: hard
+
+"axios@npm:^0.25.0":
+ version: 0.25.0
+ resolution: "axios@npm:0.25.0"
+ dependencies:
+ follow-redirects: ^1.14.7
+ checksum: 2a8a3787c05f2a0c9c3878f49782357e2a9f38945b93018fb0c4fd788171c43dceefbb577988628e09fea53952744d1ecebde234b561f1e703aa43e0a598a3ad
+ languageName: node
+ linkType: hard
+
+"babel-loader@npm:^8.2.5":
+ version: 8.3.0
+ resolution: "babel-loader@npm:8.3.0"
+ dependencies:
+ find-cache-dir: ^3.3.1
+ loader-utils: ^2.0.0
+ make-dir: ^3.1.0
+ schema-utils: ^2.6.5
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ webpack: ">=2"
+ checksum: d48bcf9e030e598656ad3ff5fb85967db2eaaf38af5b4a4b99d25618a2057f9f100e6b231af2a46c1913206db506115ca7a8cbdf52c9c73d767070dae4352ab5
+ languageName: node
+ linkType: hard
+
+"babel-plugin-apply-mdx-type-prop@npm:1.6.22":
+ version: 1.6.22
+ resolution: "babel-plugin-apply-mdx-type-prop@npm:1.6.22"
+ dependencies:
+ "@babel/helper-plugin-utils": 7.10.4
+ "@mdx-js/util": 1.6.22
+ peerDependencies:
+ "@babel/core": ^7.11.6
+ checksum: 43e2100164a8f3e46fddd76afcbfb1f02cbebd5612cfe63f3d344a740b0afbdc4d2bf5659cffe9323dd2554c7b86b23ebedae9dadcec353b6594f4292a1a28e2
+ languageName: node
+ linkType: hard
+
+"babel-plugin-dynamic-import-node@npm:^2.3.3":
+ version: 2.3.3
+ resolution: "babel-plugin-dynamic-import-node@npm:2.3.3"
+ dependencies:
+ object.assign: ^4.1.0
+ checksum: c9d24415bcc608d0db7d4c8540d8002ac2f94e2573d2eadced137a29d9eab7e25d2cbb4bc6b9db65cf6ee7430f7dd011d19c911a9a778f0533b4a05ce8292c9b
+ languageName: node
+ linkType: hard
+
+"babel-plugin-extract-import-names@npm:1.6.22":
+ version: 1.6.22
+ resolution: "babel-plugin-extract-import-names@npm:1.6.22"
+ dependencies:
+ "@babel/helper-plugin-utils": 7.10.4
+ checksum: 145ccf09c96d36411d340e78086555f8d4d5924ea39fcb0eca461c066cfa98bc4344982bb35eb85d054ef88f8d4dfc0205ba27370c1d8fcc78191b02908d044d
+ languageName: node
+ linkType: hard
+
+"babel-plugin-polyfill-corejs2@npm:^0.3.3":
+ version: 0.3.3
+ resolution: "babel-plugin-polyfill-corejs2@npm:0.3.3"
+ dependencies:
+ "@babel/compat-data": ^7.17.7
+ "@babel/helper-define-polyfill-provider": ^0.3.3
+ semver: ^6.1.1
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 7db3044993f3dddb3cc3d407bc82e640964a3bfe22de05d90e1f8f7a5cb71460011ab136d3c03c6c1ba428359ebf635688cd6205e28d0469bba221985f5c6179
+ languageName: node
+ linkType: hard
+
+"babel-plugin-polyfill-corejs3@npm:^0.6.0":
+ version: 0.6.0
+ resolution: "babel-plugin-polyfill-corejs3@npm:0.6.0"
+ dependencies:
+ "@babel/helper-define-polyfill-provider": ^0.3.3
+ core-js-compat: ^3.25.1
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 470bb8c59f7c0912bd77fe1b5a2e72f349b3f65bbdee1d60d6eb7e1f4a085c6f24b2dd5ab4ac6c2df6444a96b070ef6790eccc9edb6a2668c60d33133bfb62c6
+ languageName: node
+ linkType: hard
+
+"babel-plugin-polyfill-regenerator@npm:^0.4.1":
+ version: 0.4.1
+ resolution: "babel-plugin-polyfill-regenerator@npm:0.4.1"
+ dependencies:
+ "@babel/helper-define-polyfill-provider": ^0.3.3
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: ab0355efbad17d29492503230387679dfb780b63b25408990d2e4cf421012dae61d6199ddc309f4d2409ce4e9d3002d187702700dd8f4f8770ebbba651ed066c
+ languageName: node
+ linkType: hard
+
+"backstage-microsite@workspace:.":
+ version: 0.0.0-use.local
+ resolution: "backstage-microsite@workspace:."
+ dependencies:
+ "@docusaurus/core": 2.2.0
+ "@docusaurus/preset-classic": 2.2.0
+ "@spotify/prettier-config": ^14.0.0
+ clsx: ^1.1.1
+ js-yaml: ^4.1.0
+ prettier: ^2.6.2
+ react: ^17.0.2
+ react-dom: ^17.0.2
+ languageName: unknown
+ linkType: soft
+
+"bail@npm:^1.0.0":
+ version: 1.0.5
+ resolution: "bail@npm:1.0.5"
+ checksum: 6c334940d7eaa4e656a12fb12407b6555649b6deb6df04270fa806e0da82684ebe4a4e47815b271c794b40f8d6fa286e0c248b14ddbabb324a917fab09b7301a
+ languageName: node
+ linkType: hard
+
+"balanced-match@npm:^1.0.0":
+ version: 1.0.2
+ resolution: "balanced-match@npm:1.0.2"
+ checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65
+ languageName: node
+ linkType: hard
+
+"base16@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "base16@npm:1.0.0"
+ checksum: 0cd449a2db0f0f957e4b6b57e33bc43c9e20d4f1dd744065db94b5da35e8e71fa4dc4bc7a901e59a84d5f8b6936e3c520e2471787f667fc155fb0f50d8540f5d
+ languageName: node
+ linkType: hard
+
+"batch@npm:0.6.1":
+ version: 0.6.1
+ resolution: "batch@npm:0.6.1"
+ checksum: 61f9934c7378a51dce61b915586191078ef7f1c3eca707fdd58b96ff2ff56d9e0af2bdab66b1462301a73c73374239e6542d9821c0af787f3209a23365d07e7f
+ languageName: node
+ linkType: hard
+
+"big.js@npm:^5.2.2":
+ version: 5.2.2
+ resolution: "big.js@npm:5.2.2"
+ checksum: b89b6e8419b097a8fb4ed2399a1931a68c612bce3cfd5ca8c214b2d017531191070f990598de2fc6f3f993d91c0f08aa82697717f6b3b8732c9731866d233c9e
+ languageName: node
+ linkType: hard
+
+"binary-extensions@npm:^2.0.0":
+ version: 2.2.0
+ resolution: "binary-extensions@npm:2.2.0"
+ checksum: ccd267956c58d2315f5d3ea6757cf09863c5fc703e50fbeb13a7dc849b812ef76e3cf9ca8f35a0c48498776a7478d7b4a0418e1e2b8cb9cb9731f2922aaad7f8
+ languageName: node
+ linkType: hard
+
+"body-parser@npm:1.20.1":
+ version: 1.20.1
+ resolution: "body-parser@npm:1.20.1"
+ dependencies:
+ bytes: 3.1.2
+ content-type: ~1.0.4
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
+ http-errors: 2.0.0
+ iconv-lite: 0.4.24
+ on-finished: 2.4.1
+ qs: 6.11.0
+ raw-body: 2.5.1
+ type-is: ~1.6.18
+ unpipe: 1.0.0
+ checksum: f1050dbac3bede6a78f0b87947a8d548ce43f91ccc718a50dd774f3c81f2d8b04693e52acf62659fad23101827dd318da1fb1363444ff9a8482b886a3e4a5266
+ languageName: node
+ linkType: hard
+
+"bonjour-service@npm:^1.0.11":
+ version: 1.0.14
+ resolution: "bonjour-service@npm:1.0.14"
+ dependencies:
+ array-flatten: ^2.1.2
+ dns-equal: ^1.0.0
+ fast-deep-equal: ^3.1.3
+ multicast-dns: ^7.2.5
+ checksum: 4a825bbf1824147ba8295a182fb3e86a8bae5159a08e2f118e829a0c988043a559f1f6e4eab425fe17ee9a1f080115d30430e78962e53f75bb03e2021ee7c5b2
+ languageName: node
+ linkType: hard
+
+"boolbase@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "boolbase@npm:1.0.0"
+ checksum: 3e25c80ef626c3a3487c73dbfc70ac322ec830666c9ad915d11b701142fab25ec1e63eff2c450c74347acfd2de854ccde865cd79ef4db1683f7c7b046ea43bb0
+ languageName: node
+ linkType: hard
+
+"boxen@npm:^5.0.0":
+ version: 5.1.2
+ resolution: "boxen@npm:5.1.2"
+ dependencies:
+ ansi-align: ^3.0.0
+ camelcase: ^6.2.0
+ chalk: ^4.1.0
+ cli-boxes: ^2.2.1
+ string-width: ^4.2.2
+ type-fest: ^0.20.2
+ widest-line: ^3.1.0
+ wrap-ansi: ^7.0.0
+ checksum: 82d03e42a72576ff235123f17b7c505372fe05c83f75f61e7d4fa4bcb393897ec95ce766fecb8f26b915f0f7a7227d66e5ec7cef43f5b2bd9d3aeed47ec55877
+ languageName: node
+ linkType: hard
+
+"boxen@npm:^6.2.1":
+ version: 6.2.1
+ resolution: "boxen@npm:6.2.1"
+ dependencies:
+ ansi-align: ^3.0.1
+ camelcase: ^6.2.0
+ chalk: ^4.1.2
+ cli-boxes: ^3.0.0
+ string-width: ^5.0.1
+ type-fest: ^2.5.0
+ widest-line: ^4.0.1
+ wrap-ansi: ^8.0.1
+ checksum: 2b3226092f1ff8e149c02979098c976552afa15f9e0231c9ed2dfcaaf84604494d16a6f13b647f718439f64d3140a088e822d47c7db00d2266e9ffc8d7321774
+ languageName: node
+ linkType: hard
+
+"brace-expansion@npm:^1.1.7":
+ version: 1.1.11
+ resolution: "brace-expansion@npm:1.1.11"
+ dependencies:
+ balanced-match: ^1.0.0
+ concat-map: 0.0.1
+ checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07
+ languageName: node
+ linkType: hard
+
+"brace-expansion@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "brace-expansion@npm:2.0.1"
+ dependencies:
+ balanced-match: ^1.0.0
+ checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1
+ languageName: node
+ linkType: hard
+
+"braces@npm:^3.0.2, braces@npm:~3.0.2":
+ version: 3.0.2
+ resolution: "braces@npm:3.0.2"
+ dependencies:
+ fill-range: ^7.0.1
+ checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459
+ languageName: node
+ linkType: hard
+
+"browserslist@npm:^4.0.0, browserslist@npm:^4.14.5, browserslist@npm:^4.16.6, browserslist@npm:^4.18.1, browserslist@npm:^4.21.3, browserslist@npm:^4.21.4":
+ version: 4.21.4
+ resolution: "browserslist@npm:4.21.4"
+ dependencies:
+ caniuse-lite: ^1.0.30001400
+ electron-to-chromium: ^1.4.251
+ node-releases: ^2.0.6
+ update-browserslist-db: ^1.0.9
+ bin:
+ browserslist: cli.js
+ checksum: 4af3793704dbb4615bcd29059ab472344dc7961c8680aa6c4bb84f05340e14038d06a5aead58724eae69455b8fade8b8c69f1638016e87e5578969d74c078b79
+ languageName: node
+ linkType: hard
+
+"buffer-from@npm:^1.0.0":
+ version: 1.1.2
+ resolution: "buffer-from@npm:1.1.2"
+ checksum: 0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb
+ languageName: node
+ linkType: hard
+
+"bytes@npm:3.0.0":
+ version: 3.0.0
+ resolution: "bytes@npm:3.0.0"
+ checksum: a2b386dd8188849a5325f58eef69c3b73c51801c08ffc6963eddc9be244089ba32d19347caf6d145c86f315ae1b1fc7061a32b0c1aa6379e6a719090287ed101
+ languageName: node
+ linkType: hard
+
+"bytes@npm:3.1.2":
+ version: 3.1.2
+ resolution: "bytes@npm:3.1.2"
+ checksum: e4bcd3948d289c5127591fbedf10c0b639ccbf00243504e4e127374a15c3bc8eed0d28d4aaab08ff6f1cf2abc0cce6ba3085ed32f4f90e82a5683ce0014e1b6e
+ languageName: node
+ linkType: hard
+
+"cacache@npm:^16.1.0":
+ version: 16.1.3
+ resolution: "cacache@npm:16.1.3"
+ dependencies:
+ "@npmcli/fs": ^2.1.0
+ "@npmcli/move-file": ^2.0.0
+ chownr: ^2.0.0
+ fs-minipass: ^2.1.0
+ glob: ^8.0.1
+ infer-owner: ^1.0.4
+ lru-cache: ^7.7.1
+ minipass: ^3.1.6
+ minipass-collect: ^1.0.2
+ minipass-flush: ^1.0.5
+ minipass-pipeline: ^1.2.4
+ mkdirp: ^1.0.4
+ p-map: ^4.0.0
+ promise-inflight: ^1.0.1
+ rimraf: ^3.0.2
+ ssri: ^9.0.0
+ tar: ^6.1.11
+ unique-filename: ^2.0.0
+ checksum: d91409e6e57d7d9a3a25e5dcc589c84e75b178ae8ea7de05cbf6b783f77a5fae938f6e8fda6f5257ed70000be27a681e1e44829251bfffe4c10216002f8f14e6
+ languageName: node
+ linkType: hard
+
+"cacheable-request@npm:^6.0.0":
+ version: 6.1.0
+ resolution: "cacheable-request@npm:6.1.0"
+ dependencies:
+ clone-response: ^1.0.2
+ get-stream: ^5.1.0
+ http-cache-semantics: ^4.0.0
+ keyv: ^3.0.0
+ lowercase-keys: ^2.0.0
+ normalize-url: ^4.1.0
+ responselike: ^1.0.2
+ checksum: b510b237b18d17e89942e9ee2d2a077cb38db03f12167fd100932dfa8fc963424bfae0bfa1598df4ae16c944a5484e43e03df8f32105b04395ee9495e9e4e9f1
+ languageName: node
+ linkType: hard
+
+"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "call-bind@npm:1.0.2"
+ dependencies:
+ function-bind: ^1.1.1
+ get-intrinsic: ^1.0.2
+ checksum: f8e31de9d19988a4b80f3e704788c4a2d6b6f3d17cfec4f57dc29ced450c53a49270dc66bf0fbd693329ee948dd33e6c90a329519aef17474a4d961e8d6426b0
+ languageName: node
+ linkType: hard
+
+"callsites@npm:^3.0.0":
+ version: 3.1.0
+ resolution: "callsites@npm:3.1.0"
+ checksum: 072d17b6abb459c2ba96598918b55868af677154bec7e73d222ef95a8fdb9bbf7dae96a8421085cdad8cd190d86653b5b6dc55a4484f2e5b2e27d5e0c3fc15b3
+ languageName: node
+ linkType: hard
+
+"camel-case@npm:^4.1.2":
+ version: 4.1.2
+ resolution: "camel-case@npm:4.1.2"
+ dependencies:
+ pascal-case: ^3.1.2
+ tslib: ^2.0.3
+ checksum: bcbd25cd253b3cbc69be3f535750137dbf2beb70f093bdc575f73f800acc8443d34fd52ab8f0a2413c34f1e8203139ffc88428d8863e4dfe530cfb257a379ad6
+ languageName: node
+ linkType: hard
+
+"camelcase-css@npm:2.0.1":
+ version: 2.0.1
+ resolution: "camelcase-css@npm:2.0.1"
+ checksum: 1cec2b3b3dcb5026688a470b00299a8db7d904c4802845c353dbd12d9d248d3346949a814d83bfd988d4d2e5b9904c07efe76fecd195a1d4f05b543e7c0b56b1
+ languageName: node
+ linkType: hard
+
+"camelcase@npm:^6.2.0":
+ version: 6.3.0
+ resolution: "camelcase@npm:6.3.0"
+ checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d
+ languageName: node
+ linkType: hard
+
+"caniuse-api@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "caniuse-api@npm:3.0.0"
+ dependencies:
+ browserslist: ^4.0.0
+ caniuse-lite: ^1.0.0
+ lodash.memoize: ^4.1.2
+ lodash.uniq: ^4.5.0
+ checksum: db2a229383b20d0529b6b589dde99d7b6cb56ba371366f58cbbfa2929c9f42c01f873e2b6ef641d4eda9f0b4118de77dbb2805814670bdad4234bf08e720b0b4
+ languageName: node
+ linkType: hard
+
+"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001400, caniuse-lite@npm:^1.0.30001426":
+ version: 1.0.30001439
+ resolution: "caniuse-lite@npm:1.0.30001439"
+ checksum: 3912dd536c9735713ca85e47721988bbcefb881ddb4886b0b9923fa984247fd22cba032cf268e57d158af0e8a2ae2eae042ae01942a1d6d7849fa9fa5d62fb82
+ languageName: node
+ linkType: hard
+
+"ccount@npm:^1.0.0":
+ version: 1.1.0
+ resolution: "ccount@npm:1.1.0"
+ checksum: b335a79d0aa4308919cf7507babcfa04ac63d389ebed49dbf26990d4607c8a4713cde93cc83e707d84571ddfe1e7615dad248be9bc422ae4c188210f71b08b78
+ languageName: node
+ linkType: hard
+
+"chalk@npm:^2.0.0":
+ version: 2.4.2
+ resolution: "chalk@npm:2.4.2"
+ dependencies:
+ ansi-styles: ^3.2.1
+ escape-string-regexp: ^1.0.5
+ supports-color: ^5.3.0
+ checksum: ec3661d38fe77f681200f878edbd9448821924e0f93a9cefc0e26a33b145f1027a2084bf19967160d11e1f03bfe4eaffcabf5493b89098b2782c3fe0b03d80c2
+ languageName: node
+ linkType: hard
+
+"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2":
+ version: 4.1.2
+ resolution: "chalk@npm:4.1.2"
+ dependencies:
+ ansi-styles: ^4.1.0
+ supports-color: ^7.1.0
+ checksum: fe75c9d5c76a7a98d45495b91b2172fa3b7a09e0cc9370e5c8feb1c567b85c4288e2b3fded7cfdd7359ac28d6b3844feb8b82b8686842e93d23c827c417e83fc
+ languageName: node
+ linkType: hard
+
+"character-entities-legacy@npm:^1.0.0":
+ version: 1.1.4
+ resolution: "character-entities-legacy@npm:1.1.4"
+ checksum: fe03a82c154414da3a0c8ab3188e4237ec68006cbcd681cf23c7cfb9502a0e76cd30ab69a2e50857ca10d984d57de3b307680fff5328ccd427f400e559c3a811
+ languageName: node
+ linkType: hard
+
+"character-entities@npm:^1.0.0":
+ version: 1.2.4
+ resolution: "character-entities@npm:1.2.4"
+ checksum: e1545716571ead57beac008433c1ff69517cd8ca5b336889321c5b8ff4a99c29b65589a701e9c086cda8a5e346a67295e2684f6c7ea96819fe85cbf49bf8686d
+ languageName: node
+ linkType: hard
+
+"character-reference-invalid@npm:^1.0.0":
+ version: 1.1.4
+ resolution: "character-reference-invalid@npm:1.1.4"
+ checksum: 20274574c70e05e2f81135f3b93285536bc8ff70f37f0809b0d17791a832838f1e49938382899ed4cb444e5bbd4314ca1415231344ba29f4222ce2ccf24fea0b
+ languageName: node
+ linkType: hard
+
+"cheerio-select@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "cheerio-select@npm:2.1.0"
+ dependencies:
+ boolbase: ^1.0.0
+ css-select: ^5.1.0
+ css-what: ^6.1.0
+ domelementtype: ^2.3.0
+ domhandler: ^5.0.3
+ domutils: ^3.0.1
+ checksum: 843d6d479922f28a6c5342c935aff1347491156814de63c585a6eb73baf7bb4185c1b4383a1195dca0f12e3946d737c7763bcef0b9544c515d905c5c44c5308b
+ languageName: node
+ linkType: hard
+
+"cheerio@npm:^1.0.0-rc.12":
+ version: 1.0.0-rc.12
+ resolution: "cheerio@npm:1.0.0-rc.12"
+ dependencies:
+ cheerio-select: ^2.1.0
+ dom-serializer: ^2.0.0
+ domhandler: ^5.0.3
+ domutils: ^3.0.1
+ htmlparser2: ^8.0.1
+ parse5: ^7.0.0
+ parse5-htmlparser2-tree-adapter: ^7.0.0
+ checksum: 5d4c1b7a53cf22d3a2eddc0aff70cf23cbb30d01a4c79013e703a012475c02461aa1fcd99127e8d83a02216386ed6942b2c8103845fd0812300dd199e6e7e054
+ languageName: node
+ linkType: hard
+
+"chokidar@npm:^3.4.2, chokidar@npm:^3.5.3":
+ version: 3.5.3
+ resolution: "chokidar@npm:3.5.3"
+ dependencies:
+ anymatch: ~3.1.2
+ braces: ~3.0.2
+ fsevents: ~2.3.2
+ glob-parent: ~5.1.2
+ is-binary-path: ~2.1.0
+ is-glob: ~4.0.1
+ normalize-path: ~3.0.0
+ readdirp: ~3.6.0
+ dependenciesMeta:
+ fsevents:
+ optional: true
+ checksum: b49fcde40176ba007ff361b198a2d35df60d9bb2a5aab228279eb810feae9294a6b4649ab15981304447afe1e6ffbf4788ad5db77235dc770ab777c6e771980c
+ languageName: node
+ linkType: hard
+
+"chownr@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "chownr@npm:2.0.0"
+ checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f
+ languageName: node
+ linkType: hard
+
+"chrome-trace-event@npm:^1.0.2":
+ version: 1.0.3
+ resolution: "chrome-trace-event@npm:1.0.3"
+ checksum: cb8b1fc7e881aaef973bd0c4a43cd353c2ad8323fb471a041e64f7c2dd849cde4aad15f8b753331a32dda45c973f032c8a03b8177fc85d60eaa75e91e08bfb97
+ languageName: node
+ linkType: hard
+
+"ci-info@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "ci-info@npm:2.0.0"
+ checksum: 3b374666a85ea3ca43fa49aa3a048d21c9b475c96eb13c133505d2324e7ae5efd6a454f41efe46a152269e9b6a00c9edbe63ec7fa1921957165aae16625acd67
+ languageName: node
+ linkType: hard
+
+"ci-info@npm:^3.2.0":
+ version: 3.7.0
+ resolution: "ci-info@npm:3.7.0"
+ checksum: 6e5df0250382ff3732703b36b958d2d892dd3c481f9671666f96c2ab7888be744bc4dca81395be958dcb828502d94f18fa9aa8901c5a3c9923cda212df02724c
+ languageName: node
+ linkType: hard
+
+"clean-css@npm:^5.2.2, clean-css@npm:^5.3.0":
+ version: 5.3.1
+ resolution: "clean-css@npm:5.3.1"
+ dependencies:
+ source-map: ~0.6.0
+ checksum: 860696c60503cbfec480b5f92f62729246304b55950571af7292f2687b57f86b277f2b9fefe6f64643d409008018b78383972b55c2cc859792dcc8658988fb16
+ languageName: node
+ linkType: hard
+
+"clean-stack@npm:^2.0.0":
+ version: 2.2.0
+ resolution: "clean-stack@npm:2.2.0"
+ checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68
+ languageName: node
+ linkType: hard
+
+"cli-boxes@npm:^2.2.1":
+ version: 2.2.1
+ resolution: "cli-boxes@npm:2.2.1"
+ checksum: be79f8ec23a558b49e01311b39a1ea01243ecee30539c880cf14bf518a12e223ef40c57ead0cb44f509bffdffc5c129c746cd50d863ab879385370112af4f585
+ languageName: node
+ linkType: hard
+
+"cli-boxes@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "cli-boxes@npm:3.0.0"
+ checksum: 637d84419d293a9eac40a1c8c96a2859e7d98b24a1a317788e13c8f441be052fc899480c6acab3acc82eaf1bccda6b7542d7cdcf5c9c3cc39227175dc098d5b2
+ languageName: node
+ linkType: hard
+
+"cli-table3@npm:^0.6.2":
+ version: 0.6.3
+ resolution: "cli-table3@npm:0.6.3"
+ dependencies:
+ "@colors/colors": 1.5.0
+ string-width: ^4.2.0
+ dependenciesMeta:
+ "@colors/colors":
+ optional: true
+ checksum: 09897f68467973f827c04e7eaadf13b55f8aec49ecd6647cc276386ea660059322e2dd8020a8b6b84d422dbdd619597046fa89cbbbdc95b2cea149a2df7c096c
+ languageName: node
+ linkType: hard
+
+"clone-deep@npm:^4.0.1":
+ version: 4.0.1
+ resolution: "clone-deep@npm:4.0.1"
+ dependencies:
+ is-plain-object: ^2.0.4
+ kind-of: ^6.0.2
+ shallow-clone: ^3.0.0
+ checksum: 770f912fe4e6f21873c8e8fbb1e99134db3b93da32df271d00589ea4a29dbe83a9808a322c93f3bcaf8584b8b4fa6fc269fc8032efbaa6728e0c9886c74467d2
+ languageName: node
+ linkType: hard
+
+"clone-response@npm:^1.0.2":
+ version: 1.0.3
+ resolution: "clone-response@npm:1.0.3"
+ dependencies:
+ mimic-response: ^1.0.0
+ checksum: 4e671cac39b11c60aa8ba0a450657194a5d6504df51bca3fac5b3bd0145c4f8e8464898f87c8406b83232e3bc5cca555f51c1f9c8ac023969ebfbf7f6bdabb2e
+ languageName: node
+ linkType: hard
+
+"clsx@npm:^1.1.1, clsx@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "clsx@npm:1.2.1"
+ checksum: 30befca8019b2eb7dbad38cff6266cf543091dae2825c856a62a8ccf2c3ab9c2907c4d12b288b73101196767f66812365400a227581484a05f968b0307cfaf12
+ languageName: node
+ linkType: hard
+
+"collapse-white-space@npm:^1.0.2":
+ version: 1.0.6
+ resolution: "collapse-white-space@npm:1.0.6"
+ checksum: 9673fb797952c5c888341435596c69388b22cd5560c8cd3f40edb72734a9c820f56a7c9525166bcb7068b5d5805372e6fd0c4b9f2869782ad070cb5d3faf26e7
+ languageName: node
+ linkType: hard
+
+"color-convert@npm:^1.9.0":
+ version: 1.9.3
+ resolution: "color-convert@npm:1.9.3"
+ dependencies:
+ color-name: 1.1.3
+ checksum: fd7a64a17cde98fb923b1dd05c5f2e6f7aefda1b60d67e8d449f9328b4e53b228a428fd38bfeaeb2db2ff6b6503a776a996150b80cdf224062af08a5c8a3a203
+ languageName: node
+ linkType: hard
+
+"color-convert@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "color-convert@npm:2.0.1"
+ dependencies:
+ color-name: ~1.1.4
+ checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336
+ languageName: node
+ linkType: hard
+
+"color-name@npm:1.1.3":
+ version: 1.1.3
+ resolution: "color-name@npm:1.1.3"
+ checksum: 09c5d3e33d2105850153b14466501f2bfb30324a2f76568a408763a3b7433b0e50e5b4ab1947868e65cb101bb7cb75029553f2c333b6d4b8138a73fcc133d69d
+ languageName: node
+ linkType: hard
+
+"color-name@npm:~1.1.4":
+ version: 1.1.4
+ resolution: "color-name@npm:1.1.4"
+ checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610
+ languageName: node
+ linkType: hard
+
+"color-support@npm:^1.1.3":
+ version: 1.1.3
+ resolution: "color-support@npm:1.1.3"
+ bin:
+ color-support: bin.js
+ checksum: 9b7356817670b9a13a26ca5af1c21615463b500783b739b7634a0c2047c16cef4b2865d7576875c31c3cddf9dd621fa19285e628f20198b233a5cfdda6d0793b
+ languageName: node
+ linkType: hard
+
+"colord@npm:^2.9.1":
+ version: 2.9.3
+ resolution: "colord@npm:2.9.3"
+ checksum: 95d909bfbcfd8d5605cbb5af56f2d1ce2b323990258fd7c0d2eb0e6d3bb177254d7fb8213758db56bb4ede708964f78c6b992b326615f81a18a6aaf11d64c650
+ languageName: node
+ linkType: hard
+
+"colorette@npm:^2.0.10":
+ version: 2.0.19
+ resolution: "colorette@npm:2.0.19"
+ checksum: 888cf5493f781e5fcf54ce4d49e9d7d698f96ea2b2ef67906834bb319a392c667f9ec69f4a10e268d2946d13a9503d2d19b3abaaaf174e3451bfe91fb9d82427
+ languageName: node
+ linkType: hard
+
+"combine-promises@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "combine-promises@npm:1.1.0"
+ checksum: 23b55f66d5cea3ddf39608c07f7a96065c7bb7cc4f54c7f217040771262ad97e808b30f7f267c553a9ca95552fc9813fb465232f5d82e190e118b33238186af8
+ languageName: node
+ linkType: hard
+
+"comma-separated-tokens@npm:^1.0.0":
+ version: 1.0.8
+ resolution: "comma-separated-tokens@npm:1.0.8"
+ checksum: 0adcb07174fa4d08cf0f5c8e3aec40a36b5ff0c2c720e5e23f50fe02e6789d1d00a67036c80e0c1e1539f41d3e7f0101b074039dd833b4e4a59031b659d6ca0d
+ languageName: node
+ linkType: hard
+
+"commander@npm:^2.20.0":
+ version: 2.20.3
+ resolution: "commander@npm:2.20.3"
+ checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e
+ languageName: node
+ linkType: hard
+
+"commander@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "commander@npm:5.1.0"
+ checksum: 0b7fec1712fbcc6230fcb161d8d73b4730fa91a21dc089515489402ad78810547683f058e2a9835929c212fead1d6a6ade70db28bbb03edbc2829a9ab7d69447
+ languageName: node
+ linkType: hard
+
+"commander@npm:^7.2.0":
+ version: 7.2.0
+ resolution: "commander@npm:7.2.0"
+ checksum: 53501cbeee61d5157546c0bef0fedb6cdfc763a882136284bed9a07225f09a14b82d2a84e7637edfd1a679fb35ed9502fd58ef1d091e6287f60d790147f68ddc
+ languageName: node
+ linkType: hard
+
+"commander@npm:^8.3.0":
+ version: 8.3.0
+ resolution: "commander@npm:8.3.0"
+ checksum: 0f82321821fc27b83bd409510bb9deeebcfa799ff0bf5d102128b500b7af22872c0c92cb6a0ebc5a4cf19c6b550fba9cedfa7329d18c6442a625f851377bacf0
+ languageName: node
+ linkType: hard
+
+"commondir@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "commondir@npm:1.0.1"
+ checksum: 59715f2fc456a73f68826285718503340b9f0dd89bfffc42749906c5cf3d4277ef11ef1cca0350d0e79204f00f1f6d83851ececc9095dc88512a697ac0b9bdcb
+ languageName: node
+ linkType: hard
+
+"compressible@npm:~2.0.16":
+ version: 2.0.18
+ resolution: "compressible@npm:2.0.18"
+ dependencies:
+ mime-db: ">= 1.43.0 < 2"
+ checksum: 58321a85b375d39230405654721353f709d0c1442129e9a17081771b816302a012471a9b8f4864c7dbe02eef7f2aaac3c614795197092262e94b409c9be108f0
+ languageName: node
+ linkType: hard
+
+"compression@npm:^1.7.4":
+ version: 1.7.4
+ resolution: "compression@npm:1.7.4"
+ dependencies:
+ accepts: ~1.3.5
+ bytes: 3.0.0
+ compressible: ~2.0.16
+ debug: 2.6.9
+ on-headers: ~1.0.2
+ safe-buffer: 5.1.2
+ vary: ~1.1.2
+ checksum: 35c0f2eb1f28418978615dc1bc02075b34b1568f7f56c62d60f4214d4b7cc00d0f6d282b5f8a954f59872396bd770b6b15ffd8aa94c67d4bce9b8887b906999b
+ languageName: node
+ linkType: hard
+
+"concat-map@npm:0.0.1":
+ version: 0.0.1
+ resolution: "concat-map@npm:0.0.1"
+ checksum: 902a9f5d8967a3e2faf138d5cb784b9979bad2e6db5357c5b21c568df4ebe62bcb15108af1b2253744844eb964fc023fbd9afbbbb6ddd0bcc204c6fb5b7bf3af
+ languageName: node
+ linkType: hard
+
+"configstore@npm:^5.0.1":
+ version: 5.0.1
+ resolution: "configstore@npm:5.0.1"
+ dependencies:
+ dot-prop: ^5.2.0
+ graceful-fs: ^4.1.2
+ make-dir: ^3.0.0
+ unique-string: ^2.0.0
+ write-file-atomic: ^3.0.0
+ xdg-basedir: ^4.0.0
+ checksum: 60ef65d493b63f96e14b11ba7ec072fdbf3d40110a94fb7199d1c287761bdea5c5244e76b2596325f30c1b652213aa75de96ea20afd4a5f82065e61ea090988e
+ languageName: node
+ linkType: hard
+
+"connect-history-api-fallback@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "connect-history-api-fallback@npm:2.0.0"
+ checksum: dc5368690f4a5c413889792f8df70d5941ca9da44523cde3f87af0745faee5ee16afb8195434550f0504726642734f2683d6c07f8b460f828a12c45fbd4c9a68
+ languageName: node
+ linkType: hard
+
+"consola@npm:^2.15.3":
+ version: 2.15.3
+ resolution: "consola@npm:2.15.3"
+ checksum: 8ef7a09b703ec67ac5c389a372a33b6dc97eda6c9876443a60d76a3076eea0259e7f67a4e54fd5a52f97df73690822d090cf8b7e102b5761348afef7c6d03e28
+ languageName: node
+ linkType: hard
+
+"console-control-strings@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "console-control-strings@npm:1.1.0"
+ checksum: 8755d76787f94e6cf79ce4666f0c5519906d7f5b02d4b884cf41e11dcd759ed69c57da0670afd9236d229a46e0f9cf519db0cd829c6dca820bb5a5c3def584ed
+ languageName: node
+ linkType: hard
+
+"content-disposition@npm:0.5.2":
+ version: 0.5.2
+ resolution: "content-disposition@npm:0.5.2"
+ checksum: 298d7da63255a38f7858ee19c7b6aae32b167e911293174b4c1349955e97e78e1d0b0d06c10e229405987275b417cf36ff65cbd4821a98bc9df4e41e9372cde7
+ languageName: node
+ linkType: hard
+
+"content-disposition@npm:0.5.4":
+ version: 0.5.4
+ resolution: "content-disposition@npm:0.5.4"
+ dependencies:
+ safe-buffer: 5.2.1
+ checksum: afb9d545e296a5171d7574fcad634b2fdf698875f4006a9dd04a3e1333880c5c0c98d47b560d01216fb6505a54a2ba6a843ee3a02ec86d7e911e8315255f56c3
+ languageName: node
+ linkType: hard
+
+"content-type@npm:~1.0.4":
+ version: 1.0.4
+ resolution: "content-type@npm:1.0.4"
+ checksum: 3d93585fda985d1554eca5ebd251994327608d2e200978fdbfba21c0c679914d5faf266d17027de44b34a72c7b0745b18584ecccaa7e1fdfb6a68ac7114f12e0
+ languageName: node
+ linkType: hard
+
+"convert-source-map@npm:^1.7.0":
+ version: 1.9.0
+ resolution: "convert-source-map@npm:1.9.0"
+ checksum: dc55a1f28ddd0e9485ef13565f8f756b342f9a46c4ae18b843fe3c30c675d058d6a4823eff86d472f187b176f0adf51ea7b69ea38be34be4a63cbbf91b0593c8
+ languageName: node
+ linkType: hard
+
+"cookie-signature@npm:1.0.6":
+ version: 1.0.6
+ resolution: "cookie-signature@npm:1.0.6"
+ checksum: f4e1b0a98a27a0e6e66fd7ea4e4e9d8e038f624058371bf4499cfcd8f3980be9a121486995202ba3fca74fbed93a407d6d54d43a43f96fd28d0bd7a06761591a
+ languageName: node
+ linkType: hard
+
+"cookie@npm:0.5.0":
+ version: 0.5.0
+ resolution: "cookie@npm:0.5.0"
+ checksum: 1f4bd2ca5765f8c9689a7e8954183f5332139eb72b6ff783d8947032ec1fdf43109852c178e21a953a30c0dd42257828185be01b49d1eb1a67fd054ca588a180
+ languageName: node
+ linkType: hard
+
+"copy-text-to-clipboard@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "copy-text-to-clipboard@npm:3.0.1"
+ checksum: 4c301b9a65c8bf337e26a74d28849096651697fac829a364c463df81ba5ddfeea0741214f9f1232832fffd229ebd5659d3abcccea3fe54d7010a22e515cc38bc
+ languageName: node
+ linkType: hard
+
+"copy-webpack-plugin@npm:^11.0.0":
+ version: 11.0.0
+ resolution: "copy-webpack-plugin@npm:11.0.0"
+ dependencies:
+ fast-glob: ^3.2.11
+ glob-parent: ^6.0.1
+ globby: ^13.1.1
+ normalize-path: ^3.0.0
+ schema-utils: ^4.0.0
+ serialize-javascript: ^6.0.0
+ peerDependencies:
+ webpack: ^5.1.0
+ checksum: df4f8743f003a29ee7dd3d9b1789998a3a99051c92afb2ba2203d3dacfa696f4e757b275560fafb8f206e520a0aa78af34b990324a0e36c2326cefdeef3ca82e
+ languageName: node
+ linkType: hard
+
+"core-js-compat@npm:^3.25.1":
+ version: 3.26.1
+ resolution: "core-js-compat@npm:3.26.1"
+ dependencies:
+ browserslist: ^4.21.4
+ checksum: f222bce0002eae405327d68286e1d566037e8ac21906a47d7ecd15858adca7b12e82140db11dc43c8cc1fc066c5306120f3c27bfb2d7dbc2d20a72a2d90d38dc
+ languageName: node
+ linkType: hard
+
+"core-js-pure@npm:^3.25.1":
+ version: 3.26.1
+ resolution: "core-js-pure@npm:3.26.1"
+ checksum: d88c40e5e29e413c11d1ef991a8d5b6a63f00bd94707af0f649d3fc18b3524108b202f4ae75ce77620a1557d1ba340bc3362b4f25d590eccc37cf80fc75f7cd4
+ languageName: node
+ linkType: hard
+
+"core-js@npm:^3.23.3":
+ version: 3.26.1
+ resolution: "core-js@npm:3.26.1"
+ checksum: 0a01149f51ff1e9f41d1ea49cc4c9222047949ea597189ede7c4cf8cde3b097766b9c7615acc77c86fe65b4002f20b638a133dfba7b41dba830d707aeeed45ad
+ languageName: node
+ linkType: hard
+
+"core-util-is@npm:~1.0.0":
+ version: 1.0.3
+ resolution: "core-util-is@npm:1.0.3"
+ checksum: 9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99
+ languageName: node
+ linkType: hard
+
+"cosmiconfig@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "cosmiconfig@npm:6.0.0"
+ dependencies:
+ "@types/parse-json": ^4.0.0
+ import-fresh: ^3.1.0
+ parse-json: ^5.0.0
+ path-type: ^4.0.0
+ yaml: ^1.7.2
+ checksum: 8eed7c854b91643ecb820767d0deb038b50780ecc3d53b0b19e03ed8aabed4ae77271198d1ae3d49c3b110867edf679f5faad924820a8d1774144a87cb6f98fc
+ languageName: node
+ linkType: hard
+
+"cosmiconfig@npm:^7.0.0, cosmiconfig@npm:^7.0.1":
+ version: 7.1.0
+ resolution: "cosmiconfig@npm:7.1.0"
+ dependencies:
+ "@types/parse-json": ^4.0.0
+ import-fresh: ^3.2.1
+ parse-json: ^5.0.0
+ path-type: ^4.0.0
+ yaml: ^1.10.0
+ checksum: c53bf7befc1591b2651a22414a5e786cd5f2eeaa87f3678a3d49d6069835a9d8d1aef223728e98aa8fec9a95bf831120d245096db12abe019fecb51f5696c96f
+ languageName: node
+ linkType: hard
+
+"cross-fetch@npm:^3.1.5":
+ version: 3.1.5
+ resolution: "cross-fetch@npm:3.1.5"
+ dependencies:
+ node-fetch: 2.6.7
+ checksum: f6b8c6ee3ef993ace6277fd789c71b6acf1b504fd5f5c7128df4ef2f125a429e29cd62dc8c127523f04a5f2fa4771ed80e3f3d9695617f441425045f505cf3bb
+ languageName: node
+ linkType: hard
+
+"cross-spawn@npm:^7.0.3":
+ version: 7.0.3
+ resolution: "cross-spawn@npm:7.0.3"
+ dependencies:
+ path-key: ^3.1.0
+ shebang-command: ^2.0.0
+ which: ^2.0.1
+ checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52
+ languageName: node
+ linkType: hard
+
+"crypto-random-string@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "crypto-random-string@npm:2.0.0"
+ checksum: 0283879f55e7c16fdceacc181f87a0a65c53bc16ffe1d58b9d19a6277adcd71900d02bb2c4843dd55e78c51e30e89b0fec618a7f170ebcc95b33182c28f05fd6
+ languageName: node
+ linkType: hard
+
+"css-declaration-sorter@npm:^6.3.1":
+ version: 6.3.1
+ resolution: "css-declaration-sorter@npm:6.3.1"
+ peerDependencies:
+ postcss: ^8.0.9
+ checksum: ff0d9989ee21ec4c42430b9bb86c43f973ed5024d68f30edc1e3fb07a22828ce3c3e5b922019f2ccbff606722e43c407c5c76e3cddac523ac4afcb31e4b2601c
+ languageName: node
+ linkType: hard
+
+"css-loader@npm:^6.7.1":
+ version: 6.7.2
+ resolution: "css-loader@npm:6.7.2"
+ dependencies:
+ icss-utils: ^5.1.0
+ postcss: ^8.4.18
+ postcss-modules-extract-imports: ^3.0.0
+ postcss-modules-local-by-default: ^4.0.0
+ postcss-modules-scope: ^3.0.0
+ postcss-modules-values: ^4.0.0
+ postcss-value-parser: ^4.2.0
+ semver: ^7.3.8
+ peerDependencies:
+ webpack: ^5.0.0
+ checksum: f3c980cc9c033a02e60df7e5a2f33a1e8c2c3dd552f017485d2d81b383be623ae8c4189404e7a4a7403b52744683ae4b516def0f7ccf125c2b198cb647e46543
+ languageName: node
+ linkType: hard
+
+"css-minimizer-webpack-plugin@npm:^4.0.0":
+ version: 4.2.2
+ resolution: "css-minimizer-webpack-plugin@npm:4.2.2"
+ dependencies:
+ cssnano: ^5.1.8
+ jest-worker: ^29.1.2
+ postcss: ^8.4.17
+ schema-utils: ^4.0.0
+ serialize-javascript: ^6.0.0
+ source-map: ^0.6.1
+ peerDependencies:
+ webpack: ^5.0.0
+ peerDependenciesMeta:
+ "@parcel/css":
+ optional: true
+ "@swc/css":
+ optional: true
+ clean-css:
+ optional: true
+ csso:
+ optional: true
+ esbuild:
+ optional: true
+ lightningcss:
+ optional: true
+ checksum: 5417e76a445f35832aa96807c835b8e92834a6cd285b1b788dfe3ca0fa90fec7eb2dd6efa9d3649f9d8244b99b7da2d065951603b94918e8f6a366a5049cacdd
+ languageName: node
+ linkType: hard
+
+"css-select@npm:^4.1.3":
+ version: 4.3.0
+ resolution: "css-select@npm:4.3.0"
+ dependencies:
+ boolbase: ^1.0.0
+ css-what: ^6.0.1
+ domhandler: ^4.3.1
+ domutils: ^2.8.0
+ nth-check: ^2.0.1
+ checksum: d6202736839194dd7f910320032e7cfc40372f025e4bf21ca5bf6eb0a33264f322f50ba9c0adc35dadd342d3d6fae5ca244779a4873afbfa76561e343f2058e0
+ languageName: node
+ linkType: hard
+
+"css-select@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "css-select@npm:5.1.0"
+ dependencies:
+ boolbase: ^1.0.0
+ css-what: ^6.1.0
+ domhandler: ^5.0.2
+ domutils: ^3.0.1
+ nth-check: ^2.0.1
+ checksum: 2772c049b188d3b8a8159907192e926e11824aea525b8282981f72ba3f349cf9ecd523fdf7734875ee2cb772246c22117fc062da105b6d59afe8dcd5c99c9bda
+ languageName: node
+ linkType: hard
+
+"css-tree@npm:^1.1.2, css-tree@npm:^1.1.3":
+ version: 1.1.3
+ resolution: "css-tree@npm:1.1.3"
+ dependencies:
+ mdn-data: 2.0.14
+ source-map: ^0.6.1
+ checksum: 79f9b81803991b6977b7fcb1588799270438274d89066ce08f117f5cdb5e20019b446d766c61506dd772c839df84caa16042d6076f20c97187f5abe3b50e7d1f
+ languageName: node
+ linkType: hard
+
+"css-what@npm:^6.0.1, css-what@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "css-what@npm:6.1.0"
+ checksum: b975e547e1e90b79625918f84e67db5d33d896e6de846c9b584094e529f0c63e2ab85ee33b9daffd05bff3a146a1916bec664e18bb76dd5f66cbff9fc13b2bbe
+ languageName: node
+ linkType: hard
+
+"cssesc@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "cssesc@npm:3.0.0"
+ bin:
+ cssesc: bin/cssesc
+ checksum: f8c4ababffbc5e2ddf2fa9957dda1ee4af6048e22aeda1869d0d00843223c1b13ad3f5d88b51caa46c994225eacb636b764eb807a8883e2fb6f99b4f4e8c48b2
+ languageName: node
+ linkType: hard
+
+"cssnano-preset-advanced@npm:^5.3.8":
+ version: 5.3.9
+ resolution: "cssnano-preset-advanced@npm:5.3.9"
+ dependencies:
+ autoprefixer: ^10.4.12
+ cssnano-preset-default: ^5.2.13
+ postcss-discard-unused: ^5.1.0
+ postcss-merge-idents: ^5.1.1
+ postcss-reduce-idents: ^5.2.0
+ postcss-zindex: ^5.1.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 094eb446107254b14f46257068376078c6daa0828c154df0a1d5cc6eabf13bd6015ce84be5de9c2cc34c60383dd27335c0496cecd1a30ce7557a6c5db4502d2d
+ languageName: node
+ linkType: hard
+
+"cssnano-preset-default@npm:^5.2.13":
+ version: 5.2.13
+ resolution: "cssnano-preset-default@npm:5.2.13"
+ dependencies:
+ css-declaration-sorter: ^6.3.1
+ cssnano-utils: ^3.1.0
+ postcss-calc: ^8.2.3
+ postcss-colormin: ^5.3.0
+ postcss-convert-values: ^5.1.3
+ postcss-discard-comments: ^5.1.2
+ postcss-discard-duplicates: ^5.1.0
+ postcss-discard-empty: ^5.1.1
+ postcss-discard-overridden: ^5.1.0
+ postcss-merge-longhand: ^5.1.7
+ postcss-merge-rules: ^5.1.3
+ postcss-minify-font-values: ^5.1.0
+ postcss-minify-gradients: ^5.1.1
+ postcss-minify-params: ^5.1.4
+ postcss-minify-selectors: ^5.2.1
+ postcss-normalize-charset: ^5.1.0
+ postcss-normalize-display-values: ^5.1.0
+ postcss-normalize-positions: ^5.1.1
+ postcss-normalize-repeat-style: ^5.1.1
+ postcss-normalize-string: ^5.1.0
+ postcss-normalize-timing-functions: ^5.1.0
+ postcss-normalize-unicode: ^5.1.1
+ postcss-normalize-url: ^5.1.0
+ postcss-normalize-whitespace: ^5.1.1
+ postcss-ordered-values: ^5.1.3
+ postcss-reduce-initial: ^5.1.1
+ postcss-reduce-transforms: ^5.1.0
+ postcss-svgo: ^5.1.0
+ postcss-unique-selectors: ^5.1.1
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: f773de44f67f71e7301e1f4b4664b894c3a48bba4dadc16c559acd0b14ceafed228bdc76fe19d500b0ded9394732377069daadff2184465fa369f8dfd72d47e2
+ languageName: node
+ linkType: hard
+
+"cssnano-utils@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "cssnano-utils@npm:3.1.0"
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 975c84ce9174cf23bb1da1e9faed8421954607e9ea76440cd3bb0c1bea7e17e490d800fca5ae2812d1d9e9d5524eef23ede0a3f52497d7ccc628e5d7321536f2
+ languageName: node
+ linkType: hard
+
+"cssnano@npm:^5.1.12, cssnano@npm:^5.1.8":
+ version: 5.1.14
+ resolution: "cssnano@npm:5.1.14"
+ dependencies:
+ cssnano-preset-default: ^5.2.13
+ lilconfig: ^2.0.3
+ yaml: ^1.10.2
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 73463c723c5e598b37b8b4d2f014145bd72133e6581349a1b154904e0830e58de17afb1e801ed3ea3b18e386883964ce4d0299e43d4dc37d339214a956c6697f
+ languageName: node
+ linkType: hard
+
+"csso@npm:^4.2.0":
+ version: 4.2.0
+ resolution: "csso@npm:4.2.0"
+ dependencies:
+ css-tree: ^1.1.2
+ checksum: 380ba9663da3bcea58dee358a0d8c4468bb6539be3c439dc266ac41c047217f52fd698fb7e4b6b6ccdfb8cf53ef4ceed8cc8ceccb8dfca2aa628319826b5b998
+ languageName: node
+ linkType: hard
+
+"csstype@npm:^3.0.2":
+ version: 3.1.1
+ resolution: "csstype@npm:3.1.1"
+ checksum: 1f7b4f5fdd955b7444b18ebdddf3f5c699159f13e9cf8ac9027ae4a60ae226aef9bbb14a6e12ca7dba3358b007cee6354b116e720262867c398de6c955ea451d
+ languageName: node
+ linkType: hard
+
+"debug@npm:2.6.9, debug@npm:^2.6.0":
+ version: 2.6.9
+ resolution: "debug@npm:2.6.9"
+ dependencies:
+ ms: 2.0.0
+ checksum: d2f51589ca66df60bf36e1fa6e4386b318c3f1e06772280eea5b1ae9fd3d05e9c2b7fd8a7d862457d00853c75b00451aa2d7459b924629ee385287a650f58fe6
+ languageName: node
+ linkType: hard
+
+"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.3":
+ version: 4.3.4
+ resolution: "debug@npm:4.3.4"
+ dependencies:
+ ms: 2.1.2
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708
+ languageName: node
+ linkType: hard
+
+"decompress-response@npm:^3.3.0":
+ version: 3.3.0
+ resolution: "decompress-response@npm:3.3.0"
+ dependencies:
+ mimic-response: ^1.0.0
+ checksum: 952552ac3bd7de2fc18015086b09468645c9638d98a551305e485230ada278c039c91116e946d07894b39ee53c0f0d5b6473f25a224029344354513b412d7380
+ languageName: node
+ linkType: hard
+
+"deep-extend@npm:^0.6.0":
+ version: 0.6.0
+ resolution: "deep-extend@npm:0.6.0"
+ checksum: 7be7e5a8d468d6b10e6a67c3de828f55001b6eb515d014f7aeb9066ce36bd5717161eb47d6a0f7bed8a9083935b465bc163ee2581c8b128d29bf61092fdf57a7
+ languageName: node
+ linkType: hard
+
+"deepmerge@npm:^4.2.2":
+ version: 4.2.2
+ resolution: "deepmerge@npm:4.2.2"
+ checksum: a8c43a1ed8d6d1ed2b5bf569fa4c8eb9f0924034baf75d5d406e47e157a451075c4db353efea7b6bcc56ec48116a8ce72fccf867b6e078e7c561904b5897530b
+ languageName: node
+ linkType: hard
+
+"default-gateway@npm:^6.0.3":
+ version: 6.0.3
+ resolution: "default-gateway@npm:6.0.3"
+ dependencies:
+ execa: ^5.0.0
+ checksum: 126f8273ecac8ee9ff91ea778e8784f6cd732d77c3157e8c5bdd6ed03651b5291f71446d05bc02d04073b1e67583604db5394ea3cf992ede0088c70ea15b7378
+ languageName: node
+ linkType: hard
+
+"defer-to-connect@npm:^1.0.1":
+ version: 1.1.3
+ resolution: "defer-to-connect@npm:1.1.3"
+ checksum: 9491b301dcfa04956f989481ba7a43c2231044206269eb4ab64a52d6639ee15b1252262a789eb4239fb46ab63e44d4e408641bae8e0793d640aee55398cb3930
+ languageName: node
+ linkType: hard
+
+"define-lazy-prop@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "define-lazy-prop@npm:2.0.0"
+ checksum: 0115fdb065e0490918ba271d7339c42453d209d4cb619dfe635870d906731eff3e1ade8028bb461ea27ce8264ec5e22c6980612d332895977e89c1bbc80fcee2
+ languageName: node
+ linkType: hard
+
+"define-properties@npm:^1.1.4":
+ version: 1.1.4
+ resolution: "define-properties@npm:1.1.4"
+ dependencies:
+ has-property-descriptors: ^1.0.0
+ object-keys: ^1.1.1
+ checksum: ce0aef3f9eb193562b5cfb79b2d2c86b6a109dfc9fdcb5f45d680631a1a908c06824ddcdb72b7573b54e26ace07f0a23420aaba0d5c627b34d2c1de8ef527e2b
+ languageName: node
+ linkType: hard
+
+"del@npm:^6.1.1":
+ version: 6.1.1
+ resolution: "del@npm:6.1.1"
+ dependencies:
+ globby: ^11.0.1
+ graceful-fs: ^4.2.4
+ is-glob: ^4.0.1
+ is-path-cwd: ^2.2.0
+ is-path-inside: ^3.0.2
+ p-map: ^4.0.0
+ rimraf: ^3.0.2
+ slash: ^3.0.0
+ checksum: 563288b73b8b19a7261c47fd21a330eeab6e2acd7c6208c49790dfd369127120dd7836cdf0c1eca216b77c94782a81507eac6b4734252d3bef2795cb366996b6
+ languageName: node
+ linkType: hard
+
+"delegates@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "delegates@npm:1.0.0"
+ checksum: a51744d9b53c164ba9c0492471a1a2ffa0b6727451bdc89e31627fdf4adda9d51277cfcbfb20f0a6f08ccb3c436f341df3e92631a3440226d93a8971724771fd
+ languageName: node
+ linkType: hard
+
+"depd@npm:2.0.0":
+ version: 2.0.0
+ resolution: "depd@npm:2.0.0"
+ checksum: abbe19c768c97ee2eed6282d8ce3031126662252c58d711f646921c9623f9052e3e1906443066beec1095832f534e57c523b7333f8e7e0d93051ab6baef5ab3a
+ languageName: node
+ linkType: hard
+
+"depd@npm:^1.1.2, depd@npm:~1.1.2":
+ version: 1.1.2
+ resolution: "depd@npm:1.1.2"
+ checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9
+ languageName: node
+ linkType: hard
+
+"destroy@npm:1.2.0":
+ version: 1.2.0
+ resolution: "destroy@npm:1.2.0"
+ checksum: 0acb300b7478a08b92d810ab229d5afe0d2f4399272045ab22affa0d99dbaf12637659411530a6fcd597a9bdac718fc94373a61a95b4651bbc7b83684a565e38
+ languageName: node
+ linkType: hard
+
+"detab@npm:2.0.4":
+ version: 2.0.4
+ resolution: "detab@npm:2.0.4"
+ dependencies:
+ repeat-string: ^1.5.4
+ checksum: 34b077521ecd4c6357d32ff7923be644d34aa6f6b7d717d40ec4a9168243eefaea2b512a75a460a6f70c31b0bbc31ff90f820a891803b4ddaf99e9d04d0d389d
+ languageName: node
+ linkType: hard
+
+"detect-node@npm:^2.0.4":
+ version: 2.1.0
+ resolution: "detect-node@npm:2.1.0"
+ checksum: 832184ec458353e41533ac9c622f16c19f7c02d8b10c303dfd3a756f56be93e903616c0bb2d4226183c9351c15fc0b3dba41a17a2308262afabcfa3776e6ae6e
+ languageName: node
+ linkType: hard
+
+"detect-port-alt@npm:^1.1.6":
+ version: 1.1.6
+ resolution: "detect-port-alt@npm:1.1.6"
+ dependencies:
+ address: ^1.0.1
+ debug: ^2.6.0
+ bin:
+ detect: ./bin/detect-port
+ detect-port: ./bin/detect-port
+ checksum: 9dc37b1fa4a9dd6d4889e1045849b8d841232b598d1ca888bf712f4035b07a17cf6d537465a0d7323250048d3a5a0540e3b7cf89457efc222f96f77e2c40d16a
+ languageName: node
+ linkType: hard
+
+"detect-port@npm:^1.3.0":
+ version: 1.5.1
+ resolution: "detect-port@npm:1.5.1"
+ dependencies:
+ address: ^1.0.1
+ debug: 4
+ bin:
+ detect: bin/detect-port.js
+ detect-port: bin/detect-port.js
+ checksum: b48da9340481742547263d5d985e65d078592557863402ecf538511735e83575867e94f91fe74405ea19b61351feb99efccae7e55de9a151d5654e3417cea05b
+ languageName: node
+ linkType: hard
+
+"dir-glob@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "dir-glob@npm:3.0.1"
+ dependencies:
+ path-type: ^4.0.0
+ checksum: fa05e18324510d7283f55862f3161c6759a3f2f8dbce491a2fc14c8324c498286c54282c1f0e933cb930da8419b30679389499b919122952a4f8592362ef4615
+ languageName: node
+ linkType: hard
+
+"dns-equal@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "dns-equal@npm:1.0.0"
+ checksum: a8471ac849c7c13824f053babea1bc26e2f359394dd5a460f8340d8abd13434be01e3327a5c59d212f8c8997817450efd3f3ac77bec709b21979cf0235644524
+ languageName: node
+ linkType: hard
+
+"dns-packet@npm:^5.2.2":
+ version: 5.4.0
+ resolution: "dns-packet@npm:5.4.0"
+ dependencies:
+ "@leichtgewicht/ip-codec": ^2.0.1
+ checksum: a169963848e8539dfd8a19058562f9e1c15c0f82cbf76fa98942f11c46f3c74e7e7c82e3a8a5182d4c9e6ff19e21be738dbd098a876dde755d3aedd2cc730880
+ languageName: node
+ linkType: hard
+
+"dom-converter@npm:^0.2.0":
+ version: 0.2.0
+ resolution: "dom-converter@npm:0.2.0"
+ dependencies:
+ utila: ~0.4
+ checksum: ea52fe303f5392e48dea563abef0e6fb3a478b8dbe3c599e99bb5d53981c6c38fc4944e56bb92a8ead6bb989d10b7914722ae11febbd2fd0910e33b9fc4aaa77
+ languageName: node
+ linkType: hard
+
+"dom-serializer@npm:^1.0.1":
+ version: 1.4.1
+ resolution: "dom-serializer@npm:1.4.1"
+ dependencies:
+ domelementtype: ^2.0.1
+ domhandler: ^4.2.0
+ entities: ^2.0.0
+ checksum: fbb0b01f87a8a2d18e6e5a388ad0f7ec4a5c05c06d219377da1abc7bb0f674d804f4a8a94e3f71ff15f6cb7dcfc75704a54b261db672b9b3ab03da6b758b0b22
+ languageName: node
+ linkType: hard
+
+"dom-serializer@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "dom-serializer@npm:2.0.0"
+ dependencies:
+ domelementtype: ^2.3.0
+ domhandler: ^5.0.2
+ entities: ^4.2.0
+ checksum: cd1810544fd8cdfbd51fa2c0c1128ec3a13ba92f14e61b7650b5de421b88205fd2e3f0cc6ace82f13334114addb90ed1c2f23074a51770a8e9c1273acbc7f3e6
+ languageName: node
+ linkType: hard
+
+"domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0, domelementtype@npm:^2.3.0":
+ version: 2.3.0
+ resolution: "domelementtype@npm:2.3.0"
+ checksum: ee837a318ff702622f383409d1f5b25dd1024b692ef64d3096ff702e26339f8e345820f29a68bcdcea8cfee3531776b3382651232fbeae95612d6f0a75efb4f6
+ languageName: node
+ linkType: hard
+
+"domhandler@npm:^4.0.0, domhandler@npm:^4.2.0, domhandler@npm:^4.3.1":
+ version: 4.3.1
+ resolution: "domhandler@npm:4.3.1"
+ dependencies:
+ domelementtype: ^2.2.0
+ checksum: 4c665ceed016e1911bf7d1dadc09dc888090b64dee7851cccd2fcf5442747ec39c647bb1cb8c8919f8bbdd0f0c625a6bafeeed4b2d656bbecdbae893f43ffaaa
+ languageName: node
+ linkType: hard
+
+"domhandler@npm:^5.0.1, domhandler@npm:^5.0.2, domhandler@npm:^5.0.3":
+ version: 5.0.3
+ resolution: "domhandler@npm:5.0.3"
+ dependencies:
+ domelementtype: ^2.3.0
+ checksum: 0f58f4a6af63e6f3a4320aa446d28b5790a009018707bce2859dcb1d21144c7876482b5188395a188dfa974238c019e0a1e610d2fc269a12b2c192ea2b0b131c
+ languageName: node
+ linkType: hard
+
+"domutils@npm:^2.5.2, domutils@npm:^2.8.0":
+ version: 2.8.0
+ resolution: "domutils@npm:2.8.0"
+ dependencies:
+ dom-serializer: ^1.0.1
+ domelementtype: ^2.2.0
+ domhandler: ^4.2.0
+ checksum: abf7434315283e9aadc2a24bac0e00eab07ae4313b40cc239f89d84d7315ebdfd2fb1b5bf750a96bc1b4403d7237c7b2ebf60459be394d625ead4ca89b934391
+ languageName: node
+ linkType: hard
+
+"domutils@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "domutils@npm:3.0.1"
+ dependencies:
+ dom-serializer: ^2.0.0
+ domelementtype: ^2.3.0
+ domhandler: ^5.0.1
+ checksum: 23aa7a840572d395220e173cb6263b0d028596e3950100520870a125af33ff819e6f609e1606d6f7d73bd9e7feb03bb404286e57a39063b5384c62b724d987b3
+ languageName: node
+ linkType: hard
+
+"dot-case@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "dot-case@npm:3.0.4"
+ dependencies:
+ no-case: ^3.0.4
+ tslib: ^2.0.3
+ checksum: a65e3519414856df0228b9f645332f974f2bf5433370f544a681122eab59e66038fc3349b4be1cdc47152779dac71a5864f1ccda2f745e767c46e9c6543b1169
+ languageName: node
+ linkType: hard
+
+"dot-prop@npm:^5.2.0":
+ version: 5.3.0
+ resolution: "dot-prop@npm:5.3.0"
+ dependencies:
+ is-obj: ^2.0.0
+ checksum: d5775790093c234ef4bfd5fbe40884ff7e6c87573e5339432870616331189f7f5d86575c5b5af2dcf0f61172990f4f734d07844b1f23482fff09e3c4bead05ea
+ languageName: node
+ linkType: hard
+
+"duplexer3@npm:^0.1.4":
+ version: 0.1.5
+ resolution: "duplexer3@npm:0.1.5"
+ checksum: e677cb4c48f031ca728601d6a20bf6aed4c629d69ef9643cb89c67583d673c4ec9317cc6427501f38bd8c368d3a18f173987cc02bd99d8cf8fe3d94259a22a20
+ languageName: node
+ linkType: hard
+
+"duplexer@npm:^0.1.2":
+ version: 0.1.2
+ resolution: "duplexer@npm:0.1.2"
+ checksum: 62ba61a830c56801db28ff6305c7d289b6dc9f859054e8c982abd8ee0b0a14d2e9a8e7d086ffee12e868d43e2bbe8a964be55ddbd8c8957714c87373c7a4f9b0
+ languageName: node
+ linkType: hard
+
+"eastasianwidth@npm:^0.2.0":
+ version: 0.2.0
+ resolution: "eastasianwidth@npm:0.2.0"
+ checksum: 7d00d7cd8e49b9afa762a813faac332dee781932d6f2c848dc348939c4253f1d4564341b7af1d041853bc3f32c2ef141b58e0a4d9862c17a7f08f68df1e0f1ed
+ languageName: node
+ linkType: hard
+
+"ee-first@npm:1.1.1":
+ version: 1.1.1
+ resolution: "ee-first@npm:1.1.1"
+ checksum: 1b4cac778d64ce3b582a7e26b218afe07e207a0f9bfe13cc7395a6d307849cfe361e65033c3251e00c27dd060cab43014c2d6b2647676135e18b77d2d05b3f4f
+ languageName: node
+ linkType: hard
+
+"electron-to-chromium@npm:^1.4.251":
+ version: 1.4.284
+ resolution: "electron-to-chromium@npm:1.4.284"
+ checksum: be496e9dca6509dbdbb54dc32146fc99f8eb716d28a7ee8ccd3eba0066561df36fc51418d8bd7cf5a5891810bf56c0def3418e74248f51ea4a843d423603d10a
+ languageName: node
+ linkType: hard
+
+"emoji-regex@npm:^8.0.0":
+ version: 8.0.0
+ resolution: "emoji-regex@npm:8.0.0"
+ checksum: d4c5c39d5a9868b5fa152f00cada8a936868fd3367f33f71be515ecee4c803132d11b31a6222b2571b1e5f7e13890156a94880345594d0ce7e3c9895f560f192
+ languageName: node
+ linkType: hard
+
+"emoji-regex@npm:^9.2.2":
+ version: 9.2.2
+ resolution: "emoji-regex@npm:9.2.2"
+ checksum: 8487182da74aabd810ac6d6f1994111dfc0e331b01271ae01ec1eb0ad7b5ecc2bbbbd2f053c05cb55a1ac30449527d819bbfbf0e3de1023db308cbcb47f86601
+ languageName: node
+ linkType: hard
+
+"emojis-list@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "emojis-list@npm:3.0.0"
+ checksum: ddaaa02542e1e9436c03970eeed445f4ed29a5337dfba0fe0c38dfdd2af5da2429c2a0821304e8a8d1cadf27fdd5b22ff793571fa803ae16852a6975c65e8e70
+ languageName: node
+ linkType: hard
+
+"emoticon@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "emoticon@npm:3.2.0"
+ checksum: f30649d18b672ab3139e95cb04f77b2442feb95c99dc59372ff80fbfd639b2bf4018bc68ab0b549bd765aecf8230d7899c43f86cfcc7b6370c06c3232783e24f
+ languageName: node
+ linkType: hard
+
+"encodeurl@npm:~1.0.2":
+ version: 1.0.2
+ resolution: "encodeurl@npm:1.0.2"
+ checksum: e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c
+ languageName: node
+ linkType: hard
+
+"encoding@npm:^0.1.13":
+ version: 0.1.13
+ resolution: "encoding@npm:0.1.13"
+ dependencies:
+ iconv-lite: ^0.6.2
+ checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f
+ languageName: node
+ linkType: hard
+
+"end-of-stream@npm:^1.1.0":
+ version: 1.4.4
+ resolution: "end-of-stream@npm:1.4.4"
+ dependencies:
+ once: ^1.4.0
+ checksum: 530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b
+ languageName: node
+ linkType: hard
+
+"enhanced-resolve@npm:^5.10.0":
+ version: 5.12.0
+ resolution: "enhanced-resolve@npm:5.12.0"
+ dependencies:
+ graceful-fs: ^4.2.4
+ tapable: ^2.2.0
+ checksum: bf3f787facaf4ce3439bef59d148646344e372bef5557f0d37ea8aa02c51f50a925cd1f07b8d338f18992c29f544ec235a8c64bcdb56030196c48832a5494174
+ languageName: node
+ linkType: hard
+
+"entities@npm:^2.0.0":
+ version: 2.2.0
+ resolution: "entities@npm:2.2.0"
+ checksum: 19010dacaf0912c895ea262b4f6128574f9ccf8d4b3b65c7e8334ad0079b3706376360e28d8843ff50a78aabcb8f08f0a32dbfacdc77e47ed77ca08b713669b3
+ languageName: node
+ linkType: hard
+
+"entities@npm:^4.2.0, entities@npm:^4.3.0, entities@npm:^4.4.0":
+ version: 4.4.0
+ resolution: "entities@npm:4.4.0"
+ checksum: 84d250329f4b56b40fa93ed067b194db21e8815e4eb9b59f43a086f0ecd342814f6bc483de8a77da5d64e0f626033192b1b4f1792232a7ea6b970ebe0f3187c2
+ languageName: node
+ linkType: hard
+
+"env-paths@npm:^2.2.0":
+ version: 2.2.1
+ resolution: "env-paths@npm:2.2.1"
+ checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e
+ languageName: node
+ linkType: hard
+
+"err-code@npm:^2.0.2":
+ version: 2.0.3
+ resolution: "err-code@npm:2.0.3"
+ checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54
+ languageName: node
+ linkType: hard
+
+"error-ex@npm:^1.3.1":
+ version: 1.3.2
+ resolution: "error-ex@npm:1.3.2"
+ dependencies:
+ is-arrayish: ^0.2.1
+ checksum: c1c2b8b65f9c91b0f9d75f0debaa7ec5b35c266c2cac5de412c1a6de86d4cbae04ae44e510378cb14d032d0645a36925d0186f8bb7367bcc629db256b743a001
+ languageName: node
+ linkType: hard
+
+"es-module-lexer@npm:^0.9.0":
+ version: 0.9.3
+ resolution: "es-module-lexer@npm:0.9.3"
+ checksum: 84bbab23c396281db2c906c766af58b1ae2a1a2599844a504df10b9e8dc77ec800b3211fdaa133ff700f5703d791198807bba25d9667392d27a5e9feda344da8
+ languageName: node
+ linkType: hard
+
+"escalade@npm:^3.1.1":
+ version: 3.1.1
+ resolution: "escalade@npm:3.1.1"
+ checksum: a3e2a99f07acb74b3ad4989c48ca0c3140f69f923e56d0cba0526240ee470b91010f9d39001f2a4a313841d237ede70a729e92125191ba5d21e74b106800b133
+ languageName: node
+ linkType: hard
+
+"escape-goat@npm:^2.0.0":
+ version: 2.1.1
+ resolution: "escape-goat@npm:2.1.1"
+ checksum: ce05c70c20dd7007b60d2d644b625da5412325fdb57acf671ba06cb2ab3cd6789e2087026921a05b665b0a03fadee2955e7fc0b9a67da15a6551a980b260eba7
+ languageName: node
+ linkType: hard
+
+"escape-html@npm:^1.0.3, escape-html@npm:~1.0.3":
+ version: 1.0.3
+ resolution: "escape-html@npm:1.0.3"
+ checksum: 6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24
+ languageName: node
+ linkType: hard
+
+"escape-string-regexp@npm:^1.0.5":
+ version: 1.0.5
+ resolution: "escape-string-regexp@npm:1.0.5"
+ checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410
+ languageName: node
+ linkType: hard
+
+"escape-string-regexp@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "escape-string-regexp@npm:4.0.0"
+ checksum: 98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5
+ languageName: node
+ linkType: hard
+
+"eslint-scope@npm:5.1.1":
+ version: 5.1.1
+ resolution: "eslint-scope@npm:5.1.1"
+ dependencies:
+ esrecurse: ^4.3.0
+ estraverse: ^4.1.1
+ checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb
+ languageName: node
+ linkType: hard
+
+"esprima@npm:^4.0.0":
+ version: 4.0.1
+ resolution: "esprima@npm:4.0.1"
+ bin:
+ esparse: ./bin/esparse.js
+ esvalidate: ./bin/esvalidate.js
+ checksum: b45bc805a613dbea2835278c306b91aff6173c8d034223fa81498c77dcbce3b2931bf6006db816f62eacd9fd4ea975dfd85a5b7f3c6402cfd050d4ca3c13a628
+ languageName: node
+ linkType: hard
+
+"esrecurse@npm:^4.3.0":
+ version: 4.3.0
+ resolution: "esrecurse@npm:4.3.0"
+ dependencies:
+ estraverse: ^5.2.0
+ checksum: ebc17b1a33c51cef46fdc28b958994b1dc43cd2e86237515cbc3b4e5d2be6a811b2315d0a1a4d9d340b6d2308b15322f5c8291059521cc5f4802f65e7ec32837
+ languageName: node
+ linkType: hard
+
+"estraverse@npm:^4.1.1":
+ version: 4.3.0
+ resolution: "estraverse@npm:4.3.0"
+ checksum: a6299491f9940bb246124a8d44b7b7a413a8336f5436f9837aaa9330209bd9ee8af7e91a654a3545aee9c54b3308e78ee360cef1d777d37cfef77d2fa33b5827
+ languageName: node
+ linkType: hard
+
+"estraverse@npm:^5.2.0":
+ version: 5.3.0
+ resolution: "estraverse@npm:5.3.0"
+ checksum: 072780882dc8416ad144f8fe199628d2b3e7bbc9989d9ed43795d2c90309a2047e6bc5979d7e2322a341163d22cfad9e21f4110597fe487519697389497e4e2b
+ languageName: node
+ linkType: hard
+
+"esutils@npm:^2.0.2":
+ version: 2.0.3
+ resolution: "esutils@npm:2.0.3"
+ checksum: 22b5b08f74737379a840b8ed2036a5fb35826c709ab000683b092d9054e5c2a82c27818f12604bfc2a9a76b90b6834ef081edbc1c7ae30d1627012e067c6ec87
+ languageName: node
+ linkType: hard
+
+"eta@npm:^1.12.3":
+ version: 1.12.3
+ resolution: "eta@npm:1.12.3"
+ checksum: 390c1cd320755cb98fd5a4a911539e8ed498fc49b82414f0023033ff606d80a34e6df0aeeb9fb0b519b318a750e6d17a72fc25f8a8c686cfc52d638e998237a1
+ languageName: node
+ linkType: hard
+
+"etag@npm:~1.8.1":
+ version: 1.8.1
+ resolution: "etag@npm:1.8.1"
+ checksum: 571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff
+ languageName: node
+ linkType: hard
+
+"eval@npm:^0.1.8":
+ version: 0.1.8
+ resolution: "eval@npm:0.1.8"
+ dependencies:
+ "@types/node": "*"
+ require-like: ">= 0.1.1"
+ checksum: d005567f394cfbe60948e34982e4637d2665030f9aa7dcac581ea6f9ec6eceb87133ed3dc0ae21764aa362485c242a731dbb6371f1f1a86807c58676431e9d1a
+ languageName: node
+ linkType: hard
+
+"eventemitter3@npm:^4.0.0":
+ version: 4.0.7
+ resolution: "eventemitter3@npm:4.0.7"
+ checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374
+ languageName: node
+ linkType: hard
+
+"events@npm:^3.2.0":
+ version: 3.3.0
+ resolution: "events@npm:3.3.0"
+ checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780
+ languageName: node
+ linkType: hard
+
+"execa@npm:^5.0.0":
+ version: 5.1.1
+ resolution: "execa@npm:5.1.1"
+ dependencies:
+ cross-spawn: ^7.0.3
+ get-stream: ^6.0.0
+ human-signals: ^2.1.0
+ is-stream: ^2.0.0
+ merge-stream: ^2.0.0
+ npm-run-path: ^4.0.1
+ onetime: ^5.1.2
+ signal-exit: ^3.0.3
+ strip-final-newline: ^2.0.0
+ checksum: fba9022c8c8c15ed862847e94c252b3d946036d7547af310e344a527e59021fd8b6bb0723883ea87044dc4f0201f949046993124a42ccb0855cae5bf8c786343
+ languageName: node
+ linkType: hard
+
+"express@npm:^4.17.3":
+ version: 4.18.2
+ resolution: "express@npm:4.18.2"
+ dependencies:
+ accepts: ~1.3.8
+ array-flatten: 1.1.1
+ body-parser: 1.20.1
+ content-disposition: 0.5.4
+ content-type: ~1.0.4
+ cookie: 0.5.0
+ cookie-signature: 1.0.6
+ debug: 2.6.9
+ depd: 2.0.0
+ encodeurl: ~1.0.2
+ escape-html: ~1.0.3
+ etag: ~1.8.1
+ finalhandler: 1.2.0
+ fresh: 0.5.2
+ http-errors: 2.0.0
+ merge-descriptors: 1.0.1
+ methods: ~1.1.2
+ on-finished: 2.4.1
+ parseurl: ~1.3.3
+ path-to-regexp: 0.1.7
+ proxy-addr: ~2.0.7
+ qs: 6.11.0
+ range-parser: ~1.2.1
+ safe-buffer: 5.2.1
+ send: 0.18.0
+ serve-static: 1.15.0
+ setprototypeof: 1.2.0
+ statuses: 2.0.1
+ type-is: ~1.6.18
+ utils-merge: 1.0.1
+ vary: ~1.1.2
+ checksum: 3c4b9b076879442f6b968fe53d85d9f1eeacbb4f4c41e5f16cc36d77ce39a2b0d81b3f250514982110d815b2f7173f5561367f9110fcc541f9371948e8c8b037
+ languageName: node
+ linkType: hard
+
+"extend-shallow@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "extend-shallow@npm:2.0.1"
+ dependencies:
+ is-extendable: ^0.1.0
+ checksum: 8fb58d9d7a511f4baf78d383e637bd7d2e80843bd9cd0853649108ea835208fb614da502a553acc30208e1325240bb7cc4a68473021612496bb89725483656d8
+ languageName: node
+ linkType: hard
+
+"extend@npm:^3.0.0":
+ version: 3.0.2
+ resolution: "extend@npm:3.0.2"
+ checksum: a50a8309ca65ea5d426382ff09f33586527882cf532931cb08ca786ea3146c0553310bda688710ff61d7668eba9f96b923fe1420cdf56a2c3eaf30fcab87b515
+ languageName: node
+ linkType: hard
+
+"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3":
+ version: 3.1.3
+ resolution: "fast-deep-equal@npm:3.1.3"
+ checksum: e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d
+ languageName: node
+ linkType: hard
+
+"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.9":
+ version: 3.2.12
+ resolution: "fast-glob@npm:3.2.12"
+ dependencies:
+ "@nodelib/fs.stat": ^2.0.2
+ "@nodelib/fs.walk": ^1.2.3
+ glob-parent: ^5.1.2
+ merge2: ^1.3.0
+ micromatch: ^4.0.4
+ checksum: 0b1990f6ce831c7e28c4d505edcdaad8e27e88ab9fa65eedadb730438cfc7cde4910d6c975d6b7b8dc8a73da4773702ebcfcd6e3518e73938bb1383badfe01c2
+ languageName: node
+ linkType: hard
+
+"fast-json-stable-stringify@npm:^2.0.0":
+ version: 2.1.0
+ resolution: "fast-json-stable-stringify@npm:2.1.0"
+ checksum: b191531e36c607977e5b1c47811158733c34ccb3bfde92c44798929e9b4154884378536d26ad90dfecd32e1ffc09c545d23535ad91b3161a27ddbb8ebe0cbecb
+ languageName: node
+ linkType: hard
+
+"fast-url-parser@npm:1.1.3":
+ version: 1.1.3
+ resolution: "fast-url-parser@npm:1.1.3"
+ dependencies:
+ punycode: ^1.3.2
+ checksum: 5043d0c4a8d775ff58504d56c096563c11b113e4cb8a2668c6f824a1cd4fb3812e2fdf76537eb24a7ce4ae7def6bd9747da630c617cf2a4b6ce0c42514e4f21c
+ languageName: node
+ linkType: hard
+
+"fastq@npm:^1.6.0":
+ version: 1.14.0
+ resolution: "fastq@npm:1.14.0"
+ dependencies:
+ reusify: ^1.0.4
+ checksum: da2c05ec1446ef77b8ba2b76619c90d483404f5087e71e77469fbee797280a1f4ef26a63be15b2377198bc20d09fdf25c7d6e1e492a1e568a29dfdd9bcb7538c
+ languageName: node
+ linkType: hard
+
+"faye-websocket@npm:^0.11.3":
+ version: 0.11.4
+ resolution: "faye-websocket@npm:0.11.4"
+ dependencies:
+ websocket-driver: ">=0.5.1"
+ checksum: d49a62caf027f871149fc2b3f3c7104dc6d62744277eb6f9f36e2d5714e847d846b9f7f0d0b7169b25a012e24a594cde11a93034b30732e4c683f20b8a5019fa
+ languageName: node
+ linkType: hard
+
+"fbemitter@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "fbemitter@npm:3.0.0"
+ dependencies:
+ fbjs: ^3.0.0
+ checksum: 069690b8cdff3521ade3c9beb92ba0a38d818a86ef36dff8690e66749aef58809db4ac0d6938eb1cacea2dbef5f2a508952d455669590264cdc146bbe839f605
+ languageName: node
+ linkType: hard
+
+"fbjs-css-vars@npm:^1.0.0":
+ version: 1.0.2
+ resolution: "fbjs-css-vars@npm:1.0.2"
+ checksum: 72baf6d22c45b75109118b4daecb6c8016d4c83c8c0f23f683f22e9d7c21f32fff6201d288df46eb561e3c7d4bb4489b8ad140b7f56444c453ba407e8bd28511
+ languageName: node
+ linkType: hard
+
+"fbjs@npm:^3.0.0, fbjs@npm:^3.0.1":
+ version: 3.0.4
+ resolution: "fbjs@npm:3.0.4"
+ dependencies:
+ cross-fetch: ^3.1.5
+ fbjs-css-vars: ^1.0.0
+ loose-envify: ^1.0.0
+ object-assign: ^4.1.0
+ promise: ^7.1.1
+ setimmediate: ^1.0.5
+ ua-parser-js: ^0.7.30
+ checksum: 8b23a3550fcda8a9109fca9475a3416590c18bb6825ea884192864ed686f67fcd618e308a140c9e5444fbd0168732e1ff3c092ba3d0c0ae1768969f32ba280c7
+ languageName: node
+ linkType: hard
+
+"feed@npm:^4.2.2":
+ version: 4.2.2
+ resolution: "feed@npm:4.2.2"
+ dependencies:
+ xml-js: ^1.6.11
+ checksum: 2e6992a675a049511eef7bda8ca6c08cb9540cd10e8b275ec4c95d166228ec445a335fa8de990358759f248a92861e51decdcd32bf1c54737d5b7aed7c7ffe97
+ languageName: node
+ linkType: hard
+
+"file-loader@npm:^6.2.0":
+ version: 6.2.0
+ resolution: "file-loader@npm:6.2.0"
+ dependencies:
+ loader-utils: ^2.0.0
+ schema-utils: ^3.0.0
+ peerDependencies:
+ webpack: ^4.0.0 || ^5.0.0
+ checksum: faf43eecf233f4897b0150aaa874eeeac214e4f9de49738a9e0ef734a30b5260059e85b7edadf852b98e415f875bd5f12587768a93fd52aaf2e479ecf95fab20
+ languageName: node
+ linkType: hard
+
+"filesize@npm:^8.0.6":
+ version: 8.0.7
+ resolution: "filesize@npm:8.0.7"
+ checksum: 8603d27c5287b984cb100733640645e078f5f5ad65c6d913173e01fb99e09b0747828498fd86647685ccecb69be31f3587b9739ab1e50732116b2374aff4cbf9
+ languageName: node
+ linkType: hard
+
+"fill-range@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "fill-range@npm:7.0.1"
+ dependencies:
+ to-regex-range: ^5.0.1
+ checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917
+ languageName: node
+ linkType: hard
+
+"finalhandler@npm:1.2.0":
+ version: 1.2.0
+ resolution: "finalhandler@npm:1.2.0"
+ dependencies:
+ debug: 2.6.9
+ encodeurl: ~1.0.2
+ escape-html: ~1.0.3
+ on-finished: 2.4.1
+ parseurl: ~1.3.3
+ statuses: 2.0.1
+ unpipe: ~1.0.0
+ checksum: 92effbfd32e22a7dff2994acedbd9bcc3aa646a3e919ea6a53238090e87097f8ef07cced90aa2cc421abdf993aefbdd5b00104d55c7c5479a8d00ed105b45716
+ languageName: node
+ linkType: hard
+
+"find-cache-dir@npm:^3.3.1":
+ version: 3.3.2
+ resolution: "find-cache-dir@npm:3.3.2"
+ dependencies:
+ commondir: ^1.0.1
+ make-dir: ^3.0.2
+ pkg-dir: ^4.1.0
+ checksum: 1e61c2e64f5c0b1c535bd85939ae73b0e5773142713273818cc0b393ee3555fb0fd44e1a5b161b8b6c3e03e98c2fcc9c227d784850a13a90a8ab576869576817
+ languageName: node
+ linkType: hard
+
+"find-up@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "find-up@npm:3.0.0"
+ dependencies:
+ locate-path: ^3.0.0
+ checksum: 38eba3fe7a66e4bc7f0f5a1366dc25508b7cfc349f852640e3678d26ad9a6d7e2c43eff0a472287de4a9753ef58f066a0ea892a256fa3636ad51b3fe1e17fae9
+ languageName: node
+ linkType: hard
+
+"find-up@npm:^4.0.0":
+ version: 4.1.0
+ resolution: "find-up@npm:4.1.0"
+ dependencies:
+ locate-path: ^5.0.0
+ path-exists: ^4.0.0
+ checksum: 4c172680e8f8c1f78839486e14a43ef82e9decd0e74145f40707cc42e7420506d5ec92d9a11c22bd2c48fb0c384ea05dd30e10dd152fefeec6f2f75282a8b844
+ languageName: node
+ linkType: hard
+
+"find-up@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "find-up@npm:5.0.0"
+ dependencies:
+ locate-path: ^6.0.0
+ path-exists: ^4.0.0
+ checksum: 07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095
+ languageName: node
+ linkType: hard
+
+"flux@npm:^4.0.1":
+ version: 4.0.3
+ resolution: "flux@npm:4.0.3"
+ dependencies:
+ fbemitter: ^3.0.0
+ fbjs: ^3.0.1
+ peerDependencies:
+ react: ^15.0.2 || ^16.0.0 || ^17.0.0
+ checksum: 6b3f5150bcce481ce5bc09e54dbe4bf2a052f9fbc04c1de64f8d816adc4f90ad7955d9aed0022c7b6a2ed11b809ac40527bb50c2cd89c23d42f56694abe20748
+ languageName: node
+ linkType: hard
+
+"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.7":
+ version: 1.15.2
+ resolution: "follow-redirects@npm:1.15.2"
+ peerDependenciesMeta:
+ debug:
+ optional: true
+ checksum: faa66059b66358ba65c234c2f2a37fcec029dc22775f35d9ad6abac56003268baf41e55f9ee645957b32c7d9f62baf1f0b906e68267276f54ec4b4c597c2b190
+ languageName: node
+ linkType: hard
+
+"fork-ts-checker-webpack-plugin@npm:^6.5.0":
+ version: 6.5.2
+ resolution: "fork-ts-checker-webpack-plugin@npm:6.5.2"
+ dependencies:
+ "@babel/code-frame": ^7.8.3
+ "@types/json-schema": ^7.0.5
+ chalk: ^4.1.0
+ chokidar: ^3.4.2
+ cosmiconfig: ^6.0.0
+ deepmerge: ^4.2.2
+ fs-extra: ^9.0.0
+ glob: ^7.1.6
+ memfs: ^3.1.2
+ minimatch: ^3.0.4
+ schema-utils: 2.7.0
+ semver: ^7.3.2
+ tapable: ^1.0.0
+ peerDependencies:
+ eslint: ">= 6"
+ typescript: ">= 2.7"
+ vue-template-compiler: "*"
+ webpack: ">= 4"
+ peerDependenciesMeta:
+ eslint:
+ optional: true
+ vue-template-compiler:
+ optional: true
+ checksum: c823de02ee258a26ea5c0c488b2f1825b941f72292417478689862468a9140b209ad7df52f67bd134228fe9f40e9115b604fc8f88a69338929fe52be869469b6
+ languageName: node
+ linkType: hard
+
+"forwarded@npm:0.2.0":
+ version: 0.2.0
+ resolution: "forwarded@npm:0.2.0"
+ checksum: fd27e2394d8887ebd16a66ffc889dc983fbbd797d5d3f01087c020283c0f019a7d05ee85669383d8e0d216b116d720fc0cef2f6e9b7eb9f4c90c6e0bc7fd28e6
+ languageName: node
+ linkType: hard
+
+"fraction.js@npm:^4.2.0":
+ version: 4.2.0
+ resolution: "fraction.js@npm:4.2.0"
+ checksum: 8c76a6e21dedea87109d6171a0ac77afa14205794a565d71cb10d2925f629a3922da61bf45ea52dbc30bce4d8636dc0a27213a88cbd600eab047d82f9a3a94c5
+ languageName: node
+ linkType: hard
+
+"fresh@npm:0.5.2":
+ version: 0.5.2
+ resolution: "fresh@npm:0.5.2"
+ checksum: 13ea8b08f91e669a64e3ba3a20eb79d7ca5379a81f1ff7f4310d54e2320645503cc0c78daedc93dfb6191287295f6479544a649c64d8e41a1c0fb0c221552346
+ languageName: node
+ linkType: hard
+
+"fs-extra@npm:^10.1.0":
+ version: 10.1.0
+ resolution: "fs-extra@npm:10.1.0"
+ dependencies:
+ graceful-fs: ^4.2.0
+ jsonfile: ^6.0.1
+ universalify: ^2.0.0
+ checksum: dc94ab37096f813cc3ca12f0f1b5ad6744dfed9ed21e953d72530d103cea193c2f81584a39e9dee1bea36de5ee66805678c0dddc048e8af1427ac19c00fffc50
+ languageName: node
+ linkType: hard
+
+"fs-extra@npm:^9.0.0":
+ version: 9.1.0
+ resolution: "fs-extra@npm:9.1.0"
+ dependencies:
+ at-least-node: ^1.0.0
+ graceful-fs: ^4.2.0
+ jsonfile: ^6.0.1
+ universalify: ^2.0.0
+ checksum: ba71ba32e0faa74ab931b7a0031d1523c66a73e225de7426e275e238e312d07313d2da2d33e34a52aa406c8763ade5712eb3ec9ba4d9edce652bcacdc29e6b20
+ languageName: node
+ linkType: hard
+
+"fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "fs-minipass@npm:2.1.0"
+ dependencies:
+ minipass: ^3.0.0
+ checksum: 1b8d128dae2ac6cc94230cc5ead341ba3e0efaef82dab46a33d171c044caaa6ca001364178d42069b2809c35a1c3c35079a32107c770e9ffab3901b59af8c8b1
+ languageName: node
+ linkType: hard
+
+"fs-monkey@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "fs-monkey@npm:1.0.3"
+ checksum: cf50804833f9b88a476911ae911fe50f61a98d986df52f890bd97e7262796d023698cb2309fa9b74fdd8974f04315b648748a0a8ee059e7d5257b293bfc409c0
+ languageName: node
+ linkType: hard
+
+"fs.realpath@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "fs.realpath@npm:1.0.0"
+ checksum: 99ddea01a7e75aa276c250a04eedeffe5662bce66c65c07164ad6264f9de18fb21be9433ead460e54cff20e31721c811f4fb5d70591799df5f85dce6d6746fd0
+ languageName: node
+ linkType: hard
+
+"fsevents@npm:~2.3.2":
+ version: 2.3.2
+ resolution: "fsevents@npm:2.3.2"
+ dependencies:
+ node-gyp: latest
+ checksum: 97ade64e75091afee5265e6956cb72ba34db7819b4c3e94c431d4be2b19b8bb7a2d4116da417950c3425f17c8fe693d25e20212cac583ac1521ad066b77ae31f
+ conditions: os=darwin
+ languageName: node
+ linkType: hard
+
+"fsevents@patch:fsevents@~2.3.2#~builtin":
+ version: 2.3.2
+ resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7"
+ dependencies:
+ node-gyp: latest
+ conditions: os=darwin
+ languageName: node
+ linkType: hard
+
+"function-bind@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "function-bind@npm:1.1.1"
+ checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a
+ languageName: node
+ linkType: hard
+
+"gauge@npm:^4.0.3":
+ version: 4.0.4
+ resolution: "gauge@npm:4.0.4"
+ dependencies:
+ aproba: ^1.0.3 || ^2.0.0
+ color-support: ^1.1.3
+ console-control-strings: ^1.1.0
+ has-unicode: ^2.0.1
+ signal-exit: ^3.0.7
+ string-width: ^4.2.3
+ strip-ansi: ^6.0.1
+ wide-align: ^1.1.5
+ checksum: 788b6bfe52f1dd8e263cda800c26ac0ca2ff6de0b6eee2fe0d9e3abf15e149b651bd27bf5226be10e6e3edb5c4e5d5985a5a1a98137e7a892f75eff76467ad2d
+ languageName: node
+ linkType: hard
+
+"gensync@npm:^1.0.0-beta.1, gensync@npm:^1.0.0-beta.2":
+ version: 1.0.0-beta.2
+ resolution: "gensync@npm:1.0.0-beta.2"
+ checksum: a7437e58c6be12aa6c90f7730eac7fa9833dc78872b4ad2963d2031b00a3367a93f98aec75f9aaac7220848e4026d67a8655e870b24f20a543d103c0d65952ec
+ languageName: node
+ linkType: hard
+
+"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1":
+ version: 1.1.3
+ resolution: "get-intrinsic@npm:1.1.3"
+ dependencies:
+ function-bind: ^1.1.1
+ has: ^1.0.3
+ has-symbols: ^1.0.3
+ checksum: 152d79e87251d536cf880ba75cfc3d6c6c50e12b3a64e1ea960e73a3752b47c69f46034456eae1b0894359ce3bc64c55c186f2811f8a788b75b638b06fab228a
+ languageName: node
+ linkType: hard
+
+"get-own-enumerable-property-symbols@npm:^3.0.0":
+ version: 3.0.2
+ resolution: "get-own-enumerable-property-symbols@npm:3.0.2"
+ checksum: 8f0331f14159f939830884799f937343c8c0a2c330506094bc12cbee3665d88337fe97a4ea35c002cc2bdba0f5d9975ad7ec3abb925015cdf2a93e76d4759ede
+ languageName: node
+ linkType: hard
+
+"get-stream@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "get-stream@npm:4.1.0"
+ dependencies:
+ pump: ^3.0.0
+ checksum: 443e1914170c15bd52ff8ea6eff6dfc6d712b031303e36302d2778e3de2506af9ee964d6124010f7818736dcfde05c04ba7ca6cc26883106e084357a17ae7d73
+ languageName: node
+ linkType: hard
+
+"get-stream@npm:^5.1.0":
+ version: 5.2.0
+ resolution: "get-stream@npm:5.2.0"
+ dependencies:
+ pump: ^3.0.0
+ checksum: 8bc1a23174a06b2b4ce600df38d6c98d2ef6d84e020c1ddad632ad75bac4e092eeb40e4c09e0761c35fc2dbc5e7fff5dab5e763a383582c4a167dd69a905bd12
+ languageName: node
+ linkType: hard
+
+"get-stream@npm:^6.0.0":
+ version: 6.0.1
+ resolution: "get-stream@npm:6.0.1"
+ checksum: e04ecece32c92eebf5b8c940f51468cd53554dcbb0ea725b2748be583c9523d00128137966afce410b9b051eb2ef16d657cd2b120ca8edafcf5a65e81af63cad
+ languageName: node
+ linkType: hard
+
+"github-slugger@npm:^1.4.0":
+ version: 1.5.0
+ resolution: "github-slugger@npm:1.5.0"
+ checksum: c70988224578b3bdaa25df65973ffc8c24594a77a28550c3636e495e49d17aef5cdb04c04fa3f1744babef98c61eecc6a43299a13ea7f3cc33d680bf9053ffbe
+ languageName: node
+ linkType: hard
+
+"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2":
+ version: 5.1.2
+ resolution: "glob-parent@npm:5.1.2"
+ dependencies:
+ is-glob: ^4.0.1
+ checksum: f4f2bfe2425296e8a47e36864e4f42be38a996db40420fe434565e4480e3322f18eb37589617a98640c5dc8fdec1a387007ee18dbb1f3f5553409c34d17f425e
+ languageName: node
+ linkType: hard
+
+"glob-parent@npm:^6.0.1":
+ version: 6.0.2
+ resolution: "glob-parent@npm:6.0.2"
+ dependencies:
+ is-glob: ^4.0.3
+ checksum: c13ee97978bef4f55106b71e66428eb1512e71a7466ba49025fc2aec59a5bfb0954d5abd58fc5ee6c9b076eef4e1f6d3375c2e964b88466ca390da4419a786a8
+ languageName: node
+ linkType: hard
+
+"glob-to-regexp@npm:^0.4.1":
+ version: 0.4.1
+ resolution: "glob-to-regexp@npm:0.4.1"
+ checksum: e795f4e8f06d2a15e86f76e4d92751cf8bbfcf0157cea5c2f0f35678a8195a750b34096b1256e436f0cebc1883b5ff0888c47348443e69546a5a87f9e1eb1167
+ languageName: node
+ linkType: hard
+
+"glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6":
+ version: 7.2.3
+ resolution: "glob@npm:7.2.3"
+ dependencies:
+ fs.realpath: ^1.0.0
+ inflight: ^1.0.4
+ inherits: 2
+ minimatch: ^3.1.1
+ once: ^1.3.0
+ path-is-absolute: ^1.0.0
+ checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133
+ languageName: node
+ linkType: hard
+
+"glob@npm:^8.0.1":
+ version: 8.0.3
+ resolution: "glob@npm:8.0.3"
+ dependencies:
+ fs.realpath: ^1.0.0
+ inflight: ^1.0.4
+ inherits: 2
+ minimatch: ^5.0.1
+ once: ^1.3.0
+ checksum: 50bcdea19d8e79d8de5f460b1939ffc2b3299eac28deb502093fdca22a78efebc03e66bf54f0abc3d3d07d8134d19a32850288b7440d77e072aa55f9d33b18c5
+ languageName: node
+ linkType: hard
+
+"global-dirs@npm:^3.0.0":
+ version: 3.0.1
+ resolution: "global-dirs@npm:3.0.1"
+ dependencies:
+ ini: 2.0.0
+ checksum: 70147b80261601fd40ac02a104581432325c1c47329706acd773f3a6ce99bb36d1d996038c85ccacd482ad22258ec233c586b6a91535b1a116b89663d49d6438
+ languageName: node
+ linkType: hard
+
+"global-modules@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "global-modules@npm:2.0.0"
+ dependencies:
+ global-prefix: ^3.0.0
+ checksum: d6197f25856c878c2fb5f038899f2dca7cbb2f7b7cf8999660c0104972d5cfa5c68b5a0a77fa8206bb536c3903a4615665acb9709b4d80846e1bb47eaef65430
+ languageName: node
+ linkType: hard
+
+"global-prefix@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "global-prefix@npm:3.0.0"
+ dependencies:
+ ini: ^1.3.5
+ kind-of: ^6.0.2
+ which: ^1.3.1
+ checksum: 8a82fc1d6f22c45484a4e34656cc91bf021a03e03213b0035098d605bfc612d7141f1e14a21097e8a0413b4884afd5b260df0b6a25605ce9d722e11f1df2881d
+ languageName: node
+ linkType: hard
+
+"globals@npm:^11.1.0":
+ version: 11.12.0
+ resolution: "globals@npm:11.12.0"
+ checksum: 67051a45eca3db904aee189dfc7cd53c20c7d881679c93f6146ddd4c9f4ab2268e68a919df740d39c71f4445d2b38ee360fc234428baea1dbdfe68bbcb46979e
+ languageName: node
+ linkType: hard
+
+"globby@npm:^11.0.1, globby@npm:^11.0.4, globby@npm:^11.1.0":
+ version: 11.1.0
+ resolution: "globby@npm:11.1.0"
+ dependencies:
+ array-union: ^2.1.0
+ dir-glob: ^3.0.1
+ fast-glob: ^3.2.9
+ ignore: ^5.2.0
+ merge2: ^1.4.1
+ slash: ^3.0.0
+ checksum: b4be8885e0cfa018fc783792942d53926c35c50b3aefd3fdcfb9d22c627639dc26bd2327a40a0b74b074100ce95bb7187bfeae2f236856aa3de183af7a02aea6
+ languageName: node
+ linkType: hard
+
+"globby@npm:^13.1.1":
+ version: 13.1.2
+ resolution: "globby@npm:13.1.2"
+ dependencies:
+ dir-glob: ^3.0.1
+ fast-glob: ^3.2.11
+ ignore: ^5.2.0
+ merge2: ^1.4.1
+ slash: ^4.0.0
+ checksum: c148fcda0c981f00fb434bb94ca258f0a9d23cedbde6fb3f37098e1abde5b065019e2c63fe2aa2fad4daf2b54bf360b4d0423d85fb3a63d09ed75a2837d4de0f
+ languageName: node
+ linkType: hard
+
+"got@npm:^9.6.0":
+ version: 9.6.0
+ resolution: "got@npm:9.6.0"
+ dependencies:
+ "@sindresorhus/is": ^0.14.0
+ "@szmarczak/http-timer": ^1.1.2
+ cacheable-request: ^6.0.0
+ decompress-response: ^3.3.0
+ duplexer3: ^0.1.4
+ get-stream: ^4.1.0
+ lowercase-keys: ^1.0.1
+ mimic-response: ^1.0.1
+ p-cancelable: ^1.0.0
+ to-readable-stream: ^1.0.0
+ url-parse-lax: ^3.0.0
+ checksum: 941807bd9704bacf5eb401f0cc1212ffa1f67c6642f2d028fd75900471c221b1da2b8527f4553d2558f3faeda62ea1cf31665f8b002c6137f5de8732f07370b0
+ languageName: node
+ linkType: hard
+
+"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9":
+ version: 4.2.10
+ resolution: "graceful-fs@npm:4.2.10"
+ checksum: 3f109d70ae123951905d85032ebeae3c2a5a7a997430df00ea30df0e3a6c60cf6689b109654d6fdacd28810a053348c4d14642da1d075049e6be1ba5216218da
+ languageName: node
+ linkType: hard
+
+"gray-matter@npm:^4.0.3":
+ version: 4.0.3
+ resolution: "gray-matter@npm:4.0.3"
+ dependencies:
+ js-yaml: ^3.13.1
+ kind-of: ^6.0.2
+ section-matter: ^1.0.0
+ strip-bom-string: ^1.0.0
+ checksum: 37717bd424344487d655392251ce8d8878a1275ee087003e61208fba3bfd59cbb73a85b2159abf742ae95e23db04964813fdc33ae18b074208428b2528205222
+ languageName: node
+ linkType: hard
+
+"gzip-size@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "gzip-size@npm:6.0.0"
+ dependencies:
+ duplexer: ^0.1.2
+ checksum: 2df97f359696ad154fc171dcb55bc883fe6e833bca7a65e457b9358f3cb6312405ed70a8da24a77c1baac0639906cd52358dc0ce2ec1a937eaa631b934c94194
+ languageName: node
+ linkType: hard
+
+"handle-thing@npm:^2.0.0":
+ version: 2.0.1
+ resolution: "handle-thing@npm:2.0.1"
+ checksum: 68071f313062315cd9dce55710e9496873945f1dd425107007058fc1629f93002a7649fcc3e464281ce02c7e809a35f5925504ab8105d972cf649f1f47cb7d6c
+ languageName: node
+ linkType: hard
+
+"has-flag@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "has-flag@npm:3.0.0"
+ checksum: 4a15638b454bf086c8148979aae044dd6e39d63904cd452d970374fa6a87623423da485dfb814e7be882e05c096a7ccf1ebd48e7e7501d0208d8384ff4dea73b
+ languageName: node
+ linkType: hard
+
+"has-flag@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "has-flag@npm:4.0.0"
+ checksum: 261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad
+ languageName: node
+ linkType: hard
+
+"has-property-descriptors@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "has-property-descriptors@npm:1.0.0"
+ dependencies:
+ get-intrinsic: ^1.1.1
+ checksum: a6d3f0a266d0294d972e354782e872e2fe1b6495b321e6ef678c9b7a06a40408a6891817350c62e752adced73a94ac903c54734fee05bf65b1905ee1368194bb
+ languageName: node
+ linkType: hard
+
+"has-symbols@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "has-symbols@npm:1.0.3"
+ checksum: a054c40c631c0d5741a8285010a0777ea0c068f99ed43e5d6eb12972da223f8af553a455132fdb0801bdcfa0e0f443c0c03a68d8555aa529b3144b446c3f2410
+ languageName: node
+ linkType: hard
+
+"has-unicode@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "has-unicode@npm:2.0.1"
+ checksum: 1eab07a7436512db0be40a710b29b5dc21fa04880b7f63c9980b706683127e3c1b57cb80ea96d47991bdae2dfe479604f6a1ba410106ee1046a41d1bd0814400
+ languageName: node
+ linkType: hard
+
+"has-yarn@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "has-yarn@npm:2.1.0"
+ checksum: 5eb1d0bb8518103d7da24532bdbc7124ffc6d367b5d3c10840b508116f2f1bcbcf10fd3ba843ff6e2e991bdf9969fd862d42b2ed58aade88343326c950b7e7f7
+ languageName: node
+ linkType: hard
+
+"has@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "has@npm:1.0.3"
+ dependencies:
+ function-bind: ^1.1.1
+ checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792
+ languageName: node
+ linkType: hard
+
+"hast-to-hyperscript@npm:^9.0.0":
+ version: 9.0.1
+ resolution: "hast-to-hyperscript@npm:9.0.1"
+ dependencies:
+ "@types/unist": ^2.0.3
+ comma-separated-tokens: ^1.0.0
+ property-information: ^5.3.0
+ space-separated-tokens: ^1.0.0
+ style-to-object: ^0.3.0
+ unist-util-is: ^4.0.0
+ web-namespaces: ^1.0.0
+ checksum: de570d789853018fff2fd38fc096549b9814e366b298f60c90c159a57018230eefc44d46a246027b0e2426ed9e99f2e270050bc183d5bdfe4c9487c320b392cd
+ languageName: node
+ linkType: hard
+
+"hast-util-from-parse5@npm:^6.0.0":
+ version: 6.0.1
+ resolution: "hast-util-from-parse5@npm:6.0.1"
+ dependencies:
+ "@types/parse5": ^5.0.0
+ hastscript: ^6.0.0
+ property-information: ^5.0.0
+ vfile: ^4.0.0
+ vfile-location: ^3.2.0
+ web-namespaces: ^1.0.0
+ checksum: 4daa78201468af7779161e7caa2513c329830778e0528481ab16b3e1bcef4b831f6285b526aacdddbee802f3bd9d64df55f80f010591ea1916da535e3a923b83
+ languageName: node
+ linkType: hard
+
+"hast-util-parse-selector@npm:^2.0.0":
+ version: 2.2.5
+ resolution: "hast-util-parse-selector@npm:2.2.5"
+ checksum: 22ee4afbd11754562144cb3c4f3ec52524dafba4d90ee52512902d17cf11066d83b38f7bdf6ca571bbc2541f07ba30db0d234657b6ecb8ca4631587466459605
+ languageName: node
+ linkType: hard
+
+"hast-util-raw@npm:6.0.1":
+ version: 6.0.1
+ resolution: "hast-util-raw@npm:6.0.1"
+ dependencies:
+ "@types/hast": ^2.0.0
+ hast-util-from-parse5: ^6.0.0
+ hast-util-to-parse5: ^6.0.0
+ html-void-elements: ^1.0.0
+ parse5: ^6.0.0
+ unist-util-position: ^3.0.0
+ vfile: ^4.0.0
+ web-namespaces: ^1.0.0
+ xtend: ^4.0.0
+ zwitch: ^1.0.0
+ checksum: f6d960644f9fbbe0b92d0227b20a24d659cce021d5f9fd218e077154931b4524ee920217b7fd5a45ec2736ec1dee53de9209fe449f6f89454c01d225ff0e7851
+ languageName: node
+ linkType: hard
+
+"hast-util-to-parse5@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "hast-util-to-parse5@npm:6.0.0"
+ dependencies:
+ hast-to-hyperscript: ^9.0.0
+ property-information: ^5.0.0
+ web-namespaces: ^1.0.0
+ xtend: ^4.0.0
+ zwitch: ^1.0.0
+ checksum: 91a36244e37df1d63c8b7e865ab0c0a25bb7396155602be005cf71d95c348e709568f80e0f891681a3711d733ad896e70642dc41a05b574eddf2e07d285408a8
+ languageName: node
+ linkType: hard
+
+"hastscript@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "hastscript@npm:6.0.0"
+ dependencies:
+ "@types/hast": ^2.0.0
+ comma-separated-tokens: ^1.0.0
+ hast-util-parse-selector: ^2.0.0
+ property-information: ^5.0.0
+ space-separated-tokens: ^1.0.0
+ checksum: 5e50b85af0d2cb7c17979cb1ddca75d6b96b53019dd999b39e7833192c9004201c3cee6445065620ea05d0087d9ae147a4844e582d64868be5bc6b0232dfe52d
+ languageName: node
+ linkType: hard
+
+"he@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "he@npm:1.2.0"
+ bin:
+ he: bin/he
+ checksum: 3d4d6babccccd79c5c5a3f929a68af33360d6445587d628087f39a965079d84f18ce9c3d3f917ee1e3978916fc833bb8b29377c3b403f919426f91bc6965e7a7
+ languageName: node
+ linkType: hard
+
+"history@npm:^4.9.0":
+ version: 4.10.1
+ resolution: "history@npm:4.10.1"
+ dependencies:
+ "@babel/runtime": ^7.1.2
+ loose-envify: ^1.2.0
+ resolve-pathname: ^3.0.0
+ tiny-invariant: ^1.0.2
+ tiny-warning: ^1.0.0
+ value-equal: ^1.0.1
+ checksum: addd84bc4683929bae4400419b5af132ff4e4e9b311a0d4e224579ea8e184a6b80d7f72c55927e4fa117f69076a9e47ce082d8d0b422f1a9ddac7991490ca1d0
+ languageName: node
+ linkType: hard
+
+"hoist-non-react-statics@npm:^3.1.0":
+ version: 3.3.2
+ resolution: "hoist-non-react-statics@npm:3.3.2"
+ dependencies:
+ react-is: ^16.7.0
+ checksum: b1538270429b13901ee586aa44f4cc3ecd8831c061d06cb8322e50ea17b3f5ce4d0e2e66394761e6c8e152cd8c34fb3b4b690116c6ce2bd45b18c746516cb9e8
+ languageName: node
+ linkType: hard
+
+"hpack.js@npm:^2.1.6":
+ version: 2.1.6
+ resolution: "hpack.js@npm:2.1.6"
+ dependencies:
+ inherits: ^2.0.1
+ obuf: ^1.0.0
+ readable-stream: ^2.0.1
+ wbuf: ^1.1.0
+ checksum: 2de144115197967ad6eeee33faf41096c6ba87078703c5cb011632dcfbffeb45784569e0cf02c317bd79c48375597c8ec88c30fff5bb0b023e8f654fb6e9c06e
+ languageName: node
+ linkType: hard
+
+"html-entities@npm:^2.3.2":
+ version: 2.3.3
+ resolution: "html-entities@npm:2.3.3"
+ checksum: 92521501da8aa5f66fee27f0f022d6e9ceae62667dae93aa6a2f636afa71ad530b7fb24a18d4d6c124c9885970cac5f8a52dbf1731741161002816ae43f98196
+ languageName: node
+ linkType: hard
+
+"html-minifier-terser@npm:^6.0.2, html-minifier-terser@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "html-minifier-terser@npm:6.1.0"
+ dependencies:
+ camel-case: ^4.1.2
+ clean-css: ^5.2.2
+ commander: ^8.3.0
+ he: ^1.2.0
+ param-case: ^3.0.4
+ relateurl: ^0.2.7
+ terser: ^5.10.0
+ bin:
+ html-minifier-terser: cli.js
+ checksum: ac52c14006476f773204c198b64838477859dc2879490040efab8979c0207424da55d59df7348153f412efa45a0840a1ca3c757bf14767d23a15e3e389d37a93
+ languageName: node
+ linkType: hard
+
+"html-tags@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "html-tags@npm:3.2.0"
+ checksum: a0c9e96ac26c84adad9cc66d15d6711a17f60acda8d987218f1d4cbaacd52864939b230e635cce5a1179f3ddab2a12b9231355617dfbae7945fcfec5e96d2041
+ languageName: node
+ linkType: hard
+
+"html-void-elements@npm:^1.0.0":
+ version: 1.0.5
+ resolution: "html-void-elements@npm:1.0.5"
+ checksum: 1a56f4f6cfbeb994c21701ff72b4b7f556fe784a70e5e554d1566ff775af83b91ea93f10664f039a67802d9f7b40d4a7f1ed20312bab47bd88d89bd792ea84ca
+ languageName: node
+ linkType: hard
+
+"html-webpack-plugin@npm:^5.5.0":
+ version: 5.5.0
+ resolution: "html-webpack-plugin@npm:5.5.0"
+ dependencies:
+ "@types/html-minifier-terser": ^6.0.0
+ html-minifier-terser: ^6.0.2
+ lodash: ^4.17.21
+ pretty-error: ^4.0.0
+ tapable: ^2.0.0
+ peerDependencies:
+ webpack: ^5.20.0
+ checksum: f3d84d0df71fe2f5bac533cc74dce41ab058558cdcc6ff767d166a2abf1cf6fb8491d54d60ddbb34e95c00394e379ba52e0468e0284d1d0cc6a42987056e8219
+ languageName: node
+ linkType: hard
+
+"htmlparser2@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "htmlparser2@npm:6.1.0"
+ dependencies:
+ domelementtype: ^2.0.1
+ domhandler: ^4.0.0
+ domutils: ^2.5.2
+ entities: ^2.0.0
+ checksum: 81a7b3d9c3bb9acb568a02fc9b1b81ffbfa55eae7f1c41ae0bf840006d1dbf54cb3aa245b2553e2c94db674840a9f0fdad7027c9a9d01a062065314039058c4e
+ languageName: node
+ linkType: hard
+
+"htmlparser2@npm:^8.0.1":
+ version: 8.0.1
+ resolution: "htmlparser2@npm:8.0.1"
+ dependencies:
+ domelementtype: ^2.3.0
+ domhandler: ^5.0.2
+ domutils: ^3.0.1
+ entities: ^4.3.0
+ checksum: 06d5c71e8313597722bc429ae2a7a8333d77bd3ab07ccb916628384b37332027b047f8619448d8f4a3312b6609c6ea3302a4e77435d859e9e686999e6699ca39
+ languageName: node
+ linkType: hard
+
+"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "http-cache-semantics@npm:4.1.0"
+ checksum: 974de94a81c5474be07f269f9fd8383e92ebb5a448208223bfb39e172a9dbc26feff250192ecc23b9593b3f92098e010406b0f24bd4d588d631f80214648ed42
+ languageName: node
+ linkType: hard
+
+"http-deceiver@npm:^1.2.7":
+ version: 1.2.7
+ resolution: "http-deceiver@npm:1.2.7"
+ checksum: 64d7d1ae3a6933eb0e9a94e6f27be4af45a53a96c3c34e84ff57113787105a89fff9d1c3df263ef63add823df019b0e8f52f7121e32393bb5ce9a713bf100b41
+ languageName: node
+ linkType: hard
+
+"http-errors@npm:2.0.0":
+ version: 2.0.0
+ resolution: "http-errors@npm:2.0.0"
+ dependencies:
+ depd: 2.0.0
+ inherits: 2.0.4
+ setprototypeof: 1.2.0
+ statuses: 2.0.1
+ toidentifier: 1.0.1
+ checksum: 9b0a3782665c52ce9dc658a0d1560bcb0214ba5699e4ea15aefb2a496e2ca83db03ebc42e1cce4ac1f413e4e0d2d736a3fd755772c556a9a06853ba2a0b7d920
+ languageName: node
+ linkType: hard
+
+"http-errors@npm:~1.6.2":
+ version: 1.6.3
+ resolution: "http-errors@npm:1.6.3"
+ dependencies:
+ depd: ~1.1.2
+ inherits: 2.0.3
+ setprototypeof: 1.1.0
+ statuses: ">= 1.4.0 < 2"
+ checksum: a9654ee027e3d5de305a56db1d1461f25709ac23267c6dc28cdab8323e3f96caa58a9a6a5e93ac15d7285cee0c2f019378c3ada9026e7fe19c872d695f27de7c
+ languageName: node
+ linkType: hard
+
+"http-parser-js@npm:>=0.5.1":
+ version: 0.5.8
+ resolution: "http-parser-js@npm:0.5.8"
+ checksum: 6bbdf2429858e8cf13c62375b0bfb6dc3955ca0f32e58237488bc86cd2378f31d31785fd3ac4ce93f1c74e0189cf8823c91f5cb061696214fd368d2452dc871d
+ languageName: node
+ linkType: hard
+
+"http-proxy-agent@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "http-proxy-agent@npm:5.0.0"
+ dependencies:
+ "@tootallnate/once": 2
+ agent-base: 6
+ debug: 4
+ checksum: e2ee1ff1656a131953839b2a19cd1f3a52d97c25ba87bd2559af6ae87114abf60971e498021f9b73f9fd78aea8876d1fb0d4656aac8a03c6caa9fc175f22b786
+ languageName: node
+ linkType: hard
+
+"http-proxy-middleware@npm:^2.0.3":
+ version: 2.0.6
+ resolution: "http-proxy-middleware@npm:2.0.6"
+ dependencies:
+ "@types/http-proxy": ^1.17.8
+ http-proxy: ^1.18.1
+ is-glob: ^4.0.1
+ is-plain-obj: ^3.0.0
+ micromatch: ^4.0.2
+ peerDependencies:
+ "@types/express": ^4.17.13
+ peerDependenciesMeta:
+ "@types/express":
+ optional: true
+ checksum: 2ee85bc878afa6cbf34491e972ece0f5be0a3e5c98a60850cf40d2a9a5356e1fc57aab6cff33c1fc37691b0121c3a42602d2b1956c52577e87a5b77b62ae1c3a
+ languageName: node
+ linkType: hard
+
+"http-proxy@npm:^1.18.1":
+ version: 1.18.1
+ resolution: "http-proxy@npm:1.18.1"
+ dependencies:
+ eventemitter3: ^4.0.0
+ follow-redirects: ^1.0.0
+ requires-port: ^1.0.0
+ checksum: f5bd96bf83e0b1e4226633dbb51f8b056c3e6321917df402deacec31dd7fe433914fc7a2c1831cf7ae21e69c90b3a669b8f434723e9e8b71fd68afe30737b6a5
+ languageName: node
+ linkType: hard
+
+"https-proxy-agent@npm:^5.0.0":
+ version: 5.0.1
+ resolution: "https-proxy-agent@npm:5.0.1"
+ dependencies:
+ agent-base: 6
+ debug: 4
+ checksum: 571fccdf38184f05943e12d37d6ce38197becdd69e58d03f43637f7fa1269cf303a7d228aa27e5b27bbd3af8f09fd938e1c91dcfefff2df7ba77c20ed8dfc765
+ languageName: node
+ linkType: hard
+
+"human-signals@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "human-signals@npm:2.1.0"
+ checksum: b87fd89fce72391625271454e70f67fe405277415b48bcc0117ca73d31fa23a4241787afdc8d67f5a116cf37258c052f59ea82daffa72364d61351423848e3b8
+ languageName: node
+ linkType: hard
+
+"humanize-ms@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "humanize-ms@npm:1.2.1"
+ dependencies:
+ ms: ^2.0.0
+ checksum: 9c7a74a2827f9294c009266c82031030eae811ca87b0da3dceb8d6071b9bde22c9f3daef0469c3c533cc67a97d8a167cd9fc0389350e5f415f61a79b171ded16
+ languageName: node
+ linkType: hard
+
+"iconv-lite@npm:0.4.24":
+ version: 0.4.24
+ resolution: "iconv-lite@npm:0.4.24"
+ dependencies:
+ safer-buffer: ">= 2.1.2 < 3"
+ checksum: bd9f120f5a5b306f0bc0b9ae1edeb1577161503f5f8252a20f1a9e56ef8775c9959fd01c55f2d3a39d9a8abaf3e30c1abeb1895f367dcbbe0a8fd1c9ca01c4f6
+ languageName: node
+ linkType: hard
+
+"iconv-lite@npm:^0.6.2":
+ version: 0.6.3
+ resolution: "iconv-lite@npm:0.6.3"
+ dependencies:
+ safer-buffer: ">= 2.1.2 < 3.0.0"
+ checksum: 3f60d47a5c8fc3313317edfd29a00a692cc87a19cac0159e2ce711d0ebc9019064108323b5e493625e25594f11c6236647d8e256fbe7a58f4a3b33b89e6d30bf
+ languageName: node
+ linkType: hard
+
+"icss-utils@npm:^5.0.0, icss-utils@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "icss-utils@npm:5.1.0"
+ peerDependencies:
+ postcss: ^8.1.0
+ checksum: 5c324d283552b1269cfc13a503aaaa172a280f914e5b81544f3803bc6f06a3b585fb79f66f7c771a2c052db7982c18bf92d001e3b47282e3abbbb4c4cc488d68
+ languageName: node
+ linkType: hard
+
+"ignore@npm:^5.2.0":
+ version: 5.2.1
+ resolution: "ignore@npm:5.2.1"
+ checksum: 7251d00cba49fe88c4f3565fadeb4aa726ba38294a9a79ffed542edc47bafd989d4b2ccf65700c5b1b26a1e91dfc7218fb23017937c79216025d5caeec0ee9d5
+ languageName: node
+ linkType: hard
+
+"image-size@npm:^1.0.1":
+ version: 1.0.2
+ resolution: "image-size@npm:1.0.2"
+ dependencies:
+ queue: 6.0.2
+ bin:
+ image-size: bin/image-size.js
+ checksum: 01745fdb47f87cecf538e69c63f9adc5bfab30a345345c2de91105f3afbd1bfcfba1256af02bf3323077b33b0004469a837e077bf0cbb9c907e9c1e9e7547585
+ languageName: node
+ linkType: hard
+
+"immer@npm:^9.0.7":
+ version: 9.0.16
+ resolution: "immer@npm:9.0.16"
+ checksum: e9a5ca65c929b329da7a3b7beccf7984271cda7bdd47b2cab619eac3277dcd56598c211b55cc340786b6eff0c06652ac018808d9fd744443f06882364dece6bc
+ languageName: node
+ linkType: hard
+
+"import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0":
+ version: 3.3.0
+ resolution: "import-fresh@npm:3.3.0"
+ dependencies:
+ parent-module: ^1.0.0
+ resolve-from: ^4.0.0
+ checksum: 2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa
+ languageName: node
+ linkType: hard
+
+"import-lazy@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "import-lazy@npm:2.1.0"
+ checksum: 05294f3b9dd4971d3a996f0d2f176410fb6745d491d6e73376429189f5c1c3d290548116b2960a7cf3e89c20cdf11431739d1d2d8c54b84061980795010e803a
+ languageName: node
+ linkType: hard
+
+"imurmurhash@npm:^0.1.4":
+ version: 0.1.4
+ resolution: "imurmurhash@npm:0.1.4"
+ checksum: 7cae75c8cd9a50f57dadd77482359f659eaebac0319dd9368bcd1714f55e65badd6929ca58569da2b6494ef13fdd5598cd700b1eba23f8b79c5f19d195a3ecf7
+ languageName: node
+ linkType: hard
+
+"indent-string@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "indent-string@npm:4.0.0"
+ checksum: 824cfb9929d031dabf059bebfe08cf3137365e112019086ed3dcff6a0a7b698cb80cf67ccccde0e25b9e2d7527aa6cc1fed1ac490c752162496caba3e6699612
+ languageName: node
+ linkType: hard
+
+"infer-owner@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "infer-owner@npm:1.0.4"
+ checksum: 181e732764e4a0611576466b4b87dac338972b839920b2a8cde43642e4ed6bd54dc1fb0b40874728f2a2df9a1b097b8ff83b56d5f8f8e3927f837fdcb47d8a89
+ languageName: node
+ linkType: hard
+
+"infima@npm:0.2.0-alpha.42":
+ version: 0.2.0-alpha.42
+ resolution: "infima@npm:0.2.0-alpha.42"
+ checksum: 7206f36639c00a08daab811fedc748068951497efb5ec948cba846fb23856443668015f6bd65ddebe857cc2235f6ca98429f7018c73dcac47b0361ef4721bb8f
+ languageName: node
+ linkType: hard
+
+"inflight@npm:^1.0.4":
+ version: 1.0.6
+ resolution: "inflight@npm:1.0.6"
+ dependencies:
+ once: ^1.3.0
+ wrappy: 1
+ checksum: f4f76aa072ce19fae87ce1ef7d221e709afb59d445e05d47fba710e85470923a75de35bfae47da6de1b18afc3ce83d70facf44cfb0aff89f0a3f45c0a0244dfd
+ languageName: node
+ linkType: hard
+
+"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.0, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:~2.0.3":
+ version: 2.0.4
+ resolution: "inherits@npm:2.0.4"
+ checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1
+ languageName: node
+ linkType: hard
+
+"inherits@npm:2.0.3":
+ version: 2.0.3
+ resolution: "inherits@npm:2.0.3"
+ checksum: 78cb8d7d850d20a5e9a7f3620db31483aa00ad5f722ce03a55b110e5a723539b3716a3b463e2b96ce3fe286f33afc7c131fa2f91407528ba80cea98a7545d4c0
+ languageName: node
+ linkType: hard
+
+"ini@npm:2.0.0":
+ version: 2.0.0
+ resolution: "ini@npm:2.0.0"
+ checksum: e7aadc5fb2e4aefc666d74ee2160c073995a4061556b1b5b4241ecb19ad609243b9cceafe91bae49c219519394bbd31512516cb22a3b1ca6e66d869e0447e84e
+ languageName: node
+ linkType: hard
+
+"ini@npm:^1.3.5, ini@npm:~1.3.0":
+ version: 1.3.8
+ resolution: "ini@npm:1.3.8"
+ checksum: dfd98b0ca3a4fc1e323e38a6c8eb8936e31a97a918d3b377649ea15bdb15d481207a0dda1021efbd86b464cae29a0d33c1d7dcaf6c5672bee17fa849bc50a1b3
+ languageName: node
+ linkType: hard
+
+"inline-style-parser@npm:0.1.1":
+ version: 0.1.1
+ resolution: "inline-style-parser@npm:0.1.1"
+ checksum: 5d545056a3e1f2bf864c928a886a0e1656a3517127d36917b973de581bd54adc91b4bf1febcb0da054f204b4934763f1a4e09308b4d55002327cf1d48ac5d966
+ languageName: node
+ linkType: hard
+
+"interpret@npm:^1.0.0":
+ version: 1.4.0
+ resolution: "interpret@npm:1.4.0"
+ checksum: 2e5f51268b5941e4a17e4ef0575bc91ed0ab5f8515e3cf77486f7c14d13f3010df9c0959f37063dcc96e78d12dc6b0bb1b9e111cdfe69771f4656d2993d36155
+ languageName: node
+ linkType: hard
+
+"invariant@npm:^2.2.4":
+ version: 2.2.4
+ resolution: "invariant@npm:2.2.4"
+ dependencies:
+ loose-envify: ^1.0.0
+ checksum: cc3182d793aad82a8d1f0af697b462939cb46066ec48bbf1707c150ad5fad6406137e91a262022c269702e01621f35ef60269f6c0d7fd178487959809acdfb14
+ languageName: node
+ linkType: hard
+
+"ip@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "ip@npm:2.0.0"
+ checksum: cfcfac6b873b701996d71ec82a7dd27ba92450afdb421e356f44044ed688df04567344c36cbacea7d01b1c39a4c732dc012570ebe9bebfb06f27314bca625349
+ languageName: node
+ linkType: hard
+
+"ipaddr.js@npm:1.9.1":
+ version: 1.9.1
+ resolution: "ipaddr.js@npm:1.9.1"
+ checksum: f88d3825981486f5a1942414c8d77dd6674dd71c065adcfa46f578d677edcb99fda25af42675cb59db492fdf427b34a5abfcde3982da11a8fd83a500b41cfe77
+ languageName: node
+ linkType: hard
+
+"ipaddr.js@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "ipaddr.js@npm:2.0.1"
+ checksum: dd194a394a843d470f88d17191b0948f383ed1c8e320813f850c336a0fcb5e9215d97ec26ca35ab4fbbd31392c8b3467f3e8344628029ed3710b2ff6b5d1034e
+ languageName: node
+ linkType: hard
+
+"is-alphabetical@npm:1.0.4, is-alphabetical@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "is-alphabetical@npm:1.0.4"
+ checksum: 6508cce44fd348f06705d377b260974f4ce68c74000e7da4045f0d919e568226dc3ce9685c5a2af272195384df6930f748ce9213fc9f399b5d31b362c66312cb
+ languageName: node
+ linkType: hard
+
+"is-alphanumerical@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "is-alphanumerical@npm:1.0.4"
+ dependencies:
+ is-alphabetical: ^1.0.0
+ is-decimal: ^1.0.0
+ checksum: e2e491acc16fcf5b363f7c726f666a9538dba0a043665740feb45bba1652457a73441e7c5179c6768a638ed396db3437e9905f403644ec7c468fb41f4813d03f
+ languageName: node
+ linkType: hard
+
+"is-arrayish@npm:^0.2.1":
+ version: 0.2.1
+ resolution: "is-arrayish@npm:0.2.1"
+ checksum: eef4417e3c10e60e2c810b6084942b3ead455af16c4509959a27e490e7aee87cfb3f38e01bbde92220b528a0ee1a18d52b787e1458ee86174d8c7f0e58cd488f
+ languageName: node
+ linkType: hard
+
+"is-binary-path@npm:~2.1.0":
+ version: 2.1.0
+ resolution: "is-binary-path@npm:2.1.0"
+ dependencies:
+ binary-extensions: ^2.0.0
+ checksum: 84192eb88cff70d320426f35ecd63c3d6d495da9d805b19bc65b518984b7c0760280e57dbf119b7e9be6b161784a5a673ab2c6abe83abb5198a432232ad5b35c
+ languageName: node
+ linkType: hard
+
+"is-buffer@npm:^2.0.0":
+ version: 2.0.5
+ resolution: "is-buffer@npm:2.0.5"
+ checksum: 764c9ad8b523a9f5a32af29bdf772b08eb48c04d2ad0a7240916ac2688c983bf5f8504bf25b35e66240edeb9d9085461f9b5dae1f3d2861c6b06a65fe983de42
+ languageName: node
+ linkType: hard
+
+"is-ci@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "is-ci@npm:2.0.0"
+ dependencies:
+ ci-info: ^2.0.0
+ bin:
+ is-ci: bin.js
+ checksum: 77b869057510f3efa439bbb36e9be429d53b3f51abd4776eeea79ab3b221337fe1753d1e50058a9e2c650d38246108beffb15ccfd443929d77748d8c0cc90144
+ languageName: node
+ linkType: hard
+
+"is-core-module@npm:^2.9.0":
+ version: 2.11.0
+ resolution: "is-core-module@npm:2.11.0"
+ dependencies:
+ has: ^1.0.3
+ checksum: f96fd490c6b48eb4f6d10ba815c6ef13f410b0ba6f7eb8577af51697de523e5f2cd9de1c441b51d27251bf0e4aebc936545e33a5d26d5d51f28d25698d4a8bab
+ languageName: node
+ linkType: hard
+
+"is-decimal@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "is-decimal@npm:1.0.4"
+ checksum: ed483a387517856dc395c68403a10201fddcc1b63dc56513fbe2fe86ab38766120090ecdbfed89223d84ca8b1cd28b0641b93cb6597b6e8f4c097a7c24e3fb96
+ languageName: node
+ linkType: hard
+
+"is-docker@npm:^2.0.0, is-docker@npm:^2.1.1":
+ version: 2.2.1
+ resolution: "is-docker@npm:2.2.1"
+ bin:
+ is-docker: cli.js
+ checksum: 3fef7ddbf0be25958e8991ad941901bf5922ab2753c46980b60b05c1bf9c9c2402d35e6dc32e4380b980ef5e1970a5d9d5e5aa2e02d77727c3b6b5e918474c56
+ languageName: node
+ linkType: hard
+
+"is-extendable@npm:^0.1.0":
+ version: 0.1.1
+ resolution: "is-extendable@npm:0.1.1"
+ checksum: 3875571d20a7563772ecc7a5f36cb03167e9be31ad259041b4a8f73f33f885441f778cee1f1fe0085eb4bc71679b9d8c923690003a36a6a5fdf8023e6e3f0672
+ languageName: node
+ linkType: hard
+
+"is-extglob@npm:^2.1.1":
+ version: 2.1.1
+ resolution: "is-extglob@npm:2.1.1"
+ checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85
+ languageName: node
+ linkType: hard
+
+"is-fullwidth-code-point@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "is-fullwidth-code-point@npm:3.0.0"
+ checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348
+ languageName: node
+ linkType: hard
+
+"is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1":
+ version: 4.0.3
+ resolution: "is-glob@npm:4.0.3"
+ dependencies:
+ is-extglob: ^2.1.1
+ checksum: d381c1319fcb69d341cc6e6c7cd588e17cd94722d9a32dbd60660b993c4fb7d0f19438674e68dfec686d09b7c73139c9166b47597f846af387450224a8101ab4
+ languageName: node
+ linkType: hard
+
+"is-hexadecimal@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "is-hexadecimal@npm:1.0.4"
+ checksum: a452e047587b6069332d83130f54d30da4faf2f2ebaa2ce6d073c27b5703d030d58ed9e0b729c8e4e5b52c6f1dab26781bb77b7bc6c7805f14f320e328ff8cd5
+ languageName: node
+ linkType: hard
+
+"is-installed-globally@npm:^0.4.0":
+ version: 0.4.0
+ resolution: "is-installed-globally@npm:0.4.0"
+ dependencies:
+ global-dirs: ^3.0.0
+ is-path-inside: ^3.0.2
+ checksum: 3359840d5982d22e9b350034237b2cda2a12bac1b48a721912e1ab8e0631dd07d45a2797a120b7b87552759a65ba03e819f1bd63f2d7ab8657ec0b44ee0bf399
+ languageName: node
+ linkType: hard
+
+"is-lambda@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "is-lambda@npm:1.0.1"
+ checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35
+ languageName: node
+ linkType: hard
+
+"is-npm@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "is-npm@npm:5.0.0"
+ checksum: 9baff02b0c69a3d3c79b162cb2f9e67fb40ef6d172c16601b2e2471c21e9a4fa1fc9885a308d7bc6f3a3cd2a324c27fa0bf284c133c3349bb22571ab70d041cc
+ languageName: node
+ linkType: hard
+
+"is-number@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "is-number@npm:7.0.0"
+ checksum: 456ac6f8e0f3111ed34668a624e45315201dff921e5ac181f8ec24923b99e9f32ca1a194912dc79d539c97d33dba17dc635202ff0b2cf98326f608323276d27a
+ languageName: node
+ linkType: hard
+
+"is-obj@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "is-obj@npm:1.0.1"
+ checksum: 3ccf0efdea12951e0b9c784e2b00e77e87b2f8bd30b42a498548a8afcc11b3287342a2030c308e473e93a7a19c9ea7854c99a8832a476591c727df2a9c79796c
+ languageName: node
+ linkType: hard
+
+"is-obj@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "is-obj@npm:2.0.0"
+ checksum: c9916ac8f4621962a42f5e80e7ffdb1d79a3fab7456ceaeea394cd9e0858d04f985a9ace45be44433bf605673c8be8810540fe4cc7f4266fc7526ced95af5a08
+ languageName: node
+ linkType: hard
+
+"is-path-cwd@npm:^2.2.0":
+ version: 2.2.0
+ resolution: "is-path-cwd@npm:2.2.0"
+ checksum: 46a840921bb8cc0dc7b5b423a14220e7db338072a4495743a8230533ce78812dc152548c86f4b828411fe98c5451959f07cf841c6a19f611e46600bd699e8048
+ languageName: node
+ linkType: hard
+
+"is-path-inside@npm:^3.0.2":
+ version: 3.0.3
+ resolution: "is-path-inside@npm:3.0.3"
+ checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9
+ languageName: node
+ linkType: hard
+
+"is-plain-obj@npm:^2.0.0":
+ version: 2.1.0
+ resolution: "is-plain-obj@npm:2.1.0"
+ checksum: cec9100678b0a9fe0248a81743041ed990c2d4c99f893d935545cfbc42876cbe86d207f3b895700c690ad2fa520e568c44afc1605044b535a7820c1d40e38daa
+ languageName: node
+ linkType: hard
+
+"is-plain-obj@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "is-plain-obj@npm:3.0.0"
+ checksum: a6ebdf8e12ab73f33530641972a72a4b8aed6df04f762070d823808303e4f76d87d5ea5bd76f96a7bbe83d93f04ac7764429c29413bd9049853a69cb630fb21c
+ languageName: node
+ linkType: hard
+
+"is-plain-object@npm:^2.0.4":
+ version: 2.0.4
+ resolution: "is-plain-object@npm:2.0.4"
+ dependencies:
+ isobject: ^3.0.1
+ checksum: 2a401140cfd86cabe25214956ae2cfee6fbd8186809555cd0e84574f88de7b17abacb2e477a6a658fa54c6083ecbda1e6ae404c7720244cd198903848fca70ca
+ languageName: node
+ linkType: hard
+
+"is-regexp@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "is-regexp@npm:1.0.0"
+ checksum: be692828e24cba479ec33644326fa98959ec68ba77965e0291088c1a741feaea4919d79f8031708f85fd25e39de002b4520622b55460660b9c369e6f7187faef
+ languageName: node
+ linkType: hard
+
+"is-root@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "is-root@npm:2.1.0"
+ checksum: 37eea0822a2a9123feb58a9d101558ba276771a6d830f87005683349a9acff15958a9ca590a44e778c6b335660b83e85c744789080d734f6081a935a4880aee2
+ languageName: node
+ linkType: hard
+
+"is-stream@npm:^2.0.0":
+ version: 2.0.1
+ resolution: "is-stream@npm:2.0.1"
+ checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66
+ languageName: node
+ linkType: hard
+
+"is-typedarray@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "is-typedarray@npm:1.0.0"
+ checksum: 3508c6cd0a9ee2e0df2fa2e9baabcdc89e911c7bd5cf64604586697212feec525aa21050e48affb5ffc3df20f0f5d2e2cf79b08caa64e1ccc9578e251763aef7
+ languageName: node
+ linkType: hard
+
+"is-whitespace-character@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "is-whitespace-character@npm:1.0.4"
+ checksum: adab8ad9847ccfcb6f1b7000b8f622881b5ba2a09ce8be2794a6d2b10c3af325b469fc562c9fb889f468eed27be06e227ac609d0aa1e3a59b4dbcc88e2b0418e
+ languageName: node
+ linkType: hard
+
+"is-word-character@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "is-word-character@npm:1.0.4"
+ checksum: 1821d6c6abe5bc0b3abe3fdc565d66d7c8a74ea4e93bc77b4a47d26e2e2a306d6ab7d92b353b0d2b182869e3ecaa8f4a346c62d0e31d38ebc0ceaf7cae182c3f
+ languageName: node
+ linkType: hard
+
+"is-wsl@npm:^2.2.0":
+ version: 2.2.0
+ resolution: "is-wsl@npm:2.2.0"
+ dependencies:
+ is-docker: ^2.0.0
+ checksum: 20849846ae414997d290b75e16868e5261e86ff5047f104027026fd61d8b5a9b0b3ade16239f35e1a067b3c7cc02f70183cb661010ed16f4b6c7c93dad1b19d8
+ languageName: node
+ linkType: hard
+
+"is-yarn-global@npm:^0.3.0":
+ version: 0.3.0
+ resolution: "is-yarn-global@npm:0.3.0"
+ checksum: bca013d65fee2862024c9fbb3ba13720ffca2fe750095174c1c80922fdda16402b5c233f5ac9e265bc12ecb5446e7b7f519a32d9541788f01d4d44e24d2bf481
+ languageName: node
+ linkType: hard
+
+"isarray@npm:0.0.1":
+ version: 0.0.1
+ resolution: "isarray@npm:0.0.1"
+ checksum: 49191f1425681df4a18c2f0f93db3adb85573bcdd6a4482539d98eac9e705d8961317b01175627e860516a2fc45f8f9302db26e5a380a97a520e272e2a40a8d4
+ languageName: node
+ linkType: hard
+
+"isarray@npm:~1.0.0":
+ version: 1.0.0
+ resolution: "isarray@npm:1.0.0"
+ checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab
+ languageName: node
+ linkType: hard
+
+"isexe@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "isexe@npm:2.0.0"
+ checksum: 26bf6c5480dda5161c820c5b5c751ae1e766c587b1f951ea3fcfc973bafb7831ae5b54a31a69bd670220e42e99ec154475025a468eae58ea262f813fdc8d1c62
+ languageName: node
+ linkType: hard
+
+"isobject@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "isobject@npm:3.0.1"
+ checksum: db85c4c970ce30693676487cca0e61da2ca34e8d4967c2e1309143ff910c207133a969f9e4ddb2dc6aba670aabce4e0e307146c310350b298e74a31f7d464703
+ languageName: node
+ linkType: hard
+
+"jest-util@npm:^29.3.1":
+ version: 29.3.1
+ resolution: "jest-util@npm:29.3.1"
+ dependencies:
+ "@jest/types": ^29.3.1
+ "@types/node": "*"
+ chalk: ^4.0.0
+ ci-info: ^3.2.0
+ graceful-fs: ^4.2.9
+ picomatch: ^2.2.3
+ checksum: f67c60f062b94d21cb60e84b3b812d64b7bfa81fe980151de5c17a74eb666042d0134e2e756d099b7606a1fcf1d633824d2e58197d01d76dde1e2dc00dfcd413
+ languageName: node
+ linkType: hard
+
+"jest-worker@npm:^27.4.5":
+ version: 27.5.1
+ resolution: "jest-worker@npm:27.5.1"
+ dependencies:
+ "@types/node": "*"
+ merge-stream: ^2.0.0
+ supports-color: ^8.0.0
+ checksum: 98cd68b696781caed61c983a3ee30bf880b5bd021c01d98f47b143d4362b85d0737f8523761e2713d45e18b4f9a2b98af1eaee77afade4111bb65c77d6f7c980
+ languageName: node
+ linkType: hard
+
+"jest-worker@npm:^29.1.2":
+ version: 29.3.1
+ resolution: "jest-worker@npm:29.3.1"
+ dependencies:
+ "@types/node": "*"
+ jest-util: ^29.3.1
+ merge-stream: ^2.0.0
+ supports-color: ^8.0.0
+ checksum: 38687fcbdc2b7ddc70bbb5dfc703ae095b46b3c7f206d62ecdf5f4d16e336178e217302138f3b906125576bb1cfe4cfe8d43681276fa5899d138ed9422099fb3
+ languageName: node
+ linkType: hard
+
+"joi@npm:^17.6.0":
+ version: 17.7.0
+ resolution: "joi@npm:17.7.0"
+ dependencies:
+ "@hapi/hoek": ^9.0.0
+ "@hapi/topo": ^5.0.0
+ "@sideway/address": ^4.1.3
+ "@sideway/formula": ^3.0.0
+ "@sideway/pinpoint": ^2.0.0
+ checksum: 767a847936cb66787256c4351ff86e1b9e8d7383cbe81a5c827064032c2a8e8b6e938baef5ad32c4035fe4c56e537bd90aa2a952be8a0658601c920cdeb4fb3c
+ languageName: node
+ linkType: hard
+
+"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "js-tokens@npm:4.0.0"
+ checksum: 8a95213a5a77deb6cbe94d86340e8d9ace2b93bc367790b260101d2f36a2eaf4e4e22d9fa9cf459b38af3a32fb4190e638024cf82ec95ef708680e405ea7cc78
+ languageName: node
+ linkType: hard
+
+"js-yaml@npm:^3.13.1":
+ version: 3.14.1
+ resolution: "js-yaml@npm:3.14.1"
+ dependencies:
+ argparse: ^1.0.7
+ esprima: ^4.0.0
+ bin:
+ js-yaml: bin/js-yaml.js
+ checksum: bef146085f472d44dee30ec34e5cf36bf89164f5d585435a3d3da89e52622dff0b188a580e4ad091c3341889e14cb88cac6e4deb16dc5b1e9623bb0601fc255c
+ languageName: node
+ linkType: hard
+
+"js-yaml@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "js-yaml@npm:4.1.0"
+ dependencies:
+ argparse: ^2.0.1
+ bin:
+ js-yaml: bin/js-yaml.js
+ checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a
+ languageName: node
+ linkType: hard
+
+"jsesc@npm:^2.5.1":
+ version: 2.5.2
+ resolution: "jsesc@npm:2.5.2"
+ bin:
+ jsesc: bin/jsesc
+ checksum: 4dc190771129e12023f729ce20e1e0bfceac84d73a85bc3119f7f938843fe25a4aeccb54b6494dce26fcf263d815f5f31acdefac7cc9329efb8422a4f4d9fa9d
+ languageName: node
+ linkType: hard
+
+"jsesc@npm:~0.5.0":
+ version: 0.5.0
+ resolution: "jsesc@npm:0.5.0"
+ bin:
+ jsesc: bin/jsesc
+ checksum: b8b44cbfc92f198ad972fba706ee6a1dfa7485321ee8c0b25f5cedd538dcb20cde3197de16a7265430fce8277a12db066219369e3d51055038946039f6e20e17
+ languageName: node
+ linkType: hard
+
+"json-buffer@npm:3.0.0":
+ version: 3.0.0
+ resolution: "json-buffer@npm:3.0.0"
+ checksum: 0cecacb8025370686a916069a2ff81f7d55167421b6aa7270ee74e244012650dd6bce22b0852202ea7ff8624fce50ff0ec1bdf95914ccb4553426e290d5a63fa
+ languageName: node
+ linkType: hard
+
+"json-parse-even-better-errors@npm:^2.3.0, json-parse-even-better-errors@npm:^2.3.1":
+ version: 2.3.1
+ resolution: "json-parse-even-better-errors@npm:2.3.1"
+ checksum: 798ed4cf3354a2d9ccd78e86d2169515a0097a5c133337807cdf7f1fc32e1391d207ccfc276518cc1d7d8d4db93288b8a50ba4293d212ad1336e52a8ec0a941f
+ languageName: node
+ linkType: hard
+
+"json-schema-traverse@npm:^0.4.1":
+ version: 0.4.1
+ resolution: "json-schema-traverse@npm:0.4.1"
+ checksum: 7486074d3ba247769fda17d5181b345c9fb7d12e0da98b22d1d71a5db9698d8b4bd900a3ec1a4ffdd60846fc2556274a5c894d0c48795f14cb03aeae7b55260b
+ languageName: node
+ linkType: hard
+
+"json-schema-traverse@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "json-schema-traverse@npm:1.0.0"
+ checksum: 02f2f466cdb0362558b2f1fd5e15cce82ef55d60cd7f8fa828cf35ba74330f8d767fcae5c5c2adb7851fa811766c694b9405810879bc4e1ddd78a7c0e03658ad
+ languageName: node
+ linkType: hard
+
+"json5@npm:^2.1.2, json5@npm:^2.2.1":
+ version: 2.2.1
+ resolution: "json5@npm:2.2.1"
+ bin:
+ json5: lib/cli.js
+ checksum: 74b8a23b102a6f2bf2d224797ae553a75488b5adbaee9c9b6e5ab8b510a2fc6e38f876d4c77dea672d4014a44b2399e15f2051ac2b37b87f74c0c7602003543b
+ languageName: node
+ linkType: hard
+
+"jsonfile@npm:^6.0.1":
+ version: 6.1.0
+ resolution: "jsonfile@npm:6.1.0"
+ dependencies:
+ graceful-fs: ^4.1.6
+ universalify: ^2.0.0
+ dependenciesMeta:
+ graceful-fs:
+ optional: true
+ checksum: 7af3b8e1ac8fe7f1eccc6263c6ca14e1966fcbc74b618d3c78a0a2075579487547b94f72b7a1114e844a1e15bb00d440e5d1720bfc4612d790a6f285d5ea8354
+ languageName: node
+ linkType: hard
+
+"keyv@npm:^3.0.0":
+ version: 3.1.0
+ resolution: "keyv@npm:3.1.0"
+ dependencies:
+ json-buffer: 3.0.0
+ checksum: bb7e8f3acffdbafbc2dd5b63f377fe6ec4c0e2c44fc82720449ef8ab54f4a7ce3802671ed94c0f475ae0a8549703353a2124561fcf3317010c141b32ca1ce903
+ languageName: node
+ linkType: hard
+
+"kind-of@npm:^6.0.0, kind-of@npm:^6.0.2":
+ version: 6.0.3
+ resolution: "kind-of@npm:6.0.3"
+ checksum: 3ab01e7b1d440b22fe4c31f23d8d38b4d9b91d9f291df683476576493d5dfd2e03848a8b05813dd0c3f0e835bc63f433007ddeceb71f05cb25c45ae1b19c6d3b
+ languageName: node
+ linkType: hard
+
+"kleur@npm:^3.0.3":
+ version: 3.0.3
+ resolution: "kleur@npm:3.0.3"
+ checksum: df82cd1e172f957bae9c536286265a5cdbd5eeca487cb0a3b2a7b41ef959fc61f8e7c0e9aeea9c114ccf2c166b6a8dd45a46fd619c1c569d210ecd2765ad5169
+ languageName: node
+ linkType: hard
+
+"klona@npm:^2.0.5":
+ version: 2.0.5
+ resolution: "klona@npm:2.0.5"
+ checksum: 8c976126ea252b766e648a4866e1bccff9d3b08432474ad80c559f6c7265cf7caede2498d463754d8c88c4759895edd8210c85c0d3155e6aae4968362889466f
+ languageName: node
+ linkType: hard
+
+"latest-version@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "latest-version@npm:5.1.0"
+ dependencies:
+ package-json: ^6.3.0
+ checksum: fbc72b071eb66c40f652441fd783a9cca62f08bf42433651937f078cd9ef94bf728ec7743992777826e4e89305aef24f234b515e6030503a2cbee7fc9bdc2c0f
+ languageName: node
+ linkType: hard
+
+"leven@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "leven@npm:3.1.0"
+ checksum: 638401d534585261b6003db9d99afd244dfe82d75ddb6db5c0df412842d5ab30b2ef18de471aaec70fe69a46f17b4ae3c7f01d8a4e6580ef7adb9f4273ad1e55
+ languageName: node
+ linkType: hard
+
+"lilconfig@npm:^2.0.3":
+ version: 2.0.6
+ resolution: "lilconfig@npm:2.0.6"
+ checksum: 40a3cd72f103b1be5975f2ac1850810b61d4053e20ab09be8d3aeddfe042187e1ba70b4651a7e70f95efa1642e7dc8b2ae395b317b7d7753b241b43cef7c0f7d
+ languageName: node
+ linkType: hard
+
+"lines-and-columns@npm:^1.1.6":
+ version: 1.2.4
+ resolution: "lines-and-columns@npm:1.2.4"
+ checksum: 0c37f9f7fa212b38912b7145e1cd16a5f3cd34d782441c3e6ca653485d326f58b3caccda66efce1c5812bde4961bbde3374fae4b0d11bf1226152337f3894aa5
+ languageName: node
+ linkType: hard
+
+"loader-runner@npm:^4.2.0":
+ version: 4.3.0
+ resolution: "loader-runner@npm:4.3.0"
+ checksum: a90e00dee9a16be118ea43fec3192d0b491fe03a32ed48a4132eb61d498f5536a03a1315531c19d284392a8726a4ecad71d82044c28d7f22ef62e029bf761569
+ languageName: node
+ linkType: hard
+
+"loader-utils@npm:^2.0.0":
+ version: 2.0.4
+ resolution: "loader-utils@npm:2.0.4"
+ dependencies:
+ big.js: ^5.2.2
+ emojis-list: ^3.0.0
+ json5: ^2.1.2
+ checksum: a5281f5fff1eaa310ad5e1164095689443630f3411e927f95031ab4fb83b4a98f388185bb1fe949e8ab8d4247004336a625e9255c22122b815bb9a4c5d8fc3b7
+ languageName: node
+ linkType: hard
+
+"loader-utils@npm:^3.2.0":
+ version: 3.2.1
+ resolution: "loader-utils@npm:3.2.1"
+ checksum: 4e3ea054cdc8be1ab1f1238f49f42fdf0483039eff920fb1d442039f3f0ad4ebd11fb8e584ccdf2cb7e3c56b3d40c1832416e6408a55651b843da288960cc792
+ languageName: node
+ linkType: hard
+
+"locate-path@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "locate-path@npm:3.0.0"
+ dependencies:
+ p-locate: ^3.0.0
+ path-exists: ^3.0.0
+ checksum: 53db3996672f21f8b0bf2a2c645ae2c13ffdae1eeecfcd399a583bce8516c0b88dcb4222ca6efbbbeb6949df7e46860895be2c02e8d3219abd373ace3bfb4e11
+ languageName: node
+ linkType: hard
+
+"locate-path@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "locate-path@npm:5.0.0"
+ dependencies:
+ p-locate: ^4.1.0
+ checksum: 83e51725e67517287d73e1ded92b28602e3ae5580b301fe54bfb76c0c723e3f285b19252e375712316774cf52006cb236aed5704692c32db0d5d089b69696e30
+ languageName: node
+ linkType: hard
+
+"locate-path@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "locate-path@npm:6.0.0"
+ dependencies:
+ p-locate: ^5.0.0
+ checksum: 72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a
+ languageName: node
+ linkType: hard
+
+"lodash.curry@npm:^4.0.1":
+ version: 4.1.1
+ resolution: "lodash.curry@npm:4.1.1"
+ checksum: 9192b70fe7df4d1ff780c0260bee271afa9168c93fe4fa24bc861900240531b59781b5fdaadf4644fea8f4fbcd96f0700539ab294b579ffc1022c6c15dcc462a
+ languageName: node
+ linkType: hard
+
+"lodash.debounce@npm:^4.0.8":
+ version: 4.0.8
+ resolution: "lodash.debounce@npm:4.0.8"
+ checksum: a3f527d22c548f43ae31c861ada88b2637eb48ac6aa3eb56e82d44917971b8aa96fbb37aa60efea674dc4ee8c42074f90f7b1f772e9db375435f6c83a19b3bc6
+ languageName: node
+ linkType: hard
+
+"lodash.flow@npm:^3.3.0":
+ version: 3.5.0
+ resolution: "lodash.flow@npm:3.5.0"
+ checksum: a9a62ad344e3c5a1f42bc121da20f64dd855aaafecee24b1db640f29b88bd165d81c37ff7e380a7191de6f70b26f5918abcebbee8396624f78f3618a0b18634c
+ languageName: node
+ linkType: hard
+
+"lodash.memoize@npm:^4.1.2":
+ version: 4.1.2
+ resolution: "lodash.memoize@npm:4.1.2"
+ checksum: 9ff3942feeccffa4f1fafa88d32f0d24fdc62fd15ded5a74a5f950ff5f0c6f61916157246744c620173dddf38d37095a92327d5fd3861e2063e736a5c207d089
+ languageName: node
+ linkType: hard
+
+"lodash.uniq@npm:4.5.0, lodash.uniq@npm:^4.5.0":
+ version: 4.5.0
+ resolution: "lodash.uniq@npm:4.5.0"
+ checksum: a4779b57a8d0f3c441af13d9afe7ecff22dd1b8ce1129849f71d9bbc8e8ee4e46dfb4b7c28f7ad3d67481edd6e51126e4e2a6ee276e25906d10f7140187c392d
+ languageName: node
+ linkType: hard
+
+"lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21":
+ version: 4.17.21
+ resolution: "lodash@npm:4.17.21"
+ checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7
+ languageName: node
+ linkType: hard
+
+"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0":
+ version: 1.4.0
+ resolution: "loose-envify@npm:1.4.0"
+ dependencies:
+ js-tokens: ^3.0.0 || ^4.0.0
+ bin:
+ loose-envify: cli.js
+ checksum: 6517e24e0cad87ec9888f500c5b5947032cdfe6ef65e1c1936a0c48a524b81e65542c9c3edc91c97d5bddc806ee2a985dbc79be89215d613b1de5db6d1cfe6f4
+ languageName: node
+ linkType: hard
+
+"lower-case@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "lower-case@npm:2.0.2"
+ dependencies:
+ tslib: ^2.0.3
+ checksum: 83a0a5f159ad7614bee8bf976b96275f3954335a84fad2696927f609ddae902802c4f3312d86668722e668bef41400254807e1d3a7f2e8c3eede79691aa1f010
+ languageName: node
+ linkType: hard
+
+"lowercase-keys@npm:^1.0.0, lowercase-keys@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "lowercase-keys@npm:1.0.1"
+ checksum: 4d045026595936e09953e3867722e309415ff2c80d7701d067546d75ef698dac218a4f53c6d1d0e7368b47e45fd7529df47e6cb56fbb90523ba599f898b3d147
+ languageName: node
+ linkType: hard
+
+"lowercase-keys@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "lowercase-keys@npm:2.0.0"
+ checksum: 24d7ebd56ccdf15ff529ca9e08863f3c54b0b9d1edb97a3ae1af34940ae666c01a1e6d200707bce730a8ef76cb57cc10e65f245ecaaf7e6bc8639f2fb460ac23
+ languageName: node
+ linkType: hard
+
+"lru-cache@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "lru-cache@npm:6.0.0"
+ dependencies:
+ yallist: ^4.0.0
+ checksum: f97f499f898f23e4585742138a22f22526254fdba6d75d41a1c2526b3b6cc5747ef59c5612ba7375f42aca4f8461950e925ba08c991ead0651b4918b7c978297
+ languageName: node
+ linkType: hard
+
+"lru-cache@npm:^7.7.1":
+ version: 7.14.1
+ resolution: "lru-cache@npm:7.14.1"
+ checksum: d72c6713c6a6d86836a7a6523b3f1ac6764768cca47ec99341c3e76db06aacd4764620e5e2cda719a36848785a52a70e531822dc2b33fb071fa709683746c104
+ languageName: node
+ linkType: hard
+
+"make-dir@npm:^3.0.0, make-dir@npm:^3.0.2, make-dir@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "make-dir@npm:3.1.0"
+ dependencies:
+ semver: ^6.0.0
+ checksum: 484200020ab5a1fdf12f393fe5f385fc8e4378824c940fba1729dcd198ae4ff24867bc7a5646331e50cead8abff5d9270c456314386e629acec6dff4b8016b78
+ languageName: node
+ linkType: hard
+
+"make-fetch-happen@npm:^10.0.3":
+ version: 10.2.1
+ resolution: "make-fetch-happen@npm:10.2.1"
+ dependencies:
+ agentkeepalive: ^4.2.1
+ cacache: ^16.1.0
+ http-cache-semantics: ^4.1.0
+ http-proxy-agent: ^5.0.0
+ https-proxy-agent: ^5.0.0
+ is-lambda: ^1.0.1
+ lru-cache: ^7.7.1
+ minipass: ^3.1.6
+ minipass-collect: ^1.0.2
+ minipass-fetch: ^2.0.3
+ minipass-flush: ^1.0.5
+ minipass-pipeline: ^1.2.4
+ negotiator: ^0.6.3
+ promise-retry: ^2.0.1
+ socks-proxy-agent: ^7.0.0
+ ssri: ^9.0.0
+ checksum: 2332eb9a8ec96f1ffeeea56ccefabcb4193693597b132cd110734d50f2928842e22b84cfa1508e921b8385cdfd06dda9ad68645fed62b50fff629a580f5fb72c
+ languageName: node
+ linkType: hard
+
+"markdown-escapes@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "markdown-escapes@npm:1.0.4"
+ checksum: 6833a93d72d3f70a500658872312c6fa8015c20cc835a85ae6901fa232683fbc6ed7118ebe920fea7c80039a560f339c026597d96eee0e9de602a36921804997
+ languageName: node
+ linkType: hard
+
+"mdast-squeeze-paragraphs@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "mdast-squeeze-paragraphs@npm:4.0.0"
+ dependencies:
+ unist-util-remove: ^2.0.0
+ checksum: dfe8ec8e8a62171f020e82b088cc35cb9da787736dc133a3b45ce8811782a93e69bf06d147072e281079f09fac67be8a36153ffffd9bfbf89ed284e4c4f56f75
+ languageName: node
+ linkType: hard
+
+"mdast-util-definitions@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "mdast-util-definitions@npm:4.0.0"
+ dependencies:
+ unist-util-visit: ^2.0.0
+ checksum: 2325f20b82b3fb8cb5fda77038ee0bbdd44f82cfca7c48a854724b58bc1fe5919630a3ce7c45e210726df59d46c881d020b2da7a493bfd1ee36eb2bbfef5d78e
+ languageName: node
+ linkType: hard
+
+"mdast-util-to-hast@npm:10.0.1":
+ version: 10.0.1
+ resolution: "mdast-util-to-hast@npm:10.0.1"
+ dependencies:
+ "@types/mdast": ^3.0.0
+ "@types/unist": ^2.0.0
+ mdast-util-definitions: ^4.0.0
+ mdurl: ^1.0.0
+ unist-builder: ^2.0.0
+ unist-util-generated: ^1.0.0
+ unist-util-position: ^3.0.0
+ unist-util-visit: ^2.0.0
+ checksum: e5f385757df7e9b37db4d6f326bf7b4fc1b40f9ad01fc335686578f44abe0ba46d3e60af4d5e5b763556d02e65069ef9a09c49db049b52659203a43e7fa9084d
+ languageName: node
+ linkType: hard
+
+"mdast-util-to-string@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "mdast-util-to-string@npm:2.0.0"
+ checksum: 0b2113ada10e002fbccb014170506dabe2f2ddacaacbe4bc1045c33f986652c5a162732a2c057c5335cdb58419e2ad23e368e5be226855d4d4e280b81c4e9ec2
+ languageName: node
+ linkType: hard
+
+"mdn-data@npm:2.0.14":
+ version: 2.0.14
+ resolution: "mdn-data@npm:2.0.14"
+ checksum: 9d0128ed425a89f4cba8f787dca27ad9408b5cb1b220af2d938e2a0629d17d879a34d2cb19318bdb26c3f14c77dd5dfbae67211f5caaf07b61b1f2c5c8c7dc16
+ languageName: node
+ linkType: hard
+
+"mdurl@npm:^1.0.0":
+ version: 1.0.1
+ resolution: "mdurl@npm:1.0.1"
+ checksum: 71731ecba943926bfbf9f9b51e28b5945f9411c4eda80894221b47cc105afa43ba2da820732b436f0798fd3edbbffcd1fc1415843c41a87fea08a41cc1e3d02b
+ languageName: node
+ linkType: hard
+
+"media-typer@npm:0.3.0":
+ version: 0.3.0
+ resolution: "media-typer@npm:0.3.0"
+ checksum: af1b38516c28ec95d6b0826f6c8f276c58aec391f76be42aa07646b4e39d317723e869700933ca6995b056db4b09a78c92d5440dc23657e6764be5d28874bba1
+ languageName: node
+ linkType: hard
+
+"memfs@npm:^3.1.2, memfs@npm:^3.4.3":
+ version: 3.4.12
+ resolution: "memfs@npm:3.4.12"
+ dependencies:
+ fs-monkey: ^1.0.3
+ checksum: dab8dec1ae0b2a92e4d563ac86846047cd7aeb17cde4ad51da85cff6e580c32d12b886354527788e36eb75f733dd8edbaf174476b7cea73fed9c5a0e45a6b428
+ languageName: node
+ linkType: hard
+
+"merge-descriptors@npm:1.0.1":
+ version: 1.0.1
+ resolution: "merge-descriptors@npm:1.0.1"
+ checksum: 5abc259d2ae25bb06d19ce2b94a21632583c74e2a9109ee1ba7fd147aa7362b380d971e0251069f8b3eb7d48c21ac839e21fa177b335e82c76ec172e30c31a26
+ languageName: node
+ linkType: hard
+
+"merge-stream@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "merge-stream@npm:2.0.0"
+ checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4
+ languageName: node
+ linkType: hard
+
+"merge2@npm:^1.3.0, merge2@npm:^1.4.1":
+ version: 1.4.1
+ resolution: "merge2@npm:1.4.1"
+ checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2
+ languageName: node
+ linkType: hard
+
+"methods@npm:~1.1.2":
+ version: 1.1.2
+ resolution: "methods@npm:1.1.2"
+ checksum: 0917ff4041fa8e2f2fda5425a955fe16ca411591fbd123c0d722fcf02b73971ed6f764d85f0a6f547ce49ee0221ce2c19a5fa692157931cecb422984f1dcd13a
+ languageName: node
+ linkType: hard
+
+"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5":
+ version: 4.0.5
+ resolution: "micromatch@npm:4.0.5"
+ dependencies:
+ braces: ^3.0.2
+ picomatch: ^2.3.1
+ checksum: 02a17b671c06e8fefeeb6ef996119c1e597c942e632a21ef589154f23898c9c6a9858526246abb14f8bca6e77734aa9dcf65476fca47cedfb80d9577d52843fc
+ languageName: node
+ linkType: hard
+
+"mime-db@npm:1.52.0, mime-db@npm:>= 1.43.0 < 2":
+ version: 1.52.0
+ resolution: "mime-db@npm:1.52.0"
+ checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f
+ languageName: node
+ linkType: hard
+
+"mime-db@npm:~1.33.0":
+ version: 1.33.0
+ resolution: "mime-db@npm:1.33.0"
+ checksum: 281a0772187c9b8f6096976cb193ac639c6007ac85acdbb8dc1617ed7b0f4777fa001d1b4f1b634532815e60717c84b2f280201d55677fb850c9d45015b50084
+ languageName: node
+ linkType: hard
+
+"mime-types@npm:2.1.18":
+ version: 2.1.18
+ resolution: "mime-types@npm:2.1.18"
+ dependencies:
+ mime-db: ~1.33.0
+ checksum: 729265eff1e5a0e87cb7f869da742a610679585167d2f2ec997a7387fc6aedf8e5cad078e99b0164a927bdf3ace34fca27430d6487456ad090cba5594441ba43
+ languageName: node
+ linkType: hard
+
+"mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34":
+ version: 2.1.35
+ resolution: "mime-types@npm:2.1.35"
+ dependencies:
+ mime-db: 1.52.0
+ checksum: 89a5b7f1def9f3af5dad6496c5ed50191ae4331cc5389d7c521c8ad28d5fdad2d06fd81baf38fed813dc4e46bb55c8145bb0ff406330818c9cf712fb2e9b3836
+ languageName: node
+ linkType: hard
+
+"mime@npm:1.6.0":
+ version: 1.6.0
+ resolution: "mime@npm:1.6.0"
+ bin:
+ mime: cli.js
+ checksum: fef25e39263e6d207580bdc629f8872a3f9772c923c7f8c7e793175cee22777bbe8bba95e5d509a40aaa292d8974514ce634ae35769faa45f22d17edda5e8557
+ languageName: node
+ linkType: hard
+
+"mimic-fn@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "mimic-fn@npm:2.1.0"
+ checksum: d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a
+ languageName: node
+ linkType: hard
+
+"mimic-response@npm:^1.0.0, mimic-response@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "mimic-response@npm:1.0.1"
+ checksum: 034c78753b0e622bc03c983663b1cdf66d03861050e0c8606563d149bc2b02d63f62ce4d32be4ab50d0553ae0ffe647fc34d1f5281184c6e1e8cf4d85e8d9823
+ languageName: node
+ linkType: hard
+
+"mini-css-extract-plugin@npm:^2.6.1":
+ version: 2.7.2
+ resolution: "mini-css-extract-plugin@npm:2.7.2"
+ dependencies:
+ schema-utils: ^4.0.0
+ peerDependencies:
+ webpack: ^5.0.0
+ checksum: cd65611d6dc452f230c6ebba8a47bc5f5146b813b13b0b402c6f4a69f6451242eeea781152bebd31cad8ca7c7e95dac91e7e464087f18fb65b2d1097b58cf4ae
+ languageName: node
+ linkType: hard
+
+"minimalistic-assert@npm:^1.0.0":
+ version: 1.0.1
+ resolution: "minimalistic-assert@npm:1.0.1"
+ checksum: cc7974a9268fbf130fb055aff76700d7e2d8be5f761fb5c60318d0ed010d839ab3661a533ad29a5d37653133385204c503bfac995aaa4236f4e847461ea32ba7
+ languageName: node
+ linkType: hard
+
+"minimatch@npm:3.1.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1":
+ version: 3.1.2
+ resolution: "minimatch@npm:3.1.2"
+ dependencies:
+ brace-expansion: ^1.1.7
+ checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a
+ languageName: node
+ linkType: hard
+
+"minimatch@npm:^5.0.1":
+ version: 5.1.1
+ resolution: "minimatch@npm:5.1.1"
+ dependencies:
+ brace-expansion: ^2.0.1
+ checksum: 215edd0978320a3354188f84a537d45841f2449af4df4379f79b9b777e71aa4f5722cc9d1717eabd2a70d38ef76ab7b708d24d83ea6a6c909dfd8833de98b437
+ languageName: node
+ linkType: hard
+
+"minimist@npm:^1.2.0, minimist@npm:^1.2.5":
+ version: 1.2.7
+ resolution: "minimist@npm:1.2.7"
+ checksum: 7346574a1038ca23c32e02252f603801f09384dd1d78b69a943a4e8c2c28730b80e96193882d3d3b22a063445f460e48316b29b8a25addca2d7e5e8f75478bec
+ languageName: node
+ linkType: hard
+
+"minipass-collect@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "minipass-collect@npm:1.0.2"
+ dependencies:
+ minipass: ^3.0.0
+ checksum: 14df761028f3e47293aee72888f2657695ec66bd7d09cae7ad558da30415fdc4752bbfee66287dcc6fd5e6a2fa3466d6c484dc1cbd986525d9393b9523d97f10
+ languageName: node
+ linkType: hard
+
+"minipass-fetch@npm:^2.0.3":
+ version: 2.1.2
+ resolution: "minipass-fetch@npm:2.1.2"
+ dependencies:
+ encoding: ^0.1.13
+ minipass: ^3.1.6
+ minipass-sized: ^1.0.3
+ minizlib: ^2.1.2
+ dependenciesMeta:
+ encoding:
+ optional: true
+ checksum: 3f216be79164e915fc91210cea1850e488793c740534985da017a4cbc7a5ff50506956d0f73bb0cb60e4fe91be08b6b61ef35101706d3ef5da2c8709b5f08f91
+ languageName: node
+ linkType: hard
+
+"minipass-flush@npm:^1.0.5":
+ version: 1.0.5
+ resolution: "minipass-flush@npm:1.0.5"
+ dependencies:
+ minipass: ^3.0.0
+ checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf
+ languageName: node
+ linkType: hard
+
+"minipass-pipeline@npm:^1.2.4":
+ version: 1.2.4
+ resolution: "minipass-pipeline@npm:1.2.4"
+ dependencies:
+ minipass: ^3.0.0
+ checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b
+ languageName: node
+ linkType: hard
+
+"minipass-sized@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "minipass-sized@npm:1.0.3"
+ dependencies:
+ minipass: ^3.0.0
+ checksum: 79076749fcacf21b5d16dd596d32c3b6bf4d6e62abb43868fac21674078505c8b15eaca4e47ed844985a4514854f917d78f588fcd029693709417d8f98b2bd60
+ languageName: node
+ linkType: hard
+
+"minipass@npm:^3.0.0, minipass@npm:^3.1.1, minipass@npm:^3.1.6":
+ version: 3.3.6
+ resolution: "minipass@npm:3.3.6"
+ dependencies:
+ yallist: ^4.0.0
+ checksum: a30d083c8054cee83cdcdc97f97e4641a3f58ae743970457b1489ce38ee1167b3aaf7d815cd39ec7a99b9c40397fd4f686e83750e73e652b21cb516f6d845e48
+ languageName: node
+ linkType: hard
+
+"minipass@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "minipass@npm:4.0.0"
+ dependencies:
+ yallist: ^4.0.0
+ checksum: 7a609afbf394abfcf9c48e6c90226f471676c8f2a67f07f6838871afb03215ede431d1433feffe1b855455bcb13ef0eb89162841b9796109d6fed8d89790f381
+ languageName: node
+ linkType: hard
+
+"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2":
+ version: 2.1.2
+ resolution: "minizlib@npm:2.1.2"
+ dependencies:
+ minipass: ^3.0.0
+ yallist: ^4.0.0
+ checksum: f1fdeac0b07cf8f30fcf12f4b586795b97be856edea22b5e9072707be51fc95d41487faec3f265b42973a304fe3a64acd91a44a3826a963e37b37bafde0212c3
+ languageName: node
+ linkType: hard
+
+"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "mkdirp@npm:1.0.4"
+ bin:
+ mkdirp: bin/cmd.js
+ checksum: a96865108c6c3b1b8e1d5e9f11843de1e077e57737602de1b82030815f311be11f96f09cce59bd5b903d0b29834733e5313f9301e3ed6d6f6fba2eae0df4298f
+ languageName: node
+ linkType: hard
+
+"mrmime@npm:^1.0.0":
+ version: 1.0.1
+ resolution: "mrmime@npm:1.0.1"
+ checksum: cc979da44bbbffebaa8eaf7a45117e851f2d4cb46a3ada6ceb78130466a04c15a0de9a9ce1c8b8ba6f6e1b8618866b1352992bf1757d241c0ddca558b9f28a77
+ languageName: node
+ linkType: hard
+
+"ms@npm:2.0.0":
+ version: 2.0.0
+ resolution: "ms@npm:2.0.0"
+ checksum: 0e6a22b8b746d2e0b65a430519934fefd41b6db0682e3477c10f60c76e947c4c0ad06f63ffdf1d78d335f83edee8c0aa928aa66a36c7cd95b69b26f468d527f4
+ languageName: node
+ linkType: hard
+
+"ms@npm:2.1.2":
+ version: 2.1.2
+ resolution: "ms@npm:2.1.2"
+ checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f
+ languageName: node
+ linkType: hard
+
+"ms@npm:2.1.3, ms@npm:^2.0.0":
+ version: 2.1.3
+ resolution: "ms@npm:2.1.3"
+ checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d
+ languageName: node
+ linkType: hard
+
+"multicast-dns@npm:^7.2.5":
+ version: 7.2.5
+ resolution: "multicast-dns@npm:7.2.5"
+ dependencies:
+ dns-packet: ^5.2.2
+ thunky: ^1.0.2
+ bin:
+ multicast-dns: cli.js
+ checksum: 00b8a57df152d4cd0297946320a94b7c3cdf75a46a2247f32f958a8927dea42958177f9b7fdae69fab2e4e033fb3416881af1f5e9055a3e1542888767139e2fb
+ languageName: node
+ linkType: hard
+
+"nanoid@npm:^3.3.4":
+ version: 3.3.4
+ resolution: "nanoid@npm:3.3.4"
+ bin:
+ nanoid: bin/nanoid.cjs
+ checksum: 2fddd6dee994b7676f008d3ffa4ab16035a754f4bb586c61df5a22cf8c8c94017aadd360368f47d653829e0569a92b129979152ff97af23a558331e47e37cd9c
+ languageName: node
+ linkType: hard
+
+"negotiator@npm:0.6.3, negotiator@npm:^0.6.3":
+ version: 0.6.3
+ resolution: "negotiator@npm:0.6.3"
+ checksum: b8ffeb1e262eff7968fc90a2b6767b04cfd9842582a9d0ece0af7049537266e7b2506dfb1d107a32f06dd849ab2aea834d5830f7f4d0e5cb7d36e1ae55d021d9
+ languageName: node
+ linkType: hard
+
+"neo-async@npm:^2.6.2":
+ version: 2.6.2
+ resolution: "neo-async@npm:2.6.2"
+ checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9
+ languageName: node
+ linkType: hard
+
+"no-case@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "no-case@npm:3.0.4"
+ dependencies:
+ lower-case: ^2.0.2
+ tslib: ^2.0.3
+ checksum: 0b2ebc113dfcf737d48dde49cfebf3ad2d82a8c3188e7100c6f375e30eafbef9e9124aadc3becef237b042fd5eb0aad2fd78669c20972d045bbe7fea8ba0be5c
+ languageName: node
+ linkType: hard
+
+"node-emoji@npm:^1.10.0":
+ version: 1.11.0
+ resolution: "node-emoji@npm:1.11.0"
+ dependencies:
+ lodash: ^4.17.21
+ checksum: e8c856c04a1645062112a72e59a98b203505ed5111ff84a3a5f40611afa229b578c7d50f1e6a7f17aa62baeea4a640d2e2f61f63afc05423aa267af10977fb2b
+ languageName: node
+ linkType: hard
+
+"node-fetch@npm:2.6.7":
+ version: 2.6.7
+ resolution: "node-fetch@npm:2.6.7"
+ dependencies:
+ whatwg-url: ^5.0.0
+ peerDependencies:
+ encoding: ^0.1.0
+ peerDependenciesMeta:
+ encoding:
+ optional: true
+ checksum: 8d816ffd1ee22cab8301c7756ef04f3437f18dace86a1dae22cf81db8ef29c0bf6655f3215cb0cdb22b420b6fe141e64b26905e7f33f9377a7fa59135ea3e10b
+ languageName: node
+ linkType: hard
+
+"node-forge@npm:^1":
+ version: 1.3.1
+ resolution: "node-forge@npm:1.3.1"
+ checksum: 08fb072d3d670599c89a1704b3e9c649ff1b998256737f0e06fbd1a5bf41cae4457ccaee32d95052d80bbafd9ffe01284e078c8071f0267dc9744e51c5ed42a9
+ languageName: node
+ linkType: hard
+
+"node-gyp@npm:latest":
+ version: 9.3.0
+ resolution: "node-gyp@npm:9.3.0"
+ dependencies:
+ env-paths: ^2.2.0
+ glob: ^7.1.4
+ graceful-fs: ^4.2.6
+ make-fetch-happen: ^10.0.3
+ nopt: ^6.0.0
+ npmlog: ^6.0.0
+ rimraf: ^3.0.2
+ semver: ^7.3.5
+ tar: ^6.1.2
+ which: ^2.0.2
+ bin:
+ node-gyp: bin/node-gyp.js
+ checksum: 589ddd3ed967724ef425f9624bfa47cf73022640ab3eba6d556e92cdc4ddef33b63fce3a467c93b995a3f61df92eafd3c3d1e8dbe4a2c00c383334487dea99c3
+ languageName: node
+ linkType: hard
+
+"node-releases@npm:^2.0.6":
+ version: 2.0.6
+ resolution: "node-releases@npm:2.0.6"
+ checksum: e86a926dc9fbb3b41b4c4a89d998afdf140e20a4e8dbe6c0a807f7b2948b42ea97d7fd3ad4868041487b6e9ee98409829c6e4d84a734a4215dff060a7fbeb4bf
+ languageName: node
+ linkType: hard
+
+"nopt@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "nopt@npm:6.0.0"
+ dependencies:
+ abbrev: ^1.0.0
+ bin:
+ nopt: bin/nopt.js
+ checksum: 82149371f8be0c4b9ec2f863cc6509a7fd0fa729929c009f3a58e4eb0c9e4cae9920e8f1f8eb46e7d032fec8fb01bede7f0f41a67eb3553b7b8e14fa53de1dac
+ languageName: node
+ linkType: hard
+
+"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0":
+ version: 3.0.0
+ resolution: "normalize-path@npm:3.0.0"
+ checksum: 88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20
+ languageName: node
+ linkType: hard
+
+"normalize-range@npm:^0.1.2":
+ version: 0.1.2
+ resolution: "normalize-range@npm:0.1.2"
+ checksum: 9b2f14f093593f367a7a0834267c24f3cb3e887a2d9809c77d8a7e5fd08738bcd15af46f0ab01cc3a3d660386f015816b5c922cea8bf2ee79777f40874063184
+ languageName: node
+ linkType: hard
+
+"normalize-url@npm:^4.1.0":
+ version: 4.5.1
+ resolution: "normalize-url@npm:4.5.1"
+ checksum: 9a9dee01df02ad23e171171893e56e22d752f7cff86fb96aafeae074819b572ea655b60f8302e2d85dbb834dc885c972cc1c573892fea24df46b2765065dd05a
+ languageName: node
+ linkType: hard
+
+"normalize-url@npm:^6.0.1":
+ version: 6.1.0
+ resolution: "normalize-url@npm:6.1.0"
+ checksum: 4a4944631173e7d521d6b80e4c85ccaeceb2870f315584fa30121f505a6dfd86439c5e3fdd8cd9e0e291290c41d0c3599f0cb12ab356722ed242584c30348e50
+ languageName: node
+ linkType: hard
+
+"npm-run-path@npm:^4.0.1":
+ version: 4.0.1
+ resolution: "npm-run-path@npm:4.0.1"
+ dependencies:
+ path-key: ^3.0.0
+ checksum: 5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23
+ languageName: node
+ linkType: hard
+
+"npmlog@npm:^6.0.0":
+ version: 6.0.2
+ resolution: "npmlog@npm:6.0.2"
+ dependencies:
+ are-we-there-yet: ^3.0.0
+ console-control-strings: ^1.1.0
+ gauge: ^4.0.3
+ set-blocking: ^2.0.0
+ checksum: ae238cd264a1c3f22091cdd9e2b106f684297d3c184f1146984ecbe18aaa86343953f26b9520dedd1b1372bc0316905b736c1932d778dbeb1fcf5a1001390e2a
+ languageName: node
+ linkType: hard
+
+"nprogress@npm:^0.2.0":
+ version: 0.2.0
+ resolution: "nprogress@npm:0.2.0"
+ checksum: 66b7bec5d563ecf2d1c3d2815e6d5eb74ed815eee8563e0afa63d3f185ab1b9cf2ddd97e1ded263b9995c5019d26d600320e849e50f3747984daa033744619dc
+ languageName: node
+ linkType: hard
+
+"nth-check@npm:^2.0.1":
+ version: 2.1.1
+ resolution: "nth-check@npm:2.1.1"
+ dependencies:
+ boolbase: ^1.0.0
+ checksum: 5afc3dafcd1573b08877ca8e6148c52abd565f1d06b1eb08caf982e3fa289a82f2cae697ffb55b5021e146d60443f1590a5d6b944844e944714a5b549675bcd3
+ languageName: node
+ linkType: hard
+
+"object-assign@npm:^4.1.0, object-assign@npm:^4.1.1":
+ version: 4.1.1
+ resolution: "object-assign@npm:4.1.1"
+ checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f
+ languageName: node
+ linkType: hard
+
+"object-inspect@npm:^1.9.0":
+ version: 1.12.2
+ resolution: "object-inspect@npm:1.12.2"
+ checksum: a534fc1b8534284ed71f25ce3a496013b7ea030f3d1b77118f6b7b1713829262be9e6243acbcb3ef8c626e2b64186112cb7f6db74e37b2789b9c789ca23048b2
+ languageName: node
+ linkType: hard
+
+"object-keys@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "object-keys@npm:1.1.1"
+ checksum: b363c5e7644b1e1b04aa507e88dcb8e3a2f52b6ffd0ea801e4c7a62d5aa559affe21c55a07fd4b1fd55fc03a33c610d73426664b20032405d7b92a1414c34d6a
+ languageName: node
+ linkType: hard
+
+"object.assign@npm:^4.1.0":
+ version: 4.1.4
+ resolution: "object.assign@npm:4.1.4"
+ dependencies:
+ call-bind: ^1.0.2
+ define-properties: ^1.1.4
+ has-symbols: ^1.0.3
+ object-keys: ^1.1.1
+ checksum: 76cab513a5999acbfe0ff355f15a6a125e71805fcf53de4e9d4e082e1989bdb81d1e329291e1e4e0ae7719f0e4ef80e88fb2d367ae60500d79d25a6224ac8864
+ languageName: node
+ linkType: hard
+
+"obuf@npm:^1.0.0, obuf@npm:^1.1.2":
+ version: 1.1.2
+ resolution: "obuf@npm:1.1.2"
+ checksum: 41a2ba310e7b6f6c3b905af82c275bf8854896e2e4c5752966d64cbcd2f599cfffd5932006bcf3b8b419dfdacebb3a3912d5d94e10f1d0acab59876c8757f27f
+ languageName: node
+ linkType: hard
+
+"on-finished@npm:2.4.1":
+ version: 2.4.1
+ resolution: "on-finished@npm:2.4.1"
+ dependencies:
+ ee-first: 1.1.1
+ checksum: d20929a25e7f0bb62f937a425b5edeb4e4cde0540d77ba146ec9357f00b0d497cdb3b9b05b9c8e46222407d1548d08166bff69cc56dfa55ba0e4469228920ff0
+ languageName: node
+ linkType: hard
+
+"on-headers@npm:~1.0.2":
+ version: 1.0.2
+ resolution: "on-headers@npm:1.0.2"
+ checksum: 2bf13467215d1e540a62a75021e8b318a6cfc5d4fc53af8e8f84ad98dbcea02d506c6d24180cd62e1d769c44721ba542f3154effc1f7579a8288c9f7873ed8e5
+ languageName: node
+ linkType: hard
+
+"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0":
+ version: 1.4.0
+ resolution: "once@npm:1.4.0"
+ dependencies:
+ wrappy: 1
+ checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68
+ languageName: node
+ linkType: hard
+
+"onetime@npm:^5.1.2":
+ version: 5.1.2
+ resolution: "onetime@npm:5.1.2"
+ dependencies:
+ mimic-fn: ^2.1.0
+ checksum: 2478859ef817fc5d4e9c2f9e5728512ddd1dbc9fb7829ad263765bb6d3b91ce699d6e2332eef6b7dff183c2f490bd3349f1666427eaba4469fba0ac38dfd0d34
+ languageName: node
+ linkType: hard
+
+"open@npm:^8.0.9, open@npm:^8.4.0":
+ version: 8.4.0
+ resolution: "open@npm:8.4.0"
+ dependencies:
+ define-lazy-prop: ^2.0.0
+ is-docker: ^2.1.1
+ is-wsl: ^2.2.0
+ checksum: e9545bec64cdbf30a0c35c1bdc310344adf8428a117f7d8df3c0af0a0a24c513b304916a6d9b11db0190ff7225c2d578885080b761ed46a3d5f6f1eebb98b63c
+ languageName: node
+ linkType: hard
+
+"opener@npm:^1.5.2":
+ version: 1.5.2
+ resolution: "opener@npm:1.5.2"
+ bin:
+ opener: bin/opener-bin.js
+ checksum: 33b620c0d53d5b883f2abc6687dd1c5fd394d270dbe33a6356f2d71e0a2ec85b100d5bac94694198ccf5c30d592da863b2292c5539009c715a9c80c697b4f6cc
+ languageName: node
+ linkType: hard
+
+"p-cancelable@npm:^1.0.0":
+ version: 1.1.0
+ resolution: "p-cancelable@npm:1.1.0"
+ checksum: 2db3814fef6d9025787f30afaee4496a8857a28be3c5706432cbad76c688a6db1874308f48e364a42f5317f5e41e8e7b4f2ff5c8ff2256dbb6264bc361704ece
+ languageName: node
+ linkType: hard
+
+"p-limit@npm:^2.0.0, p-limit@npm:^2.2.0":
+ version: 2.3.0
+ resolution: "p-limit@npm:2.3.0"
+ dependencies:
+ p-try: ^2.0.0
+ checksum: 84ff17f1a38126c3314e91ecfe56aecbf36430940e2873dadaa773ffe072dc23b7af8e46d4b6485d302a11673fe94c6b67ca2cfbb60c989848b02100d0594ac1
+ languageName: node
+ linkType: hard
+
+"p-limit@npm:^3.0.2":
+ version: 3.1.0
+ resolution: "p-limit@npm:3.1.0"
+ dependencies:
+ yocto-queue: ^0.1.0
+ checksum: 7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360
+ languageName: node
+ linkType: hard
+
+"p-locate@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "p-locate@npm:3.0.0"
+ dependencies:
+ p-limit: ^2.0.0
+ checksum: 83991734a9854a05fe9dbb29f707ea8a0599391f52daac32b86f08e21415e857ffa60f0e120bfe7ce0cc4faf9274a50239c7895fc0d0579d08411e513b83a4ae
+ languageName: node
+ linkType: hard
+
+"p-locate@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "p-locate@npm:4.1.0"
+ dependencies:
+ p-limit: ^2.2.0
+ checksum: 513bd14a455f5da4ebfcb819ef706c54adb09097703de6aeaa5d26fe5ea16df92b48d1ac45e01e3944ce1e6aa2a66f7f8894742b8c9d6e276e16cd2049a2b870
+ languageName: node
+ linkType: hard
+
+"p-locate@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "p-locate@npm:5.0.0"
+ dependencies:
+ p-limit: ^3.0.2
+ checksum: 1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3
+ languageName: node
+ linkType: hard
+
+"p-map@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "p-map@npm:4.0.0"
+ dependencies:
+ aggregate-error: ^3.0.0
+ checksum: cb0ab21ec0f32ddffd31dfc250e3afa61e103ef43d957cc45497afe37513634589316de4eb88abdfd969fe6410c22c0b93ab24328833b8eb1ccc087fc0442a1c
+ languageName: node
+ linkType: hard
+
+"p-retry@npm:^4.5.0":
+ version: 4.6.2
+ resolution: "p-retry@npm:4.6.2"
+ dependencies:
+ "@types/retry": 0.12.0
+ retry: ^0.13.1
+ checksum: 45c270bfddaffb4a895cea16cb760dcc72bdecb6cb45fef1971fa6ea2e91ddeafddefe01e444ac73e33b1b3d5d29fb0dd18a7effb294262437221ddc03ce0f2e
+ languageName: node
+ linkType: hard
+
+"p-try@npm:^2.0.0":
+ version: 2.2.0
+ resolution: "p-try@npm:2.2.0"
+ checksum: f8a8e9a7693659383f06aec604ad5ead237c7a261c18048a6e1b5b85a5f8a067e469aa24f5bc009b991ea3b058a87f5065ef4176793a200d4917349881216cae
+ languageName: node
+ linkType: hard
+
+"package-json@npm:^6.3.0":
+ version: 6.5.0
+ resolution: "package-json@npm:6.5.0"
+ dependencies:
+ got: ^9.6.0
+ registry-auth-token: ^4.0.0
+ registry-url: ^5.0.0
+ semver: ^6.2.0
+ checksum: cc9f890d3667d7610e6184decf543278b87f657d1ace0deb4a9c9155feca738ef88f660c82200763d3348010f4e42e9c7adc91e96ab0f86a770955995b5351e2
+ languageName: node
+ linkType: hard
+
+"param-case@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "param-case@npm:3.0.4"
+ dependencies:
+ dot-case: ^3.0.4
+ tslib: ^2.0.3
+ checksum: b34227fd0f794e078776eb3aa6247442056cb47761e9cd2c4c881c86d84c64205f6a56ef0d70b41ee7d77da02c3f4ed2f88e3896a8fefe08bdfb4deca037c687
+ languageName: node
+ linkType: hard
+
+"parent-module@npm:^1.0.0":
+ version: 1.0.1
+ resolution: "parent-module@npm:1.0.1"
+ dependencies:
+ callsites: ^3.0.0
+ checksum: 6ba8b255145cae9470cf5551eb74be2d22281587af787a2626683a6c20fbb464978784661478dd2a3f1dad74d1e802d403e1b03c1a31fab310259eec8ac560ff
+ languageName: node
+ linkType: hard
+
+"parse-entities@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "parse-entities@npm:2.0.0"
+ dependencies:
+ character-entities: ^1.0.0
+ character-entities-legacy: ^1.0.0
+ character-reference-invalid: ^1.0.0
+ is-alphanumerical: ^1.0.0
+ is-decimal: ^1.0.0
+ is-hexadecimal: ^1.0.0
+ checksum: 7addfd3e7d747521afac33c8121a5f23043c6973809756920d37e806639b4898385d386fcf4b3c8e2ecf1bc28aac5ae97df0b112d5042034efbe80f44081ebce
+ languageName: node
+ linkType: hard
+
+"parse-json@npm:^5.0.0":
+ version: 5.2.0
+ resolution: "parse-json@npm:5.2.0"
+ dependencies:
+ "@babel/code-frame": ^7.0.0
+ error-ex: ^1.3.1
+ json-parse-even-better-errors: ^2.3.0
+ lines-and-columns: ^1.1.6
+ checksum: 62085b17d64da57f40f6afc2ac1f4d95def18c4323577e1eced571db75d9ab59b297d1d10582920f84b15985cbfc6b6d450ccbf317644cfa176f3ed982ad87e2
+ languageName: node
+ linkType: hard
+
+"parse-numeric-range@npm:^1.3.0":
+ version: 1.3.0
+ resolution: "parse-numeric-range@npm:1.3.0"
+ checksum: 289ca126d5b8ace7325b199218de198014f58ea6895ccc88a5247491d07f0143bf047f80b4a31784f1ca8911762278d7d6ecb90a31dfae31da91cc1a2524c8ce
+ languageName: node
+ linkType: hard
+
+"parse5-htmlparser2-tree-adapter@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "parse5-htmlparser2-tree-adapter@npm:7.0.0"
+ dependencies:
+ domhandler: ^5.0.2
+ parse5: ^7.0.0
+ checksum: fc5d01e07733142a1baf81de5c2a9c41426c04b7ab29dd218acb80cd34a63177c90aff4a4aee66cf9f1d0aeecff1389adb7452ad6f8af0a5888e3e9ad6ef733d
+ languageName: node
+ linkType: hard
+
+"parse5@npm:^6.0.0":
+ version: 6.0.1
+ resolution: "parse5@npm:6.0.1"
+ checksum: 7d569a176c5460897f7c8f3377eff640d54132b9be51ae8a8fa4979af940830b2b0c296ce75e5bd8f4041520aadde13170dbdec44889975f906098ea0002f4bd
+ languageName: node
+ linkType: hard
+
+"parse5@npm:^7.0.0":
+ version: 7.1.2
+ resolution: "parse5@npm:7.1.2"
+ dependencies:
+ entities: ^4.4.0
+ checksum: 59465dd05eb4c5ec87b76173d1c596e152a10e290b7abcda1aecf0f33be49646ea74840c69af975d7887543ea45564801736356c568d6b5e71792fd0f4055713
+ languageName: node
+ linkType: hard
+
+"parseurl@npm:~1.3.2, parseurl@npm:~1.3.3":
+ version: 1.3.3
+ resolution: "parseurl@npm:1.3.3"
+ checksum: 407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2
+ languageName: node
+ linkType: hard
+
+"pascal-case@npm:^3.1.2":
+ version: 3.1.2
+ resolution: "pascal-case@npm:3.1.2"
+ dependencies:
+ no-case: ^3.0.4
+ tslib: ^2.0.3
+ checksum: ba98bfd595fc91ef3d30f4243b1aee2f6ec41c53b4546bfa3039487c367abaa182471dcfc830a1f9e1a0df00c14a370514fa2b3a1aacc68b15a460c31116873e
+ languageName: node
+ linkType: hard
+
+"path-exists@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "path-exists@npm:3.0.0"
+ checksum: 96e92643aa34b4b28d0de1cd2eba52a1c5313a90c6542d03f62750d82480e20bfa62bc865d5cfc6165f5fcd5aeb0851043c40a39be5989646f223300021bae0a
+ languageName: node
+ linkType: hard
+
+"path-exists@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "path-exists@npm:4.0.0"
+ checksum: 505807199dfb7c50737b057dd8d351b82c033029ab94cb10a657609e00c1bc53b951cfdbccab8de04c5584d5eff31128ce6afd3db79281874a5ef2adbba55ed1
+ languageName: node
+ linkType: hard
+
+"path-is-absolute@npm:^1.0.0":
+ version: 1.0.1
+ resolution: "path-is-absolute@npm:1.0.1"
+ checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8
+ languageName: node
+ linkType: hard
+
+"path-is-inside@npm:1.0.2":
+ version: 1.0.2
+ resolution: "path-is-inside@npm:1.0.2"
+ checksum: 0b5b6c92d3018b82afb1f74fe6de6338c4c654de4a96123cb343f2b747d5606590ac0c890f956ed38220a4ab59baddfd7b713d78a62d240b20b14ab801fa02cb
+ languageName: node
+ linkType: hard
+
+"path-key@npm:^3.0.0, path-key@npm:^3.1.0":
+ version: 3.1.1
+ resolution: "path-key@npm:3.1.1"
+ checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020
+ languageName: node
+ linkType: hard
+
+"path-parse@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "path-parse@npm:1.0.7"
+ checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a
+ languageName: node
+ linkType: hard
+
+"path-to-regexp@npm:0.1.7":
+ version: 0.1.7
+ resolution: "path-to-regexp@npm:0.1.7"
+ checksum: 69a14ea24db543e8b0f4353305c5eac6907917031340e5a8b37df688e52accd09e3cebfe1660b70d76b6bd89152f52183f28c74813dbf454ba1a01c82a38abce
+ languageName: node
+ linkType: hard
+
+"path-to-regexp@npm:2.2.1":
+ version: 2.2.1
+ resolution: "path-to-regexp@npm:2.2.1"
+ checksum: b921a74e7576e25b06ad1635abf7e8125a29220d2efc2b71d74b9591f24a27e6f09078fa9a1b27516a097ea0637b7cab79d19b83d7f36a8ef3ef5422770e89d9
+ languageName: node
+ linkType: hard
+
+"path-to-regexp@npm:^1.7.0":
+ version: 1.8.0
+ resolution: "path-to-regexp@npm:1.8.0"
+ dependencies:
+ isarray: 0.0.1
+ checksum: 709f6f083c0552514ef4780cb2e7e4cf49b0cc89a97439f2b7cc69a608982b7690fb5d1720a7473a59806508fc2dae0be751ba49f495ecf89fd8fbc62abccbcd
+ languageName: node
+ linkType: hard
+
+"path-type@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "path-type@npm:4.0.0"
+ checksum: 5b1e2daa247062061325b8fdbfd1fb56dde0a448fb1455453276ea18c60685bdad23a445dc148cf87bc216be1573357509b7d4060494a6fd768c7efad833ee45
+ languageName: node
+ linkType: hard
+
+"picocolors@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "picocolors@npm:1.0.0"
+ checksum: a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981
+ languageName: node
+ linkType: hard
+
+"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1":
+ version: 2.3.1
+ resolution: "picomatch@npm:2.3.1"
+ checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf
+ languageName: node
+ linkType: hard
+
+"pkg-dir@npm:^4.1.0":
+ version: 4.2.0
+ resolution: "pkg-dir@npm:4.2.0"
+ dependencies:
+ find-up: ^4.0.0
+ checksum: 9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6
+ languageName: node
+ linkType: hard
+
+"pkg-up@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "pkg-up@npm:3.1.0"
+ dependencies:
+ find-up: ^3.0.0
+ checksum: 5bac346b7c7c903613c057ae3ab722f320716199d753f4a7d053d38f2b5955460f3e6ab73b4762c62fd3e947f58e04f1343e92089e7bb6091c90877406fcd8c8
+ languageName: node
+ linkType: hard
+
+"postcss-calc@npm:^8.2.3":
+ version: 8.2.4
+ resolution: "postcss-calc@npm:8.2.4"
+ dependencies:
+ postcss-selector-parser: ^6.0.9
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.2
+ checksum: 314b4cebb0c4ed0cf8356b4bce71eca78f5a7842e6a3942a3bba49db168d5296b2bd93c3f735ae1c616f2651d94719ade33becc03c73d2d79c7394fb7f73eabb
+ languageName: node
+ linkType: hard
+
+"postcss-colormin@npm:^5.3.0":
+ version: 5.3.0
+ resolution: "postcss-colormin@npm:5.3.0"
+ dependencies:
+ browserslist: ^4.16.6
+ caniuse-api: ^3.0.0
+ colord: ^2.9.1
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 3d3e3cc25071407fb73d68541ca1039ebd154fceb649041461a8a3cab0400cc89b42dbb34a4eeaf573be4ba2370ce23af5e01aff5e03a8d72275f40605577212
+ languageName: node
+ linkType: hard
+
+"postcss-convert-values@npm:^5.1.3":
+ version: 5.1.3
+ resolution: "postcss-convert-values@npm:5.1.3"
+ dependencies:
+ browserslist: ^4.21.4
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: df48cdaffabf9737f9cfdc58a3dc2841cf282506a7a944f6c70236cff295d3a69f63de6e0935eeb8a9d3f504324e5b4e240abc29e21df9e35a02585d3060aeb5
+ languageName: node
+ linkType: hard
+
+"postcss-discard-comments@npm:^5.1.2":
+ version: 5.1.2
+ resolution: "postcss-discard-comments@npm:5.1.2"
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: abfd064ebc27aeaf5037643dd51ffaff74d1fa4db56b0523d073ace4248cbb64ffd9787bd6924b0983a9d0bd0e9bf9f10d73b120e50391dc236e0d26c812fa2a
+ languageName: node
+ linkType: hard
+
+"postcss-discard-duplicates@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-discard-duplicates@npm:5.1.0"
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 88d6964201b1f4ed6bf7a32cefe68e86258bb6e42316ca01d9b32bdb18e7887d02594f89f4a2711d01b51ea6e3fcca8c54be18a59770fe5f4521c61d3eb6ca35
+ languageName: node
+ linkType: hard
+
+"postcss-discard-empty@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "postcss-discard-empty@npm:5.1.1"
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 970adb12fae5c214c0768236ad9a821552626e77dedbf24a8213d19cc2c4a531a757cd3b8cdd3fc22fb1742471b8692a1db5efe436a71236dec12b1318ee8ff4
+ languageName: node
+ linkType: hard
+
+"postcss-discard-overridden@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-discard-overridden@npm:5.1.0"
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: d64d4a545aa2c81b22542895cfcddc787d24119f294d35d29b0599a1c818b3cc51f4ee80b80f5a0a09db282453dd5ac49f104c2117cc09112d0ac9b40b499a41
+ languageName: node
+ linkType: hard
+
+"postcss-discard-unused@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-discard-unused@npm:5.1.0"
+ dependencies:
+ postcss-selector-parser: ^6.0.5
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 5c09403a342a065033f5f22cefe6b402c76c2dc0aac31a736a2062d82c2a09f0ff2525b3df3a0c6f4e0ffc7a0392efd44bfe7f9d018e4cae30d15b818b216622
+ languageName: node
+ linkType: hard
+
+"postcss-loader@npm:^7.0.0":
+ version: 7.0.2
+ resolution: "postcss-loader@npm:7.0.2"
+ dependencies:
+ cosmiconfig: ^7.0.0
+ klona: ^2.0.5
+ semver: ^7.3.8
+ peerDependencies:
+ postcss: ^7.0.0 || ^8.0.1
+ webpack: ^5.0.0
+ checksum: 2d251537d482eb751f812c96c8b515f46d7c9905cad7afab33f0f34872670619b7440cefc9e2babbf89fb11b4708850d522d79fa5ff788227587645e78f16638
+ languageName: node
+ linkType: hard
+
+"postcss-merge-idents@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "postcss-merge-idents@npm:5.1.1"
+ dependencies:
+ cssnano-utils: ^3.1.0
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: ed8a673617ea6ae3e15d69558063cb1a5eeee01732f78cdc0196ab910324abc30828724ab8dfc4cda27e8c0077542e25688470f829819a2604625a673387ec72
+ languageName: node
+ linkType: hard
+
+"postcss-merge-longhand@npm:^5.1.7":
+ version: 5.1.7
+ resolution: "postcss-merge-longhand@npm:5.1.7"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ stylehacks: ^5.1.1
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 81c3fc809f001b9b71a940148e242bdd6e2d77713d1bfffa15eb25c1f06f6648d5e57cb21645746d020a2a55ff31e1740d2b27900442913a9d53d8a01fb37e1b
+ languageName: node
+ linkType: hard
+
+"postcss-merge-rules@npm:^5.1.3":
+ version: 5.1.3
+ resolution: "postcss-merge-rules@npm:5.1.3"
+ dependencies:
+ browserslist: ^4.21.4
+ caniuse-api: ^3.0.0
+ cssnano-utils: ^3.1.0
+ postcss-selector-parser: ^6.0.5
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 0ddaddff98cd7f3fac2b0e716c641f529a61a8668be6d5b48d60770d0a1246126088e1d606f309b9748ff598a3794f3fd6dd5b8c3d79112f84744cab5375d4d9
+ languageName: node
+ linkType: hard
+
+"postcss-minify-font-values@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-minify-font-values@npm:5.1.0"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 35e858fa41efa05acdeb28f1c76579c409fdc7eabb1744c3bd76e895bb9fea341a016746362a67609688ab2471f587202b9a3e14ea28ad677754d663a2777ece
+ languageName: node
+ linkType: hard
+
+"postcss-minify-gradients@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "postcss-minify-gradients@npm:5.1.1"
+ dependencies:
+ colord: ^2.9.1
+ cssnano-utils: ^3.1.0
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 27354072a07c5e6dab36731103b94ca2354d4ed3c5bc6aacfdf2ede5a55fa324679d8fee5450800bc50888dbb5e9ed67569c0012040c2be128143d0cebb36d67
+ languageName: node
+ linkType: hard
+
+"postcss-minify-params@npm:^5.1.4":
+ version: 5.1.4
+ resolution: "postcss-minify-params@npm:5.1.4"
+ dependencies:
+ browserslist: ^4.21.4
+ cssnano-utils: ^3.1.0
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: bd63e2cc89edcf357bb5c2a16035f6d02ef676b8cede4213b2bddd42626b3d428403849188f95576fc9f03e43ebd73a29bf61d33a581be9a510b13b7f7f100d5
+ languageName: node
+ linkType: hard
+
+"postcss-minify-selectors@npm:^5.2.1":
+ version: 5.2.1
+ resolution: "postcss-minify-selectors@npm:5.2.1"
+ dependencies:
+ postcss-selector-parser: ^6.0.5
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 6fdbc84f99a60d56b43df8930707da397775e4c36062a106aea2fd2ac81b5e24e584a1892f4baa4469fa495cb87d1422560eaa8f6c9d500f9f0b691a5f95bab5
+ languageName: node
+ linkType: hard
+
+"postcss-modules-extract-imports@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "postcss-modules-extract-imports@npm:3.0.0"
+ peerDependencies:
+ postcss: ^8.1.0
+ checksum: 4b65f2f1382d89c4bc3c0a1bdc5942f52f3cb19c110c57bd591ffab3a5fee03fcf831604168205b0c1b631a3dce2255c70b61aaae3ef39d69cd7eb450c2552d2
+ languageName: node
+ linkType: hard
+
+"postcss-modules-local-by-default@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "postcss-modules-local-by-default@npm:4.0.0"
+ dependencies:
+ icss-utils: ^5.0.0
+ postcss-selector-parser: ^6.0.2
+ postcss-value-parser: ^4.1.0
+ peerDependencies:
+ postcss: ^8.1.0
+ checksum: 6cf570badc7bc26c265e073f3ff9596b69bb954bc6ac9c5c1b8cba2995b80834226b60e0a3cbb87d5f399dbb52e6466bba8aa1d244f6218f99d834aec431a69d
+ languageName: node
+ linkType: hard
+
+"postcss-modules-scope@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "postcss-modules-scope@npm:3.0.0"
+ dependencies:
+ postcss-selector-parser: ^6.0.4
+ peerDependencies:
+ postcss: ^8.1.0
+ checksum: 330b9398dbd44c992c92b0dc612c0626135e2cc840fee41841eb61247a6cfed95af2bd6f67ead9dd9d0bb41f5b0367129d93c6e434fa3e9c58ade391d9a5a138
+ languageName: node
+ linkType: hard
+
+"postcss-modules-values@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "postcss-modules-values@npm:4.0.0"
+ dependencies:
+ icss-utils: ^5.0.0
+ peerDependencies:
+ postcss: ^8.1.0
+ checksum: f7f2cdf14a575b60e919ad5ea52fed48da46fe80db2733318d71d523fc87db66c835814940d7d05b5746b0426e44661c707f09bdb83592c16aea06e859409db6
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-charset@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-normalize-charset@npm:5.1.0"
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: e79d92971fc05b8b3c9b72f3535a574e077d13c69bef68156a0965f397fdf157de670da72b797f57b0e3bac8f38155b5dd1735ecab143b9cc4032d72138193b4
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-display-values@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-normalize-display-values@npm:5.1.0"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: b6eb7b9b02c3bdd62bbc54e01e2b59733d73a1c156905d238e178762962efe0c6f5104544da39f32cade8a4fb40f10ff54b63a8ebfbdff51e8780afb9fbdcf86
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-positions@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "postcss-normalize-positions@npm:5.1.1"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: d9afc233729c496463c7b1cdd06732469f401deb387484c3a2422125b46ec10b4af794c101f8c023af56f01970b72b535e88373b9058ecccbbf88db81662b3c4
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-repeat-style@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "postcss-normalize-repeat-style@npm:5.1.1"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 2c6ad2b0ae10a1fda156b948c34f78c8f1e185513593de4d7e2480973586675520edfec427645fa168c337b0a6b3ceca26f92b96149741ca98a9806dad30d534
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-string@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-normalize-string@npm:5.1.0"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 6e549c6e5b2831e34c7bdd46d8419e2278f6af1d5eef6d26884a37c162844e60339340c57e5e06058cdbe32f27fc6258eef233e811ed2f71168ef2229c236ada
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-timing-functions@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-normalize-timing-functions@npm:5.1.0"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: da550f50e90b0b23e17b67449a7d1efd1aa68288e66d4aa7614ca6f5cc012896be1972b7168eee673d27da36504faccf7b9f835c0f7e81243f966a42c8c030aa
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-unicode@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "postcss-normalize-unicode@npm:5.1.1"
+ dependencies:
+ browserslist: ^4.21.4
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 4c24d26cc9f4b19a9397db4e71dd600dab690f1de8e14a3809e2aa1452dbc3791c208c38a6316bbc142f29e934fdf02858e68c94038c06174d78a4937e0f273c
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-url@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-normalize-url@npm:5.1.0"
+ dependencies:
+ normalize-url: ^6.0.1
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 3bd4b3246d6600230bc827d1760b24cb3101827ec97570e3016cbe04dc0dd28f4dbe763245d1b9d476e182c843008fbea80823061f1d2219b96f0d5c724a24c0
+ languageName: node
+ linkType: hard
+
+"postcss-normalize-whitespace@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "postcss-normalize-whitespace@npm:5.1.1"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 12d8fb6d1c1cba208cc08c1830959b7d7ad447c3f5581873f7e185f99a9a4230c43d3af21ca12c818e4690a5085a95b01635b762ad4a7bef69d642609b4c0e19
+ languageName: node
+ linkType: hard
+
+"postcss-ordered-values@npm:^5.1.3":
+ version: 5.1.3
+ resolution: "postcss-ordered-values@npm:5.1.3"
+ dependencies:
+ cssnano-utils: ^3.1.0
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 6f3ca85b6ceffc68aadaf319d9ee4c5ac16d93195bf8cba2d1559b631555ad61941461cda6d3909faab86e52389846b2b36345cff8f0c3f4eb345b1b8efadcf9
+ languageName: node
+ linkType: hard
+
+"postcss-reduce-idents@npm:^5.2.0":
+ version: 5.2.0
+ resolution: "postcss-reduce-idents@npm:5.2.0"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: f0d644c86e160dd36ee4dd924ab7d6feacac867c87702e2f98f96b409430a62de4fec2dfc3c8731bda4e14196e29a752b4558942f0af2a3e6cd7f1f4b173db8e
+ languageName: node
+ linkType: hard
+
+"postcss-reduce-initial@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "postcss-reduce-initial@npm:5.1.1"
+ dependencies:
+ browserslist: ^4.21.4
+ caniuse-api: ^3.0.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 1b704aba8c38103cbb5a75c6201dbf58ec2f3a978013c7f7e8957fd3bf3282f992050dec5a01bc050d031bad836e187dd6622b922ca78ab92bcd0afd21fb0b98
+ languageName: node
+ linkType: hard
+
+"postcss-reduce-transforms@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-reduce-transforms@npm:5.1.0"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 0c6af2cba20e3ff63eb9ad045e634ddfb9c3e5c0e614c020db2a02f3aa20632318c4ede9e0c995f9225d9a101e673de91c0a6e10bb2fa5da6d6c75d15a55882f
+ languageName: node
+ linkType: hard
+
+"postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.9":
+ version: 6.0.11
+ resolution: "postcss-selector-parser@npm:6.0.11"
+ dependencies:
+ cssesc: ^3.0.0
+ util-deprecate: ^1.0.2
+ checksum: 0b01aa9c2d2c8dbeb51e9b204796b678284be9823abc8d6d40a8b16d4149514e922c264a8ed4deb4d6dbced564b9be390f5942c058582d8656351516d6c49cde
+ languageName: node
+ linkType: hard
+
+"postcss-sort-media-queries@npm:^4.2.1":
+ version: 4.3.0
+ resolution: "postcss-sort-media-queries@npm:4.3.0"
+ dependencies:
+ sort-css-media-queries: 2.1.0
+ peerDependencies:
+ postcss: ^8.4.16
+ checksum: 7bf9fcde74781f40ca49484e84dcd26e491632b296ba77b3f4b7ea7778f816ac48f87d2c6ab0a629edf636440a4240615b69a4ece1dd7597f6a4e0678794eb0e
+ languageName: node
+ linkType: hard
+
+"postcss-svgo@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-svgo@npm:5.1.0"
+ dependencies:
+ postcss-value-parser: ^4.2.0
+ svgo: ^2.7.0
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: d86eb5213d9f700cf5efe3073799b485fb7cacae0c731db3d7749c9c2b1c9bc85e95e0baeca439d699ff32ea24815fc916c4071b08f67ed8219df229ce1129bd
+ languageName: node
+ linkType: hard
+
+"postcss-unique-selectors@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "postcss-unique-selectors@npm:5.1.1"
+ dependencies:
+ postcss-selector-parser: ^6.0.5
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 637e7b786e8558265775c30400c54b6b3b24d4748923f4a39f16a65fd0e394f564ccc9f0a1d3c0e770618a7637a7502ea1d0d79f731d429cb202255253c23278
+ languageName: node
+ linkType: hard
+
+"postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0":
+ version: 4.2.0
+ resolution: "postcss-value-parser@npm:4.2.0"
+ checksum: 819ffab0c9d51cf0acbabf8996dffbfafbafa57afc0e4c98db88b67f2094cb44488758f06e5da95d7036f19556a4a732525e84289a425f4f6fd8e412a9d7442f
+ languageName: node
+ linkType: hard
+
+"postcss-zindex@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "postcss-zindex@npm:5.1.0"
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 8581e0ee552622489dcb9fb9609a3ccc261a67a229ba91a70bd138fe102a2d04cedb14642b82b673d4cac7b559ef32574f2dafde2ff7816eecac024d231c5ead
+ languageName: node
+ linkType: hard
+
+"postcss@npm:^8.3.11, postcss@npm:^8.4.14, postcss@npm:^8.4.17, postcss@npm:^8.4.18":
+ version: 8.4.20
+ resolution: "postcss@npm:8.4.20"
+ dependencies:
+ nanoid: ^3.3.4
+ picocolors: ^1.0.0
+ source-map-js: ^1.0.2
+ checksum: 1a5609ea1c1b204f9c2974a0019ae9eef2d99bf645c2c9aac675166c4cb1005be7b5e2ba196160bc771f5d9ac896ed883f236f888c891e835e59d28fff6651aa
+ languageName: node
+ linkType: hard
+
+"prepend-http@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "prepend-http@npm:2.0.0"
+ checksum: 7694a9525405447662c1ffd352fcb41b6410c705b739b6f4e3a3e21cf5fdede8377890088e8934436b8b17ba55365a615f153960f30877bf0d0392f9e93503ea
+ languageName: node
+ linkType: hard
+
+"prettier@npm:^2.6.2":
+ version: 2.8.1
+ resolution: "prettier@npm:2.8.1"
+ bin:
+ prettier: bin-prettier.js
+ checksum: 4f21a0f1269f76fb36f54e9a8a1ea4c11e27478958bf860661fb4b6d7ac69aac1581f8724fa98ea3585e56d42a2ea317a17ff6e3324f40cb11ff9e20b73785cc
+ languageName: node
+ linkType: hard
+
+"pretty-error@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "pretty-error@npm:4.0.0"
+ dependencies:
+ lodash: ^4.17.20
+ renderkid: ^3.0.0
+ checksum: a5b9137365690104ded6947dca2e33360bf55e62a4acd91b1b0d7baa3970e43754c628cc9e16eafbdd4e8f8bcb260a5865475d4fc17c3106ff2d61db4e72cdf3
+ languageName: node
+ linkType: hard
+
+"pretty-time@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "pretty-time@npm:1.1.0"
+ checksum: a319e7009aadbc6cfedbd8b66861327d3a0c68bd3e8794bf5b86f62b40b01b9479c5a70c76bb368ad454acce52a1216daee460cc825766e2442c04f3a84a02c9
+ languageName: node
+ linkType: hard
+
+"prism-react-renderer@npm:^1.3.5":
+ version: 1.3.5
+ resolution: "prism-react-renderer@npm:1.3.5"
+ peerDependencies:
+ react: ">=0.14.9"
+ checksum: c18806dcbc4c0b4fd6fd15bd06b4f7c0a6da98d93af235c3e970854994eb9b59e23315abb6cfc29e69da26d36709a47e25da85ab27fed81b6812f0a52caf6dfa
+ languageName: node
+ linkType: hard
+
+"prismjs@npm:^1.28.0":
+ version: 1.29.0
+ resolution: "prismjs@npm:1.29.0"
+ checksum: 007a8869d4456ff8049dc59404e32d5666a07d99c3b0e30a18bd3b7676dfa07d1daae9d0f407f20983865fd8da56de91d09cb08e6aa61f5bc420a27c0beeaf93
+ languageName: node
+ linkType: hard
+
+"process-nextick-args@npm:~2.0.0":
+ version: 2.0.1
+ resolution: "process-nextick-args@npm:2.0.1"
+ checksum: 1d38588e520dab7cea67cbbe2efdd86a10cc7a074c09657635e34f035277b59fbb57d09d8638346bf7090f8e8ebc070c96fa5fd183b777fff4f5edff5e9466cf
+ languageName: node
+ linkType: hard
+
+"promise-inflight@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "promise-inflight@npm:1.0.1"
+ checksum: 22749483091d2c594261517f4f80e05226d4d5ecc1fc917e1886929da56e22b5718b7f2a75f3807e7a7d471bc3be2907fe92e6e8f373ddf5c64bae35b5af3981
+ languageName: node
+ linkType: hard
+
+"promise-retry@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "promise-retry@npm:2.0.1"
+ dependencies:
+ err-code: ^2.0.2
+ retry: ^0.12.0
+ checksum: f96a3f6d90b92b568a26f71e966cbbc0f63ab85ea6ff6c81284dc869b41510e6cdef99b6b65f9030f0db422bf7c96652a3fff9f2e8fb4a0f069d8f4430359429
+ languageName: node
+ linkType: hard
+
+"promise@npm:^7.1.1":
+ version: 7.3.1
+ resolution: "promise@npm:7.3.1"
+ dependencies:
+ asap: ~2.0.3
+ checksum: 475bb069130179fbd27ed2ab45f26d8862376a137a57314cf53310bdd85cc986a826fd585829be97ebc0aaf10e9d8e68be1bfe5a4a0364144b1f9eedfa940cf1
+ languageName: node
+ linkType: hard
+
+"prompts@npm:^2.4.2":
+ version: 2.4.2
+ resolution: "prompts@npm:2.4.2"
+ dependencies:
+ kleur: ^3.0.3
+ sisteransi: ^1.0.5
+ checksum: d8fd1fe63820be2412c13bfc5d0a01909acc1f0367e32396962e737cb2fc52d004f3302475d5ce7d18a1e8a79985f93ff04ee03007d091029c3f9104bffc007d
+ languageName: node
+ linkType: hard
+
+"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2":
+ version: 15.8.1
+ resolution: "prop-types@npm:15.8.1"
+ dependencies:
+ loose-envify: ^1.4.0
+ object-assign: ^4.1.1
+ react-is: ^16.13.1
+ checksum: c056d3f1c057cb7ff8344c645450e14f088a915d078dcda795041765047fa080d38e5d626560ccaac94a4e16e3aa15f3557c1a9a8d1174530955e992c675e459
+ languageName: node
+ linkType: hard
+
+"property-information@npm:^5.0.0, property-information@npm:^5.3.0":
+ version: 5.6.0
+ resolution: "property-information@npm:5.6.0"
+ dependencies:
+ xtend: ^4.0.0
+ checksum: fcf87c6542e59a8bbe31ca0b3255a4a63ac1059b01b04469680288998bcfa97f341ca989566adbb63975f4d85339030b82320c324a511532d390910d1c583893
+ languageName: node
+ linkType: hard
+
+"proxy-addr@npm:~2.0.7":
+ version: 2.0.7
+ resolution: "proxy-addr@npm:2.0.7"
+ dependencies:
+ forwarded: 0.2.0
+ ipaddr.js: 1.9.1
+ checksum: 29c6990ce9364648255454842f06f8c46fcd124d3e6d7c5066df44662de63cdc0bad032e9bf5a3d653ff72141cc7b6019873d685708ac8210c30458ad99f2b74
+ languageName: node
+ linkType: hard
+
+"pump@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "pump@npm:3.0.0"
+ dependencies:
+ end-of-stream: ^1.1.0
+ once: ^1.3.1
+ checksum: e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9
+ languageName: node
+ linkType: hard
+
+"punycode@npm:^1.3.2":
+ version: 1.4.1
+ resolution: "punycode@npm:1.4.1"
+ checksum: fa6e698cb53db45e4628559e557ddaf554103d2a96a1d62892c8f4032cd3bc8871796cae9eabc1bc700e2b6677611521ce5bb1d9a27700086039965d0cf34518
+ languageName: node
+ linkType: hard
+
+"punycode@npm:^2.1.0":
+ version: 2.1.1
+ resolution: "punycode@npm:2.1.1"
+ checksum: 823bf443c6dd14f669984dea25757b37993f67e8d94698996064035edd43bed8a5a17a9f12e439c2b35df1078c6bec05a6c86e336209eb1061e8025c481168e8
+ languageName: node
+ linkType: hard
+
+"pupa@npm:^2.1.1":
+ version: 2.1.1
+ resolution: "pupa@npm:2.1.1"
+ dependencies:
+ escape-goat: ^2.0.0
+ checksum: 49529e50372ffdb0cccf0efa0f3b3cb0a2c77805d0d9cc2725bd2a0f6bb414631e61c93a38561b26be1259550b7bb6c2cb92315aa09c8bf93f3bdcb49f2b2fb7
+ languageName: node
+ linkType: hard
+
+"pure-color@npm:^1.2.0":
+ version: 1.3.0
+ resolution: "pure-color@npm:1.3.0"
+ checksum: 646d8bed6e6eab89affdd5e2c11f607a85b631a7fb03c061dfa658eb4dc4806881a15feed2ac5fd8c0bad8c00c632c640d5b1cb8b9a972e6e947393a1329371b
+ languageName: node
+ linkType: hard
+
+"qs@npm:6.11.0":
+ version: 6.11.0
+ resolution: "qs@npm:6.11.0"
+ dependencies:
+ side-channel: ^1.0.4
+ checksum: 6e1f29dd5385f7488ec74ac7b6c92f4d09a90408882d0c208414a34dd33badc1a621019d4c799a3df15ab9b1d0292f97c1dd71dc7c045e69f81a8064e5af7297
+ languageName: node
+ linkType: hard
+
+"queue-microtask@npm:^1.2.2":
+ version: 1.2.3
+ resolution: "queue-microtask@npm:1.2.3"
+ checksum: b676f8c040cdc5b12723ad2f91414d267605b26419d5c821ff03befa817ddd10e238d22b25d604920340fd73efd8ba795465a0377c4adf45a4a41e4234e42dc4
+ languageName: node
+ linkType: hard
+
+"queue@npm:6.0.2":
+ version: 6.0.2
+ resolution: "queue@npm:6.0.2"
+ dependencies:
+ inherits: ~2.0.3
+ checksum: ebc23639248e4fe40a789f713c20548e513e053b3dc4924b6cb0ad741e3f264dcff948225c8737834dd4f9ec286dbc06a1a7c13858ea382d9379f4303bcc0916
+ languageName: node
+ linkType: hard
+
+"randombytes@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "randombytes@npm:2.1.0"
+ dependencies:
+ safe-buffer: ^5.1.0
+ checksum: d779499376bd4cbb435ef3ab9a957006c8682f343f14089ed5f27764e4645114196e75b7f6abf1cbd84fd247c0cb0651698444df8c9bf30e62120fbbc52269d6
+ languageName: node
+ linkType: hard
+
+"range-parser@npm:1.2.0":
+ version: 1.2.0
+ resolution: "range-parser@npm:1.2.0"
+ checksum: bdf397f43fedc15c559d3be69c01dedf38444ca7a1610f5bf5955e3f3da6057a892f34691e7ebdd8c7e1698ce18ef6c4d4811f70e658dda3ff230ef741f8423a
+ languageName: node
+ linkType: hard
+
+"range-parser@npm:^1.2.1, range-parser@npm:~1.2.1":
+ version: 1.2.1
+ resolution: "range-parser@npm:1.2.1"
+ checksum: 0a268d4fea508661cf5743dfe3d5f47ce214fd6b7dec1de0da4d669dd4ef3d2144468ebe4179049eff253d9d27e719c88dae55be64f954e80135a0cada804ec9
+ languageName: node
+ linkType: hard
+
+"raw-body@npm:2.5.1":
+ version: 2.5.1
+ resolution: "raw-body@npm:2.5.1"
+ dependencies:
+ bytes: 3.1.2
+ http-errors: 2.0.0
+ iconv-lite: 0.4.24
+ unpipe: 1.0.0
+ checksum: 5362adff1575d691bb3f75998803a0ffed8c64eabeaa06e54b4ada25a0cd1b2ae7f4f5ec46565d1bec337e08b5ac90c76eaa0758de6f72a633f025d754dec29e
+ languageName: node
+ linkType: hard
+
+"rc@npm:1.2.8, rc@npm:^1.2.8":
+ version: 1.2.8
+ resolution: "rc@npm:1.2.8"
+ dependencies:
+ deep-extend: ^0.6.0
+ ini: ~1.3.0
+ minimist: ^1.2.0
+ strip-json-comments: ~2.0.1
+ bin:
+ rc: ./cli.js
+ checksum: 2e26e052f8be2abd64e6d1dabfbd7be03f80ec18ccbc49562d31f617d0015fbdbcf0f9eed30346ea6ab789e0fdfe4337f033f8016efdbee0df5354751842080e
+ languageName: node
+ linkType: hard
+
+"react-base16-styling@npm:^0.6.0":
+ version: 0.6.0
+ resolution: "react-base16-styling@npm:0.6.0"
+ dependencies:
+ base16: ^1.0.0
+ lodash.curry: ^4.0.1
+ lodash.flow: ^3.3.0
+ pure-color: ^1.2.0
+ checksum: 00a12dddafc8a9025cca933b0dcb65fca41c81fa176d1fc3a6a9d0242127042e2c0a604f4c724a3254dd2c6aeb5ef55095522ff22f5462e419641c1341a658e4
+ languageName: node
+ linkType: hard
+
+"react-dev-utils@npm:^12.0.1":
+ version: 12.0.1
+ resolution: "react-dev-utils@npm:12.0.1"
+ dependencies:
+ "@babel/code-frame": ^7.16.0
+ address: ^1.1.2
+ browserslist: ^4.18.1
+ chalk: ^4.1.2
+ cross-spawn: ^7.0.3
+ detect-port-alt: ^1.1.6
+ escape-string-regexp: ^4.0.0
+ filesize: ^8.0.6
+ find-up: ^5.0.0
+ fork-ts-checker-webpack-plugin: ^6.5.0
+ global-modules: ^2.0.0
+ globby: ^11.0.4
+ gzip-size: ^6.0.0
+ immer: ^9.0.7
+ is-root: ^2.1.0
+ loader-utils: ^3.2.0
+ open: ^8.4.0
+ pkg-up: ^3.1.0
+ prompts: ^2.4.2
+ react-error-overlay: ^6.0.11
+ recursive-readdir: ^2.2.2
+ shell-quote: ^1.7.3
+ strip-ansi: ^6.0.1
+ text-table: ^0.2.0
+ checksum: 2c6917e47f03d9595044770b0f883a61c6b660fcaa97b8ba459a1d57c9cca9aa374cd51296b22d461ff5e432105dbe6f04732dab128e52729c79239e1c23ab56
+ languageName: node
+ linkType: hard
+
+"react-dom@npm:^17.0.2":
+ version: 17.0.2
+ resolution: "react-dom@npm:17.0.2"
+ dependencies:
+ loose-envify: ^1.1.0
+ object-assign: ^4.1.1
+ scheduler: ^0.20.2
+ peerDependencies:
+ react: 17.0.2
+ checksum: 1c1eaa3bca7c7228d24b70932e3d7c99e70d1d04e13bb0843bbf321582bc25d7961d6b8a6978a58a598af2af496d1cedcfb1bf65f6b0960a0a8161cb8dab743c
+ languageName: node
+ linkType: hard
+
+"react-error-overlay@npm:^6.0.11":
+ version: 6.0.11
+ resolution: "react-error-overlay@npm:6.0.11"
+ checksum: ce7b44c38fadba9cedd7c095cf39192e632daeccf1d0747292ed524f17dcb056d16bc197ddee5723f9dd888f0b9b19c3b486c430319e30504289b9296f2d2c42
+ languageName: node
+ linkType: hard
+
+"react-fast-compare@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "react-fast-compare@npm:3.2.0"
+ checksum: 8ef272c825ae329f61633ce4ce7f15aa5b84e5214d88bc0823880236e03e985a13195befa2c7a4eda7db3b017dc7985729152d88445823f652403cf36c2b86aa
+ languageName: node
+ linkType: hard
+
+"react-helmet-async@npm:*, react-helmet-async@npm:^1.3.0":
+ version: 1.3.0
+ resolution: "react-helmet-async@npm:1.3.0"
+ dependencies:
+ "@babel/runtime": ^7.12.5
+ invariant: ^2.2.4
+ prop-types: ^15.7.2
+ react-fast-compare: ^3.2.0
+ shallowequal: ^1.1.0
+ peerDependencies:
+ react: ^16.6.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0
+ checksum: 7ca7e47f8af14ea186688b512a87ab912bf6041312b297f92516341b140b3f0f8aedf5a44d226d99e69ed067b0cc106e38aeb9c9b738ffcc63d10721c844db90
+ languageName: node
+ linkType: hard
+
+"react-is@npm:^16.13.1, react-is@npm:^16.6.0, react-is@npm:^16.7.0":
+ version: 16.13.1
+ resolution: "react-is@npm:16.13.1"
+ checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f
+ languageName: node
+ linkType: hard
+
+"react-json-view@npm:^1.21.3":
+ version: 1.21.3
+ resolution: "react-json-view@npm:1.21.3"
+ dependencies:
+ flux: ^4.0.1
+ react-base16-styling: ^0.6.0
+ react-lifecycles-compat: ^3.0.4
+ react-textarea-autosize: ^8.3.2
+ peerDependencies:
+ react: ^17.0.0 || ^16.3.0 || ^15.5.4
+ react-dom: ^17.0.0 || ^16.3.0 || ^15.5.4
+ checksum: 5718bcd9210ad5b06eb9469cf8b9b44be9498845a7702e621343618e8251f26357e6e1c865532cf170db6165df1cb30202787e057309d8848c220bc600ec0d1a
+ languageName: node
+ linkType: hard
+
+"react-lifecycles-compat@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "react-lifecycles-compat@npm:3.0.4"
+ checksum: a904b0fc0a8eeb15a148c9feb7bc17cec7ef96e71188280061fc340043fd6d8ee3ff233381f0e8f95c1cf926210b2c4a31f38182c8f35ac55057e453d6df204f
+ languageName: node
+ linkType: hard
+
+"react-loadable-ssr-addon-v5-slorber@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "react-loadable-ssr-addon-v5-slorber@npm:1.0.1"
+ dependencies:
+ "@babel/runtime": ^7.10.3
+ peerDependencies:
+ react-loadable: "*"
+ webpack: ">=4.41.1 || 5.x"
+ checksum: 1cf7ceb488d329a5be15f891dae16727fb7ade08ef57826addd21e2c3d485e2440259ef8be94f4d54e9afb4bcbd2fcc22c3c5bad92160c9c06ae6ba7b5562497
+ languageName: node
+ linkType: hard
+
+"react-router-config@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "react-router-config@npm:5.1.1"
+ dependencies:
+ "@babel/runtime": ^7.1.2
+ peerDependencies:
+ react: ">=15"
+ react-router: ">=5"
+ checksum: bde7ee79444454bf7c3737fd9c5c268021012c8cc37bc19116b2e7daa28c4231598c275816c7f32c16f9f974dc707b91de279291a5e39efce2e1b1569355b87a
+ languageName: node
+ linkType: hard
+
+"react-router-dom@npm:^5.3.3":
+ version: 5.3.4
+ resolution: "react-router-dom@npm:5.3.4"
+ dependencies:
+ "@babel/runtime": ^7.12.13
+ history: ^4.9.0
+ loose-envify: ^1.3.1
+ prop-types: ^15.6.2
+ react-router: 5.3.4
+ tiny-invariant: ^1.0.2
+ tiny-warning: ^1.0.0
+ peerDependencies:
+ react: ">=15"
+ checksum: b86a6f2f5222f041e38adf4e4b32c7643d6735a1a915ef25855b2db285fd059d72ba8d62e5bcd5d822b8ef9520a80453209e55077f5a90d0f72e908979b8f535
+ languageName: node
+ linkType: hard
+
+"react-router@npm:5.3.4, react-router@npm:^5.3.3":
+ version: 5.3.4
+ resolution: "react-router@npm:5.3.4"
+ dependencies:
+ "@babel/runtime": ^7.12.13
+ history: ^4.9.0
+ hoist-non-react-statics: ^3.1.0
+ loose-envify: ^1.3.1
+ path-to-regexp: ^1.7.0
+ prop-types: ^15.6.2
+ react-is: ^16.6.0
+ tiny-invariant: ^1.0.2
+ tiny-warning: ^1.0.0
+ peerDependencies:
+ react: ">=15"
+ checksum: 892d4e274a23bf4f39abc2efca54472fb646d3aed4b584020cf49654d2f50d09a2bacebe7c92b4ec7cb8925077376dfcd0664bad6442a73604397cefec9f01f9
+ languageName: node
+ linkType: hard
+
+"react-textarea-autosize@npm:^8.3.2":
+ version: 8.4.0
+ resolution: "react-textarea-autosize@npm:8.4.0"
+ dependencies:
+ "@babel/runtime": ^7.10.2
+ use-composed-ref: ^1.3.0
+ use-latest: ^1.2.1
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ checksum: 055fb51b74e1ab6b286490cfcd8ed77a760f6fc90706053b5dfcb138199d02c56289a1060a1daf9f3ae37ffd66f73e9553f026d0fad446bc2243b713acf48e05
+ languageName: node
+ linkType: hard
+
+"react@npm:^17.0.2":
+ version: 17.0.2
+ resolution: "react@npm:17.0.2"
+ dependencies:
+ loose-envify: ^1.1.0
+ object-assign: ^4.1.1
+ checksum: b254cc17ce3011788330f7bbf383ab653c6848902d7936a87b09d835d091e3f295f7e9dd1597c6daac5dc80f90e778c8230218ba8ad599f74adcc11e33b9d61b
+ languageName: node
+ linkType: hard
+
+"readable-stream@npm:^2.0.1":
+ version: 2.3.7
+ resolution: "readable-stream@npm:2.3.7"
+ dependencies:
+ core-util-is: ~1.0.0
+ inherits: ~2.0.3
+ isarray: ~1.0.0
+ process-nextick-args: ~2.0.0
+ safe-buffer: ~5.1.1
+ string_decoder: ~1.1.1
+ util-deprecate: ~1.0.1
+ checksum: e4920cf7549a60f8aaf694d483a0e61b2a878b969d224f89b3bc788b8d920075132c4b55a7494ee944c7b6a9a0eada28a7f6220d80b0312ece70bbf08eeca755
+ languageName: node
+ linkType: hard
+
+"readable-stream@npm:^3.0.6, readable-stream@npm:^3.6.0":
+ version: 3.6.0
+ resolution: "readable-stream@npm:3.6.0"
+ dependencies:
+ inherits: ^2.0.3
+ string_decoder: ^1.1.1
+ util-deprecate: ^1.0.1
+ checksum: d4ea81502d3799439bb955a3a5d1d808592cf3133350ed352aeaa499647858b27b1c4013984900238b0873ec8d0d8defce72469fb7a83e61d53f5ad61cb80dc8
+ languageName: node
+ linkType: hard
+
+"readdirp@npm:~3.6.0":
+ version: 3.6.0
+ resolution: "readdirp@npm:3.6.0"
+ dependencies:
+ picomatch: ^2.2.1
+ checksum: 1ced032e6e45670b6d7352d71d21ce7edf7b9b928494dcaba6f11fba63180d9da6cd7061ebc34175ffda6ff529f481818c962952004d273178acd70f7059b320
+ languageName: node
+ linkType: hard
+
+"reading-time@npm:^1.5.0":
+ version: 1.5.0
+ resolution: "reading-time@npm:1.5.0"
+ checksum: e27bc5a70ba0f4ac337896b18531b914d38f4bee67cbad48029d0c11dd0a7a847b2a6bba895ab7ce2ad3e7ecb86912bdc477d8fa2d48405a3deda964be54d09b
+ languageName: node
+ linkType: hard
+
+"rechoir@npm:^0.6.2":
+ version: 0.6.2
+ resolution: "rechoir@npm:0.6.2"
+ dependencies:
+ resolve: ^1.1.6
+ checksum: fe76bf9c21875ac16e235defedd7cbd34f333c02a92546142b7911a0f7c7059d2e16f441fe6fb9ae203f459c05a31b2bcf26202896d89e390eda7514d5d2702b
+ languageName: node
+ linkType: hard
+
+"recursive-readdir@npm:^2.2.2":
+ version: 2.2.3
+ resolution: "recursive-readdir@npm:2.2.3"
+ dependencies:
+ minimatch: ^3.0.5
+ checksum: 88ec96e276237290607edc0872b4f9842837b95cfde0cdbb1e00ba9623dfdf3514d44cdd14496ab60a0c2dd180a6ef8a3f1c34599e6cf2273afac9b72a6fb2b5
+ languageName: node
+ linkType: hard
+
+"regenerate-unicode-properties@npm:^10.1.0":
+ version: 10.1.0
+ resolution: "regenerate-unicode-properties@npm:10.1.0"
+ dependencies:
+ regenerate: ^1.4.2
+ checksum: b1a8929588433ab8b9dc1a34cf3665b3b472f79f2af6ceae00d905fc496b332b9af09c6718fb28c730918f19a00dc1d7310adbaa9b72a2ec7ad2f435da8ace17
+ languageName: node
+ linkType: hard
+
+"regenerate@npm:^1.4.2":
+ version: 1.4.2
+ resolution: "regenerate@npm:1.4.2"
+ checksum: 3317a09b2f802da8db09aa276e469b57a6c0dd818347e05b8862959c6193408242f150db5de83c12c3fa99091ad95fb42a6db2c3329bfaa12a0ea4cbbeb30cb0
+ languageName: node
+ linkType: hard
+
+"regenerator-runtime@npm:^0.13.11":
+ version: 0.13.11
+ resolution: "regenerator-runtime@npm:0.13.11"
+ checksum: 27481628d22a1c4e3ff551096a683b424242a216fee44685467307f14d58020af1e19660bf2e26064de946bad7eff28950eae9f8209d55723e2d9351e632bbb4
+ languageName: node
+ linkType: hard
+
+"regenerator-transform@npm:^0.15.1":
+ version: 0.15.1
+ resolution: "regenerator-transform@npm:0.15.1"
+ dependencies:
+ "@babel/runtime": ^7.8.4
+ checksum: 2d15bdeadbbfb1d12c93f5775493d85874dbe1d405bec323da5c61ec6e701bc9eea36167483e1a5e752de9b2df59ab9a2dfff6bf3784f2b28af2279a673d29a4
+ languageName: node
+ linkType: hard
+
+"regexpu-core@npm:^5.2.1":
+ version: 5.2.2
+ resolution: "regexpu-core@npm:5.2.2"
+ dependencies:
+ regenerate: ^1.4.2
+ regenerate-unicode-properties: ^10.1.0
+ regjsgen: ^0.7.1
+ regjsparser: ^0.9.1
+ unicode-match-property-ecmascript: ^2.0.0
+ unicode-match-property-value-ecmascript: ^2.1.0
+ checksum: 87c56815e20d213848d38f6b047ba52f0d632f36e791b777f59327e8d350c0743b27cc25feab64c0eadc9fe9959dde6b1261af71108a9371b72c8c26beda05ef
+ languageName: node
+ linkType: hard
+
+"registry-auth-token@npm:^4.0.0":
+ version: 4.2.2
+ resolution: "registry-auth-token@npm:4.2.2"
+ dependencies:
+ rc: 1.2.8
+ checksum: c5030198546ecfdcbcb0722cbc3e260c4f5f174d8d07bdfedd4620e79bfdf17a2db735aa230d600bd388fce6edd26c0a9ed2eb7e9b4641ec15213a28a806688b
+ languageName: node
+ linkType: hard
+
+"registry-url@npm:^5.0.0":
+ version: 5.1.0
+ resolution: "registry-url@npm:5.1.0"
+ dependencies:
+ rc: ^1.2.8
+ checksum: bcea86c84a0dbb66467b53187fadebfea79017cddfb4a45cf27530d7275e49082fe9f44301976eb0164c438e395684bcf3dae4819b36ff9d1640d8cc60c73df9
+ languageName: node
+ linkType: hard
+
+"regjsgen@npm:^0.7.1":
+ version: 0.7.1
+ resolution: "regjsgen@npm:0.7.1"
+ checksum: 7cac399921c58db8e16454869283ff66871531180218064fa938ac05c11c2976792a00706c3c78bbc625e1d793ca373065ea90564e06189a751a7b4ae33acadc
+ languageName: node
+ linkType: hard
+
+"regjsparser@npm:^0.9.1":
+ version: 0.9.1
+ resolution: "regjsparser@npm:0.9.1"
+ dependencies:
+ jsesc: ~0.5.0
+ bin:
+ regjsparser: bin/parser
+ checksum: 5e1b76afe8f1d03c3beaf9e0d935dd467589c3625f6d65fb8ffa14f224d783a0fed4bf49c2c1b8211043ef92b6117313419edf055a098ed8342e340586741afc
+ languageName: node
+ linkType: hard
+
+"relateurl@npm:^0.2.7":
+ version: 0.2.7
+ resolution: "relateurl@npm:0.2.7"
+ checksum: 5891e792eae1dfc3da91c6fda76d6c3de0333a60aa5ad848982ebb6dccaa06e86385fb1235a1582c680a3d445d31be01c6bfc0804ebbcab5aaf53fa856fde6b6
+ languageName: node
+ linkType: hard
+
+"remark-emoji@npm:^2.2.0":
+ version: 2.2.0
+ resolution: "remark-emoji@npm:2.2.0"
+ dependencies:
+ emoticon: ^3.2.0
+ node-emoji: ^1.10.0
+ unist-util-visit: ^2.0.3
+ checksum: 638d4be72eb4110a447f389d4b8c454921f188c0acabf1b6579f3ddaa301ee91010173d6eebd975ea622ae3de7ed4531c0315a4ffd4f9653d80c599ef9ec21a8
+ languageName: node
+ linkType: hard
+
+"remark-footnotes@npm:2.0.0":
+ version: 2.0.0
+ resolution: "remark-footnotes@npm:2.0.0"
+ checksum: f2f87ffd6fe25892373c7164d6584a7cb03ab0ea4f186af493a73df519e24b72998a556e7f16cb996f18426cdb80556b95ff252769e252cf3ccba0fd2ca20621
+ languageName: node
+ linkType: hard
+
+"remark-mdx@npm:1.6.22":
+ version: 1.6.22
+ resolution: "remark-mdx@npm:1.6.22"
+ dependencies:
+ "@babel/core": 7.12.9
+ "@babel/helper-plugin-utils": 7.10.4
+ "@babel/plugin-proposal-object-rest-spread": 7.12.1
+ "@babel/plugin-syntax-jsx": 7.12.1
+ "@mdx-js/util": 1.6.22
+ is-alphabetical: 1.0.4
+ remark-parse: 8.0.3
+ unified: 9.2.0
+ checksum: 45e62f8a821c37261f94448d54f295de1c5c393f762ff96cd4d4b730715037fafeb6c89ef94adf6a10a09edfa72104afe1431b93b5ae5e40ce2a7677e133c3d9
+ languageName: node
+ linkType: hard
+
+"remark-parse@npm:8.0.3":
+ version: 8.0.3
+ resolution: "remark-parse@npm:8.0.3"
+ dependencies:
+ ccount: ^1.0.0
+ collapse-white-space: ^1.0.2
+ is-alphabetical: ^1.0.0
+ is-decimal: ^1.0.0
+ is-whitespace-character: ^1.0.0
+ is-word-character: ^1.0.0
+ markdown-escapes: ^1.0.0
+ parse-entities: ^2.0.0
+ repeat-string: ^1.5.4
+ state-toggle: ^1.0.0
+ trim: 0.0.1
+ trim-trailing-lines: ^1.0.0
+ unherit: ^1.0.4
+ unist-util-remove-position: ^2.0.0
+ vfile-location: ^3.0.0
+ xtend: ^4.0.1
+ checksum: 2dfea250e7606ddfc9e223b9f41e0b115c5c701be4bd35181beaadd46ee59816bc00aadc6085a420f8df00b991ada73b590ea7fd34ace14557de4a0a41805be5
+ languageName: node
+ linkType: hard
+
+"remark-squeeze-paragraphs@npm:4.0.0":
+ version: 4.0.0
+ resolution: "remark-squeeze-paragraphs@npm:4.0.0"
+ dependencies:
+ mdast-squeeze-paragraphs: ^4.0.0
+ checksum: 2071eb74d0ecfefb152c4932690a9fd950c3f9f798a676f1378a16db051da68fb20bf288688cc153ba5019dded35408ff45a31dfe9686eaa7a9f1df9edbb6c81
+ languageName: node
+ linkType: hard
+
+"renderkid@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "renderkid@npm:3.0.0"
+ dependencies:
+ css-select: ^4.1.3
+ dom-converter: ^0.2.0
+ htmlparser2: ^6.1.0
+ lodash: ^4.17.21
+ strip-ansi: ^6.0.1
+ checksum: 77162b62d6f33ab81f337c39efce0439ff0d1f6d441e29c35183151f83041c7850774fb904da163d6c844264d440d10557714e6daa0b19e4561a5cd4ef305d41
+ languageName: node
+ linkType: hard
+
+"repeat-string@npm:^1.5.4":
+ version: 1.6.1
+ resolution: "repeat-string@npm:1.6.1"
+ checksum: 1b809fc6db97decdc68f5b12c4d1a671c8e3f65ec4a40c238bc5200e44e85bcc52a54f78268ab9c29fcf5fe4f1343e805420056d1f30fa9a9ee4c2d93e3cc6c0
+ languageName: node
+ linkType: hard
+
+"require-from-string@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "require-from-string@npm:2.0.2"
+ checksum: a03ef6895445f33a4015300c426699bc66b2b044ba7b670aa238610381b56d3f07c686251740d575e22f4c87531ba662d06937508f0f3c0f1ddc04db3130560b
+ languageName: node
+ linkType: hard
+
+"require-like@npm:>= 0.1.1":
+ version: 0.1.2
+ resolution: "require-like@npm:0.1.2"
+ checksum: edb8331f05fd807381a75b76f6cca9f0ce8acaa2e910b7e116541799aa970bfbc64fde5fd6adb3a6917dba346f8386ebbddb81614c24e8dad1b4290c7af9535e
+ languageName: node
+ linkType: hard
+
+"requires-port@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "requires-port@npm:1.0.0"
+ checksum: eee0e303adffb69be55d1a214e415cf42b7441ae858c76dfc5353148644f6fd6e698926fc4643f510d5c126d12a705e7c8ed7e38061113bdf37547ab356797ff
+ languageName: node
+ linkType: hard
+
+"resolve-from@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "resolve-from@npm:4.0.0"
+ checksum: f4ba0b8494846a5066328ad33ef8ac173801a51739eb4d63408c847da9a2e1c1de1e6cbbf72699211f3d13f8fc1325648b169bd15eb7da35688e30a5fb0e4a7f
+ languageName: node
+ linkType: hard
+
+"resolve-pathname@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "resolve-pathname@npm:3.0.0"
+ checksum: 6147241ba42c423dbe83cb067a2b4af4f60908c3af57e1ea567729cc71416c089737fe2a73e9e79e7a60f00f66c91e4b45ad0d37cd4be2d43fec44963ef14368
+ languageName: node
+ linkType: hard
+
+"resolve@npm:^1.1.6, resolve@npm:^1.14.2, resolve@npm:^1.3.2":
+ version: 1.22.1
+ resolution: "resolve@npm:1.22.1"
+ dependencies:
+ is-core-module: ^2.9.0
+ path-parse: ^1.0.7
+ supports-preserve-symlinks-flag: ^1.0.0
+ bin:
+ resolve: bin/resolve
+ checksum: 07af5fc1e81aa1d866cbc9e9460fbb67318a10fa3c4deadc35c3ad8a898ee9a71a86a65e4755ac3195e0ea0cfbe201eb323ebe655ce90526fd61917313a34e4e
+ languageName: node
+ linkType: hard
+
+"resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.3.2#~builtin":
+ version: 1.22.1
+ resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=07638b"
+ dependencies:
+ is-core-module: ^2.9.0
+ path-parse: ^1.0.7
+ supports-preserve-symlinks-flag: ^1.0.0
+ bin:
+ resolve: bin/resolve
+ checksum: 5656f4d0bedcf8eb52685c1abdf8fbe73a1603bb1160a24d716e27a57f6cecbe2432ff9c89c2bd57542c3a7b9d14b1882b73bfe2e9d7849c9a4c0b8b39f02b8b
+ languageName: node
+ linkType: hard
+
+"responselike@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "responselike@npm:1.0.2"
+ dependencies:
+ lowercase-keys: ^1.0.0
+ checksum: 2e9e70f1dcca3da621a80ce71f2f9a9cad12c047145c6ece20df22f0743f051cf7c73505e109814915f23f9e34fb0d358e22827723ee3d56b623533cab8eafcd
+ languageName: node
+ linkType: hard
+
+"retry@npm:^0.12.0":
+ version: 0.12.0
+ resolution: "retry@npm:0.12.0"
+ checksum: 623bd7d2e5119467ba66202d733ec3c2e2e26568074923bc0585b6b99db14f357e79bdedb63cab56cec47491c4a0da7e6021a7465ca6dc4f481d3898fdd3158c
+ languageName: node
+ linkType: hard
+
+"retry@npm:^0.13.1":
+ version: 0.13.1
+ resolution: "retry@npm:0.13.1"
+ checksum: 47c4d5be674f7c13eee4cfe927345023972197dbbdfba5d3af7e461d13b44de1bfd663bfc80d2f601f8ef3fc8164c16dd99655a221921954a65d044a2fc1233b
+ languageName: node
+ linkType: hard
+
+"reusify@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "reusify@npm:1.0.4"
+ checksum: c3076ebcc22a6bc252cb0b9c77561795256c22b757f40c0d8110b1300723f15ec0fc8685e8d4ea6d7666f36c79ccc793b1939c748bf36f18f542744a4e379fcc
+ languageName: node
+ linkType: hard
+
+"rimraf@npm:^3.0.2":
+ version: 3.0.2
+ resolution: "rimraf@npm:3.0.2"
+ dependencies:
+ glob: ^7.1.3
+ bin:
+ rimraf: bin.js
+ checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0
+ languageName: node
+ linkType: hard
+
+"rtl-detect@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "rtl-detect@npm:1.0.4"
+ checksum: d562535baa0db62f57f0a1d4676297bff72fd6b94e88f0f0900d5c3e810ab512c5c4cadffd3e05fbe8d9c74310c919afa3ea8c1001c244e5555e8eef12d02d6f
+ languageName: node
+ linkType: hard
+
+"rtlcss@npm:^3.5.0":
+ version: 3.5.0
+ resolution: "rtlcss@npm:3.5.0"
+ dependencies:
+ find-up: ^5.0.0
+ picocolors: ^1.0.0
+ postcss: ^8.3.11
+ strip-json-comments: ^3.1.1
+ bin:
+ rtlcss: bin/rtlcss.js
+ checksum: a3763cad2cb58ce1b950de155097c3c294e7aefc8bf328b58d0cc8d5efb88bf800865edc158a78ace6d1f7f99fea6fd66fb4a354d859b172dadd3dab3e0027b3
+ languageName: node
+ linkType: hard
+
+"run-parallel@npm:^1.1.9":
+ version: 1.2.0
+ resolution: "run-parallel@npm:1.2.0"
+ dependencies:
+ queue-microtask: ^1.2.2
+ checksum: cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d
+ languageName: node
+ linkType: hard
+
+"rxjs@npm:^7.5.4":
+ version: 7.6.0
+ resolution: "rxjs@npm:7.6.0"
+ dependencies:
+ tslib: ^2.1.0
+ checksum: b3abbbfe1ddfd06fca9314b83cbd13bcddc3320429218136f75c79a4802ac430dd13873364aac1ded54fd457f8c77df332d205a92d8a1c61656565bb718c50af
+ languageName: node
+ linkType: hard
+
+"safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1":
+ version: 5.1.2
+ resolution: "safe-buffer@npm:5.1.2"
+ checksum: f2f1f7943ca44a594893a852894055cf619c1fbcb611237fc39e461ae751187e7baf4dc391a72125e0ac4fb2d8c5c0b3c71529622e6a58f46b960211e704903c
+ languageName: node
+ linkType: hard
+
+"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0":
+ version: 5.2.1
+ resolution: "safe-buffer@npm:5.2.1"
+ checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491
+ languageName: node
+ linkType: hard
+
+"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0":
+ version: 2.1.2
+ resolution: "safer-buffer@npm:2.1.2"
+ checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0
+ languageName: node
+ linkType: hard
+
+"sax@npm:^1.2.4":
+ version: 1.2.4
+ resolution: "sax@npm:1.2.4"
+ checksum: d3df7d32b897a2c2f28e941f732c71ba90e27c24f62ee918bd4d9a8cfb3553f2f81e5493c7f0be94a11c1911b643a9108f231dd6f60df3fa9586b5d2e3e9e1fe
+ languageName: node
+ linkType: hard
+
+"scheduler@npm:^0.20.2":
+ version: 0.20.2
+ resolution: "scheduler@npm:0.20.2"
+ dependencies:
+ loose-envify: ^1.1.0
+ object-assign: ^4.1.1
+ checksum: c4b35cf967c8f0d3e65753252d0f260271f81a81e427241295c5a7b783abf4ea9e905f22f815ab66676f5313be0a25f47be582254db8f9241b259213e999b8fc
+ languageName: node
+ linkType: hard
+
+"schema-utils@npm:2.7.0":
+ version: 2.7.0
+ resolution: "schema-utils@npm:2.7.0"
+ dependencies:
+ "@types/json-schema": ^7.0.4
+ ajv: ^6.12.2
+ ajv-keywords: ^3.4.1
+ checksum: 8889325b0ee1ae6a8f5d6aaa855c71e136ebbb7fd731b01a9d3ec8225dcb245f644c47c50104db4c741983b528cdff8558570021257d4d397ec6aaecd9172a8e
+ languageName: node
+ linkType: hard
+
+"schema-utils@npm:^2.6.5":
+ version: 2.7.1
+ resolution: "schema-utils@npm:2.7.1"
+ dependencies:
+ "@types/json-schema": ^7.0.5
+ ajv: ^6.12.4
+ ajv-keywords: ^3.5.2
+ checksum: 32c62fc9e28edd101e1bd83453a4216eb9bd875cc4d3775e4452b541908fa8f61a7bbac8ffde57484f01d7096279d3ba0337078e85a918ecbeb72872fb09fb2b
+ languageName: node
+ linkType: hard
+
+"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.0, schema-utils@npm:^3.1.1":
+ version: 3.1.1
+ resolution: "schema-utils@npm:3.1.1"
+ dependencies:
+ "@types/json-schema": ^7.0.8
+ ajv: ^6.12.5
+ ajv-keywords: ^3.5.2
+ checksum: fb73f3d759d43ba033c877628fe9751620a26879f6301d3dbeeb48cf2a65baec5cdf99da65d1bf3b4ff5444b2e59cbe4f81c2456b5e0d2ba7d7fd4aed5da29ce
+ languageName: node
+ linkType: hard
+
+"schema-utils@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "schema-utils@npm:4.0.0"
+ dependencies:
+ "@types/json-schema": ^7.0.9
+ ajv: ^8.8.0
+ ajv-formats: ^2.1.1
+ ajv-keywords: ^5.0.0
+ checksum: c843e92fdd1a5c145dbb6ffdae33e501867f9703afac67bdf35a685e49f85b1dcc10ea250033175a64bd9d31f0555bc6785b8359da0c90bcea30cf6dfbb55a8f
+ languageName: node
+ linkType: hard
+
+"section-matter@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "section-matter@npm:1.0.0"
+ dependencies:
+ extend-shallow: ^2.0.1
+ kind-of: ^6.0.0
+ checksum: 3cc4131705493b2955729b075dcf562359bba66183debb0332752dc9cad35616f6da7a23e42b6cab45cd2e4bb5cda113e9e84c8f05aee77adb6b0289a0229101
+ languageName: node
+ linkType: hard
+
+"select-hose@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "select-hose@npm:2.0.0"
+ checksum: d7e5fcc695a4804209d232a1b18624a5134be334d4e1114b0721f7a5e72bd73da483dcf41528c1af4f4f4892ad7cfd6a1e55c8ffb83f9c9fe723b738db609dbb
+ languageName: node
+ linkType: hard
+
+"selfsigned@npm:^2.1.1":
+ version: 2.1.1
+ resolution: "selfsigned@npm:2.1.1"
+ dependencies:
+ node-forge: ^1
+ checksum: aa9ce2150a54838978d5c0aee54d7ebe77649a32e4e690eb91775f71fdff773874a4fbafd0ac73d8ec3b702ff8a395c604df4f8e8868528f36fd6c15076fb43a
+ languageName: node
+ linkType: hard
+
+"semver-diff@npm:^3.1.1":
+ version: 3.1.1
+ resolution: "semver-diff@npm:3.1.1"
+ dependencies:
+ semver: ^6.3.0
+ checksum: 8bbe5a5d7add2d5e51b72314a9215cd294d71f41cdc2bf6bd59ee76411f3610b576172896f1d191d0d7294cb9f2f847438d2ee158adacc0c224dca79052812fe
+ languageName: node
+ linkType: hard
+
+"semver@npm:^5.4.1":
+ version: 5.7.1
+ resolution: "semver@npm:5.7.1"
+ bin:
+ semver: ./bin/semver
+ checksum: 57fd0acfd0bac382ee87cd52cd0aaa5af086a7dc8d60379dfe65fea491fb2489b6016400813930ecd61fd0952dae75c115287a1b16c234b1550887117744dfaf
+ languageName: node
+ linkType: hard
+
+"semver@npm:^6.0.0, semver@npm:^6.1.1, semver@npm:^6.1.2, semver@npm:^6.2.0, semver@npm:^6.3.0":
+ version: 6.3.0
+ resolution: "semver@npm:6.3.0"
+ bin:
+ semver: ./bin/semver.js
+ checksum: 1b26ecf6db9e8292dd90df4e781d91875c0dcc1b1909e70f5d12959a23c7eebb8f01ea581c00783bbee72ceeaad9505797c381756326073850dc36ed284b21b9
+ languageName: node
+ linkType: hard
+
+"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8":
+ version: 7.3.8
+ resolution: "semver@npm:7.3.8"
+ dependencies:
+ lru-cache: ^6.0.0
+ bin:
+ semver: bin/semver.js
+ checksum: ba9c7cbbf2b7884696523450a61fee1a09930d888b7a8d7579025ad93d459b2d1949ee5bbfeb188b2be5f4ac163544c5e98491ad6152df34154feebc2cc337c1
+ languageName: node
+ linkType: hard
+
+"send@npm:0.18.0":
+ version: 0.18.0
+ resolution: "send@npm:0.18.0"
+ dependencies:
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
+ encodeurl: ~1.0.2
+ escape-html: ~1.0.3
+ etag: ~1.8.1
+ fresh: 0.5.2
+ http-errors: 2.0.0
+ mime: 1.6.0
+ ms: 2.1.3
+ on-finished: 2.4.1
+ range-parser: ~1.2.1
+ statuses: 2.0.1
+ checksum: 74fc07ebb58566b87b078ec63e5a3e41ecd987e4272ba67b7467e86c6ad51bc6b0b0154133b6d8b08a2ddda360464f71382f7ef864700f34844a76c8027817a8
+ languageName: node
+ linkType: hard
+
+"serialize-javascript@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "serialize-javascript@npm:6.0.0"
+ dependencies:
+ randombytes: ^2.1.0
+ checksum: 56f90b562a1bdc92e55afb3e657c6397c01a902c588c0fe3d4c490efdcc97dcd2a3074ba12df9e94630f33a5ce5b76a74784a7041294628a6f4306e0ec84bf93
+ languageName: node
+ linkType: hard
+
+"serve-handler@npm:^6.1.3":
+ version: 6.1.5
+ resolution: "serve-handler@npm:6.1.5"
+ dependencies:
+ bytes: 3.0.0
+ content-disposition: 0.5.2
+ fast-url-parser: 1.1.3
+ mime-types: 2.1.18
+ minimatch: 3.1.2
+ path-is-inside: 1.0.2
+ path-to-regexp: 2.2.1
+ range-parser: 1.2.0
+ checksum: 7a98ca9cbf8692583b6cde4deb3941cff900fa38bf16adbfccccd8430209bab781e21d9a1f61c9c03e226f9f67689893bbce25941368f3ddaf985fc3858b49dc
+ languageName: node
+ linkType: hard
+
+"serve-index@npm:^1.9.1":
+ version: 1.9.1
+ resolution: "serve-index@npm:1.9.1"
+ dependencies:
+ accepts: ~1.3.4
+ batch: 0.6.1
+ debug: 2.6.9
+ escape-html: ~1.0.3
+ http-errors: ~1.6.2
+ mime-types: ~2.1.17
+ parseurl: ~1.3.2
+ checksum: e2647ce13379485b98a53ba2ea3fbad4d44b57540d00663b02b976e426e6194d62ac465c0d862cb7057f65e0de8ab8a684aa095427a4b8612412eca0d300d22f
+ languageName: node
+ linkType: hard
+
+"serve-static@npm:1.15.0":
+ version: 1.15.0
+ resolution: "serve-static@npm:1.15.0"
+ dependencies:
+ encodeurl: ~1.0.2
+ escape-html: ~1.0.3
+ parseurl: ~1.3.3
+ send: 0.18.0
+ checksum: af57fc13be40d90a12562e98c0b7855cf6e8bd4c107fe9a45c212bf023058d54a1871b1c89511c3958f70626fff47faeb795f5d83f8cf88514dbaeb2b724464d
+ languageName: node
+ linkType: hard
+
+"set-blocking@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "set-blocking@npm:2.0.0"
+ checksum: 6e65a05f7cf7ebdf8b7c75b101e18c0b7e3dff4940d480efed8aad3a36a4005140b660fa1d804cb8bce911cac290441dc728084a30504d3516ac2ff7ad607b02
+ languageName: node
+ linkType: hard
+
+"setimmediate@npm:^1.0.5":
+ version: 1.0.5
+ resolution: "setimmediate@npm:1.0.5"
+ checksum: c9a6f2c5b51a2dabdc0247db9c46460152ffc62ee139f3157440bd48e7c59425093f42719ac1d7931f054f153e2d26cf37dfeb8da17a794a58198a2705e527fd
+ languageName: node
+ linkType: hard
+
+"setprototypeof@npm:1.1.0":
+ version: 1.1.0
+ resolution: "setprototypeof@npm:1.1.0"
+ checksum: 27cb44304d6c9e1a23bc6c706af4acaae1a7aa1054d4ec13c05f01a99fd4887109a83a8042b67ad90dbfcd100d43efc171ee036eb080667172079213242ca36e
+ languageName: node
+ linkType: hard
+
+"setprototypeof@npm:1.2.0":
+ version: 1.2.0
+ resolution: "setprototypeof@npm:1.2.0"
+ checksum: be18cbbf70e7d8097c97f713a2e76edf84e87299b40d085c6bf8b65314e994cc15e2e317727342fa6996e38e1f52c59720b53fe621e2eb593a6847bf0356db89
+ languageName: node
+ linkType: hard
+
+"shallow-clone@npm:^3.0.0":
+ version: 3.0.1
+ resolution: "shallow-clone@npm:3.0.1"
+ dependencies:
+ kind-of: ^6.0.2
+ checksum: 39b3dd9630a774aba288a680e7d2901f5c0eae7b8387fc5c8ea559918b29b3da144b7bdb990d7ccd9e11be05508ac9e459ce51d01fd65e583282f6ffafcba2e7
+ languageName: node
+ linkType: hard
+
+"shallowequal@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "shallowequal@npm:1.1.0"
+ checksum: f4c1de0837f106d2dbbfd5d0720a5d059d1c66b42b580965c8f06bb1db684be8783538b684092648c981294bf817869f743a066538771dbecb293df78f765e00
+ languageName: node
+ linkType: hard
+
+"shebang-command@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "shebang-command@npm:2.0.0"
+ dependencies:
+ shebang-regex: ^3.0.0
+ checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa
+ languageName: node
+ linkType: hard
+
+"shebang-regex@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "shebang-regex@npm:3.0.0"
+ checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222
+ languageName: node
+ linkType: hard
+
+"shell-quote@npm:^1.7.3":
+ version: 1.7.4
+ resolution: "shell-quote@npm:1.7.4"
+ checksum: 2874ea9c1a7c3ebfc9ec5734a897e16533d0d06f2e4cddc22ba3d1cab5cdc07d0f825364c1b1e39abe61236f44d8e60e933c7ad7349ce44de4f5dddc7b4354e9
+ languageName: node
+ linkType: hard
+
+"shelljs@npm:^0.8.5":
+ version: 0.8.5
+ resolution: "shelljs@npm:0.8.5"
+ dependencies:
+ glob: ^7.0.0
+ interpret: ^1.0.0
+ rechoir: ^0.6.2
+ bin:
+ shjs: bin/shjs
+ checksum: 7babc46f732a98f4c054ec1f048b55b9149b98aa2da32f6cf9844c434b43c6251efebd6eec120937bd0999e13811ebd45efe17410edb3ca938f82f9381302748
+ languageName: node
+ linkType: hard
+
+"side-channel@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "side-channel@npm:1.0.4"
+ dependencies:
+ call-bind: ^1.0.0
+ get-intrinsic: ^1.0.2
+ object-inspect: ^1.9.0
+ checksum: 351e41b947079c10bd0858364f32bb3a7379514c399edb64ab3dce683933483fc63fb5e4efe0a15a2e8a7e3c436b6a91736ddb8d8c6591b0460a24bb4a1ee245
+ languageName: node
+ linkType: hard
+
+"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7":
+ version: 3.0.7
+ resolution: "signal-exit@npm:3.0.7"
+ checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318
+ languageName: node
+ linkType: hard
+
+"sirv@npm:^1.0.7":
+ version: 1.0.19
+ resolution: "sirv@npm:1.0.19"
+ dependencies:
+ "@polka/url": ^1.0.0-next.20
+ mrmime: ^1.0.0
+ totalist: ^1.0.0
+ checksum: c943cfc61baf85f05f125451796212ec35d4377af4da90ae8ec1fa23e6d7b0b4d9c74a8fbf65af83c94e669e88a09dc6451ba99154235eead4393c10dda5b07c
+ languageName: node
+ linkType: hard
+
+"sisteransi@npm:^1.0.5":
+ version: 1.0.5
+ resolution: "sisteransi@npm:1.0.5"
+ checksum: aba6438f46d2bfcef94cf112c835ab395172c75f67453fe05c340c770d3c402363018ae1ab4172a1026a90c47eaccf3af7b6ff6fa749a680c2929bd7fa2b37a4
+ languageName: node
+ linkType: hard
+
+"sitemap@npm:^7.1.1":
+ version: 7.1.1
+ resolution: "sitemap@npm:7.1.1"
+ dependencies:
+ "@types/node": ^17.0.5
+ "@types/sax": ^1.2.1
+ arg: ^5.0.0
+ sax: ^1.2.4
+ bin:
+ sitemap: dist/cli.js
+ checksum: 87a6d21b0d4a33b8c611d3bb8543d02b813c0ebfce014213ef31849b5c1439005644f19ad1593ec89815f6101355f468c9a02c251d09aa03f6fddd17e23c4be4
+ languageName: node
+ linkType: hard
+
+"slash@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "slash@npm:3.0.0"
+ checksum: 94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c
+ languageName: node
+ linkType: hard
+
+"slash@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "slash@npm:4.0.0"
+ checksum: da8e4af73712253acd21b7853b7e0dbba776b786e82b010a5bfc8b5051a1db38ed8aba8e1e8f400dd2c9f373be91eb1c42b66e91abb407ff42b10feece5e1d2d
+ languageName: node
+ linkType: hard
+
+"smart-buffer@npm:^4.2.0":
+ version: 4.2.0
+ resolution: "smart-buffer@npm:4.2.0"
+ checksum: b5167a7142c1da704c0e3af85c402002b597081dd9575031a90b4f229ca5678e9a36e8a374f1814c8156a725d17008ae3bde63b92f9cfd132526379e580bec8b
+ languageName: node
+ linkType: hard
+
+"sockjs@npm:^0.3.24":
+ version: 0.3.24
+ resolution: "sockjs@npm:0.3.24"
+ dependencies:
+ faye-websocket: ^0.11.3
+ uuid: ^8.3.2
+ websocket-driver: ^0.7.4
+ checksum: 355309b48d2c4e9755349daa29cea1c0d9ee23e49b983841c6bf7a20276b00d3c02343f9f33f26d2ee8b261a5a02961b52a25c8da88b2538c5b68d3071b4934c
+ languageName: node
+ linkType: hard
+
+"socks-proxy-agent@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "socks-proxy-agent@npm:7.0.0"
+ dependencies:
+ agent-base: ^6.0.2
+ debug: ^4.3.3
+ socks: ^2.6.2
+ checksum: 720554370154cbc979e2e9ce6a6ec6ced205d02757d8f5d93fe95adae454fc187a5cbfc6b022afab850a5ce9b4c7d73e0f98e381879cf45f66317a4895953846
+ languageName: node
+ linkType: hard
+
+"socks@npm:^2.6.2":
+ version: 2.7.1
+ resolution: "socks@npm:2.7.1"
+ dependencies:
+ ip: ^2.0.0
+ smart-buffer: ^4.2.0
+ checksum: 259d9e3e8e1c9809a7f5c32238c3d4d2a36b39b83851d0f573bfde5f21c4b1288417ce1af06af1452569cd1eb0841169afd4998f0e04ba04656f6b7f0e46d748
+ languageName: node
+ linkType: hard
+
+"sort-css-media-queries@npm:2.1.0":
+ version: 2.1.0
+ resolution: "sort-css-media-queries@npm:2.1.0"
+ checksum: 25cb8f08b148a2ed83d0bc1cf20ddb888d3dee2a3c986896099a21b28b999d5cca3e46a9ef64381bb36fca0fc820471713f2e8af2729ecc6e108ab2b3b315ea9
+ languageName: node
+ linkType: hard
+
+"source-map-js@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "source-map-js@npm:1.0.2"
+ checksum: c049a7fc4deb9a7e9b481ae3d424cc793cb4845daa690bc5a05d428bf41bf231ced49b4cf0c9e77f9d42fdb3d20d6187619fc586605f5eabe995a316da8d377c
+ languageName: node
+ linkType: hard
+
+"source-map-support@npm:~0.5.20":
+ version: 0.5.21
+ resolution: "source-map-support@npm:0.5.21"
+ dependencies:
+ buffer-from: ^1.0.0
+ source-map: ^0.6.0
+ checksum: 43e98d700d79af1d36f859bdb7318e601dfc918c7ba2e98456118ebc4c4872b327773e5a1df09b0524e9e5063bb18f0934538eace60cca2710d1fa687645d137
+ languageName: node
+ linkType: hard
+
+"source-map@npm:^0.5.0":
+ version: 0.5.7
+ resolution: "source-map@npm:0.5.7"
+ checksum: 5dc2043b93d2f194142c7f38f74a24670cd7a0063acdaf4bf01d2964b402257ae843c2a8fa822ad5b71013b5fcafa55af7421383da919752f22ff488bc553f4d
+ languageName: node
+ linkType: hard
+
+"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0":
+ version: 0.6.1
+ resolution: "source-map@npm:0.6.1"
+ checksum: 59ce8640cf3f3124f64ac289012c2b8bd377c238e316fb323ea22fbfe83da07d81e000071d7242cad7a23cd91c7de98e4df8830ec3f133cb6133a5f6e9f67bc2
+ languageName: node
+ linkType: hard
+
+"space-separated-tokens@npm:^1.0.0":
+ version: 1.1.5
+ resolution: "space-separated-tokens@npm:1.1.5"
+ checksum: 8ef68f1cfa8ccad316b7f8d0df0919d0f1f6d32101e8faeee34ea3a923ce8509c1ad562f57388585ee4951e92d27afa211ed0a077d3d5995b5ba9180331be708
+ languageName: node
+ linkType: hard
+
+"spdy-transport@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "spdy-transport@npm:3.0.0"
+ dependencies:
+ debug: ^4.1.0
+ detect-node: ^2.0.4
+ hpack.js: ^2.1.6
+ obuf: ^1.1.2
+ readable-stream: ^3.0.6
+ wbuf: ^1.7.3
+ checksum: 0fcaad3b836fb1ec0bdd39fa7008b9a7a84a553f12be6b736a2512613b323207ffc924b9551cef0378f7233c85916cff1118652e03a730bdb97c0e042243d56c
+ languageName: node
+ linkType: hard
+
+"spdy@npm:^4.0.2":
+ version: 4.0.2
+ resolution: "spdy@npm:4.0.2"
+ dependencies:
+ debug: ^4.1.0
+ handle-thing: ^2.0.0
+ http-deceiver: ^1.2.7
+ select-hose: ^2.0.0
+ spdy-transport: ^3.0.0
+ checksum: 2c739d0ff6f56ad36d2d754d0261d5ec358457bea7cbf77b1b05b0c6464f2ce65b85f196305f50b7bd9120723eb94bae9933466f28e67e5cd8cde4e27f1d75f8
+ languageName: node
+ linkType: hard
+
+"sprintf-js@npm:~1.0.2":
+ version: 1.0.3
+ resolution: "sprintf-js@npm:1.0.3"
+ checksum: 19d79aec211f09b99ec3099b5b2ae2f6e9cdefe50bc91ac4c69144b6d3928a640bb6ae5b3def70c2e85a2c3d9f5ec2719921e3a59d3ca3ef4b2fd1a4656a0df3
+ languageName: node
+ linkType: hard
+
+"ssri@npm:^9.0.0":
+ version: 9.0.1
+ resolution: "ssri@npm:9.0.1"
+ dependencies:
+ minipass: ^3.1.1
+ checksum: fb58f5e46b6923ae67b87ad5ef1c5ab6d427a17db0bead84570c2df3cd50b4ceb880ebdba2d60726588272890bae842a744e1ecce5bd2a2a582fccd5068309eb
+ languageName: node
+ linkType: hard
+
+"stable@npm:^0.1.8":
+ version: 0.1.8
+ resolution: "stable@npm:0.1.8"
+ checksum: 2ff482bb100285d16dd75cd8f7c60ab652570e8952c0bfa91828a2b5f646a0ff533f14596ea4eabd48bb7f4aeea408dce8f8515812b975d958a4cc4fa6b9dfeb
+ languageName: node
+ linkType: hard
+
+"state-toggle@npm:^1.0.0":
+ version: 1.0.3
+ resolution: "state-toggle@npm:1.0.3"
+ checksum: 17398af928413e8d8b866cf0c81fd1b1348bb7d65d8983126ff6ff2317a80d6ee023484fba0c54d8169f5aa544f125434a650ae3a71eddc935cae307d4692b4f
+ languageName: node
+ linkType: hard
+
+"statuses@npm:2.0.1":
+ version: 2.0.1
+ resolution: "statuses@npm:2.0.1"
+ checksum: 18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb
+ languageName: node
+ linkType: hard
+
+"statuses@npm:>= 1.4.0 < 2":
+ version: 1.5.0
+ resolution: "statuses@npm:1.5.0"
+ checksum: c469b9519de16a4bb19600205cffb39ee471a5f17b82589757ca7bd40a8d92ebb6ed9f98b5a540c5d302ccbc78f15dc03cc0280dd6e00df1335568a5d5758a5c
+ languageName: node
+ linkType: hard
+
+"std-env@npm:^3.0.1":
+ version: 3.3.1
+ resolution: "std-env@npm:3.3.1"
+ checksum: c4f59ecd2cb52041ce1785776d28a1aa56d346b6c4efcb8473e7e801eed1ac7612332dcee242d0b35948f35f745cceb6e226b5e825b59e588b262dca6be2b8aa
+ languageName: node
+ linkType: hard
+
+"string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3":
+ version: 4.2.3
+ resolution: "string-width@npm:4.2.3"
+ dependencies:
+ emoji-regex: ^8.0.0
+ is-fullwidth-code-point: ^3.0.0
+ strip-ansi: ^6.0.1
+ checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb
+ languageName: node
+ linkType: hard
+
+"string-width@npm:^5.0.1":
+ version: 5.1.2
+ resolution: "string-width@npm:5.1.2"
+ dependencies:
+ eastasianwidth: ^0.2.0
+ emoji-regex: ^9.2.2
+ strip-ansi: ^7.0.1
+ checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193
+ languageName: node
+ linkType: hard
+
+"string_decoder@npm:^1.1.1":
+ version: 1.3.0
+ resolution: "string_decoder@npm:1.3.0"
+ dependencies:
+ safe-buffer: ~5.2.0
+ checksum: 8417646695a66e73aefc4420eb3b84cc9ffd89572861fe004e6aeb13c7bc00e2f616247505d2dbbef24247c372f70268f594af7126f43548565c68c117bdeb56
+ languageName: node
+ linkType: hard
+
+"string_decoder@npm:~1.1.1":
+ version: 1.1.1
+ resolution: "string_decoder@npm:1.1.1"
+ dependencies:
+ safe-buffer: ~5.1.0
+ checksum: 9ab7e56f9d60a28f2be697419917c50cac19f3e8e6c28ef26ed5f4852289fe0de5d6997d29becf59028556f2c62983790c1d9ba1e2a3cc401768ca12d5183a5b
+ languageName: node
+ linkType: hard
+
+"stringify-object@npm:^3.3.0":
+ version: 3.3.0
+ resolution: "stringify-object@npm:3.3.0"
+ dependencies:
+ get-own-enumerable-property-symbols: ^3.0.0
+ is-obj: ^1.0.1
+ is-regexp: ^1.0.0
+ checksum: 6827a3f35975cfa8572e8cd3ed4f7b262def260af18655c6fde549334acdac49ddba69f3c861ea5a6e9c5a4990fe4ae870b9c0e6c31019430504c94a83b7a154
+ languageName: node
+ linkType: hard
+
+"strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "strip-ansi@npm:6.0.1"
+ dependencies:
+ ansi-regex: ^5.0.1
+ checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c
+ languageName: node
+ linkType: hard
+
+"strip-ansi@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "strip-ansi@npm:7.0.1"
+ dependencies:
+ ansi-regex: ^6.0.1
+ checksum: 257f78fa433520e7f9897722731d78599cb3fce29ff26a20a5e12ba4957463b50a01136f37c43707f4951817a75e90820174853d6ccc240997adc5df8f966039
+ languageName: node
+ linkType: hard
+
+"strip-bom-string@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "strip-bom-string@npm:1.0.0"
+ checksum: 5635a3656d8512a2c194d6c8d5dee7ef0dde6802f7be9413b91e201981ad4132506656d9cf14137f019fd50f0269390d91c7f6a2601b1bee039a4859cfce4934
+ languageName: node
+ linkType: hard
+
+"strip-final-newline@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "strip-final-newline@npm:2.0.0"
+ checksum: 69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64
+ languageName: node
+ linkType: hard
+
+"strip-json-comments@npm:^3.1.1":
+ version: 3.1.1
+ resolution: "strip-json-comments@npm:3.1.1"
+ checksum: 492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443
+ languageName: node
+ linkType: hard
+
+"strip-json-comments@npm:~2.0.1":
+ version: 2.0.1
+ resolution: "strip-json-comments@npm:2.0.1"
+ checksum: 1074ccb63270d32ca28edfb0a281c96b94dc679077828135141f27d52a5a398ef5e78bcf22809d23cadc2b81dfbe345eb5fd8699b385c8b1128907dec4a7d1e1
+ languageName: node
+ linkType: hard
+
+"style-to-object@npm:0.3.0, style-to-object@npm:^0.3.0":
+ version: 0.3.0
+ resolution: "style-to-object@npm:0.3.0"
+ dependencies:
+ inline-style-parser: 0.1.1
+ checksum: 4d7084015207f2a606dfc10c29cb5ba569f2fe8005551df7396110dd694d6ff650f2debafa95bd5d147dfb4ca50f57868e2a7f91bf5d11ef734fe7ccbd7abf59
+ languageName: node
+ linkType: hard
+
+"stylehacks@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "stylehacks@npm:5.1.1"
+ dependencies:
+ browserslist: ^4.21.4
+ postcss-selector-parser: ^6.0.4
+ peerDependencies:
+ postcss: ^8.2.15
+ checksum: 11175366ef52de65bf06cefba0ddc9db286dc3a1451fd2989e74c6ea47091a02329a4bf6ce10b1a36950056927b6bbbe47c5ab3a1f4c7032df932d010fbde5a2
+ languageName: node
+ linkType: hard
+
+"supports-color@npm:^5.3.0":
+ version: 5.5.0
+ resolution: "supports-color@npm:5.5.0"
+ dependencies:
+ has-flag: ^3.0.0
+ checksum: 95f6f4ba5afdf92f495b5a912d4abee8dcba766ae719b975c56c084f5004845f6f5a5f7769f52d53f40e21952a6d87411bafe34af4a01e65f9926002e38e1dac
+ languageName: node
+ linkType: hard
+
+"supports-color@npm:^7.1.0":
+ version: 7.2.0
+ resolution: "supports-color@npm:7.2.0"
+ dependencies:
+ has-flag: ^4.0.0
+ checksum: 3dda818de06ebbe5b9653e07842d9479f3555ebc77e9a0280caf5a14fb877ffee9ed57007c3b78f5a6324b8dbeec648d9e97a24e2ed9fdb81ddc69ea07100f4a
+ languageName: node
+ linkType: hard
+
+"supports-color@npm:^8.0.0":
+ version: 8.1.1
+ resolution: "supports-color@npm:8.1.1"
+ dependencies:
+ has-flag: ^4.0.0
+ checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406
+ languageName: node
+ linkType: hard
+
+"supports-preserve-symlinks-flag@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "supports-preserve-symlinks-flag@npm:1.0.0"
+ checksum: 53b1e247e68e05db7b3808b99b892bd36fb096e6fba213a06da7fab22045e97597db425c724f2bbd6c99a3c295e1e73f3e4de78592289f38431049e1277ca0ae
+ languageName: node
+ linkType: hard
+
+"svg-parser@npm:^2.0.4":
+ version: 2.0.4
+ resolution: "svg-parser@npm:2.0.4"
+ checksum: b3de6653048212f2ae7afe4a423e04a76ec6d2d06e1bf7eacc618a7c5f7df7faa5105561c57b94579ec831fbbdbf5f190ba56a9205ff39ed13eabdf8ab086ddf
+ languageName: node
+ linkType: hard
+
+"svgo@npm:^2.7.0, svgo@npm:^2.8.0":
+ version: 2.8.0
+ resolution: "svgo@npm:2.8.0"
+ dependencies:
+ "@trysound/sax": 0.2.0
+ commander: ^7.2.0
+ css-select: ^4.1.3
+ css-tree: ^1.1.3
+ csso: ^4.2.0
+ picocolors: ^1.0.0
+ stable: ^0.1.8
+ bin:
+ svgo: bin/svgo
+ checksum: b92f71a8541468ffd0b81b8cdb36b1e242eea320bf3c1a9b2c8809945853e9d8c80c19744267eb91cabf06ae9d5fff3592d677df85a31be4ed59ff78534fa420
+ languageName: node
+ linkType: hard
+
+"tapable@npm:^1.0.0":
+ version: 1.1.3
+ resolution: "tapable@npm:1.1.3"
+ checksum: 53ff4e7c3900051c38cc4faab428ebfd7e6ad0841af5a7ac6d5f3045c5b50e88497bfa8295b4b3fbcadd94993c9e358868b78b9fb249a76cb8b018ac8dccafd7
+ languageName: node
+ linkType: hard
+
+"tapable@npm:^2.0.0, tapable@npm:^2.1.1, tapable@npm:^2.2.0":
+ version: 2.2.1
+ resolution: "tapable@npm:2.2.1"
+ checksum: 3b7a1b4d86fa940aad46d9e73d1e8739335efd4c48322cb37d073eb6f80f5281889bf0320c6d8ffcfa1a0dd5bfdbd0f9d037e252ef972aca595330538aac4d51
+ languageName: node
+ linkType: hard
+
+"tar@npm:^6.1.11, tar@npm:^6.1.2":
+ version: 6.1.13
+ resolution: "tar@npm:6.1.13"
+ dependencies:
+ chownr: ^2.0.0
+ fs-minipass: ^2.0.0
+ minipass: ^4.0.0
+ minizlib: ^2.1.1
+ mkdirp: ^1.0.3
+ yallist: ^4.0.0
+ checksum: 8a278bed123aa9f53549b256a36b719e317c8b96fe86a63406f3c62887f78267cea9b22dc6f7007009738509800d4a4dccc444abd71d762287c90f35b002eb1c
+ languageName: node
+ linkType: hard
+
+"terser-webpack-plugin@npm:^5.1.3, terser-webpack-plugin@npm:^5.3.3":
+ version: 5.3.6
+ resolution: "terser-webpack-plugin@npm:5.3.6"
+ dependencies:
+ "@jridgewell/trace-mapping": ^0.3.14
+ jest-worker: ^27.4.5
+ schema-utils: ^3.1.1
+ serialize-javascript: ^6.0.0
+ terser: ^5.14.1
+ peerDependencies:
+ webpack: ^5.1.0
+ peerDependenciesMeta:
+ "@swc/core":
+ optional: true
+ esbuild:
+ optional: true
+ uglify-js:
+ optional: true
+ checksum: 8f3448d7fdb0434ce6a0c09d95c462bfd2f4a5a430233d854163337f734a7f5c07c74513d16081e06d4ca33d366d5b1a36f5444219bc41a7403afd6162107bad
+ languageName: node
+ linkType: hard
+
+"terser@npm:^5.10.0, terser@npm:^5.14.1":
+ version: 5.16.1
+ resolution: "terser@npm:5.16.1"
+ dependencies:
+ "@jridgewell/source-map": ^0.3.2
+ acorn: ^8.5.0
+ commander: ^2.20.0
+ source-map-support: ~0.5.20
+ bin:
+ terser: bin/terser
+ checksum: cb524123504a2f0d9140c1e1a8628c83bba9cacc404c6aca79e2493a38dfdf21275617ba75b91006b3f1ff586e401ab31121160cd253699f334c6340ea2756f5
+ languageName: node
+ linkType: hard
+
+"text-table@npm:^0.2.0":
+ version: 0.2.0
+ resolution: "text-table@npm:0.2.0"
+ checksum: b6937a38c80c7f84d9c11dd75e49d5c44f71d95e810a3250bd1f1797fc7117c57698204adf676b71497acc205d769d65c16ae8fa10afad832ae1322630aef10a
+ languageName: node
+ linkType: hard
+
+"thunky@npm:^1.0.2":
+ version: 1.1.0
+ resolution: "thunky@npm:1.1.0"
+ checksum: 993096c472b6b8f30e29dc777a8d17720e4cab448375041f20c0cb802a09a7fb2217f2a3e8cdc11851faa71c957e2db309357367fc9d7af3cb7a4d00f4b66034
+ languageName: node
+ linkType: hard
+
+"tiny-invariant@npm:^1.0.2":
+ version: 1.3.1
+ resolution: "tiny-invariant@npm:1.3.1"
+ checksum: 872dbd1ff20a21303a2fd20ce3a15602cfa7fcf9b228bd694a52e2938224313b5385a1078cb667ed7375d1612194feaca81c4ecbe93121ca1baebe344de4f84c
+ languageName: node
+ linkType: hard
+
+"tiny-warning@npm:^1.0.0":
+ version: 1.0.3
+ resolution: "tiny-warning@npm:1.0.3"
+ checksum: da62c4acac565902f0624b123eed6dd3509bc9a8d30c06e017104bedcf5d35810da8ff72864400ad19c5c7806fc0a8323c68baf3e326af7cb7d969f846100d71
+ languageName: node
+ linkType: hard
+
+"to-fast-properties@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "to-fast-properties@npm:2.0.0"
+ checksum: be2de62fe58ead94e3e592680052683b1ec986c72d589e7b21e5697f8744cdbf48c266fa72f6c15932894c10187b5f54573a3bcf7da0bfd964d5caf23d436168
+ languageName: node
+ linkType: hard
+
+"to-readable-stream@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "to-readable-stream@npm:1.0.0"
+ checksum: 2bd7778490b6214a2c40276065dd88949f4cf7037ce3964c76838b8cb212893aeb9cceaaf4352a4c486e3336214c350270f3263e1ce7a0c38863a715a4d9aeb5
+ languageName: node
+ linkType: hard
+
+"to-regex-range@npm:^5.0.1":
+ version: 5.0.1
+ resolution: "to-regex-range@npm:5.0.1"
+ dependencies:
+ is-number: ^7.0.0
+ checksum: f76fa01b3d5be85db6a2a143e24df9f60dd047d151062d0ba3df62953f2f697b16fe5dad9b0ac6191c7efc7b1d9dcaa4b768174b7b29da89d4428e64bc0a20ed
+ languageName: node
+ linkType: hard
+
+"toidentifier@npm:1.0.1":
+ version: 1.0.1
+ resolution: "toidentifier@npm:1.0.1"
+ checksum: 952c29e2a85d7123239b5cfdd889a0dde47ab0497f0913d70588f19c53f7e0b5327c95f4651e413c74b785147f9637b17410ac8c846d5d4a20a5a33eb6dc3a45
+ languageName: node
+ linkType: hard
+
+"totalist@npm:^1.0.0":
+ version: 1.1.0
+ resolution: "totalist@npm:1.1.0"
+ checksum: dfab80c7104a1d170adc8c18782d6c04b7df08352dec452191208c66395f7ef2af7537ddfa2cf1decbdcfab1a47afbbf0dec6543ea191da98c1c6e1599f86adc
+ languageName: node
+ linkType: hard
+
+"tr46@npm:~0.0.3":
+ version: 0.0.3
+ resolution: "tr46@npm:0.0.3"
+ checksum: 726321c5eaf41b5002e17ffbd1fb7245999a073e8979085dacd47c4b4e8068ff5777142fc6726d6ca1fd2ff16921b48788b87225cbc57c72636f6efa8efbffe3
+ languageName: node
+ linkType: hard
+
+"trim-trailing-lines@npm:^1.0.0":
+ version: 1.1.4
+ resolution: "trim-trailing-lines@npm:1.1.4"
+ checksum: 5d39d21c0d4b258667012fcd784f73129e148ea1c213b1851d8904f80499fc91df6710c94c7dd49a486a32da2b9cb86020dda79f285a9a2586cfa622f80490c2
+ languageName: node
+ linkType: hard
+
+"trim@npm:0.0.1":
+ version: 0.0.1
+ resolution: "trim@npm:0.0.1"
+ checksum: 2b4646dff99a222e8e1526edd4e3a43bbd925af0b8e837c340455d250157e7deefaa4da49bb891ab841e5c27b1afc5e9e32d4b57afb875d2dfcabf4e319b8f7f
+ languageName: node
+ linkType: hard
+
+"trough@npm:^1.0.0":
+ version: 1.0.5
+ resolution: "trough@npm:1.0.5"
+ checksum: d6c8564903ed00e5258bab92134b020724dbbe83148dc72e4bf6306c03ed8843efa1bcc773fa62410dd89161ecb067432dd5916501793508a9506cacbc408e25
+ languageName: node
+ linkType: hard
+
+"tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.4.0":
+ version: 2.4.1
+ resolution: "tslib@npm:2.4.1"
+ checksum: 19480d6e0313292bd6505d4efe096a6b31c70e21cf08b5febf4da62e95c265c8f571f7b36fcc3d1a17e068032f59c269fab3459d6cd3ed6949eafecf64315fca
+ languageName: node
+ linkType: hard
+
+"type-fest@npm:^0.20.2":
+ version: 0.20.2
+ resolution: "type-fest@npm:0.20.2"
+ checksum: 4fb3272df21ad1c552486f8a2f8e115c09a521ad7a8db3d56d53718d0c907b62c6e9141ba5f584af3f6830d0872c521357e512381f24f7c44acae583ad517d73
+ languageName: node
+ linkType: hard
+
+"type-fest@npm:^2.5.0":
+ version: 2.19.0
+ resolution: "type-fest@npm:2.19.0"
+ checksum: a4ef07ece297c9fba78fc1bd6d85dff4472fe043ede98bd4710d2615d15776902b595abf62bd78339ed6278f021235fb28a96361f8be86ed754f778973a0d278
+ languageName: node
+ linkType: hard
+
+"type-is@npm:~1.6.18":
+ version: 1.6.18
+ resolution: "type-is@npm:1.6.18"
+ dependencies:
+ media-typer: 0.3.0
+ mime-types: ~2.1.24
+ checksum: 2c8e47675d55f8b4e404bcf529abdf5036c537a04c2b20177bcf78c9e3c1da69da3942b1346e6edb09e823228c0ee656ef0e033765ec39a70d496ef601a0c657
+ languageName: node
+ linkType: hard
+
+"typedarray-to-buffer@npm:^3.1.5":
+ version: 3.1.5
+ resolution: "typedarray-to-buffer@npm:3.1.5"
+ dependencies:
+ is-typedarray: ^1.0.0
+ checksum: 99c11aaa8f45189fcfba6b8a4825fd684a321caa9bd7a76a27cf0c7732c174d198b99f449c52c3818107430b5f41c0ccbbfb75cb2ee3ca4a9451710986d61a60
+ languageName: node
+ linkType: hard
+
+"ua-parser-js@npm:^0.7.30":
+ version: 0.7.32
+ resolution: "ua-parser-js@npm:0.7.32"
+ checksum: 6b6b035dd78a0ab3369f166ab6f26225d823d83630788806d634f16259297a8f4ae6fe0be4e48f4353ac10dffded3971d7745c55d1432fdfc78a893ba58ef044
+ languageName: node
+ linkType: hard
+
+"unherit@npm:^1.0.4":
+ version: 1.1.3
+ resolution: "unherit@npm:1.1.3"
+ dependencies:
+ inherits: ^2.0.0
+ xtend: ^4.0.0
+ checksum: fd7922f84fc0bfb7c4df6d1f5a50b5b94a0218e3cda98a54dbbd209226ddd4072d742d3df44d0e295ab08d5ccfd304a1e193dfe31a86d2a91b7cb9fdac093194
+ languageName: node
+ linkType: hard
+
+"unicode-canonical-property-names-ecmascript@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.0"
+ checksum: 39be078afd014c14dcd957a7a46a60061bc37c4508ba146517f85f60361acf4c7539552645ece25de840e17e293baa5556268d091ca6762747fdd0c705001a45
+ languageName: node
+ linkType: hard
+
+"unicode-match-property-ecmascript@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "unicode-match-property-ecmascript@npm:2.0.0"
+ dependencies:
+ unicode-canonical-property-names-ecmascript: ^2.0.0
+ unicode-property-aliases-ecmascript: ^2.0.0
+ checksum: 1f34a7434a23df4885b5890ac36c5b2161a809887000be560f56ad4b11126d433c0c1c39baf1016bdabed4ec54829a6190ee37aa24919aa116dc1a5a8a62965a
+ languageName: node
+ linkType: hard
+
+"unicode-match-property-value-ecmascript@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "unicode-match-property-value-ecmascript@npm:2.1.0"
+ checksum: 8d6f5f586b9ce1ed0e84a37df6b42fdba1317a05b5df0c249962bd5da89528771e2d149837cad11aa26bcb84c35355cb9f58a10c3d41fa3b899181ece6c85220
+ languageName: node
+ linkType: hard
+
+"unicode-property-aliases-ecmascript@npm:^2.0.0":
+ version: 2.1.0
+ resolution: "unicode-property-aliases-ecmascript@npm:2.1.0"
+ checksum: 243524431893649b62cc674d877bd64ef292d6071dd2fd01ab4d5ad26efbc104ffcd064f93f8a06b7e4ec54c172bf03f6417921a0d8c3a9994161fe1f88f815b
+ languageName: node
+ linkType: hard
+
+"unified@npm:9.2.0":
+ version: 9.2.0
+ resolution: "unified@npm:9.2.0"
+ dependencies:
+ bail: ^1.0.0
+ extend: ^3.0.0
+ is-buffer: ^2.0.0
+ is-plain-obj: ^2.0.0
+ trough: ^1.0.0
+ vfile: ^4.0.0
+ checksum: 0cac4ae119893fbd49d309b4db48595e4d4e9f0a2dc1dde4d0074059f9a46012a2905f37c1346715e583f30c970bc8078db8462675411d39ff5036ae18b4fb8a
+ languageName: node
+ linkType: hard
+
+"unified@npm:^9.2.2":
+ version: 9.2.2
+ resolution: "unified@npm:9.2.2"
+ dependencies:
+ bail: ^1.0.0
+ extend: ^3.0.0
+ is-buffer: ^2.0.0
+ is-plain-obj: ^2.0.0
+ trough: ^1.0.0
+ vfile: ^4.0.0
+ checksum: 7c24461be7de4145939739ce50d18227c5fbdf9b3bc5a29dabb1ce26dd3e8bd4a1c385865f6f825f3b49230953ee8b591f23beab3bb3643e3e9dc37aa8a089d5
+ languageName: node
+ linkType: hard
+
+"unique-filename@npm:^2.0.0":
+ version: 2.0.1
+ resolution: "unique-filename@npm:2.0.1"
+ dependencies:
+ unique-slug: ^3.0.0
+ checksum: 807acf3381aff319086b64dc7125a9a37c09c44af7620bd4f7f3247fcd5565660ac12d8b80534dcbfd067e6fe88a67e621386dd796a8af828d1337a8420a255f
+ languageName: node
+ linkType: hard
+
+"unique-slug@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "unique-slug@npm:3.0.0"
+ dependencies:
+ imurmurhash: ^0.1.4
+ checksum: 49f8d915ba7f0101801b922062ee46b7953256c93ceca74303bd8e6413ae10aa7e8216556b54dc5382895e8221d04f1efaf75f945c2e4a515b4139f77aa6640c
+ languageName: node
+ linkType: hard
+
+"unique-string@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "unique-string@npm:2.0.0"
+ dependencies:
+ crypto-random-string: ^2.0.0
+ checksum: ef68f639136bcfe040cf7e3cd7a8dff076a665288122855148a6f7134092e6ed33bf83a7f3a9185e46c98dddc445a0da6ac25612afa1a7c38b8b654d6c02498e
+ languageName: node
+ linkType: hard
+
+"unist-builder@npm:2.0.3, unist-builder@npm:^2.0.0":
+ version: 2.0.3
+ resolution: "unist-builder@npm:2.0.3"
+ checksum: e946fdf77dbfc320feaece137ce4959ae2da6614abd1623bd39512dc741a9d5f313eb2ba79f8887d941365dccddec7fef4e953827475e392bf49b45336f597f6
+ languageName: node
+ linkType: hard
+
+"unist-util-generated@npm:^1.0.0":
+ version: 1.1.6
+ resolution: "unist-util-generated@npm:1.1.6"
+ checksum: 86239ff88a08800d52198f2f0e15911f05bab2dad17cef95550f7c2728f15ebb0344694fcc3101d05762d88adaf86cb85aa7a3300fedabd0b6d7d00b41cdcb7f
+ languageName: node
+ linkType: hard
+
+"unist-util-is@npm:^4.0.0":
+ version: 4.1.0
+ resolution: "unist-util-is@npm:4.1.0"
+ checksum: 726484cd2adc9be75a939aeedd48720f88294899c2e4a3143da413ae593f2b28037570730d5cf5fd910ff41f3bc1501e3d636b6814c478d71126581ef695f7ea
+ languageName: node
+ linkType: hard
+
+"unist-util-position@npm:^3.0.0":
+ version: 3.1.0
+ resolution: "unist-util-position@npm:3.1.0"
+ checksum: 10b3952e32a1ffabbecad41c3946237f7059f5bb6436796da05531a285f50b97e4f37cfc2f7164676d041063f40fe1ad92fbb8ca38d3ae8747328ebe738d738f
+ languageName: node
+ linkType: hard
+
+"unist-util-remove-position@npm:^2.0.0":
+ version: 2.0.1
+ resolution: "unist-util-remove-position@npm:2.0.1"
+ dependencies:
+ unist-util-visit: ^2.0.0
+ checksum: 4149294969f1a78a367b5d03eb0a138aa8320a39e1b15686647a2bec5945af3df27f2936a1e9752ecbb4a82dc23bd86f7e5a0ee048e5eeaedc2deb9237872795
+ languageName: node
+ linkType: hard
+
+"unist-util-remove@npm:^2.0.0":
+ version: 2.1.0
+ resolution: "unist-util-remove@npm:2.1.0"
+ dependencies:
+ unist-util-is: ^4.0.0
+ checksum: 99e54f3ea0523f8cf957579a6e84e5b58427bffab929cc7f6aa5119581f929db683dd4691ea5483df0c272f486dda9dbd04f4ab74dca6cae1f3ebe8e4261a4d9
+ languageName: node
+ linkType: hard
+
+"unist-util-stringify-position@npm:^2.0.0":
+ version: 2.0.3
+ resolution: "unist-util-stringify-position@npm:2.0.3"
+ dependencies:
+ "@types/unist": ^2.0.2
+ checksum: f755cadc959f9074fe999578a1a242761296705a7fe87f333a37c00044de74ab4b184b3812989a57d4cd12211f0b14ad397b327c3a594c7af84361b1c25a7f09
+ languageName: node
+ linkType: hard
+
+"unist-util-visit-parents@npm:^3.0.0":
+ version: 3.1.1
+ resolution: "unist-util-visit-parents@npm:3.1.1"
+ dependencies:
+ "@types/unist": ^2.0.0
+ unist-util-is: ^4.0.0
+ checksum: 1170e397dff88fab01e76d5154981666eb0291019d2462cff7a2961a3e76d3533b42eaa16b5b7e2d41ad42a5ea7d112301458283d255993e660511387bf67bc3
+ languageName: node
+ linkType: hard
+
+"unist-util-visit@npm:2.0.3, unist-util-visit@npm:^2.0.0, unist-util-visit@npm:^2.0.3":
+ version: 2.0.3
+ resolution: "unist-util-visit@npm:2.0.3"
+ dependencies:
+ "@types/unist": ^2.0.0
+ unist-util-is: ^4.0.0
+ unist-util-visit-parents: ^3.0.0
+ checksum: 1fe19d500e212128f96d8c3cfa3312846e586b797748a1fd195fe6479f06bc90a6f6904deb08eefc00dd58e83a1c8a32fb8677252d2273ad7a5e624525b69b8f
+ languageName: node
+ linkType: hard
+
+"universalify@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "universalify@npm:2.0.0"
+ checksum: 2406a4edf4a8830aa6813278bab1f953a8e40f2f63a37873ffa9a3bc8f9745d06cc8e88f3572cb899b7e509013f7f6fcc3e37e8a6d914167a5381d8440518c44
+ languageName: node
+ linkType: hard
+
+"unpipe@npm:1.0.0, unpipe@npm:~1.0.0":
+ version: 1.0.0
+ resolution: "unpipe@npm:1.0.0"
+ checksum: 4fa18d8d8d977c55cb09715385c203197105e10a6d220087ec819f50cb68870f02942244f1017565484237f1f8c5d3cd413631b1ae104d3096f24fdfde1b4aa2
+ languageName: node
+ linkType: hard
+
+"update-browserslist-db@npm:^1.0.9":
+ version: 1.0.10
+ resolution: "update-browserslist-db@npm:1.0.10"
+ dependencies:
+ escalade: ^3.1.1
+ picocolors: ^1.0.0
+ peerDependencies:
+ browserslist: ">= 4.21.0"
+ bin:
+ browserslist-lint: cli.js
+ checksum: 12db73b4f63029ac407b153732e7cd69a1ea8206c9100b482b7d12859cd3cd0bc59c602d7ae31e652706189f1acb90d42c53ab24a5ba563ed13aebdddc5561a0
+ languageName: node
+ linkType: hard
+
+"update-notifier@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "update-notifier@npm:5.1.0"
+ dependencies:
+ boxen: ^5.0.0
+ chalk: ^4.1.0
+ configstore: ^5.0.1
+ has-yarn: ^2.1.0
+ import-lazy: ^2.1.0
+ is-ci: ^2.0.0
+ is-installed-globally: ^0.4.0
+ is-npm: ^5.0.0
+ is-yarn-global: ^0.3.0
+ latest-version: ^5.1.0
+ pupa: ^2.1.1
+ semver: ^7.3.4
+ semver-diff: ^3.1.1
+ xdg-basedir: ^4.0.0
+ checksum: 461e5e5b002419296d3868ee2abe0f9ab3e1846d9db642936d0c46f838872ec56069eddfe662c45ce1af0a8d6d5026353728de2e0a95ab2e3546a22ea077caf1
+ languageName: node
+ linkType: hard
+
+"uri-js@npm:^4.2.2":
+ version: 4.4.1
+ resolution: "uri-js@npm:4.4.1"
+ dependencies:
+ punycode: ^2.1.0
+ checksum: 7167432de6817fe8e9e0c9684f1d2de2bb688c94388f7569f7dbdb1587c9f4ca2a77962f134ec90be0cc4d004c939ff0d05acc9f34a0db39a3c797dada262633
+ languageName: node
+ linkType: hard
+
+"url-loader@npm:^4.1.1":
+ version: 4.1.1
+ resolution: "url-loader@npm:4.1.1"
+ dependencies:
+ loader-utils: ^2.0.0
+ mime-types: ^2.1.27
+ schema-utils: ^3.0.0
+ peerDependencies:
+ file-loader: "*"
+ webpack: ^4.0.0 || ^5.0.0
+ peerDependenciesMeta:
+ file-loader:
+ optional: true
+ checksum: c1122a992c6cff70a7e56dfc2b7474534d48eb40b2cc75467cde0c6972e7597faf8e43acb4f45f93c2473645dfd803bcbc20960b57544dd1e4c96e77f72ba6fd
+ languageName: node
+ linkType: hard
+
+"url-parse-lax@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "url-parse-lax@npm:3.0.0"
+ dependencies:
+ prepend-http: ^2.0.0
+ checksum: 1040e357750451173132228036aff1fd04abbd43eac1fb3e4fca7495a078bcb8d33cb765fe71ad7e473d9c94d98fd67adca63bd2716c815a2da066198dd37217
+ languageName: node
+ linkType: hard
+
+"use-composed-ref@npm:^1.3.0":
+ version: 1.3.0
+ resolution: "use-composed-ref@npm:1.3.0"
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ checksum: f771cbadfdc91e03b7ab9eb32d0fc0cc647755711801bf507e891ad38c4bbc5f02b2509acadf9c965ec9c5f2f642fd33bdfdfb17b0873c4ad0a9b1f5e5e724bf
+ languageName: node
+ linkType: hard
+
+"use-isomorphic-layout-effect@npm:^1.1.1":
+ version: 1.1.2
+ resolution: "use-isomorphic-layout-effect@npm:1.1.2"
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: a6532f7fc9ae222c3725ff0308aaf1f1ddbd3c00d685ef9eee6714fd0684de5cb9741b432fbf51e61a784e2955424864f7ea9f99734a02f237b17ad3e18ea5cb
+ languageName: node
+ linkType: hard
+
+"use-latest@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "use-latest@npm:1.2.1"
+ dependencies:
+ use-isomorphic-layout-effect: ^1.1.1
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: ed3f2ddddf6f21825e2ede4c2e0f0db8dcce5129802b69d1f0575fc1b42380436e8c76a6cd885d4e9aa8e292e60fb8b959c955f33c6a9123b83814a1a1875367
+ languageName: node
+ linkType: hard
+
+"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1":
+ version: 1.0.2
+ resolution: "util-deprecate@npm:1.0.2"
+ checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2
+ languageName: node
+ linkType: hard
+
+"utila@npm:~0.4":
+ version: 0.4.0
+ resolution: "utila@npm:0.4.0"
+ checksum: 97ffd3bd2bb80c773429d3fb8396469115cd190dded1e733f190d8b602bd0a1bcd6216b7ce3c4395ee3c79e3c879c19d268dbaae3093564cb169ad1212d436f4
+ languageName: node
+ linkType: hard
+
+"utility-types@npm:^3.10.0":
+ version: 3.10.0
+ resolution: "utility-types@npm:3.10.0"
+ checksum: 8f274415c6196ab62883b8bd98c9d2f8829b58016e4269aaa1ebd84184ac5dda7dc2ca45800c0d5e0e0650966ba063bf9a412aaeaea6850ca4440a391283d5c8
+ languageName: node
+ linkType: hard
+
+"utils-merge@npm:1.0.1":
+ version: 1.0.1
+ resolution: "utils-merge@npm:1.0.1"
+ checksum: c81095493225ecfc28add49c106ca4f09cdf56bc66731aa8dabc2edbbccb1e1bfe2de6a115e5c6a380d3ea166d1636410b62ef216bb07b3feb1cfde1d95d5080
+ languageName: node
+ linkType: hard
+
+"uuid@npm:^8.3.2":
+ version: 8.3.2
+ resolution: "uuid@npm:8.3.2"
+ bin:
+ uuid: dist/bin/uuid
+ checksum: 5575a8a75c13120e2f10e6ddc801b2c7ed7d8f3c8ac22c7ed0c7b2ba6383ec0abda88c905085d630e251719e0777045ae3236f04c812184b7c765f63a70e58df
+ languageName: node
+ linkType: hard
+
+"value-equal@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "value-equal@npm:1.0.1"
+ checksum: bb7ae1facc76b5cf8071aeb6c13d284d023fdb370478d10a5d64508e0e6e53bb459c4bbe34258df29d82e6f561f874f0105eba38de0e61fe9edd0bdce07a77a2
+ languageName: node
+ linkType: hard
+
+"vary@npm:~1.1.2":
+ version: 1.1.2
+ resolution: "vary@npm:1.1.2"
+ checksum: ae0123222c6df65b437669d63dfa8c36cee20a504101b2fcd97b8bf76f91259c17f9f2b4d70a1e3c6bbcee7f51b28392833adb6b2770b23b01abec84e369660b
+ languageName: node
+ linkType: hard
+
+"vfile-location@npm:^3.0.0, vfile-location@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "vfile-location@npm:3.2.0"
+ checksum: 9bb3df6d0be31b5dd2d8da0170c27b7045c64493a8ba7b6ff7af8596c524fc8896924b8dd85ae12d201eead2709217a0fbc44927b7264f4bbf0aa8027a78be9c
+ languageName: node
+ linkType: hard
+
+"vfile-message@npm:^2.0.0":
+ version: 2.0.4
+ resolution: "vfile-message@npm:2.0.4"
+ dependencies:
+ "@types/unist": ^2.0.0
+ unist-util-stringify-position: ^2.0.0
+ checksum: 1bade499790f46ca5aba04bdce07a1e37c2636a8872e05cf32c26becc912826710b7eb063d30c5754fdfaeedc8a7658e78df10b3bc535c844890ec8a184f5643
+ languageName: node
+ linkType: hard
+
+"vfile@npm:^4.0.0":
+ version: 4.2.1
+ resolution: "vfile@npm:4.2.1"
+ dependencies:
+ "@types/unist": ^2.0.0
+ is-buffer: ^2.0.0
+ unist-util-stringify-position: ^2.0.0
+ vfile-message: ^2.0.0
+ checksum: ee5726e10d170472cde778fc22e0f7499caa096eb85babea5d0ce0941455b721037ee1c9e6ae506ca2803250acd313d0f464328ead0b55cfe7cb6315f1b462d6
+ languageName: node
+ linkType: hard
+
+"wait-on@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "wait-on@npm:6.0.1"
+ dependencies:
+ axios: ^0.25.0
+ joi: ^17.6.0
+ lodash: ^4.17.21
+ minimist: ^1.2.5
+ rxjs: ^7.5.4
+ bin:
+ wait-on: bin/wait-on
+ checksum: e4d62aa4145d99fe34747ccf7506d4b4d6e60dd677c0eb18a51e316d38116ace2d194e4b22a9eb7b767b0282f39878ddcc4ae9440dcb0c005c9150668747cf5b
+ languageName: node
+ linkType: hard
+
+"watchpack@npm:^2.4.0":
+ version: 2.4.0
+ resolution: "watchpack@npm:2.4.0"
+ dependencies:
+ glob-to-regexp: ^0.4.1
+ graceful-fs: ^4.1.2
+ checksum: 23d4bc58634dbe13b86093e01c6a68d8096028b664ab7139d58f0c37d962d549a940e98f2f201cecdabd6f9c340338dc73ef8bf094a2249ef582f35183d1a131
+ languageName: node
+ linkType: hard
+
+"wbuf@npm:^1.1.0, wbuf@npm:^1.7.3":
+ version: 1.7.3
+ resolution: "wbuf@npm:1.7.3"
+ dependencies:
+ minimalistic-assert: ^1.0.0
+ checksum: 2abc306c96930b757972a1c4650eb6b25b5d99f24088714957f88629e137db569368c5de0e57986c89ea70db2f1df9bba11a87cb6d0c8694b6f53a0159fab3bf
+ languageName: node
+ linkType: hard
+
+"web-namespaces@npm:^1.0.0":
+ version: 1.1.4
+ resolution: "web-namespaces@npm:1.1.4"
+ checksum: 5149842ccbfbc56fe4f8758957b3f8c8616a281874a5bb84aa1b305e4436a9bad853d21c629a7b8f174902449e1489c7a6c724fccf60965077c5636bd8aed42b
+ languageName: node
+ linkType: hard
+
+"webidl-conversions@npm:^3.0.0":
+ version: 3.0.1
+ resolution: "webidl-conversions@npm:3.0.1"
+ checksum: c92a0a6ab95314bde9c32e1d0a6dfac83b578f8fa5f21e675bc2706ed6981bc26b7eb7e6a1fab158e5ce4adf9caa4a0aee49a52505d4d13c7be545f15021b17c
+ languageName: node
+ linkType: hard
+
+"webpack-bundle-analyzer@npm:^4.5.0":
+ version: 4.7.0
+ resolution: "webpack-bundle-analyzer@npm:4.7.0"
+ dependencies:
+ acorn: ^8.0.4
+ acorn-walk: ^8.0.0
+ chalk: ^4.1.0
+ commander: ^7.2.0
+ gzip-size: ^6.0.0
+ lodash: ^4.17.20
+ opener: ^1.5.2
+ sirv: ^1.0.7
+ ws: ^7.3.1
+ bin:
+ webpack-bundle-analyzer: lib/bin/analyzer.js
+ checksum: 4ce3b379c61ce16b2219756843407cc99f2b82cd191f653043f1b705a3e32b3af03834af0dfded98ab852313a892a148bed1a8effaacd6440f028c19f41581f3
+ languageName: node
+ linkType: hard
+
+"webpack-dev-middleware@npm:^5.3.1":
+ version: 5.3.3
+ resolution: "webpack-dev-middleware@npm:5.3.3"
+ dependencies:
+ colorette: ^2.0.10
+ memfs: ^3.4.3
+ mime-types: ^2.1.31
+ range-parser: ^1.2.1
+ schema-utils: ^4.0.0
+ peerDependencies:
+ webpack: ^4.0.0 || ^5.0.0
+ checksum: dd332cc6da61222c43d25e5a2155e23147b777ff32fdf1f1a0a8777020c072fbcef7756360ce2a13939c3f534c06b4992a4d659318c4a7fe2c0530b52a8a6621
+ languageName: node
+ linkType: hard
+
+"webpack-dev-server@npm:^4.9.3":
+ version: 4.11.1
+ resolution: "webpack-dev-server@npm:4.11.1"
+ dependencies:
+ "@types/bonjour": ^3.5.9
+ "@types/connect-history-api-fallback": ^1.3.5
+ "@types/express": ^4.17.13
+ "@types/serve-index": ^1.9.1
+ "@types/serve-static": ^1.13.10
+ "@types/sockjs": ^0.3.33
+ "@types/ws": ^8.5.1
+ ansi-html-community: ^0.0.8
+ bonjour-service: ^1.0.11
+ chokidar: ^3.5.3
+ colorette: ^2.0.10
+ compression: ^1.7.4
+ connect-history-api-fallback: ^2.0.0
+ default-gateway: ^6.0.3
+ express: ^4.17.3
+ graceful-fs: ^4.2.6
+ html-entities: ^2.3.2
+ http-proxy-middleware: ^2.0.3
+ ipaddr.js: ^2.0.1
+ open: ^8.0.9
+ p-retry: ^4.5.0
+ rimraf: ^3.0.2
+ schema-utils: ^4.0.0
+ selfsigned: ^2.1.1
+ serve-index: ^1.9.1
+ sockjs: ^0.3.24
+ spdy: ^4.0.2
+ webpack-dev-middleware: ^5.3.1
+ ws: ^8.4.2
+ peerDependencies:
+ webpack: ^4.37.0 || ^5.0.0
+ peerDependenciesMeta:
+ webpack-cli:
+ optional: true
+ bin:
+ webpack-dev-server: bin/webpack-dev-server.js
+ checksum: b7601a39ee0f413988259e29a36835b0a68522cfaa161de5b7ec99b3399acdd99d44189add4aaf4a5191258bb130f9cf3e68919324a1955c7557f5fe6ab0d96c
+ languageName: node
+ linkType: hard
+
+"webpack-merge@npm:^5.8.0":
+ version: 5.8.0
+ resolution: "webpack-merge@npm:5.8.0"
+ dependencies:
+ clone-deep: ^4.0.1
+ wildcard: ^2.0.0
+ checksum: 88786ab91013f1bd2a683834ff381be81c245a4b0f63304a5103e90f6653f44dab496a0768287f8531761f8ad957d1f9f3ccb2cb55df0de1bd9ee343e079da26
+ languageName: node
+ linkType: hard
+
+"webpack-sources@npm:^3.2.2, webpack-sources@npm:^3.2.3":
+ version: 3.2.3
+ resolution: "webpack-sources@npm:3.2.3"
+ checksum: 989e401b9fe3536529e2a99dac8c1bdc50e3a0a2c8669cbafad31271eadd994bc9405f88a3039cd2e29db5e6d9d0926ceb7a1a4e7409ece021fe79c37d9c4607
+ languageName: node
+ linkType: hard
+
+"webpack@npm:^5.73.0":
+ version: 5.75.0
+ resolution: "webpack@npm:5.75.0"
+ dependencies:
+ "@types/eslint-scope": ^3.7.3
+ "@types/estree": ^0.0.51
+ "@webassemblyjs/ast": 1.11.1
+ "@webassemblyjs/wasm-edit": 1.11.1
+ "@webassemblyjs/wasm-parser": 1.11.1
+ acorn: ^8.7.1
+ acorn-import-assertions: ^1.7.6
+ browserslist: ^4.14.5
+ chrome-trace-event: ^1.0.2
+ enhanced-resolve: ^5.10.0
+ es-module-lexer: ^0.9.0
+ eslint-scope: 5.1.1
+ events: ^3.2.0
+ glob-to-regexp: ^0.4.1
+ graceful-fs: ^4.2.9
+ json-parse-even-better-errors: ^2.3.1
+ loader-runner: ^4.2.0
+ mime-types: ^2.1.27
+ neo-async: ^2.6.2
+ schema-utils: ^3.1.0
+ tapable: ^2.1.1
+ terser-webpack-plugin: ^5.1.3
+ watchpack: ^2.4.0
+ webpack-sources: ^3.2.3
+ peerDependenciesMeta:
+ webpack-cli:
+ optional: true
+ bin:
+ webpack: bin/webpack.js
+ checksum: 2bcc5f3c195f375944e8af2f00bf2feea39cb9fda5f763b0d1b00077f1c51783db25c94d3fae96a07dead9fa085e6ae7474417e5ab31719c9776ea5969ceb83a
+ languageName: node
+ linkType: hard
+
+"webpackbar@npm:^5.0.2":
+ version: 5.0.2
+ resolution: "webpackbar@npm:5.0.2"
+ dependencies:
+ chalk: ^4.1.0
+ consola: ^2.15.3
+ pretty-time: ^1.1.0
+ std-env: ^3.0.1
+ peerDependencies:
+ webpack: 3 || 4 || 5
+ checksum: 214a734b1d4d391eb8271ed1b11085f0efe6831e93f641229b292abfd6fea871422dce121612511c17ae8047522be6d65c1a2666cabb396c79549816a3612338
+ languageName: node
+ linkType: hard
+
+"websocket-driver@npm:>=0.5.1, websocket-driver@npm:^0.7.4":
+ version: 0.7.4
+ resolution: "websocket-driver@npm:0.7.4"
+ dependencies:
+ http-parser-js: ">=0.5.1"
+ safe-buffer: ">=5.1.0"
+ websocket-extensions: ">=0.1.1"
+ checksum: fffe5a33fe8eceafd21d2a065661d09e38b93877eae1de6ab5d7d2734c6ed243973beae10ae48c6613cfd675f200e5a058d1e3531bc9e6c5d4f1396ff1f0bfb9
+ languageName: node
+ linkType: hard
+
+"websocket-extensions@npm:>=0.1.1":
+ version: 0.1.4
+ resolution: "websocket-extensions@npm:0.1.4"
+ checksum: 5976835e68a86afcd64c7a9762ed85f2f27d48c488c707e67ba85e717b90fa066b98ab33c744d64255c9622d349eedecf728e65a5f921da71b58d0e9591b9038
+ languageName: node
+ linkType: hard
+
+"whatwg-url@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "whatwg-url@npm:5.0.0"
+ dependencies:
+ tr46: ~0.0.3
+ webidl-conversions: ^3.0.0
+ checksum: b8daed4ad3356cc4899048a15b2c143a9aed0dfae1f611ebd55073310c7b910f522ad75d727346ad64203d7e6c79ef25eafd465f4d12775ca44b90fa82ed9e2c
+ languageName: node
+ linkType: hard
+
+"which@npm:^1.3.1":
+ version: 1.3.1
+ resolution: "which@npm:1.3.1"
+ dependencies:
+ isexe: ^2.0.0
+ bin:
+ which: ./bin/which
+ checksum: f2e185c6242244b8426c9df1510e86629192d93c1a986a7d2a591f2c24869e7ffd03d6dac07ca863b2e4c06f59a4cc9916c585b72ee9fa1aa609d0124df15e04
+ languageName: node
+ linkType: hard
+
+"which@npm:^2.0.1, which@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "which@npm:2.0.2"
+ dependencies:
+ isexe: ^2.0.0
+ bin:
+ node-which: ./bin/node-which
+ checksum: 1a5c563d3c1b52d5f893c8b61afe11abc3bab4afac492e8da5bde69d550de701cf9806235f20a47b5c8fa8a1d6a9135841de2596535e998027a54589000e66d1
+ languageName: node
+ linkType: hard
+
+"wide-align@npm:^1.1.5":
+ version: 1.1.5
+ resolution: "wide-align@npm:1.1.5"
+ dependencies:
+ string-width: ^1.0.2 || 2 || 3 || 4
+ checksum: d5fc37cd561f9daee3c80e03b92ed3e84d80dde3365a8767263d03dacfc8fa06b065ffe1df00d8c2a09f731482fcacae745abfbb478d4af36d0a891fad4834d3
+ languageName: node
+ linkType: hard
+
+"widest-line@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "widest-line@npm:3.1.0"
+ dependencies:
+ string-width: ^4.0.0
+ checksum: 03db6c9d0af9329c37d74378ff1d91972b12553c7d72a6f4e8525fe61563fa7adb0b9d6e8d546b7e059688712ea874edd5ded475999abdeedf708de9849310e0
+ languageName: node
+ linkType: hard
+
+"widest-line@npm:^4.0.1":
+ version: 4.0.1
+ resolution: "widest-line@npm:4.0.1"
+ dependencies:
+ string-width: ^5.0.1
+ checksum: 64c48cf27171221be5f86fc54b94dd29879165bdff1a7aa92dde723d9a8c99fb108312768a5d62c8c2b80b701fa27bbd36a1ddc58367585cd45c0db7920a0cba
+ languageName: node
+ linkType: hard
+
+"wildcard@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "wildcard@npm:2.0.0"
+ checksum: 1f4fe4c03dfc492777c60f795bbba597ac78794f1b650d68f398fbee9adb765367c516ebd4220889b6a81e9626e7228bbe0d66237abb311573c2ee1f4902a5ad
+ languageName: node
+ linkType: hard
+
+"wrap-ansi@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "wrap-ansi@npm:7.0.0"
+ dependencies:
+ ansi-styles: ^4.0.0
+ string-width: ^4.1.0
+ strip-ansi: ^6.0.0
+ checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b
+ languageName: node
+ linkType: hard
+
+"wrap-ansi@npm:^8.0.1":
+ version: 8.0.1
+ resolution: "wrap-ansi@npm:8.0.1"
+ dependencies:
+ ansi-styles: ^6.1.0
+ string-width: ^5.0.1
+ strip-ansi: ^7.0.1
+ checksum: 5d7816e64f75544e466d58a736cb96ca47abad4ad57f48765b9735ba5601221013a37f436662340ca159208b011121e4e030de5a17180c76202e35157195a71e
+ languageName: node
+ linkType: hard
+
+"wrappy@npm:1":
+ version: 1.0.2
+ resolution: "wrappy@npm:1.0.2"
+ checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5
+ languageName: node
+ linkType: hard
+
+"write-file-atomic@npm:^3.0.0":
+ version: 3.0.3
+ resolution: "write-file-atomic@npm:3.0.3"
+ dependencies:
+ imurmurhash: ^0.1.4
+ is-typedarray: ^1.0.0
+ signal-exit: ^3.0.2
+ typedarray-to-buffer: ^3.1.5
+ checksum: c55b24617cc61c3a4379f425fc62a386cc51916a9b9d993f39734d005a09d5a4bb748bc251f1304e7abd71d0a26d339996c275955f527a131b1dcded67878280
+ languageName: node
+ linkType: hard
+
+"ws@npm:^7.3.1":
+ version: 7.5.9
+ resolution: "ws@npm:7.5.9"
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: ^5.0.2
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+ checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138
+ languageName: node
+ linkType: hard
+
+"ws@npm:^8.4.2":
+ version: 8.11.0
+ resolution: "ws@npm:8.11.0"
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: ^5.0.2
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+ checksum: 316b33aba32f317cd217df66dbfc5b281a2f09ff36815de222bc859e3424d83766d9eb2bd4d667de658b6ab7be151f258318fb1da812416b30be13103e5b5c67
+ languageName: node
+ linkType: hard
+
+"xdg-basedir@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "xdg-basedir@npm:4.0.0"
+ checksum: 0073d5b59a37224ed3a5ac0dd2ec1d36f09c49f0afd769008a6e9cd3cd666bd6317bd1c7ce2eab47e1de285a286bad11a9b038196413cd753b79770361855f3c
+ languageName: node
+ linkType: hard
+
+"xml-js@npm:^1.6.11":
+ version: 1.6.11
+ resolution: "xml-js@npm:1.6.11"
+ dependencies:
+ sax: ^1.2.4
+ bin:
+ xml-js: ./bin/cli.js
+ checksum: 24a55479919413687105fc2d8ab05e613ebedb1c1bc12258a108e07cff5ef793779297db854800a4edf0281303ebd1f177bc4a588442f5344e62b3dddda26c2b
+ languageName: node
+ linkType: hard
+
+"xtend@npm:^4.0.0, xtend@npm:^4.0.1":
+ version: 4.0.2
+ resolution: "xtend@npm:4.0.2"
+ checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a
+ languageName: node
+ linkType: hard
+
+"yallist@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "yallist@npm:4.0.0"
+ checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5
+ languageName: node
+ linkType: hard
+
+"yaml@npm:^1.10.0, yaml@npm:^1.10.2, yaml@npm:^1.7.2":
+ version: 1.10.2
+ resolution: "yaml@npm:1.10.2"
+ checksum: ce4ada136e8a78a0b08dc10b4b900936912d15de59905b2bf415b4d33c63df1d555d23acb2a41b23cf9fb5da41c256441afca3d6509de7247daa062fd2c5ea5f
+ languageName: node
+ linkType: hard
+
+"yocto-queue@npm:^0.1.0":
+ version: 0.1.0
+ resolution: "yocto-queue@npm:0.1.0"
+ checksum: f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700
+ languageName: node
+ linkType: hard
+
+"zwitch@npm:^1.0.0":
+ version: 1.0.5
+ resolution: "zwitch@npm:1.0.5"
+ checksum: 28a1bebacab3bc60150b6b0a2ba1db2ad033f068e81f05e4892ec0ea13ae63f5d140a1d692062ac0657840c8da076f35b94433b5f1c329d7803b247de80f064a
+ languageName: node
+ linkType: hard
diff --git a/microsite/blog/2021-05-20-adopting-backstage.md b/microsite/blog/2021-05-20-adopting-backstage.md
index 290436c875..0a606fbe60 100644
--- a/microsite/blog/2021-05-20-adopting-backstage.md
+++ b/microsite/blog/2021-05-20-adopting-backstage.md
@@ -23,12 +23,12 @@ Spotify’s developers were facing three big challenges on a daily basis:
- They needed to keep an eye on what squads around them might be building to ensure they could reuse systems when they needed to solve similar problems in the future.
In short, Spotify developers needed to continue building industry leading features at breakneck speed, while simultaneously maintaining a mental model for all the software at Spotify (oh, and help every new joiner develop that mental model as well!).
-
+
## Three jobs: Create, manage, explore
Around the same time, the [jobs to be done](https://hbr.org/2016/09/know-your-customers-jobs-to-be-done) framework was becoming popular and luckily, a few Spotifiers helped guide the vision for a _sense-making tool for developers_ toward using it. After user research and many failed attempts, we landed on three jobs Spotify developers needed to do consistently:
-
+
- **Create**: Spotify developers want to delight their customers with incredible features. They create new software to do that.
- **Manage**: Spotify developers are proud of their work and treat their software and data like products. That requires maintaining all the software they own on an ongoing basis.
@@ -73,7 +73,7 @@ Within today’s complex development environments, there are barriers both big a
After talking with companies who have already adopted Backstage, we’ve seen a few common strategies for getting started. The different strategies are based on the size of your engineering org (which often also corresponds with how fast you’re growing).

-
+
### My org has ~200 engineers (and is growing fast)
diff --git a/microsite/blog/2021-09-16-the-techdocs-beta-has-landed.md b/microsite/blog/2021-09-16-the-techdocs-beta-has-landed.md
index c4edf22de2..f3f79abf44 100644
--- a/microsite/blog/2021-09-16-the-techdocs-beta-has-landed.md
+++ b/microsite/blog/2021-09-16-the-techdocs-beta-has-landed.md
@@ -21,9 +21,7 @@ When we set out to define what beta looked like, we combed through GitHub issues
TechDocs can be transformational once fully up and running (update your code and your docs with the same pull request!). But for first-time users and especially those unfamiliar with the MkDocs ecosystem upon which TechDocs is built, there are often many small, obtuse hurdles that can get in the way of success. Leading up to the beta release, we worked to surface and improve relevant errors and other details during the documentation generation process. Better still, all of this detail is now provided to users _in real-time_, as docs are generated and refreshed.
-
🙌 Shout out to Dominik Henneke for implementing the interactive experience.
-
## Custom homepages: Make TechDocs yours
@@ -31,9 +29,7 @@ TechDocs can be transformational once fully up and running (update your code and
We strive to make it so that you can mold Backstage into the shape that best fits your organization. With this beta release, just as you can with the Catalog entities and [Search](https://backstage.io/blog/2021/06/24/announcing-backstage-search-platform#composable-search-page-experiences), you can now customize and compose your own TechDocs homepage. Use it to level up the front page of your Backstage documentation by highlighting golden documentation at your company, or use the new and improved (and Catalog-inspired) experience. Read more about [how to customize the TechDocs homepage](https://backstage.io/docs/features/techdocs/how-to-guides#how-to-customize-the-techdocs-home-page).
-
🙏 Thanks to Phil Kuang for the improved default TechDocs home experience.
-
## Simpler YAML annotations: What's in a ref?
@@ -43,9 +39,7 @@ We often forget that in order to enable TechDocs on a Catalog entity, documentat
In the beta, we've simplified this annotation dramatically for documentation authors, aligning its value with TechDocs' docs-like-code philosophy itself. In the vast majority of cases, its value will simply be `dir:.` — which means this catalog entity contains documentation and the mkdocs.yml file describing this documentation lives in the current directory. We continue to support edge cases for [other techdocs-ref annotation values](https://backstage.io/docs/features/techdocs/how-to-guides#how-to-understand-techdocs-ref-annotation-values), as well.
-
👏 Another round of applause for Dominik for driving this improvement through.
-
## Everything neat and tidy
diff --git a/microsite/data/plugins/opslevel-maturity.yaml b/microsite/data/plugins/opslevel-maturity.yaml
new file mode 100644
index 0000000000..724f46ae17
--- /dev/null
+++ b/microsite/data/plugins/opslevel-maturity.yaml
@@ -0,0 +1,14 @@
+---
+title: Service Maturity
+author: OpsLevel
+authorUrl: https://www.opslevel.com/
+category: Quality
+description: Integrate with OpsLevel to track performance against your engineering best practices and service maturity.
+documentation: https://github.com/OpsLevel/backstage-plugin
+iconUrl: https://avatars.githubusercontent.com/u/44910550?s=200&v=4
+npmPackageName: backstage-plugin-opslevel-maturity
+tags:
+ - service maturity
+ - service quality
+ - maturity score
+addedDate: '2022-12-07'
diff --git a/microsite/pages/en/index.js b/microsite/pages/en/index.js
index ab3dabe14e..b7eb3a9cf0 100644
--- a/microsite/pages/en/index.js
+++ b/microsite/pages/en/index.js
@@ -45,13 +45,21 @@ class Index extends React.Component {
ship high-quality code quickly — without compromising
autonomy.
-
- GitHub
-
+
+
+ GitHub
+
+
+ Office Hours
+
+
} />
@@ -278,14 +275,12 @@ const routes = (
);
-const App = () => (
-
+export default app.createRoot(
+ <>
{routes}
-
+ >,
);
-
-export default App;
diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md
index 3c15eac580..5514b46d41 100644
--- a/packages/backend-app-api/CHANGELOG.md
+++ b/packages/backend-app-api/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/backend-app-api
+## 0.2.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/plugin-permission-node@0.7.2-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/errors@1.1.4-next.1
+
## 0.2.4-next.2
### Patch Changes
diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md
index 5008b1efe1..33e732cf05 100644
--- a/packages/backend-app-api/api-report.md
+++ b/packages/backend-app-api/api-report.md
@@ -4,13 +4,12 @@
```ts
import { BackendFeature } from '@backstage/backend-plugin-api';
-import { BackendLifecycle } from '@backstage/backend-plugin-api';
import { Config } from '@backstage/config';
import { ExtensionPoint } from '@backstage/backend-plugin-api';
import { HttpRouterService } from '@backstage/backend-plugin-api';
-import { Logger } from '@backstage/backend-plugin-api';
-import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
-import { PermissionEvaluator } from '@backstage/plugin-permission-common';
+import { LifecycleService } from '@backstage/backend-plugin-api';
+import { LoggerService } from '@backstage/backend-plugin-api';
+import { PermissionsService } from '@backstage/backend-plugin-api';
import { PluginCacheManager } from '@backstage/backend-common';
import { PluginDatabaseManager } from '@backstage/backend-common';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
@@ -26,6 +25,8 @@ export interface Backend {
add(feature: BackendFeature): void;
// (undocumented)
start(): Promise;
+ // (undocumented)
+ stop(): Promise;
}
// @public (undocumented)
@@ -70,18 +71,22 @@ export type HttpRouterFactoryOptions = {
// @public
export const lifecycleFactory: (
options?: undefined,
-) => ServiceFactory;
+) => ServiceFactory;
// @public (undocumented)
-export const loggerFactory: (options?: undefined) => ServiceFactory;
+export const loggerFactory: (
+ options?: undefined,
+) => ServiceFactory;
// @public (undocumented)
export const permissionsFactory: (
options?: undefined,
-) => ServiceFactory;
+) => ServiceFactory;
// @public (undocumented)
-export const rootLoggerFactory: (options?: undefined) => ServiceFactory;
+export const rootLoggerFactory: (
+ options?: undefined,
+) => ServiceFactory;
// @public (undocumented)
export const schedulerFactory: (
diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json
index 7eb59ba838..3c8a936fe5 100644
--- a/packages/backend-app-api/package.json
+++ b/packages/backend-app-api/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-app-api",
"description": "Core API used by Backstage backend apps",
- "version": "0.2.4-next.2",
+ "version": "0.2.4-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
diff --git a/packages/backend-app-api/src/services/implementations/lifecycleService.ts b/packages/backend-app-api/src/services/implementations/lifecycleService.ts
index 5616296e93..317a2e45b8 100644
--- a/packages/backend-app-api/src/services/implementations/lifecycleService.ts
+++ b/packages/backend-app-api/src/services/implementations/lifecycleService.ts
@@ -14,11 +14,11 @@
* limitations under the License.
*/
import {
- BackendLifecycle,
+ LifecycleService,
createServiceFactory,
coreServices,
loggerToWinstonLogger,
- BackendLifecycleShutdownHook,
+ LifecycleServiceShutdownHook,
} from '@backstage/backend-plugin-api';
import { Logger } from 'winston';
@@ -29,11 +29,11 @@ export class BackendLifecycleImpl {
}
#isCalled = false;
- #shutdownTasks: Array =
+ #shutdownTasks: Array =
[];
addShutdownHook(
- options: BackendLifecycleShutdownHook & { pluginId: string },
+ options: LifecycleServiceShutdownHook & { pluginId: string },
): void {
this.#shutdownTasks.push(options);
}
@@ -64,12 +64,12 @@ export class BackendLifecycleImpl {
}
}
-class PluginScopedLifecycleImpl implements BackendLifecycle {
+class PluginScopedLifecycleImpl implements LifecycleService {
constructor(
private readonly lifecycle: BackendLifecycleImpl,
private readonly pluginId: string,
) {}
- addShutdownHook(options: BackendLifecycleShutdownHook): void {
+ addShutdownHook(options: LifecycleServiceShutdownHook): void {
this.lifecycle.addShutdownHook({ ...options, pluginId: this.pluginId });
}
}
diff --git a/packages/backend-app-api/src/services/implementations/rootLoggerService.ts b/packages/backend-app-api/src/services/implementations/rootLoggerService.ts
index d2bb406adb..54d40b6a12 100644
--- a/packages/backend-app-api/src/services/implementations/rootLoggerService.ts
+++ b/packages/backend-app-api/src/services/implementations/rootLoggerService.ts
@@ -17,24 +17,37 @@
import { createRootLogger } from '@backstage/backend-common';
import {
createServiceFactory,
- Logger,
+ LoggerService,
coreServices,
} from '@backstage/backend-plugin-api';
+import { LogMeta } from '@backstage/backend-plugin-api';
import { Logger as WinstonLogger } from 'winston';
-class BackstageLogger implements Logger {
+class BackstageLogger implements LoggerService {
static fromWinston(logger: WinstonLogger): BackstageLogger {
return new BackstageLogger(logger);
}
private constructor(private readonly winston: WinstonLogger) {}
- info(message: string, ...meta: any[]): void {
- this.winston.info(message, ...meta);
+ error(message: string, meta?: LogMeta): void {
+ this.winston.error(message, meta);
}
- child(fields: { [name: string]: string }): Logger {
- return new BackstageLogger(this.winston.child(fields));
+ warn(message: string, meta?: LogMeta): void {
+ this.winston.warn(message, meta);
+ }
+
+ info(message: string, meta?: LogMeta): void {
+ this.winston.info(message, meta);
+ }
+
+ debug(message: string, meta?: LogMeta): void {
+ this.winston.debug(message, meta);
+ }
+
+ child(meta: LogMeta): LoggerService {
+ return new BackstageLogger(this.winston.child(meta));
}
}
diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts
new file mode 100644
index 0000000000..8fd7441c37
--- /dev/null
+++ b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ createServiceRef,
+ createServiceFactory,
+} from '@backstage/backend-plugin-api';
+import { BackendInitializer } from './BackendInitializer';
+import { ServiceRegistry } from './ServiceRegistry';
+
+const rootRef = createServiceRef<{ x: number }>({
+ id: '1',
+ scope: 'root',
+});
+
+const pluginRef = createServiceRef<{ x: number }>({
+ id: '2',
+});
+
+describe('BackendInitializer', () => {
+ it('should initialize root scoped services', async () => {
+ const rootFactory = jest.fn();
+ const pluginFactory = jest.fn();
+
+ const registry = new ServiceRegistry([
+ createServiceFactory({
+ service: rootRef,
+ deps: {},
+ factory: rootFactory,
+ }),
+ createServiceFactory({
+ service: pluginRef,
+ deps: {},
+ factory: pluginFactory,
+ }),
+ ]);
+
+ const init = new BackendInitializer(registry);
+ await init.start();
+
+ expect(rootFactory).toHaveBeenCalled();
+ expect(pluginFactory).not.toHaveBeenCalled();
+ });
+});
diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts
index c86cd8382d..478cb30ff8 100644
--- a/packages/backend-app-api/src/wiring/BackendInitializer.ts
+++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts
@@ -17,11 +17,13 @@
import {
BackendFeature,
ExtensionPoint,
+ coreServices,
ServiceRef,
} from '@backstage/backend-plugin-api';
+import { BackendLifecycleImpl } from '../services/implementations/lifecycleService';
import {
BackendRegisterInit,
- ServiceHolder,
+ EnumerableServiceHolder,
ServiceOrExtensionPoint,
} from './types';
@@ -30,9 +32,9 @@ export class BackendInitializer {
#features = new Map();
#registerInits = new Array();
#extensionPoints = new Map, unknown>();
- #serviceHolder: ServiceHolder;
+ #serviceHolder: EnumerableServiceHolder;
- constructor(serviceHolder: ServiceHolder) {
+ constructor(serviceHolder: EnumerableServiceHolder) {
this.#serviceHolder = serviceHolder;
}
@@ -85,6 +87,14 @@ export class BackendInitializer {
}
this.#started = true;
+ // Initialize all root scoped services
+ for (const ref of this.#serviceHolder.getServiceRefs()) {
+ if (ref.scope === 'root') {
+ await this.#serviceHolder.get(ref, 'root');
+ }
+ }
+
+ // Initialize all features
for (const [feature] of this.#features) {
const provides = new Set>();
@@ -165,4 +175,23 @@ export class BackendInitializer {
return orderedRegisterInits;
}
+
+ async stop(): Promise {
+ if (!this.#started) {
+ return;
+ }
+
+ const lifecycleService = await this.#serviceHolder.get(
+ coreServices.lifecycle,
+ 'root',
+ );
+
+ // TODO(Rugvip): Find a better way to do this
+ const lifecycle = (lifecycleService as any)?.lifecycle;
+ if (lifecycle instanceof BackendLifecycleImpl) {
+ await lifecycle.shutdown();
+ } else {
+ throw new Error('Unexpected lifecycle service implementation');
+ }
+ }
}
diff --git a/packages/backend-app-api/src/wiring/BackstageBackend.ts b/packages/backend-app-api/src/wiring/BackstageBackend.ts
index 1d76161bfe..c53f47b685 100644
--- a/packages/backend-app-api/src/wiring/BackstageBackend.ts
+++ b/packages/backend-app-api/src/wiring/BackstageBackend.ts
@@ -36,7 +36,7 @@ export class BackstageBackend implements Backend {
await this.#initializer.start();
}
- // async stop(): Promise {
- // await this.#initializer.stop();
- // }
+ async stop(): Promise {
+ await this.#initializer.stop();
+ }
}
diff --git a/packages/backend-app-api/src/wiring/ServiceRegistry.ts b/packages/backend-app-api/src/wiring/ServiceRegistry.ts
index 9ff73f4270..208e5cf260 100644
--- a/packages/backend-app-api/src/wiring/ServiceRegistry.ts
+++ b/packages/backend-app-api/src/wiring/ServiceRegistry.ts
@@ -20,7 +20,7 @@ import {
coreServices,
} from '@backstage/backend-plugin-api';
import { stringifyError } from '@backstage/errors';
-
+import { EnumerableServiceHolder } from './types';
/**
* Keep in sync with `@backstage/backend-plugin-api/src/services/system/types.ts`
* @internal
@@ -31,7 +31,7 @@ export type InternalServiceRef = ServiceRef & {
) => Promise | (() => ServiceFactory)>;
};
-export class ServiceRegistry {
+export class ServiceRegistry implements EnumerableServiceHolder {
readonly #providedFactories: Map;
readonly #loadedDefaultFactories: Map>;
readonly #implementations: Map<
@@ -132,6 +132,10 @@ export class ServiceRegistry {
}
}
+ getServiceRefs(): ServiceRef[] {
+ return Array.from(this.#providedFactories.values()).map(f => f.service);
+ }
+
get(ref: ServiceRef, pluginId: string): Promise | undefined {
return this.#resolveFactory(ref, pluginId)?.then(factory => {
if (factory.scope === 'root') {
diff --git a/packages/backend-app-api/src/wiring/types.ts b/packages/backend-app-api/src/wiring/types.ts
index 40ce6aa1ae..46ac690702 100644
--- a/packages/backend-app-api/src/wiring/types.ts
+++ b/packages/backend-app-api/src/wiring/types.ts
@@ -28,6 +28,7 @@ import { BackstageBackend } from './BackstageBackend';
export interface Backend {
add(feature: BackendFeature): void;
start(): Promise;
+ stop(): Promise;
}
export interface BackendRegisterInit {
@@ -45,9 +46,16 @@ export interface CreateSpecializedBackendOptions {
services: (ServiceFactory | (() => ServiceFactory))[];
}
-export type ServiceHolder = {
+export interface ServiceHolder {
get(api: ServiceRef, pluginId: string): Promise | undefined;
-};
+}
+
+/**
+ * @internal
+ */
+export interface EnumerableServiceHolder extends ServiceHolder {
+ getServiceRefs(): ServiceRef[];
+}
/**
* @public
diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md
index e1c0d292d4..4249c2ce12 100644
--- a/packages/backend-common/CHANGELOG.md
+++ b/packages/backend-common/CHANGELOG.md
@@ -1,5 +1,18 @@
# @backstage/backend-common
+## 0.17.0-next.3
+
+### Patch Changes
+
+- 840f2113c6: Fix `GitlabUrlReader.readTree` bug when there were no matching commits
+- Updated dependencies
+ - @backstage/cli-common@0.1.11-next.0
+ - @backstage/config@1.0.5-next.1
+ - @backstage/config-loader@1.1.7-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+
## 0.17.0-next.2
### Patch Changes
diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json
index 6e8cb6faeb..ee768618a4 100644
--- a/packages/backend-common/package.json
+++ b/packages/backend-common/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
- "version": "0.17.0-next.2",
+ "version": "0.17.0-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts
index 31092e7707..3751ee868e 100644
--- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts
+++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts
@@ -229,22 +229,28 @@ describe('GitlabUrlReader', () => {
path.resolve(__dirname, '__fixtures__/gitlab-archive.tar.gz'),
);
- const projectGitlabApiResponse = {
- id: 11111111,
- default_branch: 'main',
- };
+ let projectGitlabApiResponse: any;
+ let commitsGitlabApiResponse: any;
+ let specificPathCommitsGitlabApiResponse: any;
- const commitsGitlabApiResponse = [
- {
- id: 'sha123abc',
- },
- ];
+ beforeEach(() => {
+ projectGitlabApiResponse = {
+ id: 11111111,
+ default_branch: 'main',
+ };
- const specificPathCommitsGitlabApiResponse = [
- {
- id: 'sha456def',
- },
- ];
+ commitsGitlabApiResponse = [
+ {
+ id: 'sha123abc',
+ },
+ ];
+
+ specificPathCommitsGitlabApiResponse = [
+ {
+ id: 'sha456def',
+ },
+ ];
+ });
beforeEach(() => {
worker.use(
@@ -494,6 +500,23 @@ describe('GitlabUrlReader', () => {
};
await expect(fnGitlab).rejects.toThrow(NotFoundError);
});
+
+ it('should gracefully handle no matching commits', async () => {
+ commitsGitlabApiResponse = [];
+
+ const response = await gitlabProcessor.readTree(
+ 'https://gitlab.com/backstage/mock/tree/main',
+ );
+
+ const files = await response.files();
+ expect(files.length).toBe(2);
+
+ const indexMarkdownFile = await files[0].content();
+ const mkDocsFile = await files[1].content();
+
+ expect(mkDocsFile.toString()).toBe('site_name: Test\n');
+ expect(indexMarkdownFile.toString()).toBe('# Test\n');
+ });
});
describe('search', () => {
diff --git a/packages/backend-common/src/reading/GitlabUrlReader.ts b/packages/backend-common/src/reading/GitlabUrlReader.ts
index a582f02cf0..c80f1b566c 100644
--- a/packages/backend-common/src/reading/GitlabUrlReader.ts
+++ b/packages/backend-common/src/reading/GitlabUrlReader.ts
@@ -188,8 +188,7 @@ export class GitlabUrlReader implements UrlReader {
throw new Error(message);
}
- const commitSha = (await commitsGitlabResponse.json())[0].id;
-
+ const commitSha = (await commitsGitlabResponse.json())[0]?.id ?? '';
if (etag && etag === commitSha) {
throw new NotModifiedError();
}
diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md
index fb593ef671..f1948621a2 100644
--- a/packages/backend-defaults/CHANGELOG.md
+++ b/packages/backend-defaults/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/backend-defaults
+## 0.1.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-app-api@0.2.4-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+
## 0.1.4-next.2
### Patch Changes
diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json
index 0b70fc35d9..6f69c19636 100644
--- a/packages/backend-defaults/package.json
+++ b/packages/backend-defaults/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-defaults",
"description": "Backend defaults used by Backstage backend apps",
- "version": "0.1.4-next.2",
+ "version": "0.1.4-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
diff --git a/packages/backend-next/CHANGELOG.md b/packages/backend-next/CHANGELOG.md
index 91e9441de6..f0bb4122b8 100644
--- a/packages/backend-next/CHANGELOG.md
+++ b/packages/backend-next/CHANGELOG.md
@@ -1,5 +1,15 @@
# example-backend-next
+## 0.0.6-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/plugin-scaffolder-backend@1.9.0-next.3
+ - @backstage/backend-defaults@0.1.4-next.3
+ - @backstage/plugin-app-backend@0.3.39-next.3
+
## 0.0.6-next.2
### Patch Changes
diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json
index 0eb9d02a68..93f16e0328 100644
--- a/packages/backend-next/package.json
+++ b/packages/backend-next/package.json
@@ -1,6 +1,6 @@
{
"name": "example-backend-next",
- "version": "0.0.6-next.2",
+ "version": "0.0.6-next.3",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md
index 5c600f446d..84f7cb8ba4 100644
--- a/packages/backend-plugin-api/CHANGELOG.md
+++ b/packages/backend-plugin-api/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/backend-plugin-api
+## 0.2.0-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+
## 0.2.0-next.2
### Minor Changes
diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md
index 17cae29bff..545728b386 100644
--- a/packages/backend-plugin-api/api-report.md
+++ b/packages/backend-plugin-api/api-report.md
@@ -5,7 +5,7 @@
```ts
import { Config } from '@backstage/config';
import { Handler } from 'express';
-import { Logger as Logger_2 } from 'winston';
+import { Logger } from 'winston';
import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
import { PluginCacheManager } from '@backstage/backend-common';
@@ -24,16 +24,6 @@ export interface BackendFeature {
register(reg: BackendRegistrationPoints): void;
}
-// @public (undocumented)
-export interface BackendLifecycle {
- addShutdownHook(options: BackendLifecycleShutdownHook): void;
-}
-
-// @public (undocumented)
-export type BackendLifecycleShutdownHook = {
- fn: () => void | Promise;
-};
-
// @public (undocumented)
export interface BackendModuleConfig {
// (undocumented)
@@ -75,9 +65,15 @@ export interface BackendRegistrationPoints {
}): void;
}
+// @public (undocumented)
+export type CacheService = PluginCacheManager;
+
// @public (undocumented)
const cacheServiceRef: ServiceRef;
+// @public (undocumented)
+export type ConfigService = Config;
+
// @public (undocumented)
const configServiceRef: ServiceRef;
@@ -164,9 +160,15 @@ export function createServiceRef(options: {
) => Promise | (() => ServiceFactory)>;
}): ServiceRef;
+// @public (undocumented)
+export type DatabaseService = PluginDatabaseManager;
+
// @public (undocumented)
const databaseServiceRef: ServiceRef;
+// @public (undocumented)
+export type DiscoveryService = PluginEndpointDiscovery;
+
// @public (undocumented)
const discoveryServiceRef: ServiceRef;
@@ -188,42 +190,69 @@ export interface HttpRouterService {
const httpRouterServiceRef: ServiceRef;
// @public (undocumented)
-const lifecycleServiceRef: ServiceRef;
-
-// @public (undocumented)
-export interface Logger {
- // (undocumented)
- child(fields: { [name: string]: string }): Logger;
- // (undocumented)
- info(message: string): void;
+export interface LifecycleService {
+ addShutdownHook(options: LifecycleServiceShutdownHook): void;
}
// @public (undocumented)
-const loggerServiceRef: ServiceRef;
+const lifecycleServiceRef: ServiceRef;
+
+// @public (undocumented)
+export type LifecycleServiceShutdownHook = {
+ fn: () => void | Promise;
+};
+
+// @public (undocumented)
+export interface LoggerService {
+ // (undocumented)
+ child(meta: LogMeta): LoggerService;
+ // (undocumented)
+ debug(message: string, meta?: Error | LogMeta): void;
+ // (undocumented)
+ error(message: string, meta?: Error | LogMeta): void;
+ // (undocumented)
+ info(message: string, meta?: Error | LogMeta): void;
+ // (undocumented)
+ warn(message: string, meta?: Error | LogMeta): void;
+}
+
+// @public (undocumented)
+const loggerServiceRef: ServiceRef;
// @public (undocumented)
export function loggerToWinstonLogger(
- logger: Logger,
+ logger: LoggerService,
opts?: TransportStreamOptions,
-): Logger_2;
+): Logger;
// @public (undocumented)
-const permissionsServiceRef: ServiceRef<
- PermissionAuthorizer | PermissionEvaluator,
- 'plugin'
->;
+export type LogMeta = {
+ [name: string]: unknown;
+};
// @public (undocumented)
-export interface PluginMetadata {
+export type PermissionsService = PermissionEvaluator | PermissionAuthorizer;
+
+// @public (undocumented)
+const permissionsServiceRef: ServiceRef;
+
+// @public (undocumented)
+export interface PluginMetadataService {
// (undocumented)
getId(): string;
}
// @public (undocumented)
-const pluginMetadataServiceRef: ServiceRef;
+const pluginMetadataServiceRef: ServiceRef;
// @public (undocumented)
-const rootLoggerServiceRef: ServiceRef;
+export type RootLoggerService = LoggerService;
+
+// @public (undocumented)
+const rootLoggerServiceRef: ServiceRef;
+
+// @public (undocumented)
+export type SchedulerService = PluginTaskScheduler;
// @public (undocumented)
const schedulerServiceRef: ServiceRef;
@@ -267,6 +296,9 @@ export type ServiceRef<
$$ref: 'service';
};
+// @public (undocumented)
+export type TokenManagerService = TokenManager;
+
// @public (undocumented)
const tokenManagerServiceRef: ServiceRef;
@@ -275,6 +307,9 @@ export type TypesToServiceRef = {
[key in keyof T]: ServiceRef;
};
+// @public (undocumented)
+export type UrlReaderService = UrlReader;
+
// @public (undocumented)
const urlReaderServiceRef: ServiceRef;
```
diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json
index f01f8df6ce..e1215f6210 100644
--- a/packages/backend-plugin-api/package.json
+++ b/packages/backend-plugin-api/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-plugin-api",
"description": "Core API used by Backstage backend plugins",
- "version": "0.2.0-next.2",
+ "version": "0.2.0-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
diff --git a/packages/backend-plugin-api/src/services/definitions/cacheServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/cacheServiceRef.ts
index 0b572f1712..aff913b06a 100644
--- a/packages/backend-plugin-api/src/services/definitions/cacheServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/cacheServiceRef.ts
@@ -17,9 +17,12 @@
import { createServiceRef } from '../system/types';
import { PluginCacheManager } from '@backstage/backend-common';
+/** @public */
+export type CacheService = PluginCacheManager;
+
/**
* @public
*/
-export const cacheServiceRef = createServiceRef({
+export const cacheServiceRef = createServiceRef({
id: 'core.cache',
});
diff --git a/packages/backend-plugin-api/src/services/definitions/configServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/configServiceRef.ts
index f17c5f57bc..15e9cb9aa6 100644
--- a/packages/backend-plugin-api/src/services/definitions/configServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/configServiceRef.ts
@@ -20,7 +20,12 @@ import { createServiceRef } from '../system/types';
/**
* @public
*/
-export const configServiceRef = createServiceRef({
+export type ConfigService = Config;
+
+/**
+ * @public
+ */
+export const configServiceRef = createServiceRef({
id: 'core.root.config',
scope: 'root',
});
diff --git a/packages/backend-plugin-api/src/services/definitions/databaseServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/databaseServiceRef.ts
index b41159dc9e..aaea5d304f 100644
--- a/packages/backend-plugin-api/src/services/definitions/databaseServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/databaseServiceRef.ts
@@ -17,9 +17,12 @@
import { PluginDatabaseManager } from '@backstage/backend-common';
import { createServiceRef } from '../system/types';
+/** @public */
+export type DatabaseService = PluginDatabaseManager;
+
/**
* @public
*/
-export const databaseServiceRef = createServiceRef({
+export const databaseServiceRef = createServiceRef({
id: 'core.database',
});
diff --git a/packages/backend-plugin-api/src/services/definitions/discoveryServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/discoveryServiceRef.ts
index 675ac206a2..41505e7756 100644
--- a/packages/backend-plugin-api/src/services/definitions/discoveryServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/discoveryServiceRef.ts
@@ -17,9 +17,12 @@
import { createServiceRef } from '../system/types';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
+/** @public */
+export type DiscoveryService = PluginEndpointDiscovery;
+
/**
* @public
*/
-export const discoveryServiceRef = createServiceRef({
+export const discoveryServiceRef = createServiceRef({
id: 'core.discovery',
});
diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts
index 1ff33362fa..3cf2ab4c77 100644
--- a/packages/backend-plugin-api/src/services/definitions/index.ts
+++ b/packages/backend-plugin-api/src/services/definitions/index.ts
@@ -17,10 +17,19 @@
import * as coreServices from './coreServices';
export { coreServices };
+export type { CacheService } from './cacheServiceRef';
+export type { ConfigService } from './configServiceRef';
+export type { DatabaseService } from './databaseServiceRef';
+export type { DiscoveryService } from './discoveryServiceRef';
export type { HttpRouterService } from './httpRouterServiceRef';
-export type { Logger } from './loggerServiceRef';
export type {
- BackendLifecycle,
- BackendLifecycleShutdownHook,
+ LifecycleService,
+ LifecycleServiceShutdownHook,
} from './lifecycleServiceRef';
-export type { PluginMetadata } from './pluginMetadataServiceRef';
+export type { LoggerService, LogMeta } from './loggerServiceRef';
+export type { PermissionsService } from './permissionsServiceRef';
+export type { PluginMetadataService } from './pluginMetadataServiceRef';
+export type { RootLoggerService } from './rootLoggerServiceRef';
+export type { SchedulerService } from './schedulerServiceRef';
+export type { TokenManagerService } from './tokenManagerServiceRef';
+export type { UrlReaderService } from './urlReaderServiceRef';
diff --git a/packages/backend-plugin-api/src/services/definitions/lifecycleServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/lifecycleServiceRef.ts
index 15610e2643..4061cc1da2 100644
--- a/packages/backend-plugin-api/src/services/definitions/lifecycleServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/lifecycleServiceRef.ts
@@ -19,24 +19,24 @@ import { createServiceRef } from '../system/types';
/**
* @public
**/
-export type BackendLifecycleShutdownHook = {
+export type LifecycleServiceShutdownHook = {
fn: () => void | Promise;
};
/**
* @public
**/
-export interface BackendLifecycle {
+export interface LifecycleService {
/**
* Register a function to be called when the backend is shutting down.
*/
- addShutdownHook(options: BackendLifecycleShutdownHook): void;
+ addShutdownHook(options: LifecycleServiceShutdownHook): void;
}
/**
* @public
*/
-export const lifecycleServiceRef = createServiceRef({
+export const lifecycleServiceRef = createServiceRef({
id: 'core.lifecycle',
scope: 'plugin',
});
diff --git a/packages/backend-plugin-api/src/services/definitions/loggerServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/loggerServiceRef.ts
index e99bc4e7d4..1c094549c1 100644
--- a/packages/backend-plugin-api/src/services/definitions/loggerServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/loggerServiceRef.ts
@@ -19,14 +19,23 @@ import { createServiceRef } from '../system/types';
/**
* @public
*/
-export interface Logger {
- info(message: string): void;
- child(fields: { [name: string]: string }): Logger;
+export type LogMeta = { [name: string]: unknown };
+
+/**
+ * @public
+ */
+export interface LoggerService {
+ error(message: string, meta?: Error | LogMeta): void;
+ warn(message: string, meta?: Error | LogMeta): void;
+ info(message: string, meta?: Error | LogMeta): void;
+ debug(message: string, meta?: Error | LogMeta): void;
+
+ child(meta: LogMeta): LoggerService;
}
/**
* @public
*/
-export const loggerServiceRef = createServiceRef({
+export const loggerServiceRef = createServiceRef({
id: 'core.logger',
});
diff --git a/packages/backend-plugin-api/src/services/definitions/permissionsServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/permissionsServiceRef.ts
index b13ca9e240..b24b2f5f46 100644
--- a/packages/backend-plugin-api/src/services/definitions/permissionsServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/permissionsServiceRef.ts
@@ -20,11 +20,12 @@ import {
PermissionEvaluator,
} from '@backstage/plugin-permission-common';
+/** @public */
+export type PermissionsService = PermissionEvaluator | PermissionAuthorizer;
+
/**
* @public
*/
-export const permissionsServiceRef = createServiceRef<
- PermissionEvaluator | PermissionAuthorizer
->({
+export const permissionsServiceRef = createServiceRef({
id: 'core.permissions',
});
diff --git a/packages/backend-plugin-api/src/services/definitions/pluginMetadataServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/pluginMetadataServiceRef.ts
index 3af6e54900..4c1ecb130e 100644
--- a/packages/backend-plugin-api/src/services/definitions/pluginMetadataServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/pluginMetadataServiceRef.ts
@@ -19,13 +19,15 @@ import { createServiceRef } from '../system/types';
/**
* @public
*/
-export interface PluginMetadata {
+export interface PluginMetadataService {
getId(): string;
}
/**
* @public
*/
-export const pluginMetadataServiceRef = createServiceRef({
- id: 'core.plugin-metadata',
-});
+export const pluginMetadataServiceRef = createServiceRef(
+ {
+ id: 'core.plugin-metadata',
+ },
+);
diff --git a/packages/backend-plugin-api/src/services/definitions/rootLoggerServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/rootLoggerServiceRef.ts
index 62e22c53d9..af26ce8899 100644
--- a/packages/backend-plugin-api/src/services/definitions/rootLoggerServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/rootLoggerServiceRef.ts
@@ -15,12 +15,15 @@
*/
import { createServiceRef } from '../system/types';
-import { Logger } from './loggerServiceRef';
+import { LoggerService } from './loggerServiceRef';
+
+/** @public */
+export type RootLoggerService = LoggerService;
/**
* @public
*/
-export const rootLoggerServiceRef = createServiceRef({
+export const rootLoggerServiceRef = createServiceRef({
id: 'core.root.logger',
scope: 'root',
});
diff --git a/packages/backend-plugin-api/src/services/definitions/schedulerServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/schedulerServiceRef.ts
index ca442dd34d..160f2fbb93 100644
--- a/packages/backend-plugin-api/src/services/definitions/schedulerServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/schedulerServiceRef.ts
@@ -17,9 +17,12 @@
import { createServiceRef } from '../system/types';
import { PluginTaskScheduler } from '@backstage/backend-tasks';
+/** @public */
+export type SchedulerService = PluginTaskScheduler;
+
/**
* @public
*/
-export const schedulerServiceRef = createServiceRef({
+export const schedulerServiceRef = createServiceRef({
id: 'core.scheduler',
});
diff --git a/packages/backend-plugin-api/src/services/definitions/tokenManagerServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/tokenManagerServiceRef.ts
index 6995033e81..4b12acdc58 100644
--- a/packages/backend-plugin-api/src/services/definitions/tokenManagerServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/tokenManagerServiceRef.ts
@@ -17,9 +17,12 @@
import { createServiceRef } from '../system/types';
import { TokenManager } from '@backstage/backend-common';
+/** @public */
+export type TokenManagerService = TokenManager;
+
/**
* @public
*/
-export const tokenManagerServiceRef = createServiceRef({
+export const tokenManagerServiceRef = createServiceRef({
id: 'core.tokenManager',
});
diff --git a/packages/backend-plugin-api/src/services/definitions/urlReaderServiceRef.ts b/packages/backend-plugin-api/src/services/definitions/urlReaderServiceRef.ts
index ebb32f1aed..4fc3680763 100644
--- a/packages/backend-plugin-api/src/services/definitions/urlReaderServiceRef.ts
+++ b/packages/backend-plugin-api/src/services/definitions/urlReaderServiceRef.ts
@@ -17,9 +17,12 @@
import { createServiceRef } from '../system/types';
import { UrlReader } from '@backstage/backend-common';
+/** @public */
+export type UrlReaderService = UrlReader;
+
/**
* @public
*/
-export const urlReaderServiceRef = createServiceRef({
+export const urlReaderServiceRef = createServiceRef({
id: 'core.urlReader',
});
diff --git a/packages/backend-plugin-api/src/services/helpers/loggerToWinstonLogger.ts b/packages/backend-plugin-api/src/services/helpers/loggerToWinstonLogger.ts
index b9ccd70d3f..6f435a250a 100644
--- a/packages/backend-plugin-api/src/services/helpers/loggerToWinstonLogger.ts
+++ b/packages/backend-plugin-api/src/services/helpers/loggerToWinstonLogger.ts
@@ -14,28 +14,47 @@
* limitations under the License.
*/
-import { Logger as BackstageLogger } from '../definitions';
+import { LoggerService } from '../definitions';
import { Logger as WinstonLogger, createLogger } from 'winston';
import Transport, { TransportStreamOptions } from 'winston-transport';
class BackstageLoggerTransport extends Transport {
constructor(
- private readonly backstageLogger: BackstageLogger,
+ private readonly backstageLogger: LoggerService,
opts?: TransportStreamOptions,
) {
super(opts);
}
- log(info: { message: string }, callback: VoidFunction) {
- // TODO: add support for levels and fields
- this.backstageLogger.info(info.message);
+ log(info: unknown, callback: VoidFunction) {
+ if (typeof info !== 'object' || info === null) {
+ callback();
+ return;
+ }
+ const { level, message, ...meta } = info as { [name: string]: unknown };
+ switch (level) {
+ case 'error':
+ this.backstageLogger.error(String(message), meta);
+ break;
+ case 'warn':
+ this.backstageLogger.warn(String(message), meta);
+ break;
+ case 'info':
+ this.backstageLogger.info(String(message), meta);
+ break;
+ case 'debug':
+ this.backstageLogger.debug(String(message), meta);
+ break;
+ default:
+ this.backstageLogger.info(String(message), meta);
+ }
callback();
}
}
/** @public */
export function loggerToWinstonLogger(
- logger: BackstageLogger,
+ logger: LoggerService,
opts?: TransportStreamOptions,
): WinstonLogger {
return createLogger({
diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md
index 3000b92700..9d9d300439 100644
--- a/packages/backend-tasks/CHANGELOG.md
+++ b/packages/backend-tasks/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/backend-tasks
+## 0.4.0-next.3
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+
## 0.4.0-next.2
### Patch Changes
diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json
index 1008ef5f74..bc23a082ba 100644
--- a/packages/backend-tasks/package.json
+++ b/packages/backend-tasks/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-tasks",
"description": "Common distributed task management library for Backstage backends",
- "version": "0.4.0-next.2",
+ "version": "0.4.0-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
@@ -43,7 +43,7 @@
"luxon": "^3.0.0",
"uuid": "^8.0.0",
"winston": "^3.2.1",
- "zod": "^3.9.5"
+ "zod": "~3.18.0"
},
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md
index 5b63aeb206..d9c2e769ee 100644
--- a/packages/backend-test-utils/CHANGELOG.md
+++ b/packages/backend-test-utils/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/backend-test-utils
+## 0.1.31-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.22.0-next.4
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-app-api@0.2.4-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/config@1.0.5-next.1
+
## 0.1.31-next.3
### Patch Changes
diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md
index 2fe4ed31d3..3df3f3cb21 100644
--- a/packages/backend-test-utils/api-report.md
+++ b/packages/backend-test-utils/api-report.md
@@ -3,6 +3,7 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
+import { Backend } from '@backstage/backend-app-api';
import { BackendFeature } from '@backstage/backend-plugin-api';
import { ExtensionPoint } from '@backstage/backend-plugin-api';
import { Knex } from 'knex';
@@ -23,7 +24,7 @@ export function setupRequestMockHandlers(worker: {
export function startTestBackend<
TServices extends any[],
TExtensionPoints extends any[],
->(options: TestBackendOptions): Promise;
+>(options: TestBackendOptions): Promise;
// @alpha (undocumented)
export interface TestBackendOptions<
diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json
index 8b14267b9f..dbd8b32739 100644
--- a/packages/backend-test-utils/package.json
+++ b/packages/backend-test-utils/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-test-utils",
"description": "Test helpers library for Backstage backends",
- "version": "0.1.31-next.3",
+ "version": "0.1.31-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts
index 164e06d3b5..3cc8507df3 100644
--- a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts
+++ b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts
@@ -19,9 +19,42 @@ import {
createExtensionPoint,
createServiceFactory,
createServiceRef,
+ coreServices,
} from '@backstage/backend-plugin-api';
import { startTestBackend } from './TestBackend';
+// This bit makes sure that test backends are cleaned up properly
+let globalTestBackendHasBeenStopped = false;
+beforeAll(async () => {
+ await startTestBackend({
+ services: [],
+ features: [
+ createBackendModule({
+ moduleId: 'test.module',
+ pluginId: 'test',
+ register(env) {
+ env.registerInit({
+ deps: { lifecycle: coreServices.lifecycle },
+ async init({ lifecycle }) {
+ lifecycle.addShutdownHook({
+ fn() {
+ globalTestBackendHasBeenStopped = true;
+ },
+ });
+ },
+ });
+ },
+ })(),
+ ],
+ });
+});
+
+afterAll(() => {
+ if (!globalTestBackendHasBeenStopped) {
+ throw new Error('Expected backend to have been stopped');
+ }
+});
+
describe('TestBackend', () => {
it('should get a type error if service implementation does not match', async () => {
type Obj = { a: string; b: string };
@@ -94,4 +127,32 @@ describe('TestBackend', () => {
expect(testFn).toHaveBeenCalledWith('winning');
});
+
+ it('should stop the test backend', async () => {
+ const shutdownSpy = jest.fn();
+
+ const testModule = createBackendModule({
+ moduleId: 'test.module',
+ pluginId: 'test',
+ register(env) {
+ env.registerInit({
+ deps: {
+ lifecycle: coreServices.lifecycle,
+ },
+ async init({ lifecycle }) {
+ lifecycle.addShutdownHook({ fn: shutdownSpy });
+ },
+ });
+ },
+ });
+
+ const backend = await startTestBackend({
+ services: [],
+ features: [testModule()],
+ });
+
+ expect(shutdownSpy).not.toHaveBeenCalled();
+ await backend.stop();
+ expect(shutdownSpy).toHaveBeenCalled();
+ });
});
diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.ts
index 677ba930cc..1d401bbf6f 100644
--- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts
+++ b/packages/backend-test-utils/src/next/wiring/TestBackend.ts
@@ -14,7 +14,13 @@
* limitations under the License.
*/
-import { createSpecializedBackend } from '@backstage/backend-app-api';
+import {
+ Backend,
+ createSpecializedBackend,
+ lifecycleFactory,
+ loggerFactory,
+ rootLoggerFactory,
+} from '@backstage/backend-app-api';
import {
ServiceFactory,
ServiceRef,
@@ -47,11 +53,19 @@ export interface TestBackendOptions<
features?: BackendFeature[];
}
+const defaultServiceFactories = [
+ rootLoggerFactory(),
+ loggerFactory(),
+ lifecycleFactory(),
+];
+
+const backendInstancesToCleanUp = new Array();
+
/** @alpha */
export async function startTestBackend<
TServices extends any[],
TExtensionPoints extends any[],
->(options: TestBackendOptions): Promise {
+>(options: TestBackendOptions): Promise {
const {
services = [],
extensionPoints = [],
@@ -69,22 +83,30 @@ export async function startTestBackend<
service: ref,
deps: {},
factory: async () => async () => impl,
- });
+ })();
}
return createServiceFactory({
service: ref,
deps: {},
factory: async () => impl,
- });
+ })();
}
return serviceDef as ServiceFactory;
});
+ for (const factory of defaultServiceFactories) {
+ if (!factories.some(f => f.service === factory.service)) {
+ factories.push(factory);
+ }
+ }
+
const backend = createSpecializedBackend({
...otherOptions,
services: factories,
});
+ backendInstancesToCleanUp.push(backend);
+
backend.add({
id: `---test-extension-point-registrar`,
register(reg) {
@@ -101,4 +123,32 @@ export async function startTestBackend<
}
await backend.start();
+
+ return backend;
}
+
+let registered = false;
+function registerTestHooks() {
+ if (typeof afterAll !== 'function') {
+ return;
+ }
+ if (registered) {
+ return;
+ }
+ registered = true;
+
+ afterAll(async () => {
+ await Promise.all(
+ backendInstancesToCleanUp.map(async backend => {
+ try {
+ await backend.stop();
+ } catch (error) {
+ console.error(`Failed to stop backend after tests, ${error}`);
+ }
+ }),
+ );
+ backendInstancesToCleanUp.length = 0;
+ });
+}
+
+registerTestHooks();
diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md
index 4ed3ffa212..d1f3757f7b 100644
--- a/packages/backend/CHANGELOG.md
+++ b/packages/backend/CHANGELOG.md
@@ -1,5 +1,52 @@
# example-backend
+## 0.2.78-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/plugin-scaffolder-backend-module-rails@0.4.7-next.3
+ - @backstage/plugin-scaffolder-backend@1.9.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/plugin-permission-backend@0.5.14-next.3
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-permission-node@0.7.2-next.3
+ - @backstage/plugin-playlist-backend@0.2.2-next.4
+ - @backstage/plugin-search-backend@1.2.0-next.3
+ - @backstage/plugin-kubernetes-backend@0.8.1-next.4
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/plugin-search-backend-module-elasticsearch@1.1.0-next.3
+ - @backstage/plugin-techdocs-backend@1.5.0-next.3
+ - example-app@0.2.78-next.4
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-app-backend@0.3.39-next.3
+ - @backstage/plugin-auth-backend@0.17.2-next.3
+ - @backstage/plugin-auth-node@0.2.8-next.3
+ - @backstage/plugin-azure-devops-backend@0.3.18-next.3
+ - @backstage/plugin-azure-sites-backend@0.1.1-next.3
+ - @backstage/plugin-badges-backend@0.1.33-next.3
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+ - @backstage/plugin-code-coverage-backend@0.2.5-next.3
+ - @backstage/plugin-events-backend@0.2.0-next.3
+ - @backstage/plugin-events-node@0.2.0-next.3
+ - @backstage/plugin-explore-backend@0.0.1-next.2
+ - @backstage/plugin-graphql-backend@0.1.29-next.3
+ - @backstage/plugin-jenkins-backend@0.1.29-next.3
+ - @backstage/plugin-kafka-backend@0.2.32-next.3
+ - @backstage/plugin-proxy-backend@0.2.33-next.3
+ - @backstage/plugin-rollbar-backend@0.1.36-next.3
+ - @backstage/plugin-search-backend-module-pg@0.4.3-next.3
+ - @backstage/plugin-search-backend-node@1.1.0-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+ - @backstage/plugin-tech-insights-backend@0.5.5-next.3
+ - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.23-next.3
+ - @backstage/plugin-tech-insights-node@0.3.7-next.3
+ - @backstage/plugin-todo-backend@0.1.36-next.3
+
## 0.2.78-next.3
### Patch Changes
diff --git a/packages/backend/package.json b/packages/backend/package.json
index 1e24cb46c0..781eff31a3 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -1,6 +1,6 @@
{
"name": "example-backend",
- "version": "0.2.78-next.3",
+ "version": "0.2.78-next.4",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md
index 5300cc291b..ca8b940091 100644
--- a/packages/cli/CHANGELOG.md
+++ b/packages/cli/CHANGELOG.md
@@ -1,5 +1,28 @@
# @backstage/cli
+## 0.22.0-next.4
+
+### Minor Changes
+
+- 736f893f72: The Jest configuration that was previously enabled with `BACKSTAGE_NEXT_TESTS` is now enabled by default. To revert to the old configuration you can now instead set `BACKSTAGE_OLD_TESTS`.
+
+ This new configuration uses the `babel` coverage provider rather than `v8`. It used to be that `v8` worked better when using Sucrase for transpilation, but now that we have switched to SWC, `babel` seems to work better. In addition, the new configuration also enables source maps by default, as they no longer have a negative impact on code coverage accuracy, and it also enables a modified Jest runtime with additional caching of script objects.
+
+### Patch Changes
+
+- dd721148b5: Updated Jest coverage configuration to only apply either in the root project or package configuration, depending on whether repo or package tests are run.
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- c27eabef6b: Adds new web-library package option when generating a new plugin
+- 309f2daca4: Updated dependency `esbuild` to `^0.16.0`.
+- d9d9a7a134: Removed all copyright notices from package templates.
+- Updated dependencies
+ - @backstage/cli-common@0.1.11-next.0
+ - @backstage/config@1.0.5-next.1
+ - @backstage/config-loader@1.1.7-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/release-manifests@0.0.8-next.0
+ - @backstage/types@1.0.2-next.1
+
## 0.21.2-next.3
### Patch Changes
diff --git a/packages/cli/config/jest.js b/packages/cli/config/jest.js
index 148d574441..24385a6b99 100644
--- a/packages/cli/config/jest.js
+++ b/packages/cli/config/jest.js
@@ -21,15 +21,10 @@ const glob = require('util').promisify(require('glob'));
const { version } = require('../package.json');
const envOptions = {
- nextTests: Boolean(process.env.BACKSTAGE_NEXT_TESTS),
+ oldTests: Boolean(process.env.BACKSTAGE_OLD_TESTS),
enableSourceMaps: Boolean(process.env.ENABLE_SOURCE_MAPS),
};
-if (envOptions.nextTests) {
- // Needed so that, at import-time, it can hook into Jest's internals.
- require('./jestCachingModuleLoader');
-}
-
const transformIgnorePattern = [
'@material-ui',
'ajv',
@@ -65,7 +60,7 @@ function getRoleConfig(role) {
}
}
-async function getProjectConfig(targetPath, displayName) {
+async function getProjectConfig(targetPath, extraConfig) {
const configJsPath = path.resolve(targetPath, 'jest.config.js');
const configTsPath = path.resolve(targetPath, 'jest.config.ts');
// If the package has it's own jest config, we use that instead.
@@ -125,11 +120,8 @@ async function getProjectConfig(targetPath, displayName) {
}
const options = {
- ...(displayName && { displayName }),
+ ...extraConfig,
rootDir: path.resolve(targetPath, 'src'),
- coverageDirectory: path.resolve(targetPath, 'coverage'),
- coverageProvider: envOptions.nextTests ? 'babel' : 'v8',
- collectCoverageFrom: ['**/*.{js,jsx,ts,tsx,mjs,cjs}', '!**/*.d.ts'],
moduleNameMapper: {
'\\.(css|less|scss|sss|styl)$': require.resolve('jest-css-modules'),
},
@@ -138,7 +130,7 @@ async function getProjectConfig(targetPath, displayName) {
'\\.(mjs|cjs|js)$': [
require.resolve('./jestSwcTransform'),
{
- sourceMaps: envOptions.enableSourceMaps || envOptions.nextTests,
+ sourceMaps: envOptions.enableSourceMaps || !envOptions.oldTests,
jsc: {
parser: {
syntax: 'ecmascript',
@@ -149,7 +141,7 @@ async function getProjectConfig(targetPath, displayName) {
'\\.jsx$': [
require.resolve('./jestSwcTransform'),
{
- sourceMaps: envOptions.enableSourceMaps || envOptions.nextTests,
+ sourceMaps: envOptions.enableSourceMaps || !envOptions.oldTests,
jsc: {
parser: {
syntax: 'ecmascript',
@@ -166,7 +158,7 @@ async function getProjectConfig(targetPath, displayName) {
'\\.ts$': [
require.resolve('./jestSwcTransform'),
{
- sourceMaps: envOptions.enableSourceMaps || envOptions.nextTests,
+ sourceMaps: envOptions.enableSourceMaps || !envOptions.oldTests,
jsc: {
parser: {
syntax: 'typescript',
@@ -177,7 +169,7 @@ async function getProjectConfig(targetPath, displayName) {
'\\.tsx$': [
require.resolve('./jestSwcTransform'),
{
- sourceMaps: envOptions.enableSourceMaps || envOptions.nextTests,
+ sourceMaps: envOptions.enableSourceMaps || !envOptions.oldTests,
jsc: {
parser: {
syntax: 'typescript',
@@ -199,9 +191,9 @@ async function getProjectConfig(targetPath, displayName) {
// A bit more opinionated
testMatch: ['**/*.test.{js,jsx,ts,tsx,mjs,cjs}'],
- runtime: envOptions.nextTests
- ? require.resolve('./jestCachingModuleLoader')
- : undefined,
+ runtime: envOptions.oldTests
+ ? undefined
+ : require.resolve('./jestCachingModuleLoader'),
transformIgnorePatterns: [`/node_modules/(?:${transformIgnorePattern})/`],
...getRoleConfig(closestPkgJson?.backstage?.role),
@@ -237,15 +229,21 @@ async function getRootConfig() {
const targetPackagePath = path.resolve(targetPath, 'package.json');
const exists = await fs.pathExists(targetPackagePath);
+ const coverageConfig = {
+ coverageDirectory: path.resolve(targetPath, 'coverage'),
+ coverageProvider: envOptions.oldTests ? 'v8' : 'babel',
+ collectCoverageFrom: ['**/*.{js,jsx,ts,tsx,mjs,cjs}', '!**/*.d.ts'],
+ };
+
if (!exists) {
- return getProjectConfig(targetPath);
+ return getProjectConfig(targetPath, coverageConfig);
}
// Check whether the current package is a workspace root or not
const data = await fs.readJson(targetPackagePath);
const workspacePatterns = data.workspaces && data.workspaces.packages;
if (!workspacePatterns) {
- return getProjectConfig(targetPath);
+ return getProjectConfig(targetPath, coverageConfig);
}
// If the target package is a workspace root, we find all packages in the
@@ -269,7 +267,9 @@ async function getRootConfig() {
testScript?.includes('backstage-cli test') ||
testScript?.includes('backstage-cli package test');
if (testScript && isSupportedTestScript) {
- return await getProjectConfig(projectPath, packageData.name);
+ return await getProjectConfig(projectPath, {
+ displayName: packageData.name,
+ });
}
return undefined;
@@ -279,6 +279,7 @@ async function getRootConfig() {
return {
rootDir: targetPath,
projects: configs,
+ ...coverageConfig,
};
}
diff --git a/packages/cli/config/jestCachingModuleLoader.js b/packages/cli/config/jestCachingModuleLoader.js
index 7858a7cfb7..95c6212123 100644
--- a/packages/cli/config/jestCachingModuleLoader.js
+++ b/packages/cli/config/jestCachingModuleLoader.js
@@ -14,61 +14,11 @@
* limitations under the License.
*/
-const fs = require('fs');
const { default: JestRuntime } = require('jest-runtime');
-const fileTransformCache = new Map();
const scriptTransformCache = new Map();
-let runtimeGeneration = 0;
-let isWatchMode;
-
module.exports = class CachingJestRuntime extends JestRuntime {
- // Each Jest run creates a new runtime, including when rerunning tests in
- // watch mode. This keeps track of whether we've switched runtime instance.
- __runtimeGeneration = runtimeGeneration++;
-
- transformFile(filename, options) {
- if (!isWatchMode) {
- return super.transformFile(filename, options);
- }
-
- const entry = fileTransformCache.get(filename);
- if (entry) {
- // Only check modification time if it's from a different runtime generation
- if (entry.generation === this.__runtimeGeneration) {
- return entry.code;
- }
-
- // Keep track of the modification time of files so that we can properly
- // reprocess them in watch mode.
- const { mtimeMs } = fs.statSync(filename);
- if (mtimeMs > entry.mtimeMs) {
- const code = super.transformFile(filename, options);
- fileTransformCache.set(filename, {
- code,
- mtimeMs,
- generation: this.__runtimeGeneration,
- });
- return code;
- }
-
- fileTransformCache.set(filename, {
- ...entry,
- generation: this.__runtimeGeneration,
- });
- return entry.code;
- }
-
- const code = super.transformFile(filename, options);
- fileTransformCache.set(filename, {
- code,
- mtimeMs: fs.statSync(filename).mtimeMs,
- generation: this.__runtimeGeneration,
- });
- return code;
- }
-
// This may or may not be a good idea. Theoretically I don't know why this would impact
// test correctness and flakiness, but it seems like it may introduce flakiness and strange failures.
// It does seem to speed up test execution by a fair amount though.
@@ -84,11 +34,3 @@ module.exports = class CachingJestRuntime extends JestRuntime {
return script;
}
};
-
-// Inject hook into createHasteMap, as it's the only way that we can
-// determine (from our scope here) if we're in "watch mode" or not.
-const originalCreateHasteMap = JestRuntime.createHasteMap;
-JestRuntime.createHasteMap = (config, options = undefined) => {
- isWatchMode = options && options.watch;
- return originalCreateHasteMap(config, options);
-};
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 0bd803d1db..ebda11d5e7 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/cli",
"description": "CLI for developing Backstage plugins and apps",
- "version": "0.21.2-next.3",
+ "version": "0.22.0-next.4",
"publishConfig": {
"access": "public"
},
@@ -67,7 +67,7 @@
"commander": "^9.1.0",
"css-loader": "^6.5.1",
"diff": "^5.0.0",
- "esbuild": "^0.15.0",
+ "esbuild": "^0.16.0",
"esbuild-loader": "^2.18.0",
"eslint": "^8.6.0",
"eslint-config-prettier": "^8.3.0",
@@ -125,7 +125,7 @@
"yaml": "^2.0.0",
"yml-loader": "^2.1.0",
"yn": "^4.0.0",
- "zod": "^3.11.6"
+ "zod": "~3.18.0"
},
"devDependencies": {
"@backstage/backend-common": "workspace:^",
diff --git a/packages/cli/src/lib/new/factories/index.ts b/packages/cli/src/lib/new/factories/index.ts
index 0764d33e2c..80a24702e0 100644
--- a/packages/cli/src/lib/new/factories/index.ts
+++ b/packages/cli/src/lib/new/factories/index.ts
@@ -16,5 +16,6 @@
export { frontendPlugin } from './frontendPlugin';
export { backendPlugin } from './backendPlugin';
+export { webLibraryPackage } from './webLibraryPackage';
export { pluginCommon } from './pluginCommon';
export { scaffolderModule } from './scaffolderModule';
diff --git a/packages/cli/src/lib/new/factories/webLibraryPackage.test.ts b/packages/cli/src/lib/new/factories/webLibraryPackage.test.ts
new file mode 100644
index 0000000000..03be32dbaa
--- /dev/null
+++ b/packages/cli/src/lib/new/factories/webLibraryPackage.test.ts
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import fs from 'fs-extra';
+import mockFs from 'mock-fs';
+import { resolve as resolvePath } from 'path';
+import { paths } from '../../paths';
+import { Task } from '../../tasks';
+import { FactoryRegistry } from '../FactoryRegistry';
+import { createMockOutputStream, mockPaths } from './common/testUtils';
+import { webLibraryPackage } from './webLibraryPackage';
+
+describe('webLibraryPackage factory', () => {
+ beforeEach(() => {
+ mockPaths({
+ targetRoot: '/root',
+ });
+ });
+
+ afterEach(() => {
+ mockFs.restore();
+ jest.resetAllMocks();
+ });
+
+ it('should create a web library package', async () => {
+ const expectedwebLibraryPackageName = 'test';
+
+ mockFs({
+ '/root': {
+ packages: mockFs.directory(),
+ },
+ [paths.resolveOwn('templates')]: mockFs.load(
+ paths.resolveOwn('templates'),
+ ),
+ });
+
+ const options = await FactoryRegistry.populateOptions(webLibraryPackage, {
+ id: 'test', // name of web library package
+ });
+
+ let modified = false;
+
+ const [output, mockStream] = createMockOutputStream();
+ jest.spyOn(process, 'stderr', 'get').mockReturnValue(mockStream);
+ jest.spyOn(Task, 'forCommand').mockResolvedValue();
+
+ await webLibraryPackage.create(options, {
+ private: true,
+ isMonoRepo: true,
+ defaultVersion: '1.0.0',
+ markAsModified: () => {
+ modified = true;
+ },
+ createTemporaryDirectory: () => fs.mkdtemp('test'),
+ });
+
+ expect(modified).toBe(true);
+
+ expect(output).toEqual([
+ '',
+ `Creating web-library package ${expectedwebLibraryPackageName}`,
+ 'Checking Prerequisites:',
+ `availability packages/${expectedwebLibraryPackageName}`,
+ 'creating temp dir',
+ 'Executing Template:',
+ 'copying .eslintrc.js',
+ 'templating README.md.hbs',
+ 'templating package.json.hbs',
+ 'templating index.ts.hbs',
+ 'copying setupTests.ts',
+ 'Installing:',
+ `moving packages/${expectedwebLibraryPackageName}`,
+ ]);
+
+ await expect(
+ fs.readJson(
+ `/root/packages/${expectedwebLibraryPackageName}/package.json`,
+ ),
+ ).resolves.toEqual(
+ expect.objectContaining({
+ name: expectedwebLibraryPackageName,
+ private: true,
+ version: '1.0.0',
+ }),
+ );
+
+ expect(Task.forCommand).toHaveBeenCalledTimes(2);
+ expect(Task.forCommand).toHaveBeenCalledWith('yarn install', {
+ cwd: resolvePath(`/root/packages/${expectedwebLibraryPackageName}`),
+ optional: true,
+ });
+ expect(Task.forCommand).toHaveBeenCalledWith('yarn lint --fix', {
+ cwd: resolvePath(`/root/packages/${expectedwebLibraryPackageName}`),
+ optional: true,
+ });
+ });
+
+ it('should create a web library plugin with options and codeowners', async () => {
+ const expectedwebLibraryPackageName = 'test';
+
+ mockFs({
+ '/root': {
+ CODEOWNERS: '',
+ packages: mockFs.directory(),
+ },
+ [paths.resolveOwn('templates')]: mockFs.load(
+ paths.resolveOwn('templates'),
+ ),
+ });
+
+ const options = await FactoryRegistry.populateOptions(webLibraryPackage, {
+ id: 'test',
+ owner: '@backstage/test-owners',
+ });
+
+ const [, mockStream] = createMockOutputStream();
+ jest.spyOn(process, 'stderr', 'get').mockReturnValue(mockStream);
+ jest.spyOn(Task, 'forCommand').mockResolvedValue();
+
+ await webLibraryPackage.create(options, {
+ scope: 'internal',
+ private: true,
+ isMonoRepo: false,
+ defaultVersion: '1.0.0',
+ markAsModified: () => {},
+ createTemporaryDirectory: () => fs.mkdtemp('test'),
+ });
+
+ expect(Task.forCommand).toHaveBeenCalledTimes(2);
+ expect(Task.forCommand).toHaveBeenCalledWith('yarn install', {
+ cwd: resolvePath(`/root/${expectedwebLibraryPackageName}`),
+ optional: true,
+ });
+ expect(Task.forCommand).toHaveBeenCalledWith('yarn lint --fix', {
+ cwd: resolvePath(`/root/${expectedwebLibraryPackageName}`),
+ optional: true,
+ });
+ });
+});
diff --git a/packages/cli/src/lib/new/factories/webLibraryPackage.ts b/packages/cli/src/lib/new/factories/webLibraryPackage.ts
new file mode 100644
index 0000000000..a160220cab
--- /dev/null
+++ b/packages/cli/src/lib/new/factories/webLibraryPackage.ts
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import chalk from 'chalk';
+import { paths } from '../../paths';
+import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners';
+import { createFactory, CreateContext } from '../types';
+import { Task } from '../../tasks';
+import { ownerPrompt, pluginIdPrompt } from './common/prompts';
+import { executePluginPackageTemplate } from './common/tasks';
+
+type Options = {
+ id: string;
+ owner?: string;
+ codeOwnersPath?: string;
+};
+
+export const webLibraryPackage = createFactory({
+ name: 'web-library',
+ description: 'A new web-library package',
+ optionsDiscovery: async () => ({
+ codeOwnersPath: await getCodeownersFilePath(paths.targetRoot),
+ }),
+ optionsPrompts: [pluginIdPrompt(), ownerPrompt()],
+ async create(options: Options, ctx: CreateContext) {
+ const { id } = options;
+ const name = ctx.scope ? `@${ctx.scope}/${id}` : `${id}`;
+
+ Task.log();
+ Task.log(`Creating web-library package ${chalk.cyan(name)}`);
+
+ const targetDir = ctx.isMonoRepo
+ ? paths.resolveTargetRoot('packages', id)
+ : paths.resolveTargetRoot(`${id}`);
+
+ await executePluginPackageTemplate(ctx, {
+ targetDir,
+ templateName: 'web-library-package',
+ values: {
+ id,
+ name,
+ pluginVersion: ctx.defaultVersion,
+ privatePackage: ctx.private,
+ npmRegistry: ctx.npmRegistry,
+ },
+ });
+
+ if (options.owner) {
+ await addCodeownersEntry(`/packages/${id}`, options.owner);
+ }
+
+ await Task.forCommand('yarn install', { cwd: targetDir, optional: true });
+ await Task.forCommand('yarn lint --fix', {
+ cwd: targetDir,
+ optional: true,
+ });
+ },
+});
diff --git a/packages/cli/templates/default-backend-plugin/src/index.ts b/packages/cli/templates/default-backend-plugin/src/index.ts
index ca73cb27ba..47af95cb35 100644
--- a/packages/cli/templates/default-backend-plugin/src/index.ts
+++ b/packages/cli/templates/default-backend-plugin/src/index.ts
@@ -1,17 +1 @@
-/*
- * Copyright 2020 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
export * from './service/router';
diff --git a/packages/cli/templates/default-backend-plugin/src/run.ts.hbs b/packages/cli/templates/default-backend-plugin/src/run.ts.hbs
index 0a3ed2b7f0..79c6bd6da8 100644
--- a/packages/cli/templates/default-backend-plugin/src/run.ts.hbs
+++ b/packages/cli/templates/default-backend-plugin/src/run.ts.hbs
@@ -1,19 +1,3 @@
-/*
- * Copyright 2020 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
diff --git a/packages/cli/templates/default-backend-plugin/src/service/router.test.ts b/packages/cli/templates/default-backend-plugin/src/service/router.test.ts
index 8b77a04348..4f5079744e 100644
--- a/packages/cli/templates/default-backend-plugin/src/service/router.test.ts
+++ b/packages/cli/templates/default-backend-plugin/src/service/router.test.ts
@@ -1,19 +1,3 @@
-/*
- * Copyright 2020 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
import { getVoidLogger } from '@backstage/backend-common';
import express from 'express';
import request from 'supertest';
diff --git a/packages/cli/templates/default-backend-plugin/src/service/router.ts b/packages/cli/templates/default-backend-plugin/src/service/router.ts
index 5912a87584..c15bac5892 100644
--- a/packages/cli/templates/default-backend-plugin/src/service/router.ts
+++ b/packages/cli/templates/default-backend-plugin/src/service/router.ts
@@ -1,19 +1,3 @@
-/*
- * Copyright 2020 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
import { errorHandler } from '@backstage/backend-common';
import express from 'express';
import Router from 'express-promise-router';
diff --git a/packages/cli/templates/default-backend-plugin/src/service/standaloneServer.ts.hbs b/packages/cli/templates/default-backend-plugin/src/service/standaloneServer.ts.hbs
index d5567bfed3..3433ed22ce 100644
--- a/packages/cli/templates/default-backend-plugin/src/service/standaloneServer.ts.hbs
+++ b/packages/cli/templates/default-backend-plugin/src/service/standaloneServer.ts.hbs
@@ -1,19 +1,3 @@
-/*
- * Copyright 2020 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
import { createServiceBuilder } from '@backstage/backend-common';
import { Server } from 'http';
import { Logger } from 'winston';
diff --git a/packages/cli/templates/default-backend-plugin/src/setupTests.ts b/packages/cli/templates/default-backend-plugin/src/setupTests.ts
index d3232290a7..cb0ff5c3b5 100644
--- a/packages/cli/templates/default-backend-plugin/src/setupTests.ts
+++ b/packages/cli/templates/default-backend-plugin/src/setupTests.ts
@@ -1,17 +1 @@
-/*
- * Copyright 2020 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
export {};
diff --git a/packages/cli/templates/scaffolder-module/src/actions/example/example.test.ts b/packages/cli/templates/scaffolder-module/src/actions/example/example.test.ts
index e427b2c603..3f91a8f49d 100644
--- a/packages/cli/templates/scaffolder-module/src/actions/example/example.test.ts
+++ b/packages/cli/templates/scaffolder-module/src/actions/example/example.test.ts
@@ -1,19 +1,3 @@
-/*
- * Copyright 2021 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
import { PassThrough } from 'stream';
import { createAcmeExampleAction } from './example';
import { getVoidLogger } from '@backstage/backend-common';
diff --git a/packages/cli/templates/scaffolder-module/src/actions/example/example.ts b/packages/cli/templates/scaffolder-module/src/actions/example/example.ts
index c20a4bdf25..c04132e755 100644
--- a/packages/cli/templates/scaffolder-module/src/actions/example/example.ts
+++ b/packages/cli/templates/scaffolder-module/src/actions/example/example.ts
@@ -1,19 +1,3 @@
-/*
- * Copyright 2021 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
import { createTemplateAction } from '@backstage/plugin-scaffolder-backend';
/**
diff --git a/packages/cli/templates/web-library-package/.eslintrc.js b/packages/cli/templates/web-library-package/.eslintrc.js
new file mode 100644
index 0000000000..e2a53a6ad2
--- /dev/null
+++ b/packages/cli/templates/web-library-package/.eslintrc.js
@@ -0,0 +1 @@
+module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
diff --git a/packages/cli/templates/web-library-package/README.md.hbs b/packages/cli/templates/web-library-package/README.md.hbs
new file mode 100644
index 0000000000..0e2813c87a
--- /dev/null
+++ b/packages/cli/templates/web-library-package/README.md.hbs
@@ -0,0 +1,12 @@
+# {{name}}
+
+_This package was created through the Backstage CLI_.
+
+## Installation
+
+Install the package via Yarn:
+
+```sh
+cd # if within a monorepo
+yarn add {{name}}
+```
diff --git a/packages/cli/templates/web-library-package/package.json.hbs b/packages/cli/templates/web-library-package/package.json.hbs
new file mode 100644
index 0000000000..957efef167
--- /dev/null
+++ b/packages/cli/templates/web-library-package/package.json.hbs
@@ -0,0 +1,37 @@
+{
+ "name": "{{name}}",
+ "version": "{{pluginVersion}}",
+ "main": "src/index.ts",
+ "types": "src/index.ts",
+ "license": "Apache-2.0",
+{{#if privatePackage}}
+ "private": {{privatePackage}},
+{{/if}}
+ "publishConfig": {
+{{#if npmRegistry}}
+ "registry": "{{npmRegistry}}",
+{{/if}}
+ "access": "public",
+ "main": "dist/index.esm.js",
+ "types": "dist/index.d.ts"
+ },
+ "backstage": {
+ "role": "web-library"
+ },
+ "scripts": {
+ "start": "backstage-cli package start",
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "clean": "backstage-cli package clean",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack"
+ },
+ "devDependencies": {
+ "@backstage/cli": "{{versionQuery '@backstage/cli'}}",
+ "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '5.10.1'}}"
+ },
+ "files": [
+ "dist"
+ ]
+}
diff --git a/packages/cli/templates/web-library-package/src/index.ts.hbs b/packages/cli/templates/web-library-package/src/index.ts.hbs
new file mode 100644
index 0000000000..cb0ff5c3b5
--- /dev/null
+++ b/packages/cli/templates/web-library-package/src/index.ts.hbs
@@ -0,0 +1 @@
+export {};
diff --git a/packages/cli/templates/web-library-package/src/setupTests.ts b/packages/cli/templates/web-library-package/src/setupTests.ts
new file mode 100644
index 0000000000..7b0828bfa8
--- /dev/null
+++ b/packages/cli/templates/web-library-package/src/setupTests.ts
@@ -0,0 +1 @@
+import '@testing-library/jest-dom';
diff --git a/packages/cli/templates/web-library-package/tsconfig.json b/packages/cli/templates/web-library-package/tsconfig.json
new file mode 100644
index 0000000000..ce3409d31f
--- /dev/null
+++ b/packages/cli/templates/web-library-package/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@backstage/cli/config/tsconfig.json",
+ "include": [
+ "src",
+ ],
+ "exclude": ["node_modules"],
+ "compilerOptions": {
+ "outDir": "dist-types",
+ "rootDir": "."
+ }
+}
diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md
index 859720a258..38170f490a 100644
--- a/packages/core-app-api/CHANGELOG.md
+++ b/packages/core-app-api/CHANGELOG.md
@@ -1,5 +1,65 @@
# @backstage/core-app-api
+## 1.3.0-next.4
+
+### Minor Changes
+
+- e0d9c9559a: Added a new `AppRouter` component and `app.createRoot()` method that replaces `app.getRouter()` and `app.getProvider()`, which are now deprecated. The new `AppRouter` component is a drop-in replacement for the old router component, while the new `app.createRoot()` method is used instead of the old provider component.
+
+ An old app setup might look like this:
+
+ ```tsx
+ const app = createApp(/* ... */);
+
+ const AppProvider = app.getProvider();
+ const AppRouter = app.getRouter();
+
+ const routes = ...;
+
+ const App = () => (
+
+
+
+
+ {routes}
+
+
+ );
+
+ export default App;
+ ```
+
+ With these new APIs, the setup now looks like this:
+
+ ```tsx
+ import { AppRouter } from '@backstage/core-app-api';
+
+ const app = createApp(/* ... */);
+
+ const routes = ...;
+
+ export default app.createRoot(
+ <>
+
+
+
+ {routes}
+
+ >,
+ );
+ ```
+
+ Note that `app.createRoot()` accepts a React element, rather than a component.
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- Updated dependencies
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/types@1.0.2-next.1
+ - @backstage/version-bridge@1.0.3-next.0
+
## 1.2.1-next.3
### Patch Changes
diff --git a/packages/core-app-api/api-report.md b/packages/core-app-api/api-report.md
index 70312a54a5..4d867f0b37 100644
--- a/packages/core-app-api/api-report.md
+++ b/packages/core-app-api/api-report.md
@@ -227,6 +227,15 @@ export type AppRouteBinder = <
>,
) => void;
+// @public
+export function AppRouter(props: AppRouterProps): JSX.Element;
+
+// @public
+export interface AppRouterProps {
+ // (undocumented)
+ children?: ReactNode;
+}
+
// @public
export class AppThemeSelector implements AppThemeApi {
constructor(themes: AppTheme[]);
@@ -259,6 +268,7 @@ export type AuthApiCreateOptions = {
export type BackstageApp = {
getPlugins(): BackstagePlugin[];
getSystemIcon(key: string): IconComponent | undefined;
+ createRoot(element: JSX.Element): ComponentType<{}>;
getProvider(): ComponentType<{}>;
getRouter(): ComponentType<{}>;
};
diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json
index 0e709e883e..00873e27e7 100644
--- a/packages/core-app-api/package.json
+++ b/packages/core-app-api/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/core-app-api",
"description": "Core app API used by Backstage apps",
- "version": "1.2.1-next.3",
+ "version": "1.3.0-next.4",
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -40,7 +40,7 @@
"prop-types": "^15.7.2",
"react-use": "^17.2.4",
"zen-observable": "^0.10.0",
- "zod": "^3.11.6"
+ "zod": "~3.18.0"
},
"peerDependencies": {
"@types/react": "^16.13.1 || ^17.0.0",
diff --git a/packages/core-app-api/src/app/AppManager.tsx b/packages/core-app-api/src/app/AppManager.tsx
index f4fa2d8442..5a752ad5df 100644
--- a/packages/core-app-api/src/app/AppManager.tsx
+++ b/packages/core-app-api/src/app/AppManager.tsx
@@ -17,15 +17,10 @@
import { AppConfig, Config } from '@backstage/config';
import React, {
ComponentType,
- createContext,
PropsWithChildren,
- ReactElement,
- useContext,
useMemo,
useRef,
- useState,
} from 'react';
-import { Route, Routes } from 'react-router-dom';
import useAsync from 'react-use/lib/useAsync';
import {
ApiProvider,
@@ -34,7 +29,6 @@ import {
LocalStorageFeatureFlags,
} from '../apis';
import {
- useApi,
AnyApiFactory,
ApiHolder,
IconComponent,
@@ -44,7 +38,6 @@ import {
AppThemeApi,
ConfigApi,
featureFlagsApiRef,
- IdentityApi,
identityApiRef,
BackstagePlugin,
} from '@backstage/core-plugin-api';
@@ -61,7 +54,6 @@ import {
routingV2Collector,
} from '../routing/collectors';
import { RoutingProvider } from '../routing/RoutingProvider';
-import { RouteTracker } from '../routing/RouteTracker';
import {
validateRouteParameters,
validateRouteBindings,
@@ -74,14 +66,14 @@ import {
AppContext,
AppOptions,
BackstageApp,
- SignInPageProps,
} from './types';
import { AppThemeProvider } from './AppThemeProvider';
import { defaultConfigLoader } from './defaultConfigLoader';
import { ApiRegistry } from '../apis/system/ApiRegistry';
import { resolveRouteBindings } from './resolveRouteBindings';
-import { BackstageRouteObject } from '../routing/types';
import { isReactRouterBeta } from './isReactRouterBeta';
+import { InternalAppContext } from './InternalAppContext';
+import { AppRouter, getBasePath } from './AppRouter';
type CompatiblePlugin =
| BackstagePlugin
@@ -89,39 +81,6 @@ type CompatiblePlugin =
output(): Array<{ type: 'feature-flag'; name: string }>;
});
-const InternalAppContext = createContext<{
- routeObjects: BackstageRouteObject[];
-}>({ routeObjects: [] });
-
-/**
- * Get the app base path from the configured app baseUrl.
- *
- * The returned path does not have a trailing slash.
- */
-function getBasePath(configApi: Config) {
- if (!isReactRouterBeta()) {
- // When using rr v6 stable the base path is handled through the
- // basename prop on the router component instead.
- return '';
- }
-
- return readBasePath(configApi);
-}
-
-/**
- * Read the configured base path.
- *
- * The returned path does not have a trailing slash.
- */
-function readBasePath(configApi: ConfigApi) {
- let { pathname } = new URL(
- configApi.getOptionalString('app.baseUrl') ?? '/',
- 'http://sample.dev', // baseUrl can be specified as just a path
- );
- pathname = pathname.replace(/\/*$/, '');
- return pathname;
-}
-
function useConfigLoader(
configLoader: AppConfigLoader | undefined,
components: AppComponents,
@@ -289,7 +248,23 @@ export class AppManager implements BackstageApp {
return this.components;
}
+ createRoot(element: JSX.Element): ComponentType<{}> {
+ const AppProvider = this.getProvider();
+ const AppRoot = () => {
+ return {element} ;
+ };
+ return AppRoot;
+ }
+
+ #getProviderCalled = false;
getProvider(): ComponentType<{}> {
+ if (this.#getProviderCalled) {
+ throw new Error(
+ 'app.getProvider() or app.createRoot() has already been called, and can only be called once',
+ );
+ }
+ this.#getProviderCalled = true;
+
const appContext = new AppContextImpl(this);
// We only validate routes once
@@ -413,7 +388,10 @@ export class AppManager implements BackstageApp {
basePath={getBasePath(loadedConfig.api)}
>
{children}
@@ -427,104 +405,6 @@ export class AppManager implements BackstageApp {
}
getRouter(): ComponentType<{}> {
- const { Router: RouterComponent, SignInPage: SignInPageComponent } =
- this.components;
-
- // This wraps the sign-in page and waits for sign-in to be completed before rendering the app
- const SignInPageWrapper = ({
- component: Component,
- children,
- }: {
- component: ComponentType;
- children: ReactElement;
- }) => {
- const [identityApi, setIdentityApi] = useState();
- const configApi = useApi(configApiRef);
- const basePath = getBasePath(configApi);
-
- if (!identityApi) {
- return ;
- }
-
- this.appIdentityProxy.setTarget(identityApi, {
- signOutTargetUrl: basePath || '/',
- });
- return children;
- };
-
- const AppRouter = ({ children }: PropsWithChildren<{}>) => {
- const configApi = useApi(configApiRef);
- const basePath = readBasePath(configApi);
- const mountPath = `${basePath}/*`;
- const { routeObjects } = useContext(InternalAppContext);
-
- // If the app hasn't configured a sign-in page, we just continue as guest.
- if (!SignInPageComponent) {
- this.appIdentityProxy.setTarget(
- {
- getUserId: () => 'guest',
- getIdToken: async () => undefined,
- getProfile: () => ({
- email: 'guest@example.com',
- displayName: 'Guest',
- }),
- getProfileInfo: async () => ({
- email: 'guest@example.com',
- displayName: 'Guest',
- }),
- getBackstageIdentity: async () => ({
- type: 'user',
- userEntityRef: 'user:default/guest',
- ownershipEntityRefs: ['user:default/guest'],
- }),
- getCredentials: async () => ({}),
- signOut: async () => {},
- },
- { signOutTargetUrl: basePath || '/' },
- );
-
- if (isReactRouterBeta()) {
- return (
-
-
-
- {children}>} />
-
-
- );
- }
-
- return (
-
-
- {children}
-
- );
- }
-
- if (isReactRouterBeta()) {
- return (
-
-
-
-
- {children}>} />
-
-
-
- );
- }
-
- return (
-
-
-
- <>{children}>
-
-
- );
- };
-
return AppRouter;
}
diff --git a/packages/core-app-api/src/app/AppRouter.test.tsx b/packages/core-app-api/src/app/AppRouter.test.tsx
new file mode 100644
index 0000000000..75f28a6bfe
--- /dev/null
+++ b/packages/core-app-api/src/app/AppRouter.test.tsx
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import {
+ AppComponents,
+ configApiRef,
+ IdentityApi,
+ identityApiRef,
+ SignInPageProps,
+ useApi,
+} from '@backstage/core-plugin-api';
+import { InternalAppContext } from './InternalAppContext';
+import { MemoryRouter } from 'react-router-dom';
+import { AppIdentityProxy } from '../apis/implementations/IdentityApi/AppIdentityProxy';
+import { render, screen } from '@testing-library/react';
+import { AppRouter } from './AppRouter';
+import useAsync from 'react-use/lib/useAsync';
+import { AppContextProvider } from './AppContext';
+import { TestApiProvider } from '@backstage/test-utils';
+import { ConfigReader } from '@backstage/config';
+
+function UserRefDisplay() {
+ const identityApi = useApi(identityApiRef);
+ const { value } = useAsync(() => identityApi.getBackstageIdentity());
+ return ref: {value?.userEntityRef}
;
+}
+
+describe('AppRouter', () => {
+ const mockComponents = {
+ Router: MemoryRouter,
+ } as AppComponents;
+
+ it('should fall back to guest if there is no sign-in page', async () => {
+ const appIdentityProxy = new AppIdentityProxy();
+
+ render(
+
+
+ mockComponents } as any}
+ >
+
+
+
+
+
+ ,
+ ,
+ );
+
+ await expect(
+ screen.findByText('ref: user:default/guest'),
+ ).resolves.toBeInTheDocument();
+ });
+
+ it('should use the result from the sign-in page', async () => {
+ const appIdentityProxy = new AppIdentityProxy();
+
+ const SignInPage = (props: SignInPageProps) => {
+ props.onSignInSuccess({
+ getBackstageIdentity: async () => ({
+ type: 'user',
+ userEntityRef: 'user:default/test',
+ ownershipEntityRefs: ['user:default/test'],
+ }),
+ } as IdentityApi);
+ return null;
+ };
+
+ render(
+
+
+ ({ ...mockComponents, SignInPage }),
+ } as any
+ }
+ >
+
+
+
+
+
+ ,
+ );
+
+ await expect(
+ screen.findByText('ref: user:default/test'),
+ ).resolves.toBeInTheDocument();
+ });
+});
diff --git a/packages/core-app-api/src/app/AppRouter.tsx b/packages/core-app-api/src/app/AppRouter.tsx
new file mode 100644
index 0000000000..b799983a3b
--- /dev/null
+++ b/packages/core-app-api/src/app/AppRouter.tsx
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React, { useContext, ReactNode, ComponentType, useState } from 'react';
+import {
+ ConfigApi,
+ configApiRef,
+ IdentityApi,
+ SignInPageProps,
+ useApi,
+ useApp,
+} from '@backstage/core-plugin-api';
+import { InternalAppContext } from './InternalAppContext';
+import { isReactRouterBeta } from './isReactRouterBeta';
+import { RouteTracker } from '../routing/RouteTracker';
+import { Route, Routes } from 'react-router-dom';
+import { AppIdentityProxy } from '../apis/implementations/IdentityApi/AppIdentityProxy';
+
+/**
+ * Get the app base path from the configured app baseUrl.
+ *
+ * The returned path does not have a trailing slash.
+ */
+export function getBasePath(configApi: ConfigApi) {
+ if (!isReactRouterBeta()) {
+ // When using rr v6 stable the base path is handled through the
+ // basename prop on the router component instead.
+ return '';
+ }
+
+ return readBasePath(configApi);
+}
+
+/**
+ * Read the configured base path.
+ *
+ * The returned path does not have a trailing slash.
+ */
+function readBasePath(configApi: ConfigApi) {
+ let { pathname } = new URL(
+ configApi.getOptionalString('app.baseUrl') ?? '/',
+ 'http://sample.dev', // baseUrl can be specified as just a path
+ );
+ pathname = pathname.replace(/\/*$/, '');
+ return pathname;
+}
+
+// This wraps the sign-in page and waits for sign-in to be completed before rendering the app
+function SignInPageWrapper({
+ component: Component,
+ appIdentityProxy,
+ children,
+}: {
+ component: ComponentType;
+ appIdentityProxy: AppIdentityProxy;
+ children: ReactNode;
+}) {
+ const [identityApi, setIdentityApi] = useState();
+ const configApi = useApi(configApiRef);
+ const basePath = getBasePath(configApi);
+
+ if (!identityApi) {
+ return ;
+ }
+
+ appIdentityProxy.setTarget(identityApi, {
+ signOutTargetUrl: basePath || '/',
+ });
+ return <>{children}>;
+}
+
+/**
+ * Props for the {@link AppRouter} component.
+ * @public
+ */
+export interface AppRouterProps {
+ children?: ReactNode;
+}
+
+/**
+ * App router and sign-in page wrapper.
+ *
+ * @public
+ * @remarks
+ *
+ * The AppRouter provides the routing context and renders the sign-in page.
+ * Until the user has successfully signed in, this component will render
+ * the sign-in page. Once the user has signed-in, it will instead render
+ * the app, while providing routing and route tracking for the app.
+ */
+export function AppRouter(props: AppRouterProps) {
+ const { Router: RouterComponent, SignInPage: SignInPageComponent } =
+ useApp().getComponents();
+
+ const configApi = useApi(configApiRef);
+ const basePath = readBasePath(configApi);
+ const mountPath = `${basePath}/*`;
+ const internalAppContext = useContext(InternalAppContext);
+ if (!internalAppContext) {
+ throw new Error('AppRouter must be rendered within the AppProvider');
+ }
+ const { routeObjects, appIdentityProxy } = internalAppContext;
+
+ // If the app hasn't configured a sign-in page, we just continue as guest.
+ if (!SignInPageComponent) {
+ appIdentityProxy.setTarget(
+ {
+ getUserId: () => 'guest',
+ getIdToken: async () => undefined,
+ getProfile: () => ({
+ email: 'guest@example.com',
+ displayName: 'Guest',
+ }),
+ getProfileInfo: async () => ({
+ email: 'guest@example.com',
+ displayName: 'Guest',
+ }),
+ getBackstageIdentity: async () => ({
+ type: 'user',
+ userEntityRef: 'user:default/guest',
+ ownershipEntityRefs: ['user:default/guest'],
+ }),
+ getCredentials: async () => ({}),
+ signOut: async () => {},
+ },
+ { signOutTargetUrl: basePath || '/' },
+ );
+
+ if (isReactRouterBeta()) {
+ return (
+
+
+
+ {props.children}>} />
+
+
+ );
+ }
+
+ return (
+
+
+ {props.children}
+
+ );
+ }
+
+ if (isReactRouterBeta()) {
+ return (
+
+
+
+
+ {props.children}>} />
+
+
+
+ );
+ }
+
+ return (
+
+
+
+ {props.children}
+
+
+ );
+}
diff --git a/packages/core-app-api/src/app/InternalAppContext.ts b/packages/core-app-api/src/app/InternalAppContext.ts
new file mode 100644
index 0000000000..81382acf62
--- /dev/null
+++ b/packages/core-app-api/src/app/InternalAppContext.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { createContext } from 'react';
+import { AppIdentityProxy } from '../apis/implementations/IdentityApi/AppIdentityProxy';
+import { BackstageRouteObject } from '../routing/types';
+
+export const InternalAppContext = createContext<
+ | undefined
+ | {
+ routeObjects: BackstageRouteObject[];
+ appIdentityProxy: AppIdentityProxy;
+ }
+>(undefined);
diff --git a/packages/core-app-api/src/app/index.ts b/packages/core-app-api/src/app/index.ts
index 7843b36339..156c59d0c7 100644
--- a/packages/core-app-api/src/app/index.ts
+++ b/packages/core-app-api/src/app/index.ts
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+export { AppRouter } from './AppRouter';
+export type { AppRouterProps } from './AppRouter';
export { createSpecializedApp } from './createSpecializedApp';
export { defaultConfigLoader } from './defaultConfigLoader';
export * from './types';
diff --git a/packages/core-app-api/src/app/types.ts b/packages/core-app-api/src/app/types.ts
index 70022534a1..82c05ce268 100644
--- a/packages/core-app-api/src/app/types.ts
+++ b/packages/core-app-api/src/app/types.ts
@@ -298,15 +298,44 @@ export type BackstageApp = {
*/
getSystemIcon(key: string): IconComponent | undefined;
+ /**
+ * Creates the root component that renders the entire app.
+ *
+ * @remarks
+ *
+ * This method must only be called once, and you have to provide it the entire
+ * app element tree. The element tree will be analyzed to discover plugins,
+ * routes, and other app features. The returned component will render all
+ * of the app elements wrapped within the app context provider.
+ *
+ * @example
+ * ```tsx
+ * export default app.createRoot(
+ * <>
+ *
+ *
+ *
+ * {routes}
+ *
+ * >,
+ * );
+ * ```
+ */
+ createRoot(element: JSX.Element): ComponentType<{}>;
+
/**
* Provider component that should wrap the Router created with getRouter()
* and any other components that need to be within the app context.
+ *
+ * @deprecated Use {@link BackstageApp.createRoot} instead.
*/
getProvider(): ComponentType<{}>;
/**
* Router component that should wrap the App Routes create with getRoutes()
* and any other components that should only be available while signed in.
+ *
+ * @deprecated Import and use the {@link AppRouter} component from `@backstage/core-app-api` instead
*/
getRouter(): ComponentType<{}>;
};
diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md
index 3d1baaa545..76038b2b77 100644
--- a/packages/core-components/CHANGELOG.md
+++ b/packages/core-components/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/core-components
+## 0.12.1-next.4
+
+### Patch Changes
+
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- a5a2d12298: Added option to pass additional headers to ` `, which are passed along with the request to the underlying provider
+- Updated dependencies
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/version-bridge@1.0.3-next.0
+
## 0.12.1-next.3
### Patch Changes
diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md
index d8ea9d2bbe..c46b3637cb 100644
--- a/packages/core-components/api-report.md
+++ b/packages/core-components/api-report.md
@@ -807,6 +807,7 @@ export const ProxiedSignInPage: (
// @public
export type ProxiedSignInPageProps = SignInPageProps & {
provider: string;
+ headers?: HeadersInit | (() => HeadersInit) | (() => Promise);
};
// Warning: (ae-missing-release-tag) "Ranker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
diff --git a/packages/core-components/package.json b/packages/core-components/package.json
index dc2bc08093..39f5bb31ad 100644
--- a/packages/core-components/package.json
+++ b/packages/core-components/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/core-components",
"description": "Core components used by Backstage plugins and apps",
- "version": "0.12.1-next.3",
+ "version": "0.12.1-next.4",
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -68,13 +68,12 @@
"react-window": "^1.8.6",
"remark-gfm": "^3.0.1",
"zen-observable": "^0.10.0",
- "zod": "^3.11.6"
+ "zod": "~3.18.0"
},
"peerDependencies": {
"@types/react": "^16.13.1 || ^17.0.0",
"react": "^16.13.1 || ^17.0.0",
"react-dom": "^16.13.1 || ^17.0.0",
- "react-router": "6.0.0-beta.0 || ^6.3.0",
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
},
"devDependencies": {
diff --git a/packages/core-components/src/components/Button/Button.test.tsx b/packages/core-components/src/components/Button/Button.test.tsx
index 805b3b3f10..c5942e3d78 100644
--- a/packages/core-components/src/components/Button/Button.test.tsx
+++ b/packages/core-components/src/components/Button/Button.test.tsx
@@ -18,7 +18,7 @@ import React from 'react';
import { render, fireEvent, act } from '@testing-library/react';
import { wrapInTestApp } from '@backstage/test-utils';
import { Button } from './Button';
-import { Route, Routes } from 'react-router';
+import { Route, Routes } from 'react-router-dom';
describe(' ', () => {
it('navigates using react-router', async () => {
diff --git a/packages/core-components/src/components/Link/Link.test.tsx b/packages/core-components/src/components/Link/Link.test.tsx
index d65351d840..3538b79052 100644
--- a/packages/core-components/src/components/Link/Link.test.tsx
+++ b/packages/core-components/src/components/Link/Link.test.tsx
@@ -23,7 +23,7 @@ import {
} from '@backstage/test-utils';
import { analyticsApiRef, configApiRef } from '@backstage/core-plugin-api';
import { isExternalUri, Link, useResolvedPath } from './Link';
-import { Route, Routes } from 'react-router';
+import { Route, Routes } from 'react-router-dom';
import { renderHook, WrapperComponent } from '@testing-library/react-hooks';
import { ConfigReader } from '@backstage/config';
diff --git a/packages/core-components/src/components/ProgressBars/GaugeCard.stories.tsx b/packages/core-components/src/components/ProgressBars/GaugeCard.stories.tsx
index 08c7813643..a0b6faea60 100644
--- a/packages/core-components/src/components/ProgressBars/GaugeCard.stories.tsx
+++ b/packages/core-components/src/components/ProgressBars/GaugeCard.stories.tsx
@@ -17,7 +17,7 @@
import React, { PropsWithChildren } from 'react';
import { GaugeCard } from './GaugeCard';
import Grid from '@material-ui/core/Grid';
-import { MemoryRouter } from 'react-router';
+import { MemoryRouter } from 'react-router-dom';
import Tooltip from '@material-ui/core/Tooltip';
import Info from '@material-ui/icons/Info';
diff --git a/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx b/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx
index bbdb901f33..ec91208eee 100644
--- a/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx
+++ b/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx
@@ -17,7 +17,7 @@
import { renderInTestApp } from '@backstage/test-utils';
import { act, fireEvent } from '@testing-library/react';
import React from 'react';
-import { Route, Routes } from 'react-router';
+import { Route, Routes } from 'react-router-dom';
import { RoutedTabs } from './RoutedTabs';
const testRoute1 = {
diff --git a/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx b/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx
index 197cdb2239..2a0b0eae28 100644
--- a/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx
+++ b/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx
@@ -15,7 +15,12 @@
*/
import React, { useMemo } from 'react';
import { Helmet } from 'react-helmet';
-import { matchRoutes, useNavigate, useParams, useRoutes } from 'react-router';
+import {
+ matchRoutes,
+ useNavigate,
+ useParams,
+ useRoutes,
+} from 'react-router-dom';
import { Content } from '../../layout/Content';
import { HeaderTabs } from '../../layout/HeaderTabs';
import { SubRoute } from './types';
diff --git a/packages/core-components/src/components/TabbedLayout/TabbedLayout.stories.tsx b/packages/core-components/src/components/TabbedLayout/TabbedLayout.stories.tsx
index 9686409c43..3047c6f226 100644
--- a/packages/core-components/src/components/TabbedLayout/TabbedLayout.stories.tsx
+++ b/packages/core-components/src/components/TabbedLayout/TabbedLayout.stories.tsx
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import React, { PropsWithChildren } from 'react';
-import { MemoryRouter, Route, Routes } from 'react-router';
+import { MemoryRouter, Route, Routes } from 'react-router-dom';
import { TabbedLayout } from './TabbedLayout';
export default {
diff --git a/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx b/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx
index 98a65673e3..9cfaac363e 100644
--- a/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx
+++ b/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx
@@ -19,7 +19,7 @@ import Grid from '@material-ui/core/Grid';
import { makeStyles } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import React from 'react';
-import { useNavigate } from 'react-router';
+import { useNavigate } from 'react-router-dom';
import { Link } from '../../components/Link';
import { useSupportConfig } from '../../hooks';
import { MicDrop } from './MicDrop';
diff --git a/packages/core-components/src/layout/InfoCard/InfoCard.stories.tsx b/packages/core-components/src/layout/InfoCard/InfoCard.stories.tsx
index a6509caaaf..0e136800ca 100644
--- a/packages/core-components/src/layout/InfoCard/InfoCard.stories.tsx
+++ b/packages/core-components/src/layout/InfoCard/InfoCard.stories.tsx
@@ -17,7 +17,7 @@
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import React, { PropsWithChildren } from 'react';
-import { MemoryRouter } from 'react-router';
+import { MemoryRouter } from 'react-router-dom';
import { InfoCard, Props } from './InfoCard';
export default {
diff --git a/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx b/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx
index 1d336fc5f5..f7df3d43cc 100644
--- a/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx
+++ b/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx
@@ -21,7 +21,7 @@ import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Typography from '@material-ui/core/Typography';
import React from 'react';
-import { MemoryRouter } from 'react-router';
+import { MemoryRouter } from 'react-router-dom';
import { Button } from '../../components';
import { ItemCardGrid } from './ItemCardGrid';
import { ItemCardHeader } from './ItemCardHeader';
diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts
index 3a40f5bb4b..b8c2b84085 100644
--- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts
+++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts
@@ -103,7 +103,6 @@ describe('ProxiedSignInIdentity', () => {
},
};
}
-
worker.events.on('request:match', serverCalled);
worker.use(
rest.get('http://example.com/api/auth/foo/refresh', (_, res, ctx) =>
@@ -164,5 +163,137 @@ describe('ProxiedSignInIdentity', () => {
await identity.getSessionAsync(); // now the expiry has passed
expect(serverCalled).toHaveBeenCalledTimes(2);
});
+
+ // dummy response for tests which are only testing the request behaviour
+ const dummySessionResponse = {
+ providerInfo: {},
+ profile: {},
+ backstageIdentity: {
+ token: '',
+ identity: {
+ ownershipEntityRefs: [''],
+ userEntityRef: '',
+ type: 'user',
+ },
+ },
+ };
+
+ it('handles headers passed as a promise', async () => {
+ let req1: Request;
+ const getBaseUrl = jest.fn();
+ const serverCalled = jest.fn().mockImplementation(req => {
+ req1 = req;
+ });
+
+ worker.events.on('request:match', serverCalled);
+ worker.use(
+ rest.get('http://example.com/api/auth/foo/refresh', (_, res, ctx) =>
+ res(
+ ctx.status(200),
+ ctx.set('Content-Type', 'application/json'),
+ ctx.json(dummySessionResponse),
+ ),
+ ),
+ );
+
+ const getHeaders = jest.fn().mockResolvedValue({ 'x-foo': 'bars' });
+ const identity = new ProxiedSignInIdentity({
+ provider: 'foo',
+ discoveryApi: { getBaseUrl },
+ headers: getHeaders,
+ });
+
+ getBaseUrl.mockResolvedValue('http://example.com/api/auth');
+
+ await identity.start(); // should not throw
+ expect(getBaseUrl).toHaveBeenCalledTimes(1);
+ expect(getBaseUrl).toHaveBeenLastCalledWith('auth');
+ expect(getHeaders).toHaveBeenCalledTimes(1);
+ expect(serverCalled).toHaveBeenCalledTimes(1);
+
+ expect(req1!).not.toBeUndefined();
+ // required header should be present
+ expect(req1!.headers.get('x-requested-with')).toEqual('XMLHttpRequest');
+ // optional header should be present when passed
+ expect(req1!.headers.get('x-foo')).toEqual('bars');
+ });
+
+ it('handles headers passed as an object', async () => {
+ let req1: Request;
+ const getBaseUrl = jest.fn();
+ const serverCalled = jest.fn().mockImplementation(req => {
+ req1 = req;
+ });
+
+ worker.events.on('request:match', serverCalled);
+ worker.use(
+ rest.get('http://example.com/api/auth/foo/refresh', (_, res, ctx) =>
+ res(
+ ctx.status(200),
+ ctx.set('Content-Type', 'application/json'),
+ ctx.json(dummySessionResponse),
+ ),
+ ),
+ );
+
+ const identity = new ProxiedSignInIdentity({
+ provider: 'foo',
+ discoveryApi: { getBaseUrl },
+ headers: { 'x-foo': 'bars' },
+ });
+
+ getBaseUrl.mockResolvedValue('http://example.com/api/auth');
+
+ await identity.start(); // should not throw
+ expect(getBaseUrl).toHaveBeenCalledTimes(1);
+ expect(getBaseUrl).toHaveBeenLastCalledWith('auth');
+ expect(serverCalled).toHaveBeenCalledTimes(1);
+
+ expect(req1!).not.toBeUndefined();
+ // required header should be present
+ expect(req1!.headers.get('x-requested-with')).toEqual('XMLHttpRequest');
+ // optional header should be present when passed
+ expect(req1!.headers.get('x-foo')).toEqual('bars');
+ });
+
+ it('handles headers passed as a function', async () => {
+ let req1: Request;
+ const getBaseUrl = jest.fn();
+ const serverCalled = jest.fn().mockImplementation(req => {
+ req1 = req;
+ });
+
+ worker.events.on('request:match', serverCalled);
+ worker.use(
+ rest.get('http://example.com/api/auth/foo/refresh', (_, res, ctx) =>
+ res(
+ ctx.status(200),
+ ctx.set('Content-Type', 'application/json'),
+ ctx.json(dummySessionResponse),
+ ),
+ ),
+ );
+
+ const getHeaders = jest.fn().mockReturnValue({ 'x-foo': 'bars' });
+ const identity = new ProxiedSignInIdentity({
+ provider: 'foo',
+ discoveryApi: { getBaseUrl },
+ headers: getHeaders,
+ });
+
+ getBaseUrl.mockResolvedValue('http://example.com/api/auth');
+
+ await identity.start(); // should not throw
+ expect(getBaseUrl).toHaveBeenCalledTimes(1);
+ expect(getBaseUrl).toHaveBeenLastCalledWith('auth');
+ expect(getHeaders).toHaveBeenCalledTimes(1);
+ expect(serverCalled).toHaveBeenCalledTimes(1);
+
+ expect(req1!).not.toBeUndefined();
+ // required header should be present
+ expect(req1!.headers.get('x-requested-with')).toEqual('XMLHttpRequest');
+ // optional header should be present when passed
+ expect(req1!.headers.get('x-foo')).toEqual('bars');
+ });
});
});
diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts
index 7633fc43c3..bd1fc1bf39 100644
--- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts
+++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts
@@ -51,6 +51,7 @@ export function tokenToExpiry(jwtToken: string | undefined): Date {
type ProxiedSignInIdentityOptions = {
provider: string;
discoveryApi: typeof discoveryApiRef.T;
+ headers?: HeadersInit | (() => HeadersInit) | (() => Promise);
};
type State =
@@ -193,6 +194,13 @@ export class ProxiedSignInIdentity implements IdentityApi {
async fetchSession(): Promise {
const baseUrl = await this.options.discoveryApi.getBaseUrl('auth');
+ const headers =
+ typeof this.options.headers === 'function'
+ ? await this.options.headers()
+ : this.options.headers;
+ const mergedHeaders = new Headers(headers);
+ mergedHeaders.set('X-Requested-With', 'XMLHttpRequest');
+
// Note that we do not use the fetchApi here, since this all happens before
// sign-in completes so there can be no automatic token injection and
// similar.
@@ -200,7 +208,7 @@ export class ProxiedSignInIdentity implements IdentityApi {
`${baseUrl}/${this.options.provider}/refresh`,
{
signal: this.abortController.signal,
- headers: { 'x-requested-with': 'XMLHttpRequest' },
+ headers: mergedHeaders,
credentials: 'include',
},
);
diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx
index 965c603004..ea095cd8ab 100644
--- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx
+++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx
@@ -36,6 +36,12 @@ export type ProxiedSignInPageProps = SignInPageProps & {
* a properly configured auth provider ID in the auth backend.
*/
provider: string;
+
+ /**
+ * Optional headers which are passed along with the request to the
+ * underlying provider
+ */
+ headers?: HeadersInit | (() => HeadersInit) | (() => Promise);
};
/**
@@ -60,6 +66,7 @@ export const ProxiedSignInPage = (props: ProxiedSignInPageProps) => {
const identity = new ProxiedSignInIdentity({
provider: props.provider,
discoveryApi,
+ headers: props.headers,
});
await identity.start();
diff --git a/packages/core-components/src/layout/Sidebar/Items.test.tsx b/packages/core-components/src/layout/Sidebar/Items.test.tsx
index 0f81f7ce63..eafbf3827e 100644
--- a/packages/core-components/src/layout/Sidebar/Items.test.tsx
+++ b/packages/core-components/src/layout/Sidebar/Items.test.tsx
@@ -23,7 +23,7 @@ import CreateComponentIcon from '@material-ui/icons/AddCircleOutline';
import { Sidebar } from './Bar';
import { SidebarItem, SidebarSearchField, SidebarExpandButton } from './Items';
import { renderHook } from '@testing-library/react-hooks';
-import { hexToRgb, makeStyles } from '@material-ui/core/styles';
+import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles({
spotlight: {
@@ -71,7 +71,7 @@ describe('Items', () => {
it('should render a button with custom style', async () => {
expect(
await screen.findByRole('button', { name: /create/i }),
- ).toHaveStyle(`background-color: ${hexToRgb('2b2a2a')}`);
+ ).toHaveStyle(`background-color: transparent`);
});
});
describe('SidebarSearchField', () => {
diff --git a/packages/core-components/src/layout/Sidebar/Items.tsx b/packages/core-components/src/layout/Sidebar/Items.tsx
index 031b1e5168..823320403e 100644
--- a/packages/core-components/src/layout/Sidebar/Items.tsx
+++ b/packages/core-components/src/layout/Sidebar/Items.tsx
@@ -61,6 +61,7 @@ import { useSidebarOpenState } from './SidebarOpenStateContext';
import { SidebarSubmenu, SidebarSubmenuProps } from './SidebarSubmenu';
import { SidebarSubmenuItemProps } from './SidebarSubmenuItem';
import { isLocationMatch } from './utils';
+import Button from '@material-ui/core/Button';
/** @public */
export type SidebarItemClassKey =
@@ -140,6 +141,7 @@ const makeSidebarStyles = (sidebarConfig: SidebarConfig) =>
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
+ lineHeight: '0',
},
searchRoot: {
marginBottom: 12,
@@ -371,12 +373,14 @@ const SidebarItemBase = forwardRef((props, ref) => {
const { isOpen } = useSidebarOpenState();
const divStyle =
- !isOpen && hasSubmenu ? { display: 'flex', marginLeft: '24px' } : {};
+ !isOpen && hasSubmenu
+ ? { display: 'flex', marginLeft: '20px' }
+ : { lineHeight: '0' };
const displayItemIcon = (
- {!isOpen && hasSubmenu ? : <>>}
+ {!isOpen && hasSubmenu ? : <>>}
);
@@ -421,9 +425,9 @@ const SidebarItemBase = forwardRef((props, ref) => {
if (isButtonItem(props)) {
return (
-
+
{content}
-
+
);
}
@@ -688,7 +692,8 @@ export const SidebarExpandButton = () => {
};
return (
- {
{isOpen ? : }
-
+
);
};
diff --git a/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx b/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx
index bfa841690d..9000c2f10b 100644
--- a/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx
+++ b/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx
@@ -26,7 +26,7 @@ import CloseIcon from '@material-ui/icons/Close';
import MenuIcon from '@material-ui/icons/Menu';
import { orderBy } from 'lodash';
import React, { createContext, useEffect, useState, useContext } from 'react';
-import { useLocation } from 'react-router';
+import { useLocation } from 'react-router-dom';
import { SidebarOpenStateProvider } from './SidebarOpenStateContext';
import { SidebarGroup } from './SidebarGroup';
import { SidebarConfigContext, SidebarConfig } from './config';
diff --git a/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx b/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx
index fbe4496c72..5fdd29f203 100644
--- a/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx
+++ b/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx
@@ -27,6 +27,7 @@ import ArrowDropUpIcon from '@material-ui/icons/ArrowDropUp';
import { SidebarItemWithSubmenuContext } from './config';
import { isLocationMatch } from './utils';
import Box from '@material-ui/core/Box';
+import Button from '@material-ui/core/Button';
const useStyles = makeStyles(
theme => ({
@@ -158,7 +159,8 @@ export const SidebarSubmenuItem = (props: SidebarSubmenuItemProps) => {
return (
- e.stopPropagation()}
className={classnames(
@@ -181,7 +183,7 @@ export const SidebarSubmenuItem = (props: SidebarSubmenuItemProps) => {
) : (
)}
-
+
{dropdownItems && showDropDown && (
diff --git a/packages/core-components/src/layout/TabbedCard/TabbedCard.stories.tsx b/packages/core-components/src/layout/TabbedCard/TabbedCard.stories.tsx
index 77fff64fb5..6703fe25ce 100644
--- a/packages/core-components/src/layout/TabbedCard/TabbedCard.stories.tsx
+++ b/packages/core-components/src/layout/TabbedCard/TabbedCard.stories.tsx
@@ -16,7 +16,7 @@
import Grid from '@material-ui/core/Grid';
import React, { PropsWithChildren, useState } from 'react';
-import { MemoryRouter } from 'react-router';
+import { MemoryRouter } from 'react-router-dom';
import { CardTab, TabbedCard } from './TabbedCard';
const cardContentStyle = { height: 200, width: 500 };
diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md
index c976ee02c9..280ffc3f6a 100644
--- a/packages/create-app/CHANGELOG.md
+++ b/packages/create-app/CHANGELOG.md
@@ -1,5 +1,63 @@
# @backstage/create-app
+## 0.4.35-next.4
+
+### Patch Changes
+
+- 935b66a646: Change step output template examples to use square bracket syntax.
+- dfb269fab2: Updated the template to have the `'/test'` proxy endpoint in `app-config.yaml` be commented out by default.
+- d9b3753f87: Updated the app template to use the new `AppRouter` component instead of `app.getRouter()`, as well as `app.createRoot()` instead of `app.getProvider()`.
+
+ To apply this change to an existing app, make the following change to `packages/app/src/App.tsx`:
+
+ ```diff
+ -import { FlatRoutes } from '@backstage/core-app-api';
+ +import { AppRouter, FlatRoutes } from '@backstage/core-app-api';
+
+ ...
+
+ -const AppProvider = app.getProvider();
+ -const AppRouter = app.getRouter();
+
+ ...
+
+ -const App = () => (
+ +export default app.createRoot(
+ -
+ + <>
+
+
+
+ {routes}
+
+ -
+ + >,
+ );
+ ```
+
+ The final export step should end up looking something like this:
+
+ ```tsx
+ export default app.createRoot(
+ <>
+
+
+
+ {routes}
+
+ >,
+ );
+ ```
+
+ Note that `app.createRoot()` accepts a React element, rather than a component.
+
+- 71e75c0b70: Removed the `react-router` dependency from the app package, using only `react-router-dom` instead.
+
+ This change is just a bit of cleanup and is optional. If you want to apply it to your app, remove the `react-router` dependency from `packages/app/package.json`, and replace any imports from `react-router` with `react-router-dom` instead.
+
+- Updated dependencies
+ - @backstage/cli-common@0.1.11-next.0
+
## 0.4.35-next.3
### Patch Changes
diff --git a/packages/create-app/package.json b/packages/create-app/package.json
index 7f37296908..c6f07cabf8 100644
--- a/packages/create-app/package.json
+++ b/packages/create-app/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/create-app",
"description": "A CLI that helps you create your own Backstage app",
- "version": "0.4.35-next.3",
+ "version": "0.4.35-next.4",
"publishConfig": {
"access": "public"
},
diff --git a/packages/create-app/templates/default-app/app-config.yaml.hbs b/packages/create-app/templates/default-app/app-config.yaml.hbs
index 1a45d4015b..3b5de8baa3 100644
--- a/packages/create-app/templates/default-app/app-config.yaml.hbs
+++ b/packages/create-app/templates/default-app/app-config.yaml.hbs
@@ -46,9 +46,11 @@ integrations:
# token: ${GHE_TOKEN}
proxy:
- '/test':
- target: 'https://example.com'
- changeOrigin: true
+ ### Example for how to add a proxy endpoint for the frontend.
+ ### A typical reason to do this is to handle HTTPS and CORS for internal services.
+ # '/test':
+ # target: 'https://example.com'
+ # changeOrigin: true
# Reference documentation http://backstage.io/docs/features/techdocs/configuration
# Note: After experimenting with basic setup, use CI/CD to generate docs
diff --git a/packages/create-app/templates/default-app/packages/app/package.json.hbs b/packages/create-app/templates/default-app/packages/app/package.json.hbs
index ebd8a9ee15..306c7c047d 100644
--- a/packages/create-app/templates/default-app/packages/app/package.json.hbs
+++ b/packages/create-app/templates/default-app/packages/app/package.json.hbs
@@ -48,7 +48,6 @@
"history": "^5.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
- "react-router": "^6.3.0",
"react-router-dom": "^6.3.0",
"react-use": "^17.2.4"
},
diff --git a/packages/create-app/templates/default-app/packages/app/src/App.tsx b/packages/create-app/templates/default-app/packages/app/src/App.tsx
index 46cb786399..056402f2a8 100644
--- a/packages/create-app/templates/default-app/packages/app/src/App.tsx
+++ b/packages/create-app/templates/default-app/packages/app/src/App.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { Navigate, Route } from 'react-router';
+import { Navigate, Route } from 'react-router-dom';
import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs';
import {
CatalogEntityPage,
@@ -29,7 +29,7 @@ import { Root } from './components/Root';
import { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components';
import { createApp } from '@backstage/app-defaults';
-import { FlatRoutes } from '@backstage/core-app-api';
+import { AppRouter, FlatRoutes } from '@backstage/core-app-api';
import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
import { RequirePermission } from '@backstage/plugin-permission-react';
import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';
@@ -53,9 +53,6 @@ const app = createApp({
},
});
-const AppProvider = app.getProvider();
-const AppRouter = app.getRouter();
-
const routes = (
} />
@@ -97,14 +94,12 @@ const routes = (
);
-const App = () => (
-
+export default app.createRoot(
+ <>
{routes}
-
+ >,
);
-
-export default App;
diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md
index ced7e7bf6f..65294a8ebb 100644
--- a/packages/dev-utils/CHANGELOG.md
+++ b/packages/dev-utils/CHANGELOG.md
@@ -1,5 +1,21 @@
# @backstage/dev-utils
+## 1.0.9-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-app-api@1.3.0-next.4
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/app-defaults@1.0.9-next.4
+ - @backstage/test-utils@1.2.3-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+
## 1.0.9-next.3
### Patch Changes
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index cf1aec058e..8a309b1403 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/dev-utils",
"description": "Utilities for developing Backstage plugins.",
- "version": "1.0.9-next.3",
+ "version": "1.0.9-next.4",
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -53,7 +53,6 @@
"@types/react": "^16.13.1 || ^17.0.0",
"react": "^16.13.1 || ^17.0.0",
"react-dom": "^16.13.1 || ^17.0.0",
- "react-router": "6.0.0-beta.0 || ^6.3.0",
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
},
"devDependencies": {
diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx
index 6fa73ba860..d2c91c9394 100644
--- a/packages/dev-utils/src/devApp/render.tsx
+++ b/packages/dev-utils/src/devApp/render.tsx
@@ -46,7 +46,7 @@ import { Box } from '@material-ui/core';
import BookmarkIcon from '@material-ui/icons/Bookmark';
import React, { ComponentType, ReactNode } from 'react';
import ReactDOM from 'react-dom';
-import { createRoutesFromChildren, Route } from 'react-router';
+import { createRoutesFromChildren, Route } from 'react-router-dom';
import { SidebarThemeSwitcher } from './SidebarThemeSwitcher';
export function isReactRouterBeta(): boolean {
diff --git a/packages/errors/src/errors/CustomErrorBase.ts b/packages/errors/src/errors/CustomErrorBase.ts
index 786e10ef23..b831d4eea3 100644
--- a/packages/errors/src/errors/CustomErrorBase.ts
+++ b/packages/errors/src/errors/CustomErrorBase.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { stringifyError } from '../serialization';
+import { stringifyError } from '../serialization/error';
import { isError } from './assertion';
/**
diff --git a/packages/errors/src/errors/ResponseError.ts b/packages/errors/src/errors/ResponseError.ts
index a26891ef6a..f8ba0a1ba1 100644
--- a/packages/errors/src/errors/ResponseError.ts
+++ b/packages/errors/src/errors/ResponseError.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { deserializeError } from '../serialization';
+import { deserializeError } from '../serialization/error';
import {
ErrorResponseBody,
parseErrorResponseBody,
diff --git a/packages/errors/src/serialization/error.ts b/packages/errors/src/serialization/error.ts
index 8d031949bf..e48309f1e7 100644
--- a/packages/errors/src/serialization/error.ts
+++ b/packages/errors/src/serialization/error.ts
@@ -19,7 +19,7 @@ import {
deserializeError as deserializeErrorInternal,
serializeError as serializeErrorInternal,
} from 'serialize-error';
-import { isError } from '../errors';
+import { isError } from '../errors/assertion';
/**
* The serialized form of an Error.
diff --git a/packages/integration-aws-node/.eslintrc.js b/packages/integration-aws-node/.eslintrc.js
new file mode 100644
index 0000000000..e2a53a6ad2
--- /dev/null
+++ b/packages/integration-aws-node/.eslintrc.js
@@ -0,0 +1 @@
+module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
diff --git a/packages/integration-aws-node/CHANGELOG.md b/packages/integration-aws-node/CHANGELOG.md
new file mode 100644
index 0000000000..4b70ee97b4
--- /dev/null
+++ b/packages/integration-aws-node/CHANGELOG.md
@@ -0,0 +1,13 @@
+# @backstage/integration-aws-node
+
+## 0.1.0-next.0
+
+### Minor Changes
+
+- 13278732f6: New package for AWS integration node library
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
diff --git a/packages/integration-aws-node/README.md b/packages/integration-aws-node/README.md
new file mode 100644
index 0000000000..62df26756f
--- /dev/null
+++ b/packages/integration-aws-node/README.md
@@ -0,0 +1,162 @@
+# @backstage/integration-aws-node
+
+This package providers helpers for fetching AWS account credentials
+to be used by AWS SDK clients in backend packages and plugins.
+
+## Backstage app configuration
+
+Users of plugins and packages that use this library
+will configure their AWS account information and credentials in their
+Backstage app config.
+Users can configure IAM user credentials, IAM roles, and profile names
+for their AWS accounts in their Backstage config.
+
+If the AWS integration configuration is missing, the credentials manager
+from this package will fall back to the AWS SDK default credentials chain for
+resources in the main AWS account.
+The default credentials chain for Node resolves credentials in the
+following order of precedence:
+
+1. Environment variables
+2. SSO credentials from token cache
+3. Web identity token credentials
+4. Shared credentials files
+5. The EC2/ECS Instance Metadata Service
+
+See more about the AWS SDK default credentials chain in the
+[AWS SDK for Javascript Developer Guide](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html).
+
+Configuration examples:
+
+```yaml
+aws:
+ # The main account is used as the source of credentials for calling
+ # the STS AssumeRole API to assume IAM roles in other AWS accounts.
+ # This section can be omitted to fall back to the AWS SDK's default creds chain.
+ mainAccount:
+ accessKeyId: ${MY_ACCESS_KEY_ID}
+ secretAccessKey: ${MY_SECRET_ACCESS_KEY}
+
+ # Account credentials can be configured individually per account
+ accounts:
+ # Credentials can come from a role in the account
+ - accountId: '111111111111'
+ roleName: 'my-iam-role-name'
+ externalId: 'my-external-id'
+
+ # Credentials can come from other AWS partitions
+ - accountId: '222222222222'
+ partition: 'aws-other'
+ roleName: 'my-iam-role-name'
+ # The STS region to use for the AssumeRole call
+ region: 'not-us-east-1'
+ # The creds to use when calling AssumeRole
+ accessKeyId: ${MY_ACCESS_KEY_ID_FOR_ANOTHER_PARTITION}
+ secretAccessKey: ${MY_SECRET_ACCESS_KEY_FOR_ANOTHER_PARTITION}
+
+ # Credentials can come from static credentials
+ - accountId: '333333333333'
+ accessKeyId: ${MY_OTHER_ACCESS_KEY_ID}
+ secretAccessKey: ${MY_OTHER_SECRET_ACCESS_KEY}
+
+ # Credentials can come from a profile in a shared config file on disk
+ - accountId: '444444444444'
+ profile: my-profile-name
+
+ # Credentials can come from the AWS SDK's default creds chain
+ - accountId: '555555555555'
+
+ # Credentials for accounts can fall back to a common role name.
+ # This is useful for account discovery use cases where the account
+ # IDs may not be known when writing the static config.
+ # If all accounts have a role with the same name, then the "accounts"
+ # section can be omitted entirely.
+ accountDefaults:
+ roleName: 'my-backstage-role'
+ externalId: 'my-id'
+```
+
+## Integrate new plugins
+
+Backend plugins can provide an AWS ARN or account ID to this library in order to
+retrieve a credential provider for the relevant account that can be fed directly
+to an AWS SDK client.
+The AWS SDK for Javascript V3 must be used.
+
+```typescript
+const awsCredentialsManager = DefaultAwsCredentialsManager.fromConfig(config);
+
+// provide the account ID explicitly
+const credProvider = await awsCredentialsManager.getCredentialProvider({
+ accountId,
+});
+// OR extract the account ID from the ARN
+const credProvider = await awsCredentialsManager.getCredentialProvider({ arn });
+// OR provide neither to get main account's credentials
+const credProvider = await awsCredentialsManager.getCredentialProvider({});
+
+// Example constructing an AWS Proton client with the returned credential provider
+const client = new ProtonClient({
+ region,
+ credentialDefaultProvider: () => credProvider.sdkCredentialProvider,
+});
+```
+
+Depending on the nature of your plugin, you may either have the user specify the
+relevant ARN or account ID in a catalog entity annotation or in the static Backstage
+app configuration for your plugin.
+
+For example, you can create a new catalog entity annotation for your plugin containing
+either an AWS account ID or ARN:
+
+```yaml
+apiVersion: backstage.io/v1alpha1
+kind: Component
+metadata:
+ annotations:
+ # Plugin annotation to specify an AWS account ID
+ my-plugin.io/aws-account-id: '123456789012'
+ # Plugin annotation to specify the AWS ARN of a specific resource
+ my-other-plugin.io/aws-dynamodb-table: 'arn:aws:dynamodb:us-east-2:123456789012:table/example-table'
+```
+
+In your plugin, read the annotation value so that you can retrieve the credential provider:
+
+```typescript
+const MY_AWS_ACCOUNT_ID_ANNOTATION = 'my-plugin.io/aws-account-id';
+
+const getAwsAccountId = (entity: Entity) =>
+ entity.metadata.annotations?.[MY_AWS_ACCOUNT_ID_ANNOTATION]);
+```
+
+Alternatively, you can create a new Backstage app configuration field for your plugin:
+
+```yaml
+# app-config.yaml
+my-plugin:
+ # Statically configure the AWS account ID to use
+ awsAccountId: '123456789012'
+my-other-plugin:
+ # Statically configure the AWS ARN of a specific resource
+ awsDynamoDbTable: 'arn:aws:dynamodb:us-east-2:123456789012:table/example-table'
+```
+
+In your plugin, read the configuration value so that you can retrieve the credential provider:
+
+```typescript
+// Read an account ID from your plugin's configuration
+const awsCredentialsManager = DefaultAwsCredentialsManager.fromConfig(config);
+const accountId = config.getOptionalString('my-plugin.awsAccountId');
+const credProvider = await awsCredentialsManager.getCredentialProvider({
+ accountId,
+});
+
+// Or, read an AWS ARN from your plugin's configuration
+const awsCredentialsManager = DefaultAwsCredentialsManager.fromConfig(config);
+const arn = config.getString('my-other-plugin.awsDynamoDbTable');
+const credProvider = await awsCredentialsManager.getCredentialProvider({ arn });
+```
+
+## Links
+
+- [The Backstage homepage](https://backstage.io)
diff --git a/packages/integration-aws-node/api-report.md b/packages/integration-aws-node/api-report.md
new file mode 100644
index 0000000000..d9ed25e193
--- /dev/null
+++ b/packages/integration-aws-node/api-report.md
@@ -0,0 +1,39 @@
+## API Report File for "@backstage/integration-aws-node"
+
+> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
+
+```ts
+import { AwsCredentialIdentityProvider } from '@aws-sdk/types';
+import { Config } from '@backstage/config';
+
+// @public
+export type AwsCredentialProvider = {
+ accountId?: string;
+ stsRegion?: string;
+ sdkCredentialProvider: AwsCredentialIdentityProvider;
+};
+
+// @public
+export type AwsCredentialProviderOptions = {
+ accountId?: string;
+ arn?: string;
+};
+
+// @public
+export interface AwsCredentialsManager {
+ getCredentialProvider(
+ opts?: AwsCredentialProviderOptions,
+ ): Promise;
+}
+
+// @public
+export class DefaultAwsCredentialsManager implements AwsCredentialsManager {
+ // (undocumented)
+ static fromConfig(config: Config): DefaultAwsCredentialsManager;
+ getCredentialProvider(
+ opts?: AwsCredentialProviderOptions,
+ ): Promise;
+}
+
+// (No @packageDocumentation comment for this package)
+```
diff --git a/packages/integration-aws-node/config.d.ts b/packages/integration-aws-node/config.d.ts
new file mode 100644
index 0000000000..3c5600efc3
--- /dev/null
+++ b/packages/integration-aws-node/config.d.ts
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export interface Config {
+ /** Configuration for access to AWS accounts */
+ aws?: {
+ /**
+ * Defaults for retrieving AWS account credentials
+ */
+ accountDefaults?: {
+ /**
+ * The IAM role to assume to retrieve temporary AWS credentials
+ */
+ roleName?: string;
+
+ /**
+ * The AWS partition of the IAM role, e.g. "aws", "aws-cn"
+ */
+ partition?: string;
+
+ /**
+ * The STS regional endpoint to use when retrieving temporary AWS credentials, e.g. "ap-northeast-1"
+ */
+ region?: string;
+
+ /**
+ * The unique identifier needed to assume the role to retrieve temporary AWS credentials
+ * @visibility secret
+ */
+ externalId?: string;
+ };
+
+ /**
+ * Main account to use for retrieving AWS account credentials
+ */
+ mainAccount?: {
+ /**
+ * The access key ID for a set of static AWS credentials
+ * @visibility secret
+ */
+ accessKeyId?: string;
+
+ /**
+ * The secret access key for a set of static AWS credentials
+ * @visibility secret
+ */
+ secretAccessKey?: string;
+
+ /**
+ * The configuration profile from a credentials file at ~/.aws/credentials and
+ * a configuration file at ~/.aws/config.
+ */
+ profile?: string;
+
+ /**
+ * The STS regional endpoint to use for the main account, e.g. "ap-northeast-1"
+ */
+ region?: string;
+ };
+
+ /**
+ * Configuration for retrieving AWS accounts credentials
+ */
+ accounts?: Array<{
+ /**
+ * The account ID of the target account that this matches on, e.g. "123456789012"
+ */
+ accountId: string;
+
+ /**
+ * The access key ID for a set of static AWS credentials
+ * @visibility secret
+ */
+ accessKeyId?: string;
+
+ /**
+ * The secret access key for a set of static AWS credentials
+ * @visibility secret
+ */
+ secretAccessKey?: string;
+
+ /**
+ * The configuration profile from a credentials file at ~/.aws/credentials and
+ * a configuration file at ~/.aws/config.
+ */
+ profile?: string;
+
+ /**
+ * The IAM role to assume to retrieve temporary AWS credentials
+ */
+ roleName?: string;
+
+ /**
+ * The AWS partition of the IAM role, e.g. "aws", "aws-cn"
+ */
+ partition?: string;
+
+ /**
+ * The STS regional endpoint to use when retrieving temporary AWS credentials, e.g. "ap-northeast-1"
+ */
+ region?: string;
+
+ /**
+ * The unique identifier needed to assume the role to retrieve temporary AWS credentials
+ * @visibility secret
+ */
+ externalId?: string;
+ }>;
+ };
+}
diff --git a/packages/integration-aws-node/package.json b/packages/integration-aws-node/package.json
new file mode 100644
index 0000000000..0088f08ba8
--- /dev/null
+++ b/packages/integration-aws-node/package.json
@@ -0,0 +1,55 @@
+{
+ "name": "@backstage/integration-aws-node",
+ "description": "Helpers for fetching AWS account credentials",
+ "version": "0.1.0-next.0",
+ "main": "src/index.ts",
+ "types": "src/index.ts",
+ "publishConfig": {
+ "access": "public",
+ "main": "dist/index.cjs.js",
+ "module": "dist/index.esm.js",
+ "types": "dist/index.d.ts"
+ },
+ "backstage": {
+ "role": "node-library"
+ },
+ "homepage": "https://backstage.io",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/backstage/backstage",
+ "directory": "packages/integration-aws-node"
+ },
+ "keywords": [
+ "backstage"
+ ],
+ "license": "Apache-2.0",
+ "scripts": {
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean"
+ },
+ "dependencies": {
+ "@aws-sdk/client-sts": "^3.208.0",
+ "@aws-sdk/credential-provider-node": "^3.208.0",
+ "@aws-sdk/credential-providers": "^3.208.0",
+ "@aws-sdk/types": "^3.208.0",
+ "@aws-sdk/util-arn-parser": "^3.208.0",
+ "@backstage/config": "workspace:^",
+ "@backstage/errors": "workspace:^"
+ },
+ "devDependencies": {
+ "@backstage/cli": "workspace:^",
+ "@backstage/config-loader": "workspace:^",
+ "@backstage/test-utils": "workspace:^",
+ "aws-sdk-client-mock": "^2.0.0",
+ "aws-sdk-client-mock-jest": "^2.0.0"
+ },
+ "files": [
+ "dist",
+ "config.d.ts"
+ ],
+ "configSchema": "config.d.ts"
+}
diff --git a/packages/integration-aws-node/src/DefaultAwsCredentialsManager.test.ts b/packages/integration-aws-node/src/DefaultAwsCredentialsManager.test.ts
new file mode 100644
index 0000000000..1b21d43338
--- /dev/null
+++ b/packages/integration-aws-node/src/DefaultAwsCredentialsManager.test.ts
@@ -0,0 +1,430 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { DefaultAwsCredentialsManager } from './DefaultAwsCredentialsManager';
+import { mockClient, AwsClientStub } from 'aws-sdk-client-mock';
+import 'aws-sdk-client-mock-jest';
+import {
+ STSClient,
+ GetCallerIdentityCommand,
+ AssumeRoleCommand,
+} from '@aws-sdk/client-sts';
+import { Config, ConfigReader } from '@backstage/config';
+import { promises } from 'fs';
+
+const env = process.env;
+let stsMock: AwsClientStub;
+let config: Config;
+
+jest.mock('fs', () => ({ promises: { readFile: jest.fn() } }));
+
+describe('DefaultAwsCredentialsManager', () => {
+ beforeEach(() => {
+ process.env = { ...env };
+ jest.resetAllMocks();
+
+ stsMock = mockClient(STSClient);
+
+ config = new ConfigReader({
+ aws: {
+ accounts: [
+ {
+ accountId: '111111111111',
+ roleName: 'hello',
+ externalId: 'world',
+ },
+ {
+ accountId: '222222222222',
+ roleName: 'hi',
+ partition: 'aws-other',
+ region: 'not-us-east-1',
+ accessKeyId: 'ABC',
+ secretAccessKey: 'EDF',
+ },
+ {
+ accountId: '333333333333',
+ accessKeyId: 'my-access-key',
+ secretAccessKey: 'my-secret-access-key',
+ },
+ {
+ accountId: '444444444444',
+ },
+ {
+ accountId: '555555555555',
+ profile: 'my-profile',
+ },
+ ],
+ accountDefaults: {
+ roleName: 'backstage-role',
+ externalId: 'my-id',
+ },
+ mainAccount: {
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ region: 'ap-northeast-1',
+ },
+ },
+ });
+
+ stsMock.on(GetCallerIdentityCommand).resolvesOnce({
+ Account: '123456789012',
+ });
+
+ stsMock
+ .on(AssumeRoleCommand, {
+ RoleArn: 'arn:aws:iam::111111111111:role/hello',
+ RoleSessionName: 'backstage',
+ ExternalId: 'world',
+ })
+ .resolves({
+ Credentials: {
+ AccessKeyId: 'ACCESS_KEY_ID_1',
+ SecretAccessKey: 'SECRET_ACCESS_KEY_1',
+ SessionToken: 'SESSION_TOKEN_1',
+ Expiration: new Date('2022-01-01'),
+ },
+ });
+
+ stsMock
+ .on(AssumeRoleCommand, {
+ RoleArn: 'arn:aws-other:iam::222222222222:role/hi',
+ RoleSessionName: 'backstage',
+ })
+ .resolves({
+ Credentials: {
+ AccessKeyId: 'ACCESS_KEY_ID_2',
+ SecretAccessKey: 'SECRET_ACCESS_KEY_2',
+ SessionToken: 'SESSION_TOKEN_2',
+ Expiration: new Date('2022-01-02'),
+ },
+ });
+
+ stsMock
+ .on(AssumeRoleCommand, {
+ RoleArn: 'arn:aws:iam::999999999999:role/backstage-role',
+ RoleSessionName: 'backstage',
+ ExternalId: 'my-id',
+ })
+ .resolves({
+ Credentials: {
+ AccessKeyId: 'ACCESS_KEY_ID_9',
+ SecretAccessKey: 'SECRET_ACCESS_KEY_9',
+ SessionToken: 'SESSION_TOKEN_9',
+ Expiration: new Date('2022-01-09'),
+ },
+ });
+
+ process.env.AWS_ACCESS_KEY_ID = 'ACCESS_KEY_ID_10';
+ process.env.AWS_SECRET_ACCESS_KEY = 'SECRET_ACCESS_KEY_10';
+ process.env.AWS_SESSION_TOKEN = 'SESSION_TOKEN_10';
+ process.env.AWS_CREDENTIAL_EXPIRATION = new Date(
+ '2022-01-10',
+ ).toISOString();
+
+ const mockProfile = `[my-profile]
+ aws_access_key_id=ACCESS_KEY_ID_9
+ aws_secret_access_key=SECRET_ACCESS_KEY_9
+ `;
+ (promises.readFile as jest.Mock).mockResolvedValue(mockProfile);
+ });
+
+ afterEach(() => {
+ process.env = env;
+ });
+
+ describe('#getCredentialProvider', () => {
+ it('retrieves assume-role creds for the given account ID and caches the provider', async () => {
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ accountId: '111111111111',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('111111111111');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'ACCESS_KEY_ID_1',
+ secretAccessKey: 'SECRET_ACCESS_KEY_1',
+ sessionToken: 'SESSION_TOKEN_1',
+ expiration: new Date('2022-01-01'),
+ });
+
+ const awsCredentialProvider2 = await provider.getCredentialProvider({
+ accountId: '111111111111',
+ });
+
+ expect(awsCredentialProvider).toBe(awsCredentialProvider2);
+ expect(stsMock).toHaveReceivedCommandTimes(AssumeRoleCommand, 1);
+ });
+
+ it('retrieves assume-role creds in another partition for the given account ID', async () => {
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ accountId: '222222222222',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('222222222222');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'ACCESS_KEY_ID_2',
+ secretAccessKey: 'SECRET_ACCESS_KEY_2',
+ sessionToken: 'SESSION_TOKEN_2',
+ expiration: new Date('2022-01-02'),
+ });
+ });
+
+ it('retrieves assume-role creds for an account using the account defaults', async () => {
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ accountId: '999999999999',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('999999999999');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'ACCESS_KEY_ID_9',
+ secretAccessKey: 'SECRET_ACCESS_KEY_9',
+ sessionToken: 'SESSION_TOKEN_9',
+ expiration: new Date('2022-01-09'),
+ });
+ });
+
+ it('retrieves static creds for the given account ID', async () => {
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ accountId: '333333333333',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('333333333333');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'my-access-key',
+ secretAccessKey: 'my-secret-access-key',
+ });
+ });
+
+ it('retrieves static creds from the main account', async () => {
+ const minConfig = new ConfigReader({
+ aws: {
+ mainAccount: {
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ },
+ },
+ });
+ const provider = DefaultAwsCredentialsManager.fromConfig(minConfig);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ accountId: '123456789012',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('123456789012');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ });
+ });
+
+ it('only queries the main account ID once from STS', async () => {
+ const minConfig = new ConfigReader({
+ aws: {
+ mainAccount: {
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ },
+ },
+ });
+ const provider = DefaultAwsCredentialsManager.fromConfig(minConfig);
+ const awsCredentialProvider1 = await provider.getCredentialProvider({});
+ const awsCredentialProvider2 = await provider.getCredentialProvider({});
+
+ expect(awsCredentialProvider1).toBe(awsCredentialProvider2);
+ expect(stsMock).toHaveReceivedCommandTimes(GetCallerIdentityCommand, 1);
+ });
+
+ it('retrieves the ini provider chain for the given account ID', async () => {
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ accountId: '555555555555',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('555555555555');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'ACCESS_KEY_ID_9',
+ secretAccessKey: 'SECRET_ACCESS_KEY_9',
+ });
+ });
+
+ it('retrieves the default cred provider chain for the given account ID', async () => {
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ accountId: '444444444444',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('444444444444');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'ACCESS_KEY_ID_10',
+ secretAccessKey: 'SECRET_ACCESS_KEY_10',
+ sessionToken: 'SESSION_TOKEN_10',
+ expiration: new Date('2022-01-10'),
+ });
+ });
+
+ it('retrieves ini provider chain from the main account', async () => {
+ const minConfig = new ConfigReader({
+ aws: {
+ mainAccount: {
+ profile: 'my-profile',
+ },
+ },
+ });
+ const provider = DefaultAwsCredentialsManager.fromConfig(minConfig);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ accountId: '123456789012',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('123456789012');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'ACCESS_KEY_ID_9',
+ secretAccessKey: 'SECRET_ACCESS_KEY_9',
+ });
+ });
+
+ it('retrieves default cred provider chain from the main account', async () => {
+ const minConfig = new ConfigReader({
+ aws: {},
+ });
+ const provider = DefaultAwsCredentialsManager.fromConfig(minConfig);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ accountId: '123456789012',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('123456789012');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'ACCESS_KEY_ID_10',
+ secretAccessKey: 'SECRET_ACCESS_KEY_10',
+ sessionToken: 'SESSION_TOKEN_10',
+ expiration: new Date('2022-01-10'),
+ });
+ });
+
+ it('retrieves default cred provider chain from the main account when there is no AWS integration config', async () => {
+ const minConfig = new ConfigReader({});
+ const provider = DefaultAwsCredentialsManager.fromConfig(minConfig);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ accountId: '123456789012',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('123456789012');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'ACCESS_KEY_ID_10',
+ secretAccessKey: 'SECRET_ACCESS_KEY_10',
+ sessionToken: 'SESSION_TOKEN_10',
+ expiration: new Date('2022-01-10'),
+ });
+ });
+
+ it('extracts the account ID from an ARN', async () => {
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ arn: 'arn:aws:ecs:region:111111111111:service/cluster-name/service-name',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('111111111111');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'ACCESS_KEY_ID_1',
+ secretAccessKey: 'SECRET_ACCESS_KEY_1',
+ sessionToken: 'SESSION_TOKEN_1',
+ expiration: new Date('2022-01-01'),
+ });
+ });
+
+ it('falls back to main account credentials when account ID cannot be extracted from the ARN', async () => {
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ const awsCredentialProvider = await provider.getCredentialProvider({
+ arn: 'arn:aws:s3:::bucket_name',
+ });
+
+ expect(awsCredentialProvider.accountId).toEqual('123456789012');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ });
+ });
+
+ it('falls back to main account credentials when neither account ID nor ARN are provided', async () => {
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ const awsCredentialProvider = await provider.getCredentialProvider({});
+
+ expect(awsCredentialProvider.accountId).toEqual('123456789012');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ });
+ });
+
+ it('falls back to main account credentials when no options are provided', async () => {
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ const awsCredentialProvider = await provider.getCredentialProvider();
+
+ expect(awsCredentialProvider.accountId).toEqual('123456789012');
+
+ const creds = await awsCredentialProvider.sdkCredentialProvider();
+ expect(creds).toEqual({
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ });
+ });
+
+ it('rejects account that is not configured, with no account defaults', async () => {
+ const minConfig = new ConfigReader({
+ aws: {},
+ });
+ const provider = DefaultAwsCredentialsManager.fromConfig(minConfig);
+ await expect(
+ provider.getCredentialProvider({ accountId: '111222333444' }),
+ ).rejects.toThrow(/no AWS integration that matches 111222333444/);
+ });
+
+ it('rejects main account that has invalid credentials', async () => {
+ stsMock.on(GetCallerIdentityCommand).rejects('No credentials found');
+ const provider = DefaultAwsCredentialsManager.fromConfig(config);
+ await expect(provider.getCredentialProvider({})).rejects.toThrow(
+ /No credentials found/,
+ );
+ });
+ });
+});
diff --git a/packages/integration-aws-node/src/DefaultAwsCredentialsManager.ts b/packages/integration-aws-node/src/DefaultAwsCredentialsManager.ts
new file mode 100644
index 0000000000..7799f08b4d
--- /dev/null
+++ b/packages/integration-aws-node/src/DefaultAwsCredentialsManager.ts
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ readAwsIntegrationConfig,
+ AwsIntegrationAccountConfig,
+ AwsIntegrationDefaultAccountConfig,
+ AwsIntegrationMainAccountConfig,
+} from './config';
+import {
+ AwsCredentialsManager,
+ AwsCredentialProvider,
+ AwsCredentialProviderOptions,
+} from './types';
+import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';
+import {
+ fromIni,
+ fromNodeProviderChain,
+ fromTemporaryCredentials,
+} from '@aws-sdk/credential-providers';
+import { AwsCredentialIdentityProvider } from '@aws-sdk/types';
+import { parse } from '@aws-sdk/util-arn-parser';
+import { Config } from '@backstage/config';
+
+/**
+ * Retrieves the account ID for the given credential provider from STS.
+ */
+async function fillInAccountId(credProvider: AwsCredentialProvider) {
+ if (credProvider.accountId) {
+ return;
+ }
+
+ const client = new STSClient({
+ region: credProvider.stsRegion,
+ customUserAgent: 'backstage-aws-credentials-manager',
+ credentialDefaultProvider: () => credProvider.sdkCredentialProvider,
+ });
+ const resp = await client.send(new GetCallerIdentityCommand({}));
+ credProvider.accountId = resp.Account!;
+}
+
+function getStaticCredentials(
+ accessKeyId: string,
+ secretAccessKey: string,
+): AwsCredentialIdentityProvider {
+ return async () => {
+ return Promise.resolve({
+ accessKeyId: accessKeyId,
+ secretAccessKey: secretAccessKey,
+ });
+ };
+}
+
+function getProfileCredentials(
+ profile: string,
+ region?: string,
+): AwsCredentialIdentityProvider {
+ return fromIni({
+ profile,
+ clientConfig: {
+ region,
+ customUserAgent: 'backstage-aws-credentials-manager',
+ },
+ });
+}
+
+function getDefaultCredentialsChain(): AwsCredentialIdentityProvider {
+ return fromNodeProviderChain();
+}
+
+/**
+ * Constructs the credential provider needed by the AWS SDK from the given account config
+ *
+ * Order of precedence:
+ * 1. Assume role with static creds
+ * 2. Assume role with main account creds
+ * 3. Static creds
+ * 4. Profile creds
+ * 5. Default AWS SDK creds chain
+ */
+function getSdkCredentialProvider(
+ config: AwsIntegrationAccountConfig,
+ mainAccountCredProvider: AwsCredentialIdentityProvider,
+): AwsCredentialIdentityProvider {
+ if (config.roleName) {
+ const region = config.region ?? 'us-east-1';
+ const partition = config.partition ?? 'aws';
+
+ return fromTemporaryCredentials({
+ masterCredentials: config.accessKeyId
+ ? getStaticCredentials(config.accessKeyId!, config.secretAccessKey!)
+ : mainAccountCredProvider,
+ params: {
+ RoleArn: `arn:${partition}:iam::${config.accountId}:role/${config.roleName}`,
+ RoleSessionName: 'backstage',
+ ExternalId: config.externalId,
+ },
+ clientConfig: {
+ region,
+ customUserAgent: 'backstage-aws-credentials-manager',
+ },
+ });
+ }
+
+ if (config.accessKeyId) {
+ return getStaticCredentials(config.accessKeyId!, config.secretAccessKey!);
+ }
+
+ if (config.profile) {
+ return getProfileCredentials(config.profile!, config.region);
+ }
+
+ return getDefaultCredentialsChain();
+}
+
+/**
+ * Constructs the credential provider needed by the AWS SDK for the main account
+ *
+ * Order of precedence:
+ * 1. Static creds
+ * 2. Profile creds
+ * 3. Default AWS SDK creds chain
+ */
+function getMainAccountSdkCredentialProvider(
+ config: AwsIntegrationMainAccountConfig,
+): AwsCredentialIdentityProvider {
+ if (config.accessKeyId) {
+ return getStaticCredentials(config.accessKeyId!, config.secretAccessKey!);
+ }
+
+ if (config.profile) {
+ return getProfileCredentials(config.profile!, config.region);
+ }
+
+ return getDefaultCredentialsChain();
+}
+
+/**
+ * Handles the creation and caching of credential providers for AWS accounts.
+ *
+ * @public
+ */
+export class DefaultAwsCredentialsManager implements AwsCredentialsManager {
+ static fromConfig(config: Config): DefaultAwsCredentialsManager {
+ const awsConfig = config.has('aws')
+ ? readAwsIntegrationConfig(config.getConfig('aws'))
+ : {
+ accounts: [],
+ mainAccount: {},
+ accountDefaults: {},
+ };
+
+ const mainAccountSdkCredProvider = getMainAccountSdkCredentialProvider(
+ awsConfig.mainAccount,
+ );
+ const mainAccountCredProvider: AwsCredentialProvider = {
+ sdkCredentialProvider: mainAccountSdkCredProvider,
+ };
+
+ const accountCredProviders = new Map();
+ for (const accountConfig of awsConfig.accounts) {
+ const sdkCredentialProvider = getSdkCredentialProvider(
+ accountConfig,
+ mainAccountSdkCredProvider,
+ );
+ accountCredProviders.set(accountConfig.accountId, {
+ accountId: accountConfig.accountId,
+ stsRegion: accountConfig.region,
+ sdkCredentialProvider,
+ });
+ }
+
+ return new DefaultAwsCredentialsManager(
+ accountCredProviders,
+ awsConfig.accountDefaults,
+ mainAccountCredProvider,
+ );
+ }
+
+ private constructor(
+ private readonly accountCredentialProviders: Map<
+ string,
+ AwsCredentialProvider
+ >,
+ private readonly accountDefaults: AwsIntegrationDefaultAccountConfig,
+ private readonly mainAccountCredentialProvider: AwsCredentialProvider,
+ ) {}
+
+ /**
+ * Returns an {@link AwsCredentialProvider} for a given AWS account.
+ *
+ * @example
+ * ```ts
+ * const { provider } = await getCredentialProvider({
+ * accountId: '0123456789012',
+ * })
+ *
+ * const { provider } = await getCredentialProvider({
+ * arn: 'arn:aws:ecs:us-west-2:123456789012:service/my-http-service'
+ * })
+ * ```
+ *
+ * @param opts - the AWS account ID or AWS resource ARN
+ * @returns A promise of {@link AwsCredentialProvider}.
+ */
+ async getCredentialProvider(
+ opts?: AwsCredentialProviderOptions,
+ ): Promise {
+ // If no options provided, fall back to the main account
+ if (!opts) {
+ await fillInAccountId(this.mainAccountCredentialProvider);
+ return this.mainAccountCredentialProvider;
+ }
+
+ // Determine the account ID: either explicitly provided or extracted from the provided ARN
+ let accountId = opts.accountId;
+ if (opts.arn && !accountId) {
+ const arnComponents = parse(opts.arn);
+ accountId = arnComponents.accountId;
+ }
+
+ // If the account ID was not provided (explicitly or in the ARN),
+ // fall back to the main account
+ if (!accountId) {
+ await fillInAccountId(this.mainAccountCredentialProvider);
+ return this.mainAccountCredentialProvider;
+ }
+
+ // Return a cached provider if available
+ if (this.accountCredentialProviders.has(accountId)) {
+ return this.accountCredentialProviders.get(accountId)!;
+ }
+
+ // First, fall back to using the account defaults
+ if (this.accountDefaults.roleName) {
+ const config: AwsIntegrationAccountConfig = {
+ accountId,
+ roleName: this.accountDefaults.roleName,
+ partition: this.accountDefaults.partition,
+ region: this.accountDefaults.region,
+ externalId: this.accountDefaults.externalId,
+ };
+ const sdkCredentialProvider = getSdkCredentialProvider(
+ config,
+ this.mainAccountCredentialProvider.sdkCredentialProvider,
+ );
+ const credProvider: AwsCredentialProvider = {
+ accountId,
+ sdkCredentialProvider,
+ };
+ this.accountCredentialProviders.set(accountId, credProvider);
+ return credProvider;
+ }
+
+ // Then, fall back to using the main account, but only
+ // if the account requested matches the main account ID
+ await fillInAccountId(this.mainAccountCredentialProvider);
+ if (accountId === this.mainAccountCredentialProvider.accountId) {
+ return this.mainAccountCredentialProvider;
+ }
+
+ // Otherwise, the account needs to be explicitly configured in Backstage
+ throw new Error(
+ `There is no AWS integration that matches ${accountId}. Please add a configuration for this AWS account.`,
+ );
+ }
+}
diff --git a/packages/integration-aws-node/src/config.test.ts b/packages/integration-aws-node/src/config.test.ts
new file mode 100644
index 0000000000..f761a8ac14
--- /dev/null
+++ b/packages/integration-aws-node/src/config.test.ts
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Config, ConfigReader } from '@backstage/config';
+import { AwsIntegrationConfig, readAwsIntegrationConfig } from './config';
+
+describe('readAwsIntegrationConfig', () => {
+ function buildConfig(data: Partial): Config {
+ return new ConfigReader(data);
+ }
+
+ it('reads all values', () => {
+ const output = readAwsIntegrationConfig(
+ buildConfig({
+ accounts: [
+ {
+ accountId: '111111111111',
+ accessKeyId: 'ABC',
+ secretAccessKey: 'EDF',
+ roleName: 'hello',
+ partition: 'aws',
+ region: 'us-east-1',
+ externalId: 'world',
+ },
+ {
+ accountId: '222222222222',
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ },
+ {
+ accountId: '333333333333',
+ roleName: 'hi',
+ partition: 'aws-other',
+ region: 'not-us-east-1',
+ externalId: 'there',
+ },
+ {
+ accountId: '444444444444',
+ profile: 'my-profile',
+ },
+ ],
+ accountDefaults: {
+ roleName: 'backstage-role',
+ partition: 'aws',
+ region: 'us-east-1',
+ externalId: 'my-id',
+ },
+ mainAccount: {
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ region: 'ap-northeast-1',
+ },
+ }),
+ );
+ expect(output).toEqual({
+ accounts: [
+ {
+ accountId: '111111111111',
+ accessKeyId: 'ABC',
+ secretAccessKey: 'EDF',
+ roleName: 'hello',
+ partition: 'aws',
+ region: 'us-east-1',
+ externalId: 'world',
+ },
+ {
+ accountId: '222222222222',
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ },
+ {
+ accountId: '333333333333',
+ roleName: 'hi',
+ partition: 'aws-other',
+ region: 'not-us-east-1',
+ externalId: 'there',
+ },
+ {
+ accountId: '444444444444',
+ profile: 'my-profile',
+ },
+ ],
+ accountDefaults: {
+ roleName: 'backstage-role',
+ partition: 'aws',
+ region: 'us-east-1',
+ externalId: 'my-id',
+ },
+ mainAccount: {
+ accessKeyId: 'GHI',
+ secretAccessKey: 'JKL',
+ region: 'ap-northeast-1',
+ },
+ });
+ });
+
+ it('reads profile for main account', () => {
+ const output = readAwsIntegrationConfig(
+ buildConfig({
+ accounts: [
+ {
+ accountId: '111111111111',
+ accessKeyId: 'ABC',
+ secretAccessKey: 'EDF',
+ roleName: 'hello',
+ partition: 'aws',
+ region: 'us-east-1',
+ externalId: 'world',
+ },
+ ],
+ accountDefaults: {
+ roleName: 'backstage-role',
+ partition: 'aws',
+ region: 'us-east-1',
+ externalId: 'my-id',
+ },
+ mainAccount: {
+ profile: 'my-profile',
+ },
+ }),
+ );
+ expect(output).toEqual({
+ accounts: [
+ {
+ accountId: '111111111111',
+ accessKeyId: 'ABC',
+ secretAccessKey: 'EDF',
+ roleName: 'hello',
+ partition: 'aws',
+ region: 'us-east-1',
+ externalId: 'world',
+ },
+ ],
+ accountDefaults: {
+ roleName: 'backstage-role',
+ partition: 'aws',
+ region: 'us-east-1',
+ externalId: 'my-id',
+ },
+ mainAccount: {
+ profile: 'my-profile',
+ },
+ });
+ });
+
+ it('does not fail when config is not set', () => {
+ const output = readAwsIntegrationConfig(buildConfig({}));
+ expect(output).toEqual({
+ accountDefaults: {},
+ accounts: [],
+ mainAccount: {},
+ });
+ });
+
+ it('rejects invalid combinations of account attributes', () => {
+ const validAccount: any = {
+ accountId: '111111111111',
+ accessKeyId: 'ABC',
+ secretAccessKey: 'EDF',
+ roleName: 'hello',
+ partition: 'aws',
+ region: 'us-east-1',
+ externalId: 'world',
+ };
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ accounts: [
+ validAccount,
+ {
+ accountId: '222222222222',
+ accessKeyId: 'ABC',
+ },
+ ],
+ }),
+ ),
+ ).toThrow(/no secret access key/);
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ accounts: [
+ validAccount,
+ {
+ accountId: '222222222222',
+ secretAccessKey: 'ABC',
+ },
+ ],
+ }),
+ ),
+ ).toThrow(/no access key ID/);
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ accounts: [
+ validAccount,
+ {
+ accountId: '222222222222',
+ accessKeyId: 'ABC',
+ secretAccessKey: 'DEF',
+ profile: 'my-profile',
+ },
+ ],
+ }),
+ ),
+ ).toThrow(/only one must be specified/);
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ accounts: [
+ validAccount,
+ {
+ accountId: '222222222222',
+ roleName: 'my-role',
+ profile: 'my-profile',
+ },
+ ],
+ }),
+ ),
+ ).toThrow(/only one must be specified/);
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ accounts: [
+ validAccount,
+ {
+ accountId: '222222222222',
+ partition: 'aws',
+ },
+ ],
+ }),
+ ),
+ ).toThrow(/no role name/);
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ accounts: [
+ validAccount,
+ {
+ accountId: '222222222222',
+ region: 'not-us-east-1',
+ },
+ ],
+ }),
+ ),
+ ).toThrow(/no role name/);
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ accounts: [
+ validAccount,
+ {
+ accountId: '222222222222',
+ externalId: 'hello',
+ },
+ ],
+ }),
+ ),
+ ).toThrow(/no role name/);
+ });
+
+ it('rejects invalid combinations of main account attributes', () => {
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ mainAccount: {
+ accessKeyId: 'ABC',
+ },
+ }),
+ ),
+ ).toThrow(/no secret access key/);
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ mainAccount: {
+ secretAccessKey: 'ABC',
+ },
+ }),
+ ),
+ ).toThrow(/no access key ID/);
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ mainAccount: {
+ accessKeyId: 'ABC',
+ secretAccessKey: 'DEF',
+ profile: 'my-profile',
+ },
+ }),
+ ),
+ ).toThrow(/only one must be specified/);
+ });
+
+ it('rejects invalid combinations of account default attributes', () => {
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ accountDefaults: {
+ partition: 'aws',
+ },
+ }),
+ ),
+ ).toThrow(/no role name/);
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ accountDefaults: {
+ region: 'not-us-east-1',
+ },
+ }),
+ ),
+ ).toThrow(/no role name/);
+ expect(() =>
+ readAwsIntegrationConfig(
+ buildConfig({
+ accountDefaults: {
+ externalId: 'hello',
+ },
+ }),
+ ),
+ ).toThrow(/no role name/);
+ });
+});
diff --git a/packages/integration-aws-node/src/config.ts b/packages/integration-aws-node/src/config.ts
new file mode 100644
index 0000000000..0bc8c0ed06
--- /dev/null
+++ b/packages/integration-aws-node/src/config.ts
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Config } from '@backstage/config';
+
+/**
+ * The configuration parameters for a single AWS account for the AWS integration.
+ *
+ * @public
+ */
+export type AwsIntegrationAccountConfig = {
+ /**
+ * The account ID of the target account that this matches on, e.g. "123456789012"
+ */
+ accountId: string;
+
+ /**
+ * The access key ID for a set of static AWS credentials
+ */
+ accessKeyId?: string;
+
+ /**
+ * The secret access key for a set of static AWS credentials
+ */
+ secretAccessKey?: string;
+
+ /**
+ * The configuration profile from a credentials file at ~/.aws/credentials and
+ * a configuration file at ~/.aws/config.
+ */
+ profile?: string;
+
+ /**
+ * The IAM role to assume to retrieve temporary AWS credentials
+ */
+ roleName?: string;
+
+ /**
+ * The AWS partition of the IAM role, e.g. "aws", "aws-cn"
+ */
+ partition?: string;
+
+ /**
+ * The STS regional endpoint to use when retrieving temporary AWS credentials, e.g. "ap-northeast-1"
+ */
+ region?: string;
+
+ /**
+ * The unique identifier needed to assume the role to retrieve temporary AWS credentials
+ */
+ externalId?: string;
+};
+
+/**
+ * The configuration parameters for the main AWS account for the AWS integration.
+ *
+ * @public
+ */
+export type AwsIntegrationMainAccountConfig = {
+ /**
+ * The access key ID for a set of static AWS credentials
+ */
+ accessKeyId?: string;
+
+ /**
+ * The secret access key for a set of static AWS credentials
+ */
+ secretAccessKey?: string;
+
+ /**
+ * The configuration profile from a credentials file at ~/.aws/credentials and
+ * a configuration file at ~/.aws/config.
+ */
+ profile?: string;
+
+ /**
+ * The STS regional endpoint to use for the main account, e.g. "ap-northeast-1"
+ */
+ region?: string;
+};
+
+/**
+ * The default configuration parameters to use for accounts for the AWS integration.
+ *
+ * @public
+ */
+export type AwsIntegrationDefaultAccountConfig = {
+ /**
+ * The IAM role to assume to retrieve temporary AWS credentials
+ */
+ roleName?: string;
+
+ /**
+ * The AWS partition of the IAM role, e.g. "aws", "aws-cn"
+ */
+ partition?: string;
+
+ /**
+ * The STS regional endpoint to use when retrieving temporary AWS credentials, e.g. "ap-northeast-1"
+ */
+ region?: string;
+
+ /**
+ * The unique identifier needed to assume the role to retrieve temporary AWS credentials
+ */
+ externalId?: string;
+};
+
+/**
+ * The configuration parameters for AWS account integration.
+ *
+ * @public
+ */
+export type AwsIntegrationConfig = {
+ /**
+ * Configuration for retrieving AWS accounts credentials
+ */
+ accounts: AwsIntegrationAccountConfig[];
+
+ /**
+ * Defaults for retrieving AWS account credentials
+ */
+ accountDefaults: AwsIntegrationDefaultAccountConfig;
+
+ /**
+ * Main account to use for retrieving AWS account credentials
+ */
+ mainAccount: AwsIntegrationMainAccountConfig;
+};
+
+/**
+ * Reads an AWS integration account config.
+ *
+ * @param config - The config object of a single account
+ */
+function readAwsIntegrationAccountConfig(
+ config: Config,
+): AwsIntegrationAccountConfig {
+ const accountConfig = {
+ accountId: config.getString('accountId'),
+ accessKeyId: config.getOptionalString('accessKeyId'),
+ secretAccessKey: config.getOptionalString('secretAccessKey'),
+ profile: config.getOptionalString('profile'),
+ roleName: config.getOptionalString('roleName'),
+ region: config.getOptionalString('region'),
+ partition: config.getOptionalString('partition'),
+ externalId: config.getOptionalString('externalId'),
+ };
+
+ // Validate that the account config has the right combination of attributes
+ if (accountConfig.accessKeyId && !accountConfig.secretAccessKey) {
+ throw new Error(
+ `AWS integration account ${accountConfig.accountId} has an access key ID configured, but no secret access key.`,
+ );
+ }
+
+ if (!accountConfig.accessKeyId && accountConfig.secretAccessKey) {
+ throw new Error(
+ `AWS integration account ${accountConfig.accountId} has a secret access key configured, but no access key ID`,
+ );
+ }
+
+ if (accountConfig.profile && accountConfig.accessKeyId) {
+ throw new Error(
+ `AWS integration account ${accountConfig.accountId} has both an access key ID and a profile configured, but only one must be specified`,
+ );
+ }
+
+ if (accountConfig.profile && accountConfig.roleName) {
+ throw new Error(
+ `AWS integration account ${accountConfig.accountId} has both an access key ID and a role name configured, but only one must be specified`,
+ );
+ }
+
+ if (!accountConfig.roleName && accountConfig.externalId) {
+ throw new Error(
+ `AWS integration account ${accountConfig.accountId} has an external ID configured, but no role name.`,
+ );
+ }
+
+ if (!accountConfig.roleName && accountConfig.region) {
+ throw new Error(
+ `AWS integration account ${accountConfig.accountId} has an STS region configured, but no role name.`,
+ );
+ }
+
+ if (!accountConfig.roleName && accountConfig.partition) {
+ throw new Error(
+ `AWS integration account ${accountConfig.accountId} has an IAM partition configured, but no role name.`,
+ );
+ }
+
+ return accountConfig;
+}
+
+/**
+ * Reads the main AWS integration account config.
+ *
+ * @param config - The config object of the main account
+ */
+function readMainAwsIntegrationAccountConfig(
+ config: Config,
+): AwsIntegrationMainAccountConfig {
+ const mainAccountConfig = {
+ accessKeyId: config.getOptionalString('accessKeyId'),
+ secretAccessKey: config.getOptionalString('secretAccessKey'),
+ profile: config.getOptionalString('profile'),
+ region: config.getOptionalString('region'),
+ };
+
+ // Validate that the account config has the right combination of attributes
+ if (mainAccountConfig.accessKeyId && !mainAccountConfig.secretAccessKey) {
+ throw new Error(
+ `The main AWS integration account has an access key ID configured, but no secret access key.`,
+ );
+ }
+
+ if (!mainAccountConfig.accessKeyId && mainAccountConfig.secretAccessKey) {
+ throw new Error(
+ `The main AWS integration account has a secret access key configured, but no access key ID`,
+ );
+ }
+
+ if (mainAccountConfig.profile && mainAccountConfig.accessKeyId) {
+ throw new Error(
+ `The main AWS integration account has both an access key ID and a profile configured, but only one must be specified`,
+ );
+ }
+
+ return mainAccountConfig;
+}
+
+/**
+ * Reads the default settings for retrieving credentials from AWS integration accounts.
+ *
+ * @param config - The config object of the default account settings
+ */
+function readAwsIntegrationAccountDefaultsConfig(
+ config: Config,
+): AwsIntegrationDefaultAccountConfig {
+ const defaultAccountConfig = {
+ roleName: config.getOptionalString('roleName'),
+ partition: config.getOptionalString('partition'),
+ region: config.getOptionalString('region'),
+ externalId: config.getOptionalString('externalId'),
+ };
+
+ // Validate that the account config has the right combination of attributes
+ if (!defaultAccountConfig.roleName && defaultAccountConfig.externalId) {
+ throw new Error(
+ `AWS integration account default configuration has an external ID configured, but no role name.`,
+ );
+ }
+
+ if (!defaultAccountConfig.roleName && defaultAccountConfig.region) {
+ throw new Error(
+ `AWS integration account default configuration has an STS region configured, but no role name.`,
+ );
+ }
+
+ if (!defaultAccountConfig.roleName && defaultAccountConfig.partition) {
+ throw new Error(
+ `AWS integration account default configuration has an IAM partition configured, but no role name.`,
+ );
+ }
+
+ return defaultAccountConfig;
+}
+
+/**
+ * Reads an AWS integration configuration
+ *
+ * @param config - the integration config object
+ * @public
+ */
+export function readAwsIntegrationConfig(config: Config): AwsIntegrationConfig {
+ const accounts = config
+ .getOptionalConfigArray('accounts')
+ ?.map(readAwsIntegrationAccountConfig);
+ const mainAccount = config.has('mainAccount')
+ ? readMainAwsIntegrationAccountConfig(config.getConfig('mainAccount'))
+ : {};
+ const accountDefaults = config.has('accountDefaults')
+ ? readAwsIntegrationAccountDefaultsConfig(
+ config.getConfig('accountDefaults'),
+ )
+ : {};
+
+ return {
+ accounts: accounts ?? [],
+ mainAccount,
+ accountDefaults,
+ };
+}
diff --git a/packages/integration-aws-node/src/index.ts b/packages/integration-aws-node/src/index.ts
new file mode 100644
index 0000000000..30f3e21281
--- /dev/null
+++ b/packages/integration-aws-node/src/index.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { DefaultAwsCredentialsManager } from './DefaultAwsCredentialsManager';
+export type {
+ AwsCredentialsManager,
+ AwsCredentialProvider,
+ AwsCredentialProviderOptions,
+} from './types';
diff --git a/packages/integration-aws-node/src/types.ts b/packages/integration-aws-node/src/types.ts
new file mode 100644
index 0000000000..3ff069b20b
--- /dev/null
+++ b/packages/integration-aws-node/src/types.ts
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { AwsCredentialIdentityProvider } from '@aws-sdk/types';
+
+/**
+ * A set of credentials information for an AWS account.
+ *
+ * @public
+ */
+export type AwsCredentialProvider = {
+ /**
+ * The AWS account ID of these credentials
+ */
+ accountId?: string;
+ /**
+ * The STS region used with these credentials
+ */
+ stsRegion?: string;
+ /**
+ * The credential identity provider to use when creating AWS SDK for Javascript V3 clients
+ */
+ sdkCredentialProvider: AwsCredentialIdentityProvider;
+};
+
+/**
+ * The options for specifying the AWS credentials to retrieve.
+ *
+ * @public
+ */
+export type AwsCredentialProviderOptions = {
+ /**
+ * The AWS account ID, e.g. '0123456789012'
+ */
+ accountId?: string;
+
+ /**
+ * The resource ARN that will be accessed with the returned credentials.
+ * If account ID or region are not specified, they will be inferred from the ARN.
+ */
+ arn?: string;
+};
+
+/**
+ * This allows implementations to be provided to retrieve AWS credentials.
+ *
+ * @public
+ */
+export interface AwsCredentialsManager {
+ /**
+ * Get credentials for an AWS account.
+ */
+ getCredentialProvider(
+ opts?: AwsCredentialProviderOptions,
+ ): Promise;
+}
diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md
index a6eecc5338..d071eaa6a4 100644
--- a/packages/integration-react/CHANGELOG.md
+++ b/packages/integration-react/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/integration-react
+## 1.1.7-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/theme@0.2.16
+
## 1.1.7-next.3
### Patch Changes
diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json
index b02e3dc7f3..8beee2abfb 100644
--- a/packages/integration-react/package.json
+++ b/packages/integration-react/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/integration-react",
"description": "Frontend package for managing integrations towards external systems",
- "version": "1.1.7-next.3",
+ "version": "1.1.7-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md
index 2aa40b7cb3..fd4d1f0f01 100644
--- a/packages/repo-tools/CHANGELOG.md
+++ b/packages/repo-tools/CHANGELOG.md
@@ -1,5 +1,21 @@
# @backstage/repo-tools
+## 0.1.0-next.2
+
+### Patch Changes
+
+- a8611bcac4: Add new command options to the `api-report`
+
+ - added `--allow-warnings`, `-a` to continue processing packages if selected packages have warnings
+ - added `--allow-all-warnings` to continue processing packages any packages have warnings
+ - added `--omit-messages`, `-o` to pass some warnings messages code to be omitted from the api-report.md files
+ - The `paths` argument for this command now takes as default the value on `workspaces.packages` inside the root package.json
+ - change the path resolution to use the `@backstage/cli-common` packages instead
+
+- Updated dependencies
+ - @backstage/cli-common@0.1.11-next.0
+ - @backstage/errors@1.1.4-next.1
+
## 0.1.0-next.1
### Minor Changes
diff --git a/packages/repo-tools/cli-report.md b/packages/repo-tools/cli-report.md
index 309ddad2a3..3378d20ea7 100644
--- a/packages/repo-tools/cli-report.md
+++ b/packages/repo-tools/cli-report.md
@@ -12,7 +12,7 @@ Options:
-h, --help
Commands:
- api-reports [options] [path...]
+ api-reports [options] [paths...]
type-deps
help [command]
```
@@ -20,12 +20,15 @@ Commands:
### `backstage-repo-tools api-reports`
```
-Usage: backstage-repo-tools api-reports [options] [path...]
+Usage: backstage-repo-tools api-reports [options] [paths...]
Options:
--ci
--tsc
--docs
+ -a, --allow-warnings
+ --allow-all-warnings
+ -o, --omit-messages
-h, --help
```
diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json
index a0caa3ee9c..595cbf1196 100644
--- a/packages/repo-tools/package.json
+++ b/packages/repo-tools/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/repo-tools",
"description": "CLI for Backstage repo tooling ",
- "version": "0.1.0-next.1",
+ "version": "0.1.0-next.2",
"publishConfig": {
"access": "public"
},
@@ -30,6 +30,7 @@
"backstage-repo-tools": "bin/backstage-repo-tools"
},
"dependencies": {
+ "@backstage/cli-common": "workspace:^",
"@backstage/errors": "workspace:^",
"@manypkg/get-packages": "^1.1.3",
"@microsoft/api-documenter": "^7.17.11",
@@ -39,8 +40,17 @@
"chalk": "^4.0.0",
"commander": "^9.1.0",
"fs-extra": "10.1.0",
+ "glob": "^8.0.3",
+ "is-glob": "^4.0.3",
+ "minimatch": "^5.1.1",
"ts-node": "^10.0.0"
},
+ "devDependencies": {
+ "@backstage/cli": "workspace:^",
+ "@types/is-glob": "^4.0.2",
+ "@types/mock-fs": "^4.13.0",
+ "mock-fs": "^5.1.0"
+ },
"files": [
"bin",
"dist/**/*.js"
diff --git a/packages/repo-tools/src/commands/api-reports/api-extractor.ts b/packages/repo-tools/src/commands/api-reports/api-extractor.ts
index bae62ccc7e..5ec0804ee8 100644
--- a/packages/repo-tools/src/commands/api-reports/api-extractor.ts
+++ b/packages/repo-tools/src/commands/api-reports/api-extractor.ts
@@ -16,7 +16,6 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-restricted-imports */
-
import {
resolve as resolvePath,
relative as relativePath,
@@ -65,9 +64,10 @@ import {
} from '@microsoft/api-documenter/lib/markdown/CustomMarkdownEmitter';
import { IMarkdownEmitterContext } from '@microsoft/api-documenter/lib/markdown/MarkdownEmitter';
import { AstDeclaration } from '@microsoft/api-extractor/lib/analyzer/AstDeclaration';
+import { paths as cliPaths } from '../../lib/paths';
+import minimatch from 'minimatch';
-const tmpDir = resolvePath(
- process.cwd(),
+const tmpDir = cliPaths.resolveTargetRoot(
'./node_modules/.cache/api-extractor',
);
@@ -219,89 +219,32 @@ ApiReportGenerator.generateReviewFileContent =
});
};
-const PACKAGE_ROOTS = ['packages', 'plugins'];
-
-const ALLOW_WARNINGS = [
- 'packages/core-components',
- 'plugins/catalog',
- 'plugins/catalog-import',
- 'plugins/git-release-manager',
- 'plugins/jenkins',
- 'plugins/kubernetes',
-];
-
-async function resolvePackagePath(
- packagePath: string,
-): Promise {
- const projectRoot = resolvePath(process.cwd());
- const fullPackageDir = resolvePath(projectRoot, packagePath);
-
- const stat = await fs.stat(fullPackageDir);
- if (!stat.isDirectory()) {
- return undefined;
- }
-
- try {
- const packageJsonPath = join(fullPackageDir, 'package.json');
- await fs.access(packageJsonPath);
- } catch (_) {
- return undefined;
- }
-
- return relativePath(projectRoot, fullPackageDir);
-}
-
-export async function findSpecificPackageDirs(unresolvedPackageDirs: string[]) {
- const packageDirs = new Array();
-
- for (const unresolvedPackageDir of unresolvedPackageDirs) {
- const packageDir = await resolvePackagePath(unresolvedPackageDir);
- if (!packageDir) {
- throw new Error(`'${unresolvedPackageDir}' is not a valid package path`);
- }
- packageDirs.push(packageDir);
- }
-
- if (packageDirs.length === 0) {
- return undefined;
- }
-
- return packageDirs;
-}
-
-export async function findPackageDirs() {
- const packageDirs = new Array();
- const projectRoot = resolvePath(process.cwd());
-
- for (const packageRoot of PACKAGE_ROOTS) {
- const dirs = await fs.readdir(resolvePath(projectRoot, packageRoot));
- for (const dir of dirs) {
- const packageDir = await resolvePackagePath(join(packageRoot, dir));
- if (!packageDir) {
- continue;
- }
-
- packageDirs.push(packageDir);
- }
- }
-
- return packageDirs;
-}
-
export async function createTemporaryTsConfig(includedPackageDirs: string[]) {
- const path = resolvePath(process.cwd(), 'tsconfig.tmp.json');
+ const path = cliPaths.resolveTargetRoot('tsconfig.tmp.json');
process.once('exit', () => {
fs.removeSync(path);
});
+ let assetTypeFile: string[] = [];
+
+ try {
+ assetTypeFile = [
+ require.resolve('@backstage/cli/asset-types/asset-types.d.ts'),
+ ];
+ } catch {
+ /** ignore */
+ }
+
await fs.writeJson(path, {
extends: './tsconfig.json',
include: [
// These two contain global definitions that are needed for stable API report generation
- 'packages/cli/asset-types/asset-types.d.ts',
+ ...assetTypeFile,
...includedPackageDirs.map(dir => join(dir, 'src')),
],
+ // we don't exclude node_modules so that we can use the asset-types.d.ts file
+ exclude: [],
});
return path;
@@ -375,6 +318,8 @@ interface ApiExtractionOptions {
outputDir: string;
isLocalBuild: boolean;
tsconfigFilePath: string;
+ allowWarnings?: boolean | string[];
+ omitMessages?: string[];
}
export async function runApiExtraction({
@@ -382,25 +327,37 @@ export async function runApiExtraction({
outputDir,
isLocalBuild,
tsconfigFilePath,
+ allowWarnings = false,
+ omitMessages = [],
}: ApiExtractionOptions) {
await fs.remove(outputDir);
const entryPoints = packageDirs.map(packageDir => {
- return resolvePath(
- process.cwd(),
+ return cliPaths.resolveTargetRoot(
`./dist-types/${packageDir}/src/index.d.ts`,
);
});
let compilerState: CompilerState | undefined = undefined;
+ const allowWarningPkg = Array.isArray(allowWarnings) ? allowWarnings : [];
+
+ const messagesConf: { [key: string]: { logLevel: string } } = {};
+ for (const messageCode of omitMessages) {
+ messagesConf[messageCode] = {
+ logLevel: 'none',
+ };
+ }
const warnings = new Array();
for (const packageDir of packageDirs) {
console.log(`## Processing ${packageDir}`);
- const projectFolder = resolvePath(process.cwd(), packageDir);
- const packageFolder = resolvePath(
- process.cwd(),
+ const noBail = Array.isArray(allowWarnings)
+ ? allowWarnings.some(aw => aw === packageDir || minimatch(packageDir, aw))
+ : allowWarnings;
+
+ const projectFolder = cliPaths.resolveTargetRoot(packageDir);
+ const packageFolder = cliPaths.resolveTargetRoot(
'./dist-types',
packageDir,
);
@@ -453,6 +410,7 @@ export async function runApiExtraction({
logLevel: 'warning' as ExtractorLogLevel.Warning,
addToApiReportFile: true,
},
+ ...messagesConf,
},
tsdocMessageReporting: {
default: {
@@ -543,12 +501,15 @@ export async function runApiExtraction({
}
const warningCountAfter = await countApiReportWarnings(projectFolder);
- if (warningCountAfter > 0 && !ALLOW_WARNINGS.includes(packageDir)) {
+ if (noBail) {
+ console.log(`Skipping warnings check for ${packageDir}`);
+ }
+ if (warningCountAfter > 0 && !noBail) {
throw new Error(
`The API Report for ${packageDir} is not allowed to have warnings`,
);
}
- if (warningCountAfter === 0 && ALLOW_WARNINGS.includes(packageDir)) {
+ if (warningCountAfter === 0 && allowWarningPkg.includes(packageDir)) {
console.log(
`No need to allow warnings for ${packageDir}, it does not have any`,
);
@@ -879,7 +840,9 @@ export async function buildDocs({
context.writer.writeLine('---');
for (const [name, value] of Object.entries(node.values)) {
if (value) {
- context.writer.writeLine(`${name}: ${value}`);
+ context.writer.writeLine(
+ `${name}: "${String(value).replace(/\"/g, '')}"`,
+ );
}
}
context.writer.writeLine('---');
@@ -1131,10 +1094,7 @@ export async function buildDocs({
documenter.generateFiles();
}
-export async function categorizePackageDirs(
- projectRoot: string,
- packageDirs: any[],
-) {
+export async function categorizePackageDirs(packageDirs: any[]) {
const dirs = packageDirs.slice();
const tsPackageDirs = new Array();
const cliPackageDirs = new Array();
@@ -1150,7 +1110,7 @@ export async function categorizePackageDirs(
}
const pkgJson = await fs
- .readJson(resolvePath(projectRoot, dir, 'package.json'))
+ .readJson(cliPaths.resolveTargetRoot(dir, 'package.json'))
.catch(error => {
if (error.code === 'ENOENT') {
return undefined;
@@ -1204,6 +1164,7 @@ function parseHelpPage(helpPageContent: string) {
let options = new Array();
let commands = new Array();
+ let commandArguments = new Array();
while (lines.length > 0) {
while (lines.length > 0 && !lines[0].endsWith(':')) {
@@ -1228,6 +1189,8 @@ function parseHelpPage(helpPageContent: string) {
options = sectionItems;
} else if (sectionName?.toLocaleLowerCase('en-US') === 'commands:') {
commands = sectionItems;
+ } else if (sectionName?.toLocaleLowerCase('en-US') === 'arguments:') {
+ commandArguments = sectionItems;
} else {
throw new Error(`Unknown CLI section: ${sectionName}`);
}
@@ -1238,6 +1201,7 @@ function parseHelpPage(helpPageContent: string) {
usage,
options,
commands,
+ commandArguments,
};
}
@@ -1249,6 +1213,7 @@ interface CliHelpPage {
usage: string | undefined;
options: string[];
commands: string[];
+ commandArguments: string[];
}
async function exploreCliHelpPages(
@@ -1316,19 +1281,17 @@ function generateCliReport(name: string, models: CliModel[]): string {
}
interface CliExtractionOptions {
- projectRoot: string;
packageDirs: string[];
isLocalBuild: boolean;
}
export async function runCliExtraction({
- projectRoot,
packageDirs,
isLocalBuild,
}: CliExtractionOptions) {
for (const packageDir of packageDirs) {
console.log(`## Processing ${packageDir}`);
- const fullDir = resolvePath(projectRoot, packageDir);
+ const fullDir = cliPaths.resolveTargetRoot(packageDir);
const pkgJson = await fs.readJson(resolvePath(fullDir, 'package.json'));
if (!pkgJson.bin) {
@@ -1371,7 +1334,7 @@ export async function runCliExtraction({
console.log('');
console.log(
`The conflicting file is ${relativePath(
- projectRoot,
+ cliPaths.targetRoot,
reportPath,
)}, expecting the following content:`,
);
diff --git a/packages/repo-tools/src/commands/api-reports/api-reports.test.ts b/packages/repo-tools/src/commands/api-reports/api-reports.test.ts
new file mode 100644
index 0000000000..7121d8a06f
--- /dev/null
+++ b/packages/repo-tools/src/commands/api-reports/api-reports.test.ts
@@ -0,0 +1,467 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import mockFs from 'mock-fs';
+import { resolve as resolvePath } from 'path';
+import * as pathsLib from '../../lib/paths';
+
+import {
+ buildDocs,
+ runCliExtraction,
+ runApiExtraction,
+ categorizePackageDirs,
+} from './api-extractor';
+
+import { buildApiReports } from './api-reports';
+import { generateTypeDeclarations } from './generateTypeDeclarations';
+
+jest.mock('./generateTypeDeclarations');
+// create mocks for the dependencies of the `buildApiReports` function
+jest.mock('./api-extractor', () => ({
+ createTemporaryTsConfig: jest.fn(),
+ categorizePackageDirs: jest.fn().mockImplementation(async (p: string[]) => {
+ console.log('categorizePackageDirs', p);
+ return {
+ tsPackageDirs: p,
+ cliPackageDirs: p,
+ };
+ }),
+ runApiExtraction: jest.fn(),
+ runCliExtraction: jest.fn(),
+ buildDocs: jest.fn(),
+}));
+
+const projectPaths = pathsLib.paths;
+
+jest.spyOn(projectPaths, 'targetRoot', 'get').mockReturnValue('/root');
+jest.spyOn(projectPaths, 'resolveTargetRoot').mockImplementation((...path) => {
+ return resolvePath('/root', ...path);
+});
+
+describe('buildApiReports', () => {
+ beforeEach(() => {
+ mockFs({
+ [projectPaths.targetRoot]: {
+ 'package.json': JSON.stringify({
+ workspaces: { packages: ['packages/*', 'plugins/*'] },
+ }),
+ packages: {
+ 'package-a': {
+ 'package.json': '{}',
+ },
+ 'package-b': {
+ 'package.json': '{}',
+ },
+ 'package-c': {},
+ 'README.md': 'Hello World',
+ },
+ plugins: {
+ 'plugin-a': {
+ 'package.json': '{}',
+ },
+ 'plugin-b': {
+ 'package.json': '{}',
+ },
+ 'plugin-c': {
+ 'package.json': '{}',
+ },
+ },
+ },
+ });
+ });
+
+ afterEach(() => {
+ mockFs.restore();
+ jest.clearAllMocks();
+ });
+ it('should run whitout any options', async () => {
+ const opts = {};
+ const paths: string[] = [];
+
+ await buildApiReports(paths, opts);
+
+ expect(categorizePackageDirs).toHaveBeenCalledWith([
+ 'packages/package-a',
+ 'packages/package-b',
+ 'plugins/plugin-a',
+ 'plugins/plugin-b',
+ 'plugins/plugin-c',
+ ]);
+
+ expect(generateTypeDeclarations).not.toHaveBeenCalled();
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: [
+ 'packages/package-a',
+ 'packages/package-b',
+ 'plugins/plugin-a',
+ 'plugins/plugin-b',
+ 'plugins/plugin-c',
+ ],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: [],
+ omitMessages: [],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ expect(runCliExtraction).toHaveBeenCalledWith({
+ packageDirs: [
+ 'packages/package-a',
+ 'packages/package-b',
+ 'plugins/plugin-a',
+ 'plugins/plugin-b',
+
+ 'plugins/plugin-c',
+ ],
+ isLocalBuild: true,
+ });
+
+ expect(buildDocs).not.toHaveBeenCalled();
+ });
+
+ describe('paths', () => {
+ it('should generate API reports for one specific package', async () => {
+ const paths = ['packages/package-a'];
+ const opts = {};
+
+ await buildApiReports(paths, opts);
+
+ expect(categorizePackageDirs).toHaveBeenCalledWith([
+ 'packages/package-a',
+ ]);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: [],
+ omitMessages: [],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ expect(runCliExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a'],
+ isLocalBuild: true,
+ });
+
+ expect(buildDocs).not.toHaveBeenCalled();
+ });
+ it('should generate API reports for multiple specific packages', async () => {
+ const paths = ['packages/package-a', 'packages/package-b'];
+ const opts = {};
+
+ await buildApiReports(paths, opts);
+
+ expect(categorizePackageDirs).toHaveBeenCalledWith([
+ 'packages/package-a',
+ 'packages/package-b',
+ ]);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: [],
+ omitMessages: [],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ expect(runCliExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ isLocalBuild: true,
+ });
+
+ expect(buildDocs).not.toHaveBeenCalled();
+ });
+ it('should generate API reports for all packages matching the glob pattern', async () => {
+ const paths = ['packages/*'];
+ const opts = {};
+
+ await buildApiReports(paths, opts);
+
+ expect(categorizePackageDirs).toHaveBeenCalledWith([
+ 'packages/package-a',
+ 'packages/package-b',
+ ]);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: [],
+ omitMessages: [],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ expect(runCliExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ isLocalBuild: true,
+ });
+
+ expect(buildDocs).not.toHaveBeenCalled();
+ });
+
+ it('should generate API reports for all packages matching multiple glob patterns', async () => {
+ const paths = ['packages/*', 'plugins/*a'];
+ const opts = {};
+
+ await buildApiReports(paths, opts);
+
+ expect(categorizePackageDirs).toHaveBeenCalledWith([
+ 'packages/package-a',
+ 'packages/package-b',
+ 'plugins/plugin-a',
+ ]);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: [
+ 'packages/package-a',
+ 'packages/package-b',
+ 'plugins/plugin-a',
+ ],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: [],
+ omitMessages: [],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ expect(runCliExtraction).toHaveBeenCalledWith({
+ packageDirs: [
+ 'packages/package-a',
+ 'packages/package-b',
+ 'plugins/plugin-a',
+ ],
+ isLocalBuild: true,
+ });
+
+ expect(buildDocs).not.toHaveBeenCalled();
+ });
+
+ it('should generate API reports for specific packages and glob pattern', async () => {
+ const opts = {};
+ const paths = ['packages/package-a', 'plugins/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(categorizePackageDirs).toHaveBeenCalledWith([
+ 'packages/package-a',
+ 'plugins/plugin-a',
+ 'plugins/plugin-b',
+ 'plugins/plugin-c',
+ ]);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: [
+ 'packages/package-a',
+ 'plugins/plugin-a',
+ 'plugins/plugin-b',
+ 'plugins/plugin-c',
+ ],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: [],
+ omitMessages: [],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ expect(runCliExtraction).toHaveBeenCalledWith({
+ packageDirs: [
+ 'packages/package-a',
+ 'plugins/plugin-a',
+ 'plugins/plugin-b',
+ 'plugins/plugin-c',
+ ],
+ isLocalBuild: true,
+ });
+
+ expect(buildDocs).not.toHaveBeenCalled();
+ });
+ });
+ describe('allowWarnings', () => {
+ it('should accept single path value', async () => {
+ const opts = {
+ allowWarnings: 'packages/package-a',
+ };
+ const paths = ['packages/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: ['packages/package-a'],
+ omitMessages: [],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ });
+
+ it('should accept multiple path values as comma separated string', async () => {
+ const opts = {
+ allowWarnings: 'packages/package-a,packages/package-b',
+ };
+ const paths = ['packages/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: ['packages/package-a', 'packages/package-b'],
+ omitMessages: [],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ });
+
+ it('should accept multiple path values as comma separated string with spaces', async () => {
+ const opts = {
+ allowWarnings: 'packages/package-a, packages/package-b',
+ };
+ const paths = ['packages/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: ['packages/package-a', 'packages/package-b'],
+ omitMessages: [],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ });
+ });
+ describe('allowAllWarnings', () => {
+ it('should accept boolean values', async () => {
+ const opts = {
+ allowAllWarnings: true,
+ };
+ const paths = ['packages/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: true,
+ omitMessages: [],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ });
+ });
+ describe('omitMessages', () => {
+ it('should accept single message value', async () => {
+ const opts = {
+ omitMessages: 'ae-missing-release-tag',
+ };
+ const paths = ['packages/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: [],
+ omitMessages: ['ae-missing-release-tag'],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ });
+
+ it('should accept multiple message values as comma separated string', async () => {
+ const opts = {
+ omitMessages: 'ae-missing-release-tag,ae-missing-annotations',
+ };
+ const paths = ['packages/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: [],
+ omitMessages: ['ae-missing-release-tag', 'ae-missing-annotations'],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ });
+
+ it('should accept multiple message values as comma separated string with spaces', async () => {
+ const opts = {
+ omitMessages: 'ae-missing-release-tag, ae-missing-annotations',
+ };
+ const paths = ['packages/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: [],
+ omitMessages: ['ae-missing-release-tag', 'ae-missing-annotations'],
+ isLocalBuild: true,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ });
+ });
+ describe('isCI', () => {
+ it('should set localBuild to false if CI option is passed', async () => {
+ const opts = {
+ ci: true,
+ };
+ const paths = ['packages/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(runApiExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ tsconfigFilePath: '/root/tsconfig.json',
+ allowWarnings: [],
+ omitMessages: [],
+ isLocalBuild: false,
+ outputDir: '/root/node_modules/.cache/api-extractor',
+ });
+ expect(runCliExtraction).toHaveBeenCalledWith({
+ packageDirs: ['packages/package-a', 'packages/package-b'],
+ isLocalBuild: false,
+ });
+ });
+ });
+ describe('docs', () => {
+ it('should run typedoc if docs option is passed', async () => {
+ const opts = {
+ docs: true,
+ };
+ const paths = ['packages/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(buildDocs).toHaveBeenCalledWith({
+ inputDir: '/root/node_modules/.cache/api-extractor',
+ outputDir: '/root/docs/reference',
+ });
+ });
+ });
+ describe('tsc', () => {
+ it('should run tsc if tsc option is passed', async () => {
+ const opts = {
+ tsc: true,
+ };
+ const paths = ['packages/*'];
+
+ await buildApiReports(paths, opts);
+
+ expect(generateTypeDeclarations).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/packages/repo-tools/src/commands/api-reports/api-reports.ts b/packages/repo-tools/src/commands/api-reports/api-reports.ts
index 3ac740d596..6270072912 100644
--- a/packages/repo-tools/src/commands/api-reports/api-reports.ts
+++ b/packages/repo-tools/src/commands/api-reports/api-reports.ts
@@ -15,44 +15,52 @@
*/
import { OptionValues } from 'commander';
-import { resolve as resolvePath } from 'path';
import fs from 'fs-extra';
-import { spawnSync } from 'child_process';
import {
- findSpecificPackageDirs,
createTemporaryTsConfig,
- findPackageDirs,
categorizePackageDirs,
runApiExtraction,
runCliExtraction,
buildDocs,
} from './api-extractor';
+import { findPackageDirs, paths as cliPaths } from '../../lib/paths';
+import { generateTypeDeclarations } from './generateTypeDeclarations';
-export default async (paths: string[], opts: OptionValues) => {
- const tmpDir = resolvePath(
- process.cwd(),
+type Options = {
+ ci?: boolean;
+ docs?: boolean;
+ tsc?: boolean;
+ allowWarnings?: string;
+ allowAllWarnings?: boolean;
+ omitMessages?: string;
+} & OptionValues;
+
+export const buildApiReports = async (paths: string[] = [], opts: Options) => {
+ const tmpDir = cliPaths.resolveTargetRoot(
'./node_modules/.cache/api-extractor',
);
- const projectRoot = resolvePath(process.cwd());
+
const isCiBuild = opts.ci;
const isDocsBuild = opts.docs;
const runTsc = opts.tsc;
+ const allowWarnings = parseArrayOption(opts.allowWarnings);
+ const allowAllWarnings = opts.allowAllWarnings;
+ const omitMessages = parseArrayOption(opts.omitMessages);
- const selectedPackageDirs = await findSpecificPackageDirs(paths);
+ const isAllPackages = !paths?.length;
+ const selectedPaths = isAllPackages
+ ? await getWorkspacePackagePathPatterns()
+ : paths;
+ const selectedPackageDirs = await findPackageDirs(selectedPaths);
- if (selectedPackageDirs && isCiBuild) {
- throw new Error(
- 'Package path arguments are not supported together with the --ci flag',
- );
- }
- if (!selectedPackageDirs && !isCiBuild && !isDocsBuild) {
+ if (isAllPackages && !isCiBuild && !isDocsBuild) {
console.log('');
console.log(
'TIP: You can generate api-reports for select packages by passing package paths:',
);
console.log('');
console.log(
- ' yarn build:api-reports packages/config packages/core-plugin-api',
+ ' yarn build:api-reports packages/config packages/core-plugin-api plugins/*',
);
console.log('');
}
@@ -62,34 +70,15 @@ export default async (paths: string[], opts: OptionValues) => {
temporaryTsConfigPath = await createTemporaryTsConfig(selectedPackageDirs);
}
const tsconfigFilePath =
- temporaryTsConfigPath ?? resolvePath(projectRoot, 'tsconfig.json');
+ temporaryTsConfigPath ?? cliPaths.resolveTargetRoot('tsconfig.json');
if (runTsc) {
- await fs.remove(resolvePath(projectRoot, 'dist-types'));
- const { status } = spawnSync(
- 'yarn',
- [
- 'tsc',
- ['--project', tsconfigFilePath],
- ['--skipLibCheck', 'false'],
- ['--incremental', 'false'],
- ].flat(),
- {
- stdio: 'inherit',
- shell: true,
- cwd: projectRoot,
- },
- );
- if (status !== 0) {
- process.exit(status || undefined);
- }
+ console.log('# Compiling TypeScript');
+ await generateTypeDeclarations(tsconfigFilePath);
}
- const packageDirs = selectedPackageDirs ?? (await findPackageDirs());
-
const { tsPackageDirs, cliPackageDirs } = await categorizePackageDirs(
- projectRoot,
- packageDirs,
+ selectedPackageDirs,
);
if (tsPackageDirs.length > 0) {
@@ -99,12 +88,13 @@ export default async (paths: string[], opts: OptionValues) => {
outputDir: tmpDir,
isLocalBuild: !isCiBuild,
tsconfigFilePath,
+ allowWarnings: allowAllWarnings || allowWarnings,
+ omitMessages: Array.isArray(omitMessages) ? omitMessages : [],
});
}
if (cliPackageDirs.length > 0) {
console.log('# Generating package CLI reports');
await runCliExtraction({
- projectRoot,
packageDirs: cliPackageDirs,
isLocalBuild: !isCiBuild,
});
@@ -114,7 +104,48 @@ export default async (paths: string[], opts: OptionValues) => {
console.log('# Generating package documentation');
await buildDocs({
inputDir: tmpDir,
- outputDir: resolvePath(projectRoot, 'docs/reference'),
+ outputDir: cliPaths.resolveTargetRoot('docs/reference'),
});
}
};
+
+/**
+ * Retrieves the list of package names in the "workspaces" field of the `package.json` file in the current workspace root.
+ *
+ * If the file does not exist, or the "workspaces" field is not present, returns `undefined`.
+ *
+ * @returns {Promise} The list of package names, or `undefined` if not found.
+ */
+async function getWorkspacePackagePathPatterns() {
+ const pkgJson = await fs
+ .readJson(cliPaths.resolveTargetRoot('package.json'))
+ .catch(error => {
+ if (error.code === 'ENOENT') {
+ return undefined;
+ }
+ throw error;
+ });
+ const workspaces = pkgJson?.workspaces?.packages;
+ return workspaces;
+}
+
+/**
+ * Splits the input string on comma, and returns an array of the resulting substrings.
+ * for `undefined` or an empty string, returns an empty array.
+ *
+ * @param value A string to be split on comma.
+ * @returns An array of the resulting substrings, or an empty array if the input value is `undefined` or an empty string.
+ *
+ * @example
+ * parseOption('foo,bar,baz')
+ * // returns ['foo', 'bar', 'baz']
+ *
+ * parseOption('')
+ * // returns []
+ *
+ * parseOption()
+ * // returns []
+ */
+function parseArrayOption(value: string | undefined) {
+ return value ? value.split(',').map(s => s.trim()) : [];
+}
diff --git a/packages/repo-tools/src/commands/api-reports/generateTypeDeclarations.ts b/packages/repo-tools/src/commands/api-reports/generateTypeDeclarations.ts
new file mode 100644
index 0000000000..58f4117bc2
--- /dev/null
+++ b/packages/repo-tools/src/commands/api-reports/generateTypeDeclarations.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import fs from 'fs-extra';
+import { spawnSync } from 'child_process';
+import { paths as cliPaths } from '../../lib/paths';
+
+/**
+ * Generates the TypeScript declaration files for the specified project, using the provided `tsconfig.json` file.
+ *
+ * Any existing declaration files in the `dist-types` directory will be deleted before generating the new ones.
+ *
+ * If the `tsc` command exits with a non-zero exit code, the process will be terminated with the same exit code.
+ *
+ * @param tsconfigFilePath {string} The path to the `tsconfig.json` file to use for generating the declaration files.
+ * @returns {Promise} A promise that resolves when the declaration files have been generated.
+ */
+
+export async function generateTypeDeclarations(tsconfigFilePath: string) {
+ await fs.remove(cliPaths.resolveTargetRoot('dist-types'));
+ const { status } = spawnSync(
+ 'yarn',
+ [
+ 'tsc',
+ ['--project', tsconfigFilePath],
+ ['--skipLibCheck', 'false'],
+ ['--incremental', 'false'],
+ ].flat(),
+ {
+ stdio: 'inherit',
+ shell: true,
+ cwd: cliPaths.targetRoot,
+ },
+ );
+ if (status !== 0) {
+ process.exit(status || undefined);
+ }
+}
diff --git a/packages/repo-tools/src/commands/index.ts b/packages/repo-tools/src/commands/index.ts
index ebbcb5be8e..f7a16b6d4e 100644
--- a/packages/repo-tools/src/commands/index.ts
+++ b/packages/repo-tools/src/commands/index.ts
@@ -20,13 +20,28 @@ import { exitWithError } from '../lib/errors';
export function registerCommands(program: Command) {
program
- .command('api-reports [path...]')
+ .command('api-reports [paths...]')
.option('--ci', 'CI run checks that there is no changes on API reports')
.option('--tsc', 'executes the tsc compilation before extracting the APIs')
.option('--docs', 'generates the api documentation')
+ .option(
+ '-a, --allow-warnings ',
+ 'continue processing packages after getting errors on selected packages Allows glob patterns and comma separated values (i.e. packages/core,plugins/core-*)',
+ )
+ .option(
+ '--allow-all-warnings',
+ 'continue processing packages after getting errors on all packages',
+ false,
+ )
+ .option(
+ '-o, --omit-messages ',
+ 'select some message code to be omited on the API Extractor (comma separated values i.e ae-cyclic-inherit-doc,ae-missing-getter )',
+ )
.description('Generate an API report for selected packages')
.action(
- lazy(() => import('./api-reports/api-reports').then(m => m.default)),
+ lazy(() =>
+ import('./api-reports/api-reports').then(m => m.buildApiReports),
+ ),
);
program
diff --git a/packages/repo-tools/src/lib/paths.test.ts b/packages/repo-tools/src/lib/paths.test.ts
new file mode 100644
index 0000000000..c642900612
--- /dev/null
+++ b/packages/repo-tools/src/lib/paths.test.ts
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import mockFs from 'mock-fs';
+import { resolve as resolvePath } from 'path';
+import { resolvePackagePath, paths, findPackageDirs } from './paths';
+
+describe('paths', () => {
+ jest.spyOn(paths, 'targetRoot', 'get').mockReturnValue('/root');
+ jest.spyOn(paths, 'resolveTargetRoot').mockImplementation((...path) => {
+ return resolvePath('/root', ...path);
+ });
+
+ beforeEach(() => {
+ mockFs({
+ [paths.targetRoot]: {
+ 'package.json': JSON.stringify({ name: 'test' }),
+ packages: {
+ 'package-a': {
+ 'package.json': '{}',
+ },
+ 'package-b': {
+ 'package.json': '{}',
+ },
+ 'package-c': {},
+ 'README.md': 'Hello World',
+ },
+ plugins: {
+ 'plugin-a': {
+ 'package.json': '{}',
+ },
+ 'plugin-b': {
+ 'package.json': '{}',
+ },
+ },
+ },
+ });
+ });
+
+ afterEach(() => {
+ mockFs.restore();
+ });
+
+ describe('resolvePackagePath', () => {
+ it('should return undefined if the package does not exist or does not contain a package.json', async () => {
+ expect(await resolvePackagePath('packages/package-d')).toBeUndefined();
+ expect(await resolvePackagePath('packages/package-c')).toBeUndefined();
+ });
+ it('should return the path to the package if it exists and has a package.json', async () => {
+ expect(await resolvePackagePath('packages/package-a')).toBe(
+ 'packages/package-a',
+ );
+ expect(await resolvePackagePath('packages/package-b')).toBe(
+ 'packages/package-b',
+ );
+ });
+ it('should work with absolute paths', async () => {
+ expect(await resolvePackagePath('/root/packages/package-a')).toBe(
+ 'packages/package-a',
+ );
+ });
+ it('should return undefined if the pat is not a directory', async () => {
+ expect(await resolvePackagePath('packages/README.md')).toBeUndefined();
+ });
+ });
+ describe('findPackageDirs', () => {
+ it('should return only the given packages', async () => {
+ expect(await findPackageDirs(['packages/package-a'])).toEqual([
+ 'packages/package-a',
+ ]);
+ });
+ it('should return only the given packages when using glob patterns', async () => {
+ expect(await findPackageDirs(['packages/*'])).toEqual([
+ 'packages/package-a',
+ 'packages/package-b',
+ ]);
+ expect(await findPackageDirs(['packages/*', 'plugins/*'])).toEqual([
+ 'packages/package-a',
+ 'packages/package-b',
+ 'plugins/plugin-a',
+ 'plugins/plugin-b',
+ ]);
+ });
+ it('should return only the given packages when using absolute paths', async () => {
+ expect(
+ await findPackageDirs([
+ '/root/packages/package-a',
+ '/root/plugins/plugin-b',
+ ]),
+ ).toEqual(['packages/package-a', 'plugins/plugin-b']);
+ });
+ it('should return only the given packages when using absolute paths with glob patterns', async () => {
+ expect(
+ await findPackageDirs(['/root/packages/*', '/root/plugins/*-a']),
+ ).toEqual([
+ 'packages/package-a',
+ 'packages/package-b',
+ 'plugins/plugin-a',
+ ]);
+ });
+ });
+});
diff --git a/packages/repo-tools/src/lib/paths.ts b/packages/repo-tools/src/lib/paths.ts
new file mode 100644
index 0000000000..874bb48ea1
--- /dev/null
+++ b/packages/repo-tools/src/lib/paths.ts
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2020 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { findPaths } from '@backstage/cli-common';
+import { relative as relativePath, join } from 'path';
+import fs from 'fs-extra';
+
+import g from 'glob';
+import isGlob from 'is-glob';
+
+import { promisify } from 'util';
+
+const glob = promisify(g);
+
+/* eslint-disable-next-line no-restricted-syntax */
+export const paths = findPaths(__dirname);
+
+export async function resolvePackagePath(
+ packagePath: string,
+): Promise {
+ const fullPackageDir = paths.resolveTargetRoot(packagePath);
+
+ try {
+ const stat = await fs.stat(fullPackageDir);
+ if (!stat.isDirectory()) {
+ return undefined;
+ }
+
+ const packageJsonPath = join(fullPackageDir, 'package.json');
+
+ await fs.access(packageJsonPath);
+ } catch (e) {
+ console.log(`folder omitted: ${fullPackageDir}, cause: ${e}`);
+ return undefined;
+ }
+ return relativePath(paths.targetRoot, fullPackageDir);
+}
+
+export async function findPackageDirs(selectedPaths: string[] = []) {
+ const packageDirs = new Array();
+ for (const packageRoot of selectedPaths) {
+ const fullPath = paths.resolveTargetRoot(packageRoot);
+
+ // if the path contain any glob notation we resolve all the paths to process one by one
+ const dirs = isGlob(fullPath) ? await glob(fullPath) : [fullPath];
+ for (const dir of dirs) {
+ const packageDir = await resolvePackagePath(dir);
+ if (!packageDir) {
+ continue;
+ }
+ packageDirs.push(packageDir);
+ }
+ }
+ return packageDirs;
+}
diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md
index 0b63f7ff48..5eddfdb4af 100644
--- a/packages/techdocs-cli-embedded-app/CHANGELOG.md
+++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md
@@ -1,5 +1,24 @@
# techdocs-cli-embedded-app
+## 0.2.77-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.22.0-next.4
+ - @backstage/core-app-api@1.3.0-next.4
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/app-defaults@1.0.9-next.4
+ - @backstage/test-utils@1.2.3-next.4
+ - @backstage/plugin-catalog@1.7.0-next.4
+ - @backstage/plugin-techdocs@1.4.1-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-techdocs-react@1.0.7-next.4
+
## 0.2.77-next.3
### Patch Changes
diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json
index c37057523b..b30faba062 100644
--- a/packages/techdocs-cli-embedded-app/package.json
+++ b/packages/techdocs-cli-embedded-app/package.json
@@ -1,6 +1,6 @@
{
"name": "techdocs-cli-embedded-app",
- "version": "0.2.77-next.3",
+ "version": "0.2.77-next.4",
"private": true,
"backstage": {
"role": "frontend"
@@ -25,7 +25,6 @@
"history": "^5.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
- "react-router": "^6.3.0",
"react-router-dom": "^6.3.0",
"react-use": "^17.2.4"
},
diff --git a/packages/techdocs-cli-embedded-app/src/App.tsx b/packages/techdocs-cli-embedded-app/src/App.tsx
index 194d26943d..95675954e1 100644
--- a/packages/techdocs-cli-embedded-app/src/App.tsx
+++ b/packages/techdocs-cli-embedded-app/src/App.tsx
@@ -15,7 +15,7 @@
*/
import React from 'react';
-import { Navigate, Route } from 'react-router';
+import { Navigate, Route } from 'react-router-dom';
import {
DefaultTechDocsHome,
diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md
index b2de160260..f3661fdcb3 100644
--- a/packages/techdocs-cli/CHANGELOG.md
+++ b/packages/techdocs-cli/CHANGELOG.md
@@ -1,5 +1,16 @@
# @techdocs/cli
+## 1.2.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/plugin-techdocs-node@1.4.3-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/cli-common@0.1.11-next.0
+ - @backstage/config@1.0.5-next.1
+
## 1.2.4-next.2
### Patch Changes
diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json
index 5071786f2a..59a5f229c1 100644
--- a/packages/techdocs-cli/package.json
+++ b/packages/techdocs-cli/package.json
@@ -1,7 +1,7 @@
{
"name": "@techdocs/cli",
"description": "Utility CLI for managing TechDocs sites in Backstage.",
- "version": "1.2.4-next.2",
+ "version": "1.2.4-next.3",
"publishConfig": {
"access": "public"
},
diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md
index 767be564ac..b1d10ceba5 100644
--- a/packages/test-utils/CHANGELOG.md
+++ b/packages/test-utils/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/test-utils
+## 1.2.3-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-app-api@1.3.0-next.4
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-permission-react@0.4.8-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+ - @backstage/types@1.0.2-next.1
+
## 1.2.3-next.3
### Patch Changes
diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json
index 4a74b30975..5772a52a79 100644
--- a/packages/test-utils/package.json
+++ b/packages/test-utils/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/test-utils",
"description": "Utilities to test Backstage plugins and apps.",
- "version": "1.2.3-next.3",
+ "version": "1.2.3-next.4",
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -52,7 +52,6 @@
"@types/react": "^16.13.1 || ^17.0.0",
"react": "^16.13.1 || ^17.0.0",
"react-dom": "^16.13.1 || ^17.0.0",
- "react-router": "6.0.0-beta.0 || ^6.3.0",
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
},
"devDependencies": {
diff --git a/packages/test-utils/src/testUtils/appWrappers.test.tsx b/packages/test-utils/src/testUtils/appWrappers.test.tsx
index a116c8c781..19bdc15a48 100644
--- a/packages/test-utils/src/testUtils/appWrappers.test.tsx
+++ b/packages/test-utils/src/testUtils/appWrappers.test.tsx
@@ -26,7 +26,7 @@ import {
import { withLogCollector } from './logCollector';
import { render } from '@testing-library/react';
import React, { useEffect } from 'react';
-import { Route, Routes } from 'react-router';
+import { Route, Routes } from 'react-router-dom';
import { MockErrorApi } from './apis';
import { renderInTestApp, wrapInTestApp } from './appWrappers';
import { TestApiProvider } from './TestApiProvider';
diff --git a/packages/test-utils/src/testUtils/appWrappers.tsx b/packages/test-utils/src/testUtils/appWrappers.tsx
index a19fe53301..6543f8b698 100644
--- a/packages/test-utils/src/testUtils/appWrappers.tsx
+++ b/packages/test-utils/src/testUtils/appWrappers.tsx
@@ -15,7 +15,7 @@
*/
import React, { ComponentType, ReactNode, ReactElement } from 'react';
-import { MemoryRouter } from 'react-router';
+import { MemoryRouter } from 'react-router-dom';
import { Route } from 'react-router-dom';
import { lightTheme } from '@backstage/theme';
import { ThemeProvider } from '@material-ui/core/styles';
diff --git a/plugins/adr-backend/CHANGELOG.md b/plugins/adr-backend/CHANGELOG.md
index 3f682ac3eb..9362a2b186 100644
--- a/plugins/adr-backend/CHANGELOG.md
+++ b/plugins/adr-backend/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/plugin-adr-backend
+## 0.2.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-adr-common@0.2.4-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+
## 0.2.4-next.2
### Patch Changes
diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json
index 7ba5db64ea..66886415f3 100644
--- a/plugins/adr-backend/package.json
+++ b/plugins/adr-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-adr-backend",
- "version": "0.2.4-next.2",
+ "version": "0.2.4-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/adr-common/CHANGELOG.md b/plugins/adr-common/CHANGELOG.md
index df119b6c9c..f86a76b60f 100644
--- a/plugins/adr-common/CHANGELOG.md
+++ b/plugins/adr-common/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-adr-common
+## 0.2.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-search-common@1.2.0-next.3
+
## 0.2.4-next.2
### Patch Changes
diff --git a/plugins/adr-common/package.json b/plugins/adr-common/package.json
index 6d37447b5f..595576a9fd 100644
--- a/plugins/adr-common/package.json
+++ b/plugins/adr-common/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-adr-common",
"description": "Common functionalities for the adr plugin",
- "version": "0.2.4-next.2",
+ "version": "0.2.4-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/adr/CHANGELOG.md b/plugins/adr/CHANGELOG.md
index f14d99abfc..a50b409573 100644
--- a/plugins/adr/CHANGELOG.md
+++ b/plugins/adr/CHANGELOG.md
@@ -1,5 +1,20 @@
# @backstage/plugin-adr
+## 0.2.4-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/plugin-search-react@1.3.0-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/integration-react@1.1.7-next.4
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-adr-common@0.2.4-next.3
+ - @backstage/plugin-search-common@1.2.0-next.3
+
## 0.2.4-next.3
### Patch Changes
diff --git a/plugins/adr/package.json b/plugins/adr/package.json
index b519ba8372..21e7ddd3ac 100644
--- a/plugins/adr/package.json
+++ b/plugins/adr/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-adr",
- "version": "0.2.4-next.3",
+ "version": "0.2.4-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md
index 93849c9168..8c5a191cdb 100644
--- a/plugins/airbrake-backend/CHANGELOG.md
+++ b/plugins/airbrake-backend/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-airbrake-backend
+## 0.2.12-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+
## 0.2.12-next.2
### Patch Changes
diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json
index 8c7febf282..fcb6a0da7d 100644
--- a/plugins/airbrake-backend/package.json
+++ b/plugins/airbrake-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-airbrake-backend",
- "version": "0.2.12-next.2",
+ "version": "0.2.12-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md
index 93afadaa8b..5ea2fd489e 100644
--- a/plugins/airbrake/CHANGELOG.md
+++ b/plugins/airbrake/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/plugin-airbrake
+## 0.3.12-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/dev-utils@1.0.9-next.4
+ - @backstage/test-utils@1.2.3-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
## 0.3.12-next.3
### Patch Changes
diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json
index a21a528790..9845329e11 100644
--- a/plugins/airbrake/package.json
+++ b/plugins/airbrake/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-airbrake",
- "version": "0.3.12-next.3",
+ "version": "0.3.12-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -36,7 +36,7 @@
},
"peerDependencies": {
"react": "^16.13.1 || ^17.0.0",
- "react-router": "6.0.0-beta.0 || ^6.3.0"
+ "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
},
"devDependencies": {
"@backstage/app-defaults": "workspace:^",
diff --git a/plugins/airbrake/src/extensions.test.tsx b/plugins/airbrake/src/extensions.test.tsx
index fd41f36930..b24b7febf8 100644
--- a/plugins/airbrake/src/extensions.test.tsx
+++ b/plugins/airbrake/src/extensions.test.tsx
@@ -15,7 +15,7 @@
*/
import React from 'react';
import { EntityAirbrakeContent } from './extensions';
-import { Route, Routes } from 'react-router';
+import { Route, Routes } from 'react-router-dom';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { airbrakeApiRef, MockAirbrakeApi } from './api';
import { createEntity } from './api';
diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md
index 762cdb5dfa..b5cb6574be 100644
--- a/plugins/allure/CHANGELOG.md
+++ b/plugins/allure/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-allure
+## 0.1.28-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
## 0.1.28-next.3
### Patch Changes
diff --git a/plugins/allure/package.json b/plugins/allure/package.json
index e9508a7b6d..e701545143 100644
--- a/plugins/allure/package.json
+++ b/plugins/allure/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-allure",
"description": "A Backstage plugin that integrates with Allure",
- "version": "0.1.28-next.3",
+ "version": "0.1.28-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md
index e8bd871c02..5a15ff77d5 100644
--- a/plugins/analytics-module-ga/CHANGELOG.md
+++ b/plugins/analytics-module-ga/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-analytics-module-ga
+## 0.1.23-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
## 0.1.23-next.3
### Patch Changes
diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json
index 8ed399e76d..9e8aacf5a0 100644
--- a/plugins/analytics-module-ga/package.json
+++ b/plugins/analytics-module-ga/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-analytics-module-ga",
- "version": "0.1.23-next.3",
+ "version": "0.1.23-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md
index b256f705d7..6eebd97f62 100644
--- a/plugins/apache-airflow/CHANGELOG.md
+++ b/plugins/apache-airflow/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-apache-airflow
+## 0.2.5-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+
## 0.2.5-next.3
### Patch Changes
diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json
index 871a068e04..2a346b7831 100644
--- a/plugins/apache-airflow/package.json
+++ b/plugins/apache-airflow/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-apache-airflow",
- "version": "0.2.5-next.3",
+ "version": "0.2.5-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md
index 53b807d0e8..bb842a1d64 100644
--- a/plugins/api-docs/CHANGELOG.md
+++ b/plugins/api-docs/CHANGELOG.md
@@ -1,5 +1,18 @@
# @backstage/plugin-api-docs
+## 0.8.12-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog@1.7.0-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
## 0.8.12-next.3
### Patch Changes
diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json
index b8e336a058..6bf928a82f 100644
--- a/plugins/api-docs/package.json
+++ b/plugins/api-docs/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-api-docs",
"description": "A Backstage plugin that helps represent API entities in the frontend",
- "version": "0.8.12-next.3",
+ "version": "0.8.12-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -52,7 +52,6 @@
"peerDependencies": {
"@types/react": "^16.13.1 || ^17.0.0",
"react": "^16.13.1 || ^17.0.0",
- "react-router": "6.0.0-beta.0 || ^6.3.0",
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
},
"devDependencies": {
diff --git a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx
index 760d1ab59d..ea091f75f0 100644
--- a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx
+++ b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx
@@ -16,11 +16,11 @@
import React from 'react';
import { renderInTestApp } from '@backstage/test-utils';
-import { useOutlet } from 'react-router';
+import { useOutlet } from 'react-router-dom';
import { ApiExplorerPage } from './ApiExplorerPage';
-jest.mock('react-router', () => ({
- ...jest.requireActual('react-router'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useOutlet: jest.fn().mockReturnValue('Route Children'),
}));
diff --git a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx
index 68ab0a1647..1d5d3b359e 100644
--- a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx
+++ b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx
@@ -15,7 +15,7 @@
*/
import React from 'react';
-import { useOutlet } from 'react-router';
+import { useOutlet } from 'react-router-dom';
import {
DefaultApiExplorerPage,
DefaultApiExplorerPageProps,
diff --git a/plugins/apollo-explorer/CHANGELOG.md b/plugins/apollo-explorer/CHANGELOG.md
index cf1f0431c4..7bbd7e60a5 100644
--- a/plugins/apollo-explorer/CHANGELOG.md
+++ b/plugins/apollo-explorer/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-apollo-explorer
+## 0.1.5-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
## 0.1.5-next.3
### Patch Changes
diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json
index c380aa1796..8e52a4e8be 100644
--- a/plugins/apollo-explorer/package.json
+++ b/plugins/apollo-explorer/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-apollo-explorer",
- "version": "0.1.5-next.3",
+ "version": "0.1.5-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md
index 1871be8415..2ab60bf1ee 100644
--- a/plugins/app-backend/CHANGELOG.md
+++ b/plugins/app-backend/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-app-backend
+## 0.3.39-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/config-loader@1.1.7-next.2
+ - @backstage/types@1.0.2-next.1
+
## 0.3.39-next.2
### Patch Changes
diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json
index e63c5a461b..a77ed9a80b 100644
--- a/plugins/app-backend/package.json
+++ b/plugins/app-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-app-backend",
"description": "A Backstage backend plugin that serves the Backstage frontend app",
- "version": "0.3.39-next.2",
+ "version": "0.3.39-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md
index 530da18d43..55c4fcc2a3 100644
--- a/plugins/auth-backend/CHANGELOG.md
+++ b/plugins/auth-backend/CHANGELOG.md
@@ -1,5 +1,18 @@
# @backstage/plugin-auth-backend
+## 0.17.2-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+
## 0.17.2-next.2
### Patch Changes
diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json
index 9a2da89434..c52c116de5 100644
--- a/plugins/auth-backend/package.json
+++ b/plugins/auth-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-auth-backend",
"description": "A Backstage backend plugin that handles authentication",
- "version": "0.17.2-next.2",
+ "version": "0.17.2-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md
index 1a91628a71..f383c720be 100644
--- a/plugins/auth-node/CHANGELOG.md
+++ b/plugins/auth-node/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-auth-node
+## 0.2.8-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+
## 0.2.8-next.2
### Patch Changes
diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json
index 3b7386af08..8b1b621e00 100644
--- a/plugins/auth-node/package.json
+++ b/plugins/auth-node/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-auth-node",
- "version": "0.2.8-next.2",
+ "version": "0.2.8-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md
index 4c8e00e148..642756a96f 100644
--- a/plugins/azure-devops-backend/CHANGELOG.md
+++ b/plugins/azure-devops-backend/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-azure-devops-backend
+## 0.3.18-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-azure-devops-common@0.3.0
+
## 0.3.18-next.2
### Patch Changes
diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json
index bac9e7c628..da9a498e59 100644
--- a/plugins/azure-devops-backend/package.json
+++ b/plugins/azure-devops-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-azure-devops-backend",
- "version": "0.3.18-next.2",
+ "version": "0.3.18-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md
index 61d21d4cae..70dfc9c842 100644
--- a/plugins/azure-devops/CHANGELOG.md
+++ b/plugins/azure-devops/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/plugin-azure-devops
+## 0.2.3-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-azure-devops-common@0.3.0
+
## 0.2.3-next.3
### Patch Changes
diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json
index 876778a7fb..4ad62ae759 100644
--- a/plugins/azure-devops/package.json
+++ b/plugins/azure-devops/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-azure-devops",
- "version": "0.2.3-next.3",
+ "version": "0.2.3-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -44,7 +44,7 @@
},
"peerDependencies": {
"react": "^16.13.1 || ^17.0.0",
- "react-router": "6.0.0-beta.0 || ^6.3.0"
+ "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
},
"devDependencies": {
"@backstage/cli": "workspace:^",
diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.stories.tsx b/plugins/azure-devops/src/components/BuildTable/BuildTable.stories.tsx
index 63d646b06a..b4ce0b1664 100644
--- a/plugins/azure-devops/src/components/BuildTable/BuildTable.stories.tsx
+++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.stories.tsx
@@ -21,7 +21,7 @@ import {
} from '@backstage/plugin-azure-devops-common';
import { BuildTable } from './BuildTable';
-import { MemoryRouter } from 'react-router';
+import { MemoryRouter } from 'react-router-dom';
import React from 'react';
export default {
diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestCard/PullRequestCard.stories.tsx b/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestCard/PullRequestCard.stories.tsx
index b948b616bd..6e6630c943 100644
--- a/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestCard/PullRequestCard.stories.tsx
+++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestCard/PullRequestCard.stories.tsx
@@ -22,7 +22,7 @@ import {
PullRequestVoteStatus,
} from '@backstage/plugin-azure-devops-common';
-import { MemoryRouter } from 'react-router';
+import { MemoryRouter } from 'react-router-dom';
import { PullRequestCard } from './PullRequestCard';
import React from 'react';
diff --git a/plugins/azure-sites-backend/CHANGELOG.md b/plugins/azure-sites-backend/CHANGELOG.md
index b04a3142bf..41bdef289b 100644
--- a/plugins/azure-sites-backend/CHANGELOG.md
+++ b/plugins/azure-sites-backend/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-azure-sites-backend
+## 0.1.1-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-azure-sites-common@0.1.0
+
## 0.1.1-next.2
### Patch Changes
diff --git a/plugins/azure-sites-backend/package.json b/plugins/azure-sites-backend/package.json
index 4078afdd49..66a0020123 100644
--- a/plugins/azure-sites-backend/package.json
+++ b/plugins/azure-sites-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-azure-sites-backend",
- "version": "0.1.1-next.2",
+ "version": "0.1.1-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/azure-sites/CHANGELOG.md b/plugins/azure-sites/CHANGELOG.md
index f9c9a8bcaf..a8a2561b3f 100644
--- a/plugins/azure-sites/CHANGELOG.md
+++ b/plugins/azure-sites/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-azure-sites
+## 0.1.1-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+ - @backstage/plugin-azure-sites-common@0.1.0
+
## 0.1.1-next.3
### Patch Changes
diff --git a/plugins/azure-sites/package.json b/plugins/azure-sites/package.json
index 47a8645167..50a5c968d3 100644
--- a/plugins/azure-sites/package.json
+++ b/plugins/azure-sites/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-azure-sites",
- "version": "0.1.1-next.3",
+ "version": "0.1.1-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md
index 467029a6ee..15ed919bab 100644
--- a/plugins/badges-backend/CHANGELOG.md
+++ b/plugins/badges-backend/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-badges-backend
+## 0.1.33-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+
## 0.1.33-next.2
### Patch Changes
diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json
index 9068f93455..30e3f822e0 100644
--- a/plugins/badges-backend/package.json
+++ b/plugins/badges-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-badges-backend",
"description": "A Backstage backend plugin that generates README badges for your entities",
- "version": "0.1.33-next.2",
+ "version": "0.1.33-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md
index 04d9864678..03e2200057 100644
--- a/plugins/badges/CHANGELOG.md
+++ b/plugins/badges/CHANGELOG.md
@@ -1,5 +1,18 @@
# @backstage/plugin-badges
+## 0.2.36-next.4
+
+### Patch Changes
+
+- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`.
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/theme@0.2.16
+
## 0.2.36-next.3
### Patch Changes
diff --git a/plugins/badges/package.json b/plugins/badges/package.json
index e2da4e4081..acd0f10520 100644
--- a/plugins/badges/package.json
+++ b/plugins/badges/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-badges",
"description": "A Backstage plugin that generates README badges for your entities",
- "version": "0.2.36-next.3",
+ "version": "0.2.36-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -42,7 +42,7 @@
},
"peerDependencies": {
"react": "^16.13.1 || ^17.0.0",
- "react-router": "6.0.0-beta.0 || ^6.3.0"
+ "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
},
"devDependencies": {
"@backstage/cli": "workspace:^",
diff --git a/plugins/badges/src/api/BadgesClient.ts b/plugins/badges/src/api/BadgesClient.ts
index f63003dc90..9a89806d56 100644
--- a/plugins/badges/src/api/BadgesClient.ts
+++ b/plugins/badges/src/api/BadgesClient.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { generatePath } from 'react-router';
+import { generatePath } from 'react-router-dom';
import { ResponseError } from '@backstage/errors';
import { Entity, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
import { BadgesApi, BadgeSpec } from './types';
diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md
index 1676925800..37c6b898f1 100644
--- a/plugins/bazaar-backend/CHANGELOG.md
+++ b/plugins/bazaar-backend/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-bazaar-backend
+## 0.2.2-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-test-utils@0.1.31-next.4
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-auth-node@0.2.8-next.3
+
## 0.2.2-next.3
### Patch Changes
diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json
index 64d2aaa4ca..5ee4031f46 100644
--- a/plugins/bazaar-backend/package.json
+++ b/plugins/bazaar-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-bazaar-backend",
- "version": "0.2.2-next.3",
+ "version": "0.2.2-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md
index ae0098a52c..45c1516778 100644
--- a/plugins/bazaar/CHANGELOG.md
+++ b/plugins/bazaar/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/plugin-bazaar
+## 0.2.1-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.22.0-next.4
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog@1.7.0-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/errors@1.1.4-next.1
+
## 0.2.1-next.3
### Patch Changes
diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json
index c155fd875b..39d5d82a68 100644
--- a/plugins/bazaar/package.json
+++ b/plugins/bazaar/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-bazaar",
- "version": "0.2.1-next.3",
+ "version": "0.2.1-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/bitbucket-cloud-common/bitbucket-cloud.oas.json b/plugins/bitbucket-cloud-common/bitbucket-cloud.oas.json
index 843d009265..9de3c5f9b3 100644
--- a/plugins/bitbucket-cloud-common/bitbucket-cloud.oas.json
+++ b/plugins/bitbucket-cloud-common/bitbucket-cloud.oas.json
@@ -711,96 +711,6 @@
},
"parameters": []
},
- "/repositories/{workspace_slug}/{repo_slug}/override-settings": {
- "get": {
- "tags": ["Repositories"],
- "description": "",
- "summary": "Retrieve the inheritance state for repository settings",
- "responses": {
- "200": {
- "description": "The repository setting inheritance state",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/repository_inheritance_state"
- }
- }
- }
- },
- "404": {
- "description": "If no repository exists at this location",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/error"
- }
- }
- }
- }
- },
- "security": [
- {
- "oauth2": ["repository:admin"]
- },
- {
- "basic": []
- },
- {
- "api_key": []
- }
- ]
- },
- "put": {
- "tags": ["Repositories"],
- "description": "",
- "summary": "Set the inheritance state for repository settings\n ",
- "responses": {
- "204": {
- "description": "The repository setting inheritance state was set and no content returned"
- },
- "404": {
- "description": "If no repository exists at this location",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/error"
- }
- }
- }
- }
- },
- "security": [
- {
- "oauth2": ["repository:admin"]
- },
- {
- "basic": []
- },
- {
- "api_key": []
- }
- ]
- },
- "parameters": [
- {
- "name": "repo_slug",
- "in": "path",
- "description": "This can either be the repository slug or the UUID of the repository,\nsurrounded by curly-braces, for example: `{repository UUID}`.\n",
- "required": true,
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "workspace_slug",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ]
- },
"/repositories/{workspace}": {
"get": {
"tags": ["Repositories"],
@@ -3641,7 +3551,7 @@
"/repositories/{workspace}/{repo_slug}/default-reviewers": {
"get": {
"tags": ["Pullrequests"],
- "description": "Returns the repository's default reviewers.\n\nThese are the users that are automatically added as reviewers on every\nnew pull request that is created.",
+ "description": "Returns the repository's default reviewers.\n\nThese are the users that are automatically added as reviewers on every\nnew pull request that is created. To obtain the repository's default reviewers\nas well as the default reviewers inherited from the project, use the\n[effective-default-reveiwers](#api-repositories-workspace-repo-slug-effective-default-reviewers-get) endpoint.",
"summary": "List default reviewers",
"responses": {
"200": {
@@ -5050,6 +4960,66 @@
}
]
},
+ "/repositories/{workspace}/{repo_slug}/effective-default-reviewers": {
+ "get": {
+ "tags": ["Pullrequests"],
+ "description": "Returns the repository's effective default reviewers. This includes both default\nreviewers defined at the repository level as well as those inherited from its project.\n\nThese are the users that are automatically added as reviewers on every\nnew pull request that is created.\n\n```\n$ curl https://api.bitbucket.org/2.0/repositories/{workspace_slug}/{repo_slug}/effective-default-reviewers?page=1&pagelen=20\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"user\": {\n \"display_name\": \"Patrick Wolf\",\n \"uuid\": \"{9565301a-a3cf-4b5d-88f4-dd6af8078d7e}\"\n },\n \"reviewer_type\": \"project\",\n \"type\": \"default_reviewer\",\n },\n {\n \"user\": {\n \"display_name\": \"Davis Lee\",\n \"uuid\": \"{f0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6}\"\n },\n \"reviewer_type\": \"repository\",\n \"type\": \"default_reviewer\",\n }\n ],\n \"page\": 1,\n \"size\": 2\n}\n```",
+ "summary": "List effective default reviewers",
+ "responses": {
+ "200": {
+ "description": "The paginated list of effective default reviewers",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/paginated_default_reviewer_and_type"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "If the authenticated user does not have access to view the default reviewers",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/error"
+ }
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "oauth2": ["pullrequest"]
+ },
+ {
+ "basic": []
+ },
+ {
+ "api_key": []
+ }
+ ]
+ },
+ "parameters": [
+ {
+ "name": "repo_slug",
+ "in": "path",
+ "description": "This can either be the repository slug or the UUID of the repository,\nsurrounded by curly-braces, for example: `{repository UUID}`.\n",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "workspace",
+ "in": "path",
+ "description": "This can either be the workspace ID (slug) or the workspace UUID\nsurrounded by curly-braces, for example: `{workspace UUID}`.\n",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ },
"/repositories/{workspace}/{repo_slug}/environments/": {
"get": {
"tags": ["Deployments"],
@@ -7788,6 +7758,97 @@
}
]
},
+ "/repositories/{workspace}/{repo_slug}/override-settings": {
+ "get": {
+ "tags": ["Repositories"],
+ "description": "",
+ "summary": "Retrieve the inheritance state for repository settings",
+ "responses": {
+ "200": {
+ "description": "The repository setting inheritance state",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/repository_inheritance_state"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "If no repository exists at this location",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/error"
+ }
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "oauth2": ["repository:admin"]
+ },
+ {
+ "basic": []
+ },
+ {
+ "api_key": []
+ }
+ ]
+ },
+ "put": {
+ "tags": ["Repositories"],
+ "description": "",
+ "summary": "Set the inheritance state for repository settings\n ",
+ "responses": {
+ "204": {
+ "description": "The repository setting inheritance state was set and no content returned"
+ },
+ "404": {
+ "description": "If no repository exists at this location",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/error"
+ }
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "oauth2": ["repository:admin"]
+ },
+ {
+ "basic": []
+ },
+ {
+ "api_key": []
+ }
+ ]
+ },
+ "parameters": [
+ {
+ "name": "repo_slug",
+ "in": "path",
+ "description": "This can either be the repository slug or the UUID of the repository,\nsurrounded by curly-braces, for example: `{repository UUID}`.\n",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "workspace",
+ "in": "path",
+ "description": "This can either be the workspace ID (slug) or the workspace UUID\nsurrounded by curly-braces, for example: `{workspace UUID}`.\n",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ },
"/repositories/{workspace}/{repo_slug}/patch/{spec}": {
"get": {
"tags": ["Commits"],
@@ -8075,6 +8136,16 @@
}
}
},
+ "402": {
+ "description": "You have reached your plan's user limit and must upgrade before giving access to additional users.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/error"
+ }
+ }
+ }
+ },
"403": {
"description": "The requesting user isn't an admin of the repository, or the authentication method was not via app password.",
"content": {
@@ -8141,7 +8212,7 @@
"/repositories/{workspace}/{repo_slug}/permissions-config/users": {
"get": {
"tags": ["Repositories"],
- "description": "Returns a paginated list of explicit user permissions for the given repository.\n\nExample:\n\n```\n$ curl https://api.bitbucket.org/2.0/repositories/atlassian_tutorial/geordi/permissions-config/users\n\n{\n \"pagelen\": 10,\n \"values\": [\n {\n \"type\": \"repository_user_permission\",\n \"user\": {\n \"type\": \"user\",\n \"display_name\": \"Colin Cameron\",\n \"uuid\": \"{d301aafa-d676-4ee0-88be-962be7417567}\",\n \"account_id\": \"557058:ba8948b2-49da-43a9-9e8b-e7249b8e324a\"\n },\n \"permission\": \"admin\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian_tutorial/geordi/\n permissions-config/users/557058:ba8948b2-49da-43a9-9e8b-e7249b8e324a\"\n }\n }\n },\n {\n \"type\": \"repository_user_permission\",\n \"user\": {\n \"type\": \"user\",\n \"display_name\": \"Sean Conaty\",\n \"uuid\": \"{504c3b62-8120-4f0c-a7bc-87800b9d6f70}\",\n \"account_id\": \"557058:ba8948b2-49da-43a9-9e8b-e7249b8e324c\"\n },\n \"permission\": \"write\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0//repositories/atlassian_tutorial/geordi/\n permissions-config/users/557058:ba8948b2-49da-43a9-9e8b-e7249b8e324c\"\n }\n }\n }\n ],\n \"page\": 1,\n \"size\": 2\n}\n```",
+ "description": "Returns a paginated list of explicit user permissions for the given repository.\nThis endpoint does not support BBQL features.\n\nExample:\n\n```\n$ curl https://api.bitbucket.org/2.0/repositories/atlassian_tutorial/geordi/permissions-config/users\n\n{\n \"pagelen\": 10,\n \"values\": [\n {\n \"type\": \"repository_user_permission\",\n \"user\": {\n \"type\": \"user\",\n \"display_name\": \"Colin Cameron\",\n \"uuid\": \"{d301aafa-d676-4ee0-88be-962be7417567}\",\n \"account_id\": \"557058:ba8948b2-49da-43a9-9e8b-e7249b8e324a\"\n },\n \"permission\": \"admin\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian_tutorial/geordi/\n permissions-config/users/557058:ba8948b2-49da-43a9-9e8b-e7249b8e324a\"\n }\n }\n },\n {\n \"type\": \"repository_user_permission\",\n \"user\": {\n \"type\": \"user\",\n \"display_name\": \"Sean Conaty\",\n \"uuid\": \"{504c3b62-8120-4f0c-a7bc-87800b9d6f70}\",\n \"account_id\": \"557058:ba8948b2-49da-43a9-9e8b-e7249b8e324c\"\n },\n \"permission\": \"write\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0//repositories/atlassian_tutorial/geordi/\n permissions-config/users/557058:ba8948b2-49da-43a9-9e8b-e7249b8e324c\"\n }\n }\n }\n ],\n \"page\": 1,\n \"size\": 2\n}\n```",
"summary": "List explicit user permissions for a repository",
"responses": {
"200": {
@@ -8175,7 +8246,7 @@
}
},
"404": {
- "description": "No repository exists for the given repo slug and workspace.",
+ "description": "No repository exists for the given repository slug and workspace.",
"content": {
"application/json": {
"schema": {
@@ -8363,6 +8434,16 @@
}
}
},
+ "402": {
+ "description": "You have reached your plan's user limit and must upgrade before giving access to additional users.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/error"
+ }
+ }
+ }
+ },
"403": {
"description": "The requesting user isn't an admin of the repository, or the authentication method was not via app password.",
"content": {
@@ -8374,7 +8455,7 @@
}
},
"404": {
- "description": "One or more of the workspace, repo, and selected user doesn't exist for the given identifiers.",
+ "description": "One or more of the workspace, repository, and selected user doesn't exist for the given identifiers.",
"content": {
"application/json": {
"schema": {
@@ -10847,7 +10928,7 @@
"/repositories/{workspace}/{repo_slug}/pullrequests/activity": {
"get": {
"tags": ["Pullrequests"],
- "description": "Returns a paginated list of the pull request's activity log.\n\nThis handler serves both a v20 and internal endpoint. The v20 endpoint\nreturns reviewer comments, updates, approvals and request changes. The internal\nendpoint includes those plus tasks and attachments.\n\nComments created on a file or a line of code have an inline property.\n\nComment example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"comment\": {\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695/comments/118571088\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695/_/diff#comment-118571088\"\n }\n },\n \"deleted\": false,\n \"pullrequest\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n },\n \"content\": {\n \"raw\": \"inline with to a dn from lines\",\n \"markup\": \"markdown\",\n \"html\": \"inline with to a dn from lines
\",\n \"type\": \"rendered\"\n },\n \"created_on\": \"2019-09-27T00:33:46.039178+00:00\",\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"created_on\": \"2019-09-27T00:33:46.039178+00:00\",\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"updated_on\": \"2019-09-27T00:33:46.055384+00:00\",\n \"inline\": {\n \"context_lines\": \"\",\n \"to\": null,\n \"path\": \"\",\n \"outdated\": false,\n \"from\": 211\n },\n \"type\": \"pullrequest_comment\",\n \"id\": 118571088\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```\n\nUpdates include a state property of OPEN, MERGED, or DECLINED.\n\nUpdate example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"update\": {\n \"description\": \"\",\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\",\n \"destination\": {\n \"commit\": {\n \"type\": \"commit\",\n \"hash\": \"6a2c16e4a152\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/commit/6a2c16e4a152\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/commits/6a2c16e4a152\"\n }\n }\n },\n \"branch\": {\n \"name\": \"master\"\n },\n \"repository\": {\n \"name\": \"Atlaskit-MK-2\",\n \"type\": \"repository\",\n \"full_name\": \"atlassian/atlaskit-mk-2\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2\"\n },\n \"avatar\": {\n \"href\": \"https://bytebucket.org/ravatar/%7B%7D?ts=js\"\n }\n },\n \"uuid\": \"{}\"\n }\n },\n \"reason\": \"\",\n \"source\": {\n \"commit\": {\n \"type\": \"commit\",\n \"hash\": \"728c8bad1813\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/commit/728c8bad1813\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/commits/728c8bad1813\"\n }\n }\n },\n \"branch\": {\n \"name\": \"username/NONE-add-onClick-prop-for-accessibility\"\n },\n \"repository\": {\n \"name\": \"Atlaskit-MK-2\",\n \"type\": \"repository\",\n \"full_name\": \"atlassian/atlaskit-mk-2\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2\"\n },\n \"avatar\": {\n \"href\": \"https://bytebucket.org/ravatar/%7B%7D?ts=js\"\n }\n },\n \"uuid\": \"{}\"\n }\n },\n \"state\": \"OPEN\",\n \"author\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"date\": \"2019-05-10T06:48:25.305565+00:00\"\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```\n\nApproval example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"approval\": {\n \"date\": \"2019-09-27T00:37:19.849534+00:00\",\n \"pullrequest\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n },\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n }\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```",
+ "description": "Returns a paginated list of the pull request's activity log.\n\nThis handler serves both a v20 and internal endpoint. The v20 endpoint\nreturns reviewer comments, updates, approvals and request changes. The internal\nendpoint includes those plus tasks and attachments.\n\nComments created on a file or a line of code have an inline property.\n\nComment example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"comment\": {\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695/comments/118571088\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695/_/diff#comment-118571088\"\n }\n },\n \"deleted\": false,\n \"pullrequest\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n },\n \"content\": {\n \"raw\": \"inline with to a dn from lines\",\n \"markup\": \"markdown\",\n \"html\": \"inline with to a dn from lines
\",\n \"type\": \"rendered\"\n },\n \"created_on\": \"2019-09-27T00:33:46.039178+00:00\",\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"created_on\": \"2019-09-27T00:33:46.039178+00:00\",\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"updated_on\": \"2019-09-27T00:33:46.055384+00:00\",\n \"inline\": {\n \"context_lines\": \"\",\n \"to\": null,\n \"path\": \"\",\n \"outdated\": false,\n \"from\": 211\n },\n \"type\": \"pullrequest_comment\",\n \"id\": 118571088\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```\n\nUpdates include a state property of OPEN, MERGED, or DECLINED.\n\nUpdate example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"update\": {\n \"description\": \"\",\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\",\n \"destination\": {\n \"commit\": {\n \"type\": \"commit\",\n \"hash\": \"6a2c16e4a152\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/commit/6a2c16e4a152\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/commits/6a2c16e4a152\"\n }\n }\n },\n \"branch\": {\n \"name\": \"master\"\n },\n \"repository\": {\n \"name\": \"Atlaskit-MK-2\",\n \"type\": \"repository\",\n \"full_name\": \"atlassian/atlaskit-mk-2\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2\"\n },\n \"avatar\": {\n \"href\": \"https://bytebucket.org/ravatar/%7B%7D?ts=js\"\n }\n },\n \"uuid\": \"{}\"\n }\n },\n \"reason\": \"\",\n \"source\": {\n \"commit\": {\n \"type\": \"commit\",\n \"hash\": \"728c8bad1813\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/commit/728c8bad1813\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/commits/728c8bad1813\"\n }\n }\n },\n \"branch\": {\n \"name\": \"username/NONE-add-onClick-prop-for-accessibility\"\n },\n \"repository\": {\n \"name\": \"Atlaskit-MK-2\",\n \"type\": \"repository\",\n \"full_name\": \"atlassian/atlaskit-mk-2\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2\"\n },\n \"avatar\": {\n \"href\": \"https://bytebucket.org/ravatar/%7B%7D?ts=js\"\n }\n },\n \"uuid\": \"{}\"\n }\n },\n \"state\": \"OPEN\",\n \"author\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"date\": \"2019-05-10T06:48:25.305565+00:00\"\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```\n\nApproval example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"approval\": {\n \"date\": \"2019-09-27T00:37:19.849534+00:00\",\n \"pullrequest\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n },\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n }\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```",
"summary": "List a pull request activity log",
"responses": {
"200": {
@@ -11043,7 +11124,7 @@
"/repositories/{workspace}/{repo_slug}/pullrequests/{pull_request_id}/activity": {
"get": {
"tags": ["Pullrequests"],
- "description": "Returns a paginated list of the pull request's activity log.\n\nThis handler serves both a v20 and internal endpoint. The v20 endpoint\nreturns reviewer comments, updates, approvals and request changes. The internal\nendpoint includes those plus tasks and attachments.\n\nComments created on a file or a line of code have an inline property.\n\nComment example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"comment\": {\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695/comments/118571088\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695/_/diff#comment-118571088\"\n }\n },\n \"deleted\": false,\n \"pullrequest\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n },\n \"content\": {\n \"raw\": \"inline with to a dn from lines\",\n \"markup\": \"markdown\",\n \"html\": \"inline with to a dn from lines
\",\n \"type\": \"rendered\"\n },\n \"created_on\": \"2019-09-27T00:33:46.039178+00:00\",\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"created_on\": \"2019-09-27T00:33:46.039178+00:00\",\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"updated_on\": \"2019-09-27T00:33:46.055384+00:00\",\n \"inline\": {\n \"context_lines\": \"\",\n \"to\": null,\n \"path\": \"\",\n \"outdated\": false,\n \"from\": 211\n },\n \"type\": \"pullrequest_comment\",\n \"id\": 118571088\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```\n\nUpdates include a state property of OPEN, MERGED, or DECLINED.\n\nUpdate example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"update\": {\n \"description\": \"\",\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\",\n \"destination\": {\n \"commit\": {\n \"type\": \"commit\",\n \"hash\": \"6a2c16e4a152\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/commit/6a2c16e4a152\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/commits/6a2c16e4a152\"\n }\n }\n },\n \"branch\": {\n \"name\": \"master\"\n },\n \"repository\": {\n \"name\": \"Atlaskit-MK-2\",\n \"type\": \"repository\",\n \"full_name\": \"atlassian/atlaskit-mk-2\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2\"\n },\n \"avatar\": {\n \"href\": \"https://bytebucket.org/ravatar/%7B%7D?ts=js\"\n }\n },\n \"uuid\": \"{}\"\n }\n },\n \"reason\": \"\",\n \"source\": {\n \"commit\": {\n \"type\": \"commit\",\n \"hash\": \"728c8bad1813\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/commit/728c8bad1813\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/commits/728c8bad1813\"\n }\n }\n },\n \"branch\": {\n \"name\": \"username/NONE-add-onClick-prop-for-accessibility\"\n },\n \"repository\": {\n \"name\": \"Atlaskit-MK-2\",\n \"type\": \"repository\",\n \"full_name\": \"atlassian/atlaskit-mk-2\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2\"\n },\n \"avatar\": {\n \"href\": \"https://bytebucket.org/ravatar/%7B%7D?ts=js\"\n }\n },\n \"uuid\": \"{}\"\n }\n },\n \"state\": \"OPEN\",\n \"author\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"date\": \"2019-05-10T06:48:25.305565+00:00\"\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```\n\nApproval example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"approval\": {\n \"date\": \"2019-09-27T00:37:19.849534+00:00\",\n \"pullrequest\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n },\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n }\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://bitbucket.org/!api/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```",
+ "description": "Returns a paginated list of the pull request's activity log.\n\nThis handler serves both a v20 and internal endpoint. The v20 endpoint\nreturns reviewer comments, updates, approvals and request changes. The internal\nendpoint includes those plus tasks and attachments.\n\nComments created on a file or a line of code have an inline property.\n\nComment example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"comment\": {\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695/comments/118571088\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695/_/diff#comment-118571088\"\n }\n },\n \"deleted\": false,\n \"pullrequest\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n },\n \"content\": {\n \"raw\": \"inline with to a dn from lines\",\n \"markup\": \"markdown\",\n \"html\": \"inline with to a dn from lines
\",\n \"type\": \"rendered\"\n },\n \"created_on\": \"2019-09-27T00:33:46.039178+00:00\",\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"created_on\": \"2019-09-27T00:33:46.039178+00:00\",\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"updated_on\": \"2019-09-27T00:33:46.055384+00:00\",\n \"inline\": {\n \"context_lines\": \"\",\n \"to\": null,\n \"path\": \"\",\n \"outdated\": false,\n \"from\": 211\n },\n \"type\": \"pullrequest_comment\",\n \"id\": 118571088\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```\n\nUpdates include a state property of OPEN, MERGED, or DECLINED.\n\nUpdate example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"update\": {\n \"description\": \"\",\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\",\n \"destination\": {\n \"commit\": {\n \"type\": \"commit\",\n \"hash\": \"6a2c16e4a152\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/commit/6a2c16e4a152\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/commits/6a2c16e4a152\"\n }\n }\n },\n \"branch\": {\n \"name\": \"master\"\n },\n \"repository\": {\n \"name\": \"Atlaskit-MK-2\",\n \"type\": \"repository\",\n \"full_name\": \"atlassian/atlaskit-mk-2\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2\"\n },\n \"avatar\": {\n \"href\": \"https://bytebucket.org/ravatar/%7B%7D?ts=js\"\n }\n },\n \"uuid\": \"{}\"\n }\n },\n \"reason\": \"\",\n \"source\": {\n \"commit\": {\n \"type\": \"commit\",\n \"hash\": \"728c8bad1813\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/commit/728c8bad1813\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/commits/728c8bad1813\"\n }\n }\n },\n \"branch\": {\n \"name\": \"username/NONE-add-onClick-prop-for-accessibility\"\n },\n \"repository\": {\n \"name\": \"Atlaskit-MK-2\",\n \"type\": \"repository\",\n \"full_name\": \"atlassian/atlaskit-mk-2\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2\"\n },\n \"avatar\": {\n \"href\": \"https://bytebucket.org/ravatar/%7B%7D?ts=js\"\n }\n },\n \"uuid\": \"{}\"\n }\n },\n \"state\": \"OPEN\",\n \"author\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n },\n \"date\": \"2019-05-10T06:48:25.305565+00:00\"\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```\n\nApproval example:\n```\n{\n \"pagelen\": 20,\n \"values\": [\n {\n \"approval\": {\n \"date\": \"2019-09-27T00:37:19.849534+00:00\",\n \"pullrequest\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n },\n \"user\": {\n \"display_name\": \"Name Lastname\",\n \"uuid\": \"{}\",\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/users/%7B%7D\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/%7B%7D/\"\n },\n \"avatar\": {\n \"href\": \"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/:/128\"\n }\n },\n \"type\": \"user\",\n \"nickname\": \"Name\",\n \"account_id\": \"\"\n }\n },\n \"pull_request\": {\n \"type\": \"pullrequest\",\n \"id\": 5695,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/repositories/atlassian/atlaskit-mk-2/pullrequests/5695\"\n },\n \"html\": {\n \"href\": \"https://bitbucket.org/atlassian/atlaskit-mk-2/pull-requests/5695\"\n }\n },\n \"title\": \"username/NONE: small change from onFocus to onClick to handle tabbing through the page and not expand the editor unless a click event triggers it\"\n }\n }\n ]\n}\n```",
"summary": "List a pull request activity log",
"responses": {
"200": {
@@ -18035,6 +18116,7 @@
{
"name": "project_key",
"in": "path",
+ "description": "The project in question. This is the actual `key` assigned\nto the project.\n",
"required": true,
"schema": {
"type": "string"
@@ -18182,6 +18264,7 @@
{
"name": "project_key",
"in": "path",
+ "description": "The project in question. This is the actual `key` assigned\nto the project.\n",
"required": true,
"schema": {
"type": "string"
@@ -18201,7 +18284,7 @@
"/workspaces/{workspace}/projects/{project_key}/default-reviewers": {
"get": {
"tags": ["Projects"],
- "description": "Return a list of all default reviewers for a project. This is a list of users that will be added as default\nreviewers to pull requests for any repository within the project.\n\nExample:\n```\n$ curl https://bitbucket.org/!api/2.0/.../projects/.../default-reviewers | jq .\n{\n \"pagelen\": 10,\n \"values\": [\n {\n \"user\": {\n \"display_name\": \"Davis Lee\",\n \"uuid\": \"{f0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6}\"\n },\n \"reviewer_type\": \"project\",\n \"type\": \"default_reviewer\"\n },\n {\n \"user\": {\n \"display_name\": \"Jorge Rodriguez\",\n \"uuid\": \"{1aa43376-260d-4a0b-9660-f62672b9655d}\"\n },\n \"reviewer_type\": \"project\",\n \"type\": \"default_reviewer\"\n }\n ],\n \"page\": 1,\n \"size\": 2\n}\n```",
+ "description": "Return a list of all default reviewers for a project. This is a list of users that will be added as default\nreviewers to pull requests for any repository within the project.\n\nExample:\n```\n$ curl https://api.bitbucket.org/2.0/.../projects/.../default-reviewers | jq .\n{\n \"pagelen\": 10,\n \"values\": [\n {\n \"user\": {\n \"display_name\": \"Davis Lee\",\n \"uuid\": \"{f0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6}\"\n },\n \"reviewer_type\": \"project\",\n \"type\": \"default_reviewer\"\n },\n {\n \"user\": {\n \"display_name\": \"Jorge Rodriguez\",\n \"uuid\": \"{1aa43376-260d-4a0b-9660-f62672b9655d}\"\n },\n \"reviewer_type\": \"project\",\n \"type\": \"default_reviewer\"\n }\n ],\n \"page\": 1,\n \"size\": 2\n}\n```",
"summary": "List the default reviewers in a project",
"responses": {
"200": {
@@ -18251,6 +18334,7 @@
{
"name": "project_key",
"in": "path",
+ "description": "The project in question. This is the actual `key` assigned\nto the project.\n",
"required": true,
"schema": {
"type": "string"
@@ -18270,7 +18354,7 @@
"/workspaces/{workspace}/projects/{project_key}/default-reviewers/{selected_user}": {
"delete": {
"tags": ["Projects"],
- "description": "Removes a default reviewer from the project.\n\nExample:\n```\n$ curl https://bitbucket.org/!api/2.0/.../default-reviewers/%7Bf0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6%7D\n\nHTTP/1.1 204\n```",
+ "description": "Removes a default reviewer from the project.\n\nExample:\n```\n$ curl https://api.bitbucket.org/2.0/.../default-reviewers/%7Bf0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6%7D\n\nHTTP/1.1 204\n```",
"summary": "Remove the specific user from the project's default reviewers",
"responses": {
"204": {
@@ -18321,7 +18405,7 @@
},
"get": {
"tags": ["Projects"],
- "description": "Returns the specified default reviewer.\n\nExample:\n```\n$ curl https://bitbucket.org/!api/2.0/.../default-reviewers/%7Bf0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6%7D\n{\n \"display_name\": \"Davis Lee\",\n \"type\": \"user\",\n \"uuid\": \"{f0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6}\"\n}\n```",
+ "description": "Returns the specified default reviewer.\n\nExample:\n```\n$ curl https://api.bitbucket.org/2.0/.../default-reviewers/%7Bf0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6%7D\n{\n \"display_name\": \"Davis Lee\",\n \"type\": \"user\",\n \"uuid\": \"{f0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6}\"\n}\n```",
"summary": "Get a default reviewer",
"responses": {
"200": {
@@ -18379,7 +18463,7 @@
},
"put": {
"tags": ["Projects"],
- "description": "Adds the specified user to the project's list of default reviewers. The method is\nidempotent. Accepts an optional body containing the `uuid` of the user to be added.\n\nExample:\n```\n$ curl -XPUT https://bitbucket.org/!api/2.0/.../default-reviewers/%7Bf0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6%7D\n-d { 'uuid': '{f0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6}' }\n\nHTTP/1.1 204\n```",
+ "description": "Adds the specified user to the project's list of default reviewers. The method is\nidempotent. Accepts an optional body containing the `uuid` of the user to be added.\n\nExample:\n```\n$ curl -XPUT https://api.bitbucket.org/2.0/.../default-reviewers/%7Bf0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6%7D\n-d { 'uuid': '{f0e0e8e9-66c1-4b85-a784-44a9eb9ef1a6}' }\n\nHTTP/1.1 204\n```",
"summary": "Add the specific user as a default reviewer for the project",
"responses": {
"204": {
@@ -18516,7 +18600,7 @@
},
"post": {
"tags": ["Deployments"],
- "description": "Create a new deploy key in a project.\n\nExample:\n```\n$ curl -XPOST \\\n-H \"Authorization \" \\\n-H \"Content-type: application/json\" \\\nhttps://api.bitbucket.org/!api/2.0/workspaces/jzeng/projects/JZ/deploy-keys/ -d \\\n'{\n \"key\": \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAK/b1cHHDr/TEV1JGQl+WjCwStKG6Bhrv0rFpEsYlyTBm1fzN0VOJJYn4ZOPCPJwqse6fGbXntEs+BbXiptR+++HycVgl65TMR0b5ul5AgwrVdZdT7qjCOCgaSV74/9xlHDK8oqgGnfA7ZoBBU+qpVyaloSjBdJfLtPY/xqj4yHnXKYzrtn/uFc4Kp9Tb7PUg9Io3qohSTGJGVHnsVblq/rToJG7L5xIo0OxK0SJSQ5vuId93ZuFZrCNMXj8JDHZeSEtjJzpRCBEXHxpOPhAcbm4MzULgkFHhAVgp4JbkrT99/wpvZ7r9AdkTg7HGqL3rlaDrEcWfL7Lu6TnhBdq5 mleu@C02W454JHTD8\",\n \"label\": \"mydeploykey\"\n}'\n\nOutput:\n{\n \"comment\": \"mleu@C02W454JHTD8\",\n \"last_used\": null,\n \"links\": {\n \"self\": {\n \"href\": \"https://jzeng.devbucket.org/!api/2.0/workspaces/testadfsa/projects/ASDF/deploy-keys/5/\"\n }\n },\n \"label\": \"myprojectkey\",\n \"project\": {\n ...\n },\n \"created_on\": \"2021-08-10T05:28:00.570859+00:00\",\n \"key\": \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAK/b1cHHDr/TEV1JGQl+WjCwStKG6Bhrv0rFpEsYlyTBm1fzN0VOJJYn4ZOPCPJwqse6fGbXntEs+BbXiptR+++HycVgl65TMR0b5ul5AgwrVdZdT7qjCOCgaSV74/9xlHDK8oqgGnfA7ZoBBU+qpVyaloSjBdJfLtPY/xqj4yHnXKYzrtn/uFc4Kp9Tb7PUg9Io3qohSTGJGVHnsVblq/rToJG7L5xIo0OxK0SJSQ5vuId93ZuFZrCNMXj8JDHZeSEtjJzpRCBEXHxpOPhAcbm4MzULgkFHhAVgp4JbkrT99/wpvZ7r9AdkTg7HGqL3rlaDrEcWfL7Lu6TnhBdq5\",\n \"type\": \"project_deploy_key\",\n \"id\": 5\n}\n```",
+ "description": "Create a new deploy key in a project.\n\nExample:\n```\n$ curl -XPOST \\\n-H \"Authorization \" \\\n-H \"Content-type: application/json\" \\\nhttps://api.bitbucket.org/2.0/workspaces/jzeng/projects/JZ/deploy-keys/ -d \\\n'{\n \"key\": \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAK/b1cHHDr/TEV1JGQl+WjCwStKG6Bhrv0rFpEsYlyTBm1fzN0VOJJYn4ZOPCPJwqse6fGbXntEs+BbXiptR+++HycVgl65TMR0b5ul5AgwrVdZdT7qjCOCgaSV74/9xlHDK8oqgGnfA7ZoBBU+qpVyaloSjBdJfLtPY/xqj4yHnXKYzrtn/uFc4Kp9Tb7PUg9Io3qohSTGJGVHnsVblq/rToJG7L5xIo0OxK0SJSQ5vuId93ZuFZrCNMXj8JDHZeSEtjJzpRCBEXHxpOPhAcbm4MzULgkFHhAVgp4JbkrT99/wpvZ7r9AdkTg7HGqL3rlaDrEcWfL7Lu6TnhBdq5 mleu@C02W454JHTD8\",\n \"label\": \"mydeploykey\"\n}'\n\nOutput:\n{\n \"comment\": \"mleu@C02W454JHTD8\",\n \"last_used\": null,\n \"links\": {\n \"self\": {\n \"href\": \"https://api.bitbucket.org/2.0/workspaces/testadfsa/projects/ASDF/deploy-keys/5/\"\n }\n },\n \"label\": \"myprojectkey\",\n \"project\": {\n ...\n },\n \"created_on\": \"2021-08-10T05:28:00.570859+00:00\",\n \"key\": \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAK/b1cHHDr/TEV1JGQl+WjCwStKG6Bhrv0rFpEsYlyTBm1fzN0VOJJYn4ZOPCPJwqse6fGbXntEs+BbXiptR+++HycVgl65TMR0b5ul5AgwrVdZdT7qjCOCgaSV74/9xlHDK8oqgGnfA7ZoBBU+qpVyaloSjBdJfLtPY/xqj4yHnXKYzrtn/uFc4Kp9Tb7PUg9Io3qohSTGJGVHnsVblq/rToJG7L5xIo0OxK0SJSQ5vuId93ZuFZrCNMXj8JDHZeSEtjJzpRCBEXHxpOPhAcbm4MzULgkFHhAVgp4JbkrT99/wpvZ7r9AdkTg7HGqL3rlaDrEcWfL7Lu6TnhBdq5\",\n \"type\": \"project_deploy_key\",\n \"id\": 5\n}\n```",
"summary": "Create a project deploy key",
"responses": {
"200": {
@@ -18576,6 +18660,7 @@
{
"name": "project_key",
"in": "path",
+ "description": "The project in question. This is the actual `key` assigned\nto the project.\n",
"required": true,
"schema": {
"type": "string"
@@ -18695,6 +18780,7 @@
{
"name": "project_key",
"in": "path",
+ "description": "The project in question. This is the actual `key` assigned\nto the project.\n",
"required": true,
"schema": {
"type": "string"
@@ -18894,7 +18980,7 @@
"description": "A workspace is where you create repositories, collaborate on\nyour code, and organize different streams of work in your Bitbucket\nCloud account. Workspaces replace the use of teams and users in API\ncalls.\n"
}
],
- "x-revision": "50c586d353cb",
+ "x-revision": "607fbe8bfcb2",
"x-atlassian-narrative": {
"documents": [
{
@@ -18902,7 +18988,7 @@
"title": "Authentication methods",
"description": "How to authenticate API actions",
"icon": "data:image/svg+xml;base64,b'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxOTcuNjQ3MyAxODYuODEzOCI+CiAgPGRlZnM+CiAgICA8c3R5bGU+CiAgICAgIC5jbHMtMSB7CiAgICAgICAgaXNvbGF0aW9uOiBpc29sYXRlOwogICAgICB9CgogICAgICAuY2xzLTIgewogICAgICAgIGZpbGw6ICNkZTM1MGI7CiAgICAgIH0KCiAgICAgIC5jbHMtMyB7CiAgICAgICAgZmlsbDogI2ZmNTYzMDsKICAgICAgfQoKICAgICAgLmNscy00IHsKICAgICAgICBmaWxsOiAjZGZlMWU1OwogICAgICAgIG1peC1ibGVuZC1tb2RlOiBtdWx0aXBseTsKICAgICAgfQoKICAgICAgLmNscy01IHsKICAgICAgICBmaWxsOiAjZmFmYmZjOwogICAgICB9CgogICAgICAuY2xzLTYgewogICAgICAgIGZpbGw6ICNlYmVjZjA7CiAgICAgIH0KCiAgICAgIC5jbHMtNyB7CiAgICAgICAgZmlsbDogbm9uZTsKICAgICAgICBzdHJva2U6ICMwMDY1ZmY7CiAgICAgICAgc3Ryb2tlLW1pdGVybGltaXQ6IDEwOwogICAgICAgIHN0cm9rZS13aWR0aDogMnB4OwogICAgICB9CgogICAgICAuY2xzLTggewogICAgICAgIGZpbGw6ICM1ZTZjODQ7CiAgICAgIH0KCiAgICAgIC5jbHMtOSB7CiAgICAgICAgZmlsbDogIzI1Mzg1ODsKICAgICAgfQoKICAgICAgLmNscy0xMCB7CiAgICAgICAgZmlsbDogIzI2ODRmZjsKICAgICAgfQoKICAgICAgLmNscy0xMSB7CiAgICAgICAgZmlsbDogIzAwNjVmZjsKICAgICAgfQogICAgPC9zdHlsZT4KICA8L2RlZnM+CiAgPHRpdGxlPlNlY3VyaXR5IHdpdGggS2V5PC90aXRsZT4KICA8ZyBjbGFzcz0iY2xzLTEiPgogICAgPGcgaWQ9IkxheWVyXzIiIGRhdGEtbmFtZT0iTGF5ZXIgMiI+CiAgICAgIDxnIGlkPSJPYmplY3RzIj4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik00Mi4wNjcyLDBoLjYxMTRhOCw4LDAsMCwxLDgsOFYyMy4yMzM4YTAsMCwwLDAsMSwwLDBIMzQuMDY3MmEwLDAsMCwwLDEsMCwwVjhBOCw4LDAsMCwxLDQyLjA2NzIsMFoiLz4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik0xMDguMjIsMGguNjExNGE4LDgsMCwwLDEsOCw4VjIzLjIzMzhhMCwwLDAsMCwxLDAsMEgxMDAuMjJhMCwwLDAsMCwxLDAsMFY4QTgsOCwwLDAsMSwxMDguMjIsMFoiLz4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik0xNzQuMzcyMiwwaC42MTE0YTgsOCwwLDAsMSw4LDhWMjMuMjMzOGEwLDAsMCwwLDEsMCwwSDE2Ni4zNzIyYTAsMCwwLDAsMSwwLDBWOEE4LDgsMCwwLDEsMTc0LjM3MjIsMFoiLz4KICAgICAgICA8cmVjdCBjbGFzcz0iY2xzLTIiIHg9IjM0LjA2NzIiIHk9IjIzLjIzMzgiIHdpZHRoPSIxNjMuNTgiIGhlaWdodD0iMTYzLjU4Ii8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy0yIiBkPSJNNDIuMDY3MiwwSDU5LjI5YTgsOCwwLDAsMSw4LDhWMjMuMjIyOGEwLDAsMCwwLDEsMCwwSDM0LjA2NzJhMCwwLDAsMCwxLDAsMFY4YTgsOCwwLDAsMSw4LThaIi8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy0yIiBkPSJNMTA3LjI0NTgsMGgxNy4yMjI4YTgsOCwwLDAsMSw4LDhWMjMuMjIyOGEwLDAsMCwwLDEsMCwwSDk5LjI0NThhMCwwLDAsMCwxLDAsMFY4YTgsOCwwLDAsMSw4LThaIi8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy0yIiBkPSJNMTcyLjQyNDQsMGgxNy4yMjI4YTgsOCwwLDAsMSw4LDhWMjMuMjIyOGEwLDAsMCwwLDEsMCwwSDE2NC40MjQ0YTAsMCwwLDAsMSwwLDBWOGE4LDgsMCwwLDEsOC04WiIvPgogICAgICAgIDxyZWN0IGNsYXNzPSJjbHMtMyIgeD0iMTcuNDU1OCIgeT0iMjMuMjMzOCIgd2lkdGg9IjE2My41OCIgaGVpZ2h0PSIxNjMuNTgiLz4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTMiIGQ9Ik0yNS40NTU4LDBINDIuNjc4NmE4LDgsMCwwLDEsOCw4VjIzLjIyMjhhMCwwLDAsMCwxLDAsMEgxNy40NTU4YTAsMCwwLDAsMSwwLDBWOEE4LDgsMCwwLDEsMjUuNDU1OCwwWiIvPgogICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtMyIgZD0iTTkwLjYzNDQsMGgxNy4yMjI4YTgsOCwwLDAsMSw4LDhWMjMuMjIyOGEwLDAsMCwwLDEsMCwwSDgyLjYzNDRhMCwwLDAsMCwxLDAsMFY4QTgsOCwwLDAsMSw5MC42MzQ0LDBaIi8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy0zIiBkPSJNMTU1LjgxMywwaDE3LjIyMjhhOCw4LDAsMCwxLDgsOFYyMy4yMjI4YTAsMCwwLDAsMSwwLDBIMTQ3LjgxM2EwLDAsMCwwLDEsMCwwVjhBOCw4LDAsMCwxLDE1NS44MTMsMFoiLz4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTMiIGQ9Ik0yNS40NTU4LDBINDIuNjc4NmE4LDgsMCwwLDEsOCw4VjIzLjIyMjhhMCwwLDAsMCwxLDAsMEgxNy40NTU4YTAsMCwwLDAsMSwwLDBWOEE4LDgsMCwwLDEsMjUuNDU1OCwwWiIvPgogICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtMyIgZD0iTTkwLjYzNDQsMGgxNy4yMjI4YTgsOCwwLDAsMSw4LDhWMjMuMjIyOGEwLDAsMCwwLDEsMCwwSDgyLjYzNDRhMCwwLDAsMCwxLDAsMFY4QTgsOCwwLDAsMSw5MC42MzQ0LDBaIi8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy0zIiBkPSJNMTU1LjgxMywwaDE3LjIyMjhhOCw4LDAsMCwxLDgsOFYyMy4yMjI4YTAsMCwwLDAsMSwwLDBIMTQ3LjgxM2EwLDAsMCwwLDEsMCwwVjhBOCw4LDAsMCwxLDE1NS44MTMsMFoiLz4KICAgICAgICA8cmVjdCBjbGFzcz0iY2xzLTIiIHg9IjM1Ljc1OTYiIHk9IjU2LjgwNjUiIHdpZHRoPSIzMy4yMjI4IiBoZWlnaHQ9IjE1LjYwMzgiLz4KICAgICAgICA8cmVjdCBjbGFzcz0iY2xzLTIiIHg9IjEzMS4yMDE2IiB5PSIxMzYuOTYxNSIgd2lkdGg9IjMzLjIyMjgiIGhlaWdodD0iMTUuNjAzOCIvPgogICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtNCIgZD0iTTU3LjM3MDksNzEuNjAzNmg3MC43NWE5LDksMCwwLDEsOSw5djM1LjM3NDlhNDQuMzc0OCw0NC4zNzQ4LDAsMCwxLTQ0LjM3NDgsNDQuMzc0OGgwYTQ0LjM3NDgsNDQuMzc0OCwwLDAsMS00NC4zNzQ4LTQ0LjM3NDhWODAuNjAzNkE5LDksMCwwLDEsNTcuMzcwOSw3MS42MDM2WiIvPgogICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtNSIgZD0iTTY2LjM3MSw2Ni42NjE3aDcwLjc1YTksOSwwLDAsMSw5LDl2MzUuMzc0OWE0NC4zNzQ4LDQ0LjM3NDgsMCwwLDEtNDQuMzc0OCw0NC4zNzQ4aDBBNDQuMzc0OCw0NC4zNzQ4LDAsMCwxLDU3LjM3MSwxMTEuMDM2NlY3NS42NjE3YTksOSwwLDAsMSw5LTlaIi8+CiAgICAgICAgPHBhdGggaWQ9Il9SZWN0YW5nbGVfIiBkYXRhLW5hbWU9IiZsdDtSZWN0YW5nbGUmZ3Q7IiBjbGFzcz0iY2xzLTYiIGQ9Ik02MS4zNzEsNjYuNjYxN2g3MC43NWE5LDksMCwwLDEsOSw5djM1LjM3NDlhNDQuMzc0OCw0NC4zNzQ4LDAsMCwxLTQ0LjM3NDgsNDQuMzc0OGgwQTQ0LjM3NDgsNDQuMzc0OCwwLDAsMSw1Mi4zNzEsMTExLjAzNjZWNzUuNjYxN0E5LDksMCwwLDEsNjEuMzcxLDY2LjY2MTdaIi8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy03IiBkPSJNOTYuNzQ1OSwxNDcuNzQ0MWEzNi43NDg3LDM2Ljc0ODcsMCwwLDEtMzYuNzA3NC0zNi43MDc0Vjc4LjA1ODRhMy43MzMzLDMuNzMzMywwLDAsMSwzLjcyOS0zLjcyOWg2NS45NTYzYTMuNzMzMywzLjczMzMsMCwwLDEsMy43MjksMy43Mjl2MzIuOTc4NEEzNi43NDg2LDM2Ljc0ODYsMCwwLDEsOTYuNzQ1OSwxNDcuNzQ0MVoiLz4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTQiIGQ9Ik0xMDAuNjg5MywxNjMuMzE2N1YxMTEuMDk3M2EzLjk0NDMsMy45NDQzLDAsMCwwLTcuODg4NywwdjUyLjIyYTIyLjUyNTIsMjIuNTI1MiwwLDAsMC0xOC41NDc5LDIyLjE0YzAsLjQ1Ni4wMTc4LjkwNzguMDQ0NywxLjM1NzFIODIuMjFjLS4wNDE0LS40NDc0LS4wNjg4LS44OTktLjA2ODgtMS4zNTcxYTE0LjYyLDE0LjYyLDAsMCwxLDE0LjU5NzQtMTQuNjA0MWwuMDA2MS4wMDA2LjAwNjgtLjAwMDdBMTQuNjIxMSwxNC42MjExLDAsMCwxLDExMS4zNSwxODUuNDU2NmMwLC40NTgxLS4wMjczLjkxLS4wNjg4LDEuMzU3MWg3LjkxMjhjLjAyNjktLjQ0OTMuMDQ0Ny0uOTAxMS4wNDQ3LTEuMzU3MUEyMi41MjU5LDIyLjUyNTksMCwwLDAsMTAwLjY4OTMsMTYzLjMxNjdaIi8+CiAgICAgICAgPHJlY3QgY2xhc3M9ImNscy0yIiB4PSIxNy40NTU4IiB5PSIzNi40NzAyIiB3aWR0aD0iMzMuMjIyOCIgaGVpZ2h0PSIxNS42MDM4Ii8+CiAgICAgICAgPHJlY3QgY2xhc3M9ImNscy0yIiB4PSIxNy40NTU4IiB5PSIxNTguMTIxNyIgd2lkdGg9IjMzLjIyMjgiIGhlaWdodD0iMTUuNjAzOCIvPgogICAgICAgIDxyZWN0IGNsYXNzPSJjbHMtMiIgeD0iMTQ3LjgxMyIgeT0iMzYuNDcwMiIgd2lkdGg9IjMzLjIyMjgiIGhlaWdodD0iMTUuNjAzOCIvPgogICAgICAgIDxyZWN0IGNsYXNzPSJjbHMtMiIgeD0iMTUwLjA2NDMiIHk9IjE1Ny41NTEzIiB3aWR0aD0iMzMuMjIyOCIgaGVpZ2h0PSIxNS42MDM4Ii8+CiAgICAgICAgPHBhdGggaWQ9Il9QYXRoXyIgZGF0YS1uYW1lPSImbHQ7UGF0aCZndDsiIGNsYXNzPSJjbHMtOCIgZD0iTTEwNy41MjU0LDEwMS4wMDI3YTExLjc3OTQsMTEuNzc5NCwwLDEsMC0xOS44Niw4LjU1NDhBNC4wNDE3LDQuMDQxNywwLDAsMSw4OC44NSwxMTMuNjJsLTIuMTA0LDcuMjY4MWEzLDMsMCwwLDAsMi44ODE3LDMuODM0MmgxMi4yMzcxYTMsMywwLDAsMCwyLjg4MTctMy44MzQybC0yLjA5NTktNy4yNGE0LjA3NDMsNC4wNzQzLDAsMCwxLDEuMTgwOC00LjA5NDVBMTEuNzE3MiwxMS43MTcyLDAsMCwwLDEwNy41MjU0LDEwMS4wMDI3WiIvPgogICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtOSIgZD0iTTEwNC43NDYxLDEyMC44ODc3bC0yLjA5NTktNy4yNGE0LjA3NDQsNC4wNzQ0LDAsMCwxLDEuMTgwOC00LjA5NDUsMTEuNzYyOSwxMS43NjI5LDAsMCwwLTUuMDYtMTkuOTMxMywxMS45MSwxMS45MSwwLDAsMC04Ljc5OCwxMC45OTQ5LDExLjcxODUsMTEuNzE4NSwwLDAsMCwzLjY5MjksOC45NDFBNC4wNDE2LDQuMDQxNiwwLDAsMSw5NC44NSwxMTMuNjJsLTMuMjE0LDExLjEwMjNoMTAuMjI4OEEzLDMsMCwwLDAsMTA0Ljc0NjEsMTIwLjg4NzdaIi8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy0xMCIgZD0iTTgxLjc5NzUsMTAwLjMxYTMuOTQzOSwzLjk0MzksMCwwLDAtMy45NDQzLTMuOTQ0M0g0MS4wNDE3YTMuOTQ0MywzLjk0NDMsMCwwLDAsMCw3Ljg4ODdINzcuODUzMkEzLjk0MzksMy45NDM5LDAsMCwwLDgxLjc5NzUsMTAwLjMxWiIvPgogICAgICAgIDxwYXRoIGlkPSJfUGF0aF8yIiBkYXRhLW5hbWU9IiZsdDtQYXRoJmd0OyIgY2xhc3M9ImNscy0xMSIgZD0iTTQxLjA0MTYsMTA0LjI1MzlIOTYuODUzMmEzLjk0NDMsMy45NDQzLDAsMCwwLDAtNy44ODg3SDQxLjA0MTZhMy45NDQzLDMuOTQ0MywwLDAsMCwwLDcuODg4N1oiLz4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTEwIiBkPSJNODEuNzk3NSwxMDAuMzFhMy45NDM5LDMuOTQzOSwwLDAsMC0zLjk0NDMtMy45NDQzSDQxLjA0MTdhMy45NDQzLDMuOTQ0MywwLDAsMCwwLDcuODg4N0g3Ny44NTMyQTMuOTQzOSwzLjk0MzksMCwwLDAsODEuNzk3NSwxMDAuMzFaIi8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy0xMCIgZD0iTTIyLjQ5MzIsMTIyLjgwMjlBMjIuNDkyOSwyMi40OTI5LDAsMSwxLDQ0Ljk4NTgsMTAwLjMxLDIyLjUxODUsMjIuNTE4NSwwLDAsMSwyMi40OTMyLDEyMi44MDI5Wm0wLTM3LjA5NzJBMTQuNjA0MiwxNC42MDQyLDAsMSwwLDM3LjA5NzIsMTAwLjMxLDE0LjYyMDcsMTQuNjIwNywwLDAsMCwyMi40OTMyLDg1LjcwNTdaIi8+CiAgICAgIDwvZz4KICAgIDwvZz4KICA8L2c+Cjwvc3ZnPgo='",
- "body": "\nThe purpose of this section is to describe how to authenticate when making API calls using the Bitbucket REST API.\n\n-----\n\n* [Oauth 2](#oauth-2)\n * [Making requests](#making-requests)\n * [Repository cloning](#repository-cloning)\n * [Refresh tokens](#refresh-tokens)\n* [Scopes](#scopes)\n* [Basic auth](#basic-auth)\n* [App passwords](#app-passwords)\n\n---\n\n### OAuth 2.0\n\nOur OAuth 2 implementation is merged in with our existing OAuth 1 in\nsuch a way that existing OAuth 1 consumers automatically become\nvalid OAuth 2 clients. The only thing you need to do is edit your\nexisting consumer and configure a callback URL.\n\nOnce that is in place, you'll have the following 2 URLs:\n\n https://bitbucket.org/site/oauth2/authorize\n https://bitbucket.org/site/oauth2/access_token\n\nFor obtaining access/bearer tokens, we support three of RFC-6749's grant\nflows, plus a custom Bitbucket flow for exchanging JWT tokens for access tokens.\nNote that Resource Owner Password Credentials Grant (4.3) is no longer supported.\n\n\n#### 1. Authorization Code Grant (4.1)\n\nThe full-blown 3-LO flow. Request authorization from the end user by\nsending their browser to:\n\n https://bitbucket.org/site/oauth2/authorize?client_id={client_id}&response_type=code\n\nThe callback includes the `?code={}` query parameter that you can swap\nfor an access token:\n\n $ curl -X POST -u \"client_id:secret\" \\\n https://bitbucket.org/site/oauth2/access_token \\\n -d grant_type=authorization_code -d code={code}\n\n\n#### 2. Implicit Grant (4.2)\n\nThis flow is useful for browser-based add-ons that operate without server-side backends.\n\nRequest the end user for authorization by directing the browser to:\n\n https://bitbucket.org/site/oauth2/authorize?client_id={client_id}&response_type=token\n\nThat will redirect to your preconfigured callback URL with a fragment\ncontaining the access token\n(`#access_token={token}&token_type=bearer`) where your page's js can\npull it out of the URL.\n\n\n#### 3. Client Credentials Grant (4.4)\n\nSomewhat like our existing \"2-LO\" flow for OAuth 1. Obtain an access\ntoken that represents not an end user, but the owner of the\nclient/consumer:\n\n $ curl -X POST -u \"client_id:secret\" \\\n https://bitbucket.org/site/oauth2/access_token \\\n -d grant_type=client_credentials\n\n\n#### 4. Bitbucket Cloud JWT Grant (urn:bitbucket:oauth2:jwt)\n\nIf your Atlassian Connect add-on uses JWT authentication, you can swap a\nJWT for an OAuth access token. The resulting access token represents the\naccount for which the add-on is installed.\n\nMake sure you send the JWT token in the Authorization request header\nusing the \"JWT\" scheme (case sensitive). Note that this custom scheme\nmakes this different from HTTP Basic Auth (and so you cannot use \"curl\n-u\").\n\n $ curl -X POST -H \"Authorization: JWT {jwt_token}\" \\\n https://bitbucket.org/site/oauth2/access_token \\\n -d grant_type=urn:bitbucket:oauth2:jwt\n\n\n#### Making Requests\n\nOnce you have an access token, as per RFC-6750, you can use it in a request in any of\nthe following ways (in decreasing order of desirability):\n\n1. Send it in a request header: `Authorization: Bearer {access_token}`\n2. Include it in a (application/x-www-form-urlencoded) POST body as `access_token={access_token}`\n3. Put it in the query string of a non-POST: `?access_token={access_token}`\n\n\n#### Repository Cloning\n\nSince add-ons will not be able to upload their own SSH keys to clone\nwith, access tokens can be used as Basic HTTP Auth credentials to\nclone securely over HTTPS. This is much like GitHub, yet slightly\ndifferent:\n\n $ git clone https://x-token-auth:{access_token}@bitbucket.org/user/repo.git\n\nThe literal string `x-token-auth` as a substitute for username is\nrequired (note the difference with GitHub where the actual token is in\nthe username field).\n\n\n#### Refresh Tokens\n\nOur access tokens expire in one hour. When this happens you'll get 401\nresponses.\n\nMost access tokens grant responses (Implicit and JWT excluded). Therefore, you should include a\nrefresh token that can then be used to generate a new access token,\nwithout the need for end user participation:\n\n $ curl -X POST -u \"client_id:secret\" \\\n https://bitbucket.org/site/oauth2/access_token \\\n -d grant_type=refresh_token -d refresh_token={refresh_token}\n\n\n### Scopes\n\nBitbucket's API applies a number of privilege scopes to endpoints. In order to access an endpoint, a request will need to have the necessary scopes.\n\nScopes are declared in the descriptor as a list of strings, with each string being the name of a unique scope.\n\nA descriptor lacking the `scopes` element is implicitly assumed to require all scopes and as a result, Bitbucket will require end users authorizing/installing the add-on\nto explicitly accept all scopes.\n\nOur best practice suggests you add the scopes your add-on needs, but no more than it needs.\n\nInvalid scope strings will cause the descriptor to be rejected and the installation to fail.\n\nFollowing is the set of all currently available scopes.\n\n#### repository\n\nGives the add-on read access to all the repositories the authorizing user has access to.\nNote that this scope does not give access to a repository's pull requests.\n\n* access to the repo's source code\n* clone over https\n* access the the file browsing API\n* download zip archives of the repo's contents\n* the ability to view and use the issue tracker on any repo (created issues, comment, vote, etc)\n* the ability to view and use the wiki on any repo (create/edit pages)\n\n#### repository:write\n\nGives the add-on write (not admin) access to all the repositories the authorizing user has access to. No distinction is made between public or private repos. This scope implies `repository`, which does not need to be requested separately.\nThis scope alone does not give access to the pull requests API.\n\n* push access over https\n* fork repos\n\n#### repository:admin\n\nGives the add-on admin access to all the repositories the authorizing user has access to. No distinction is made between public or private repos. This scope does not imply `repository` or `repository:write`. It gives access to the admin features of a repo only, not direct access to its contents. Of course it can be (mis)used to grant read access to another user account who can then clone the repo, but repos that need to read of write source code would also request explicit read or write.\nThis scope comes with access to the following functionality:\n\n* view and manipulate committer mappings\n* list and edit deploy keys\n* ability to delete the repo\n* view and edit repo permissions\n* view and edit branch permissions\n* import and export the issue tracker\n* enable and disable the issue tracker\n* list and edit issue tracker version, milestones and components\n* enable and disable the wiki\n* list and edit default reviewers\n* list and edit repo links (Jira/Bamboo/Custom)\n* list and edit the repository web hooks\n* initiate a repo ownership transfer\n\n#### snippet\n\nGives the add-on read access to all the snippets the authorizing user has access to.\nNo distinction is made between public and private snippets (public snippets are accessible without any form of authentication).\n\n* view any snippet\n* create snippet comments\n\n#### snippet:write\n\nGives the add-on write access to all the snippets the authorizing user can edit.\nNo distinction is made between public and private snippets (public snippets are accessible without any form of authentication).\nThis implies the Snippet Read scope which does not need to be requested separately.\n\n* edit snippets\n* delete snippets\n\n#### issue\n\nAbility to interact with issue trackers the way non-repo members can.\nThis scope does not imply any other scopes and does not give implicit access to the repository the issue is attached to.\n\n* view, list and search issues\n* create new issues\n* comment on issues\n* watch issues\n* vote for issues\n\n#### issue:write\n\nThis implies `issue`, but adds the ability to transition and delete issues.\nThis scope does not imply any other scopes and does not give implicit access to the repository the issue is attached to.\n\n* transition issues\n* delete issues\n\n#### wiki\n\nGives access to wikis. No distinction is made between read and write as wikis are always editable by anyone.\nThis scope does not imply any other scopes and does not give implicit access to the repository the wiki is attached to.\n\n* view wikis\n* create pages\n* edit pages\n* push to wikis\n* clone wikis\n\n#### pullrequest\n\nGives the add-on read access to pull requests.\nThis scope implies `repository`, giving read access to the pull request's destination repository.\n\n* see and list pull requests\n* create and resolve tasks\n* comment on pull requests\n\n#### pullrequest:write\n\nImplies `pullrequest` but adds the ability to create, merge and decline pull requests.\nThis scope implies `repository:write`, giving write access to the pull request's destination repository. This is necessary to facilitate merging.\n\n* merge pull requests\n* decline pull requests\n* create pull requests\n* approve pull requests\n\n#### project\n\nGives the app `repository` scope permissions for every repository under every project that the authorizing user has read access to.\n\n#### project:write\n\nThis scope is deprecated, and has been made obsolete by `project:admin`. Please see the deprecation notice [here](/cloud/bitbucket/deprecation-notice-project-write-scope).\n\n#### project:admin\n\nGives the app admin access to all the projects the authorizing user has access to. No distinction is made between public or private projects. This scope does not imply `project`, or `repository:write` on any repositories under the project. It gives access to the admin features of a project only, not direct access to its repositories' contents.\n\n* ability to create the project\n* ability to update the project\n* ability to delete the project\n\n#### email\n\nAbility to see the user's primary email address. This should make it easier to use Bitbucket Cloud as a login provider to add-ons or external applications.\n\n#### account\n\nAbility to see all the user's account information. Note that this does not include any ability to mutate any of the data.\n\n* see all email addresses\n* language\n* location\n* website\n* full name\n* SSH keys\n* user groups\n\n#### account:write\n\nAbility to change properties on the user's account.\n\n* delete the authorizing user's account\n* manage the user's groups\n* manupilate a user's email addresses\n* change username, display name and avatar\n\n#### webhook\n\nGives access to webhooks. This scope is required for any webhook\nrelated operation.\n\nThis scope gives read access to existing webhook subscriptions on all\nresources you can access, without needing further scopes. This means that\na client can list all existing webhook subscriptions on repository\n`foo/bar` (assuming the principal user has access to this repo). The\nadditional `repository` scope is not required for this.\n\nLikewise, existing webhook subscriptions for a repo's issue tracker can be\nretrieved without holding the `issue` scope. All that is required is the\n`webhook` scope.\n\nHowever, to create a webhook for `issue:created`, the client will need to\nhave both the `webhook` as well as `issue` scope.\n\n* list webhook subscriptions on any accessible repository, user, team, or snippet\n* create/update/delete webhook subscriptions\n\n#### pipeline\n\nGives read-only access to pipelines, steps, deployment environments and variables.\n\n#### pipeline:write\n\nGives write access to pipelines. This scope allows a user to:\n* Stop pipelines\n* Rerun failed pipelines\n* Resume halted pipelines\n* Trigger manual pipelines.\n\nThis scope is not needed to trigger a build via a push. The act to doing push will trigger the build. The token doing the push only needs repository:write scope.\n\nThis does not give write access to create variables.\n\n#### pipeline:variable\n\nGives write access to create variables in pipelines at the various levels:\n* Workspace\n* Repository\n* Deployment\n\n#### runner\n\nGives read-only access to pipelines runners setup against a workspace or repository.\n\n#### runner:write\n\nGives write access to create/edit/disable/delete pipelines runners setup against a workspace or repository.\n\n### Basic auth\n\nBasic HTTP Authentication as per [RFC-2617](https://tools.ietf.org/html/rfc2617) (Digest not supported). Note that Basic Auth is available only with username and [app password](https://bitbucket.org/account/settings/app-passwords/) as credentials.\n\n### App passwords\n\nApp passwords allow users to make API calls to their Bitbucket account through apps such as Sourcetree.\n\nSome important points about app passwords:\n\n* You cannot view an app password or adjust permissions after you create the app password. Because app passwords are encrypted on our database and cannot be viewed by anyone. They are essentially designed to be disposable. If you need to change the scopes or lost the password just create a new one.\n* You cannot use them to log into your Bitbucket account.\n* You cannot use app passwords to manage team actions.\n\n App passwords are tied to an individual account's credentials and should not be shared. If you're sharing your app password you're essentially giving direct, authenticated, access to everything that password has been scoped to do with the Bitbucket API's.\n\n* You can use them for API call authentication, even if you don't have two-step verification enabled.\n* You can set permission scopes (specific access rights) for each app password.\n\n#### Create an app password\n\nTo create an app password:\n\n1. Select **Avatar > Bitbucket settings**.\n2. [Click **App passwords** in the Access management section.](https://bitbucket.org/account/settings/app-passwords/)\n3. Click **Create app password**.\n4. Give the app password a name related to the application that will use the password.\n5. Select the specific access and permissions you want this application password to have.\n6. Copy the generated password and either record or paste it into the application you want to give access. The password is only displayed this one time.\n\nThat's all there is to creating an app password. See your applications documentation for how to apply the app password for a specific application."
+ "body": "\nThe purpose of this section is to describe how to authenticate when making API calls using the Bitbucket REST API.\n\n-----\n\n* [Oauth 2](#oauth-2)\n * [Making requests](#making-requests)\n * [Repository cloning](#repository-cloning)\n * [Refresh tokens](#refresh-tokens)\n* [Scopes](#scopes)\n* [Basic auth](#basic-auth)\n* [Repository Access Tokens](#repository-access-tokens)\n* [App passwords](#app-passwords)\n\n---\n\n### OAuth 2.0\n\nOur OAuth 2 implementation is merged in with our existing OAuth 1 in\nsuch a way that existing OAuth 1 consumers automatically become\nvalid OAuth 2 clients. The only thing you need to do is edit your\nexisting consumer and configure a callback URL.\n\nOnce that is in place, you'll have the following 2 URLs:\n\n https://bitbucket.org/site/oauth2/authorize\n https://bitbucket.org/site/oauth2/access_token\n\nFor obtaining access/bearer tokens, we support three of RFC-6749's grant\nflows, plus a custom Bitbucket flow for exchanging JWT tokens for access tokens.\nNote that Resource Owner Password Credentials Grant (4.3) is no longer supported.\n\n\n#### 1. Authorization Code Grant (4.1)\n\nThe full-blown 3-LO flow. Request authorization from the end user by\nsending their browser to:\n\n https://bitbucket.org/site/oauth2/authorize?client_id={client_id}&response_type=code\n\nThe callback includes the `?code={}` query parameter that you can swap\nfor an access token:\n\n $ curl -X POST -u \"client_id:secret\" \\\n https://bitbucket.org/site/oauth2/access_token \\\n -d grant_type=authorization_code -d code={code}\n\n\n#### 2. Implicit Grant (4.2)\n\nThis flow is useful for browser-based add-ons that operate without server-side backends.\n\nRequest the end user for authorization by directing the browser to:\n\n https://bitbucket.org/site/oauth2/authorize?client_id={client_id}&response_type=token\n\nThat will redirect to your preconfigured callback URL with a fragment\ncontaining the access token\n(`#access_token={token}&token_type=bearer`) where your page's js can\npull it out of the URL.\n\n\n#### 3. Client Credentials Grant (4.4)\n\nSomewhat like our existing \"2-LO\" flow for OAuth 1. Obtain an access\ntoken that represents not an end user, but the owner of the\nclient/consumer:\n\n $ curl -X POST -u \"client_id:secret\" \\\n https://bitbucket.org/site/oauth2/access_token \\\n -d grant_type=client_credentials\n\n\n#### 4. Bitbucket Cloud JWT Grant (urn:bitbucket:oauth2:jwt)\n\nIf your Atlassian Connect add-on uses JWT authentication, you can swap a\nJWT for an OAuth access token. The resulting access token represents the\naccount for which the add-on is installed.\n\nMake sure you send the JWT token in the Authorization request header\nusing the \"JWT\" scheme (case sensitive). Note that this custom scheme\nmakes this different from HTTP Basic Auth (and so you cannot use \"curl\n-u\").\n\n $ curl -X POST -H \"Authorization: JWT {jwt_token}\" \\\n https://bitbucket.org/site/oauth2/access_token \\\n -d grant_type=urn:bitbucket:oauth2:jwt\n\n\n#### Making Requests\n\nOnce you have an access token, as per RFC-6750, you can use it in a request in any of\nthe following ways (in decreasing order of desirability):\n\n1. Send it in a request header: `Authorization: Bearer {access_token}`\n2. Include it in a (application/x-www-form-urlencoded) POST body as `access_token={access_token}`\n3. Put it in the query string of a non-POST: `?access_token={access_token}`\n\n\n#### Repository Cloning\n\nSince add-ons will not be able to upload their own SSH keys to clone\nwith, access tokens can be used as Basic HTTP Auth credentials to\nclone securely over HTTPS. This is much like GitHub, yet slightly\ndifferent:\n\n $ git clone https://x-token-auth:{access_token}@bitbucket.org/user/repo.git\n\nThe literal string `x-token-auth` as a substitute for username is\nrequired (note the difference with GitHub where the actual token is in\nthe username field).\n\n\n#### Refresh Tokens\n\nOur access tokens expire in one hour. When this happens you'll get 401\nresponses.\n\nMost access tokens grant responses (Implicit and JWT excluded). Therefore, you should include a\nrefresh token that can then be used to generate a new access token,\nwithout the need for end user participation:\n\n $ curl -X POST -u \"client_id:secret\" \\\n https://bitbucket.org/site/oauth2/access_token \\\n -d grant_type=refresh_token -d refresh_token={refresh_token}\n\n\n### Scopes\n\nBitbucket's API applies a number of privilege scopes to endpoints. In order to access an endpoint, a request will need to have the necessary scopes.\n\nScopes are declared in the descriptor as a list of strings, with each string being the name of a unique scope.\n\nA descriptor lacking the `scopes` element is implicitly assumed to require all scopes and as a result, Bitbucket will require end users authorizing/installing the add-on\nto explicitly accept all scopes.\n\nOur best practice suggests you add the scopes your add-on needs, but no more than it needs.\n\nInvalid scope strings will cause the descriptor to be rejected and the installation to fail.\n\nThe available scopes are:\n\n- [project](#project)\n- [project:write](#project-write)\n- [project:admin](#project-admin)\n- [repository](#repository)\n- [repository:write](#repository-write)\n- [repository:admin](#repository-admin)\n- [repository:delete](#repository-delete)\n- [pullrequest](#pullrequest)\n- [pullrequest:write](#pullrequest-write)\n- [issue](#issue)\n- [issue:write](#issue-write)\n- [wiki](#wiki)\n- [webhook](#webhook)\n- [snippet](#snippet)\n- [snippet:write](#snippet-write)\n- [email](#email)\n- [account](#account)\n- [account:write](#account-write)\n- [pipeline](#pipeline)\n- [pipeline:write](#pipeline-write)\n- [pipeline:variable](#pipeline-variable)\n- [runner](#runner)\n- [runner:write](#runner-write)\n\n#### project\n\nProvides the [`repository`](#repository) scope permission for every repository under a project or projects.\n\n#### project:write\n\nThis scope is deprecated, and has been made obsolete by `project:admin`. Please see the deprecation notice [here](/cloud/bitbucket/deprecation-notice-project-write-scope).\n\n#### project:admin\n\nProvides admin access to a project or projects. No distinction is made between public and private projects. This scope doesn't implicitly grant the [`project`](#project) scope or the [`repository:write`](#repository-write) scope on any repositories under the project. It gives access to the admin features of a project only, not direct access to its repositories' contents.\n\n* ability to create the project\n* ability to update the project\n* ability to delete the project\n\n#### repository\n\nProvides read access to a repository or repositories.\nNote that this scope does not give access to a repository's pull requests.\n\n* access to the repo's source code\n* clone over HTTPS\n* access the file browsing API\n* download zip archives of the repo's contents\n* the ability to view and use the issue tracker on any repo (created issues, comment, vote, etc)\n* the ability to view and use the wiki on any repo (create/edit pages)\n\n#### repository:write\n\nProvides write (not admin) access to a repository or repositories. No distinction is made between public and private repositories. This scope implicitly grants the [`repository`](#repository) scope, which does not need to be requested separately.\nThis scope alone does not give access to the pull requests API.\n\n* push access over HTTPS\n* fork repos\n\n#### repository:admin\n\nProvides admin access to a repository or repositories. No distinction is made between public and private repositories. This scope doesn't implicitly grant the [`repository`](#repository) or the [`repository:write`](#repository-write) scopes. It gives access to the admin features of a repo only, not direct access to its contents. This scope can be used or misused to grant read access to other users, who can then clone the repo, but users that need to read and write source code would also request explicit read or write.\nThis scope comes with access to the following functionality:\n\n* view and manipulate committer mappings\n* list and edit deploy keys\n* ability to delete the repo\n* view and edit repo permissions\n* view and edit branch permissions\n* import and export the issue tracker\n* enable and disable the issue tracker\n* list and edit issue tracker version, milestones and components\n* enable and disable the wiki\n* list and edit default reviewers\n* list and edit repo links (Jira/Bamboo/Custom)\n* list and edit the repository webhooks\n* initiate a repo ownership transfer\n\n#### repository:delete\n\nProvides access to delete a repository or repositories.\n\n#### pullrequest\n\nProvides read access to pull requests.\nThis scope implies the [`repository`](#repository) scope, giving read access to the pull request's destination repository.\n\n* see and list pull requests\n* create and resolve tasks\n* comment on pull requests\n\n#### pullrequest:write\n\nImplicitly grants the [`pullrequest`](#pullrequest) scope and adds the ability to create, merge and decline pull requests.\nThis scope also implicitly grants the [`repository:write`](#repository-write) scope, giving write access to the pull request's destination repository. This is necessary to allow merging.\n\n* merge pull requests\n* decline pull requests\n* create pull requests\n* approve pull requests\n\n#### issue\n\nAbility to interact with issue trackers the way non-repo members can.\nThis scope doesn't implicitly grant any other scopes and doesn't give implicit access to the repository.\n\n* view, list and search issues\n* create new issues\n* comment on issues\n* watch issues\n* vote for issues\n\n#### issue:write\n\nThis scope implicitly grants the [`issue`](#issue) scope and adds the ability to transition and delete issues.\nThis scope doesn't implicitly grant any other scopes and doesn't give implicit access to the repository.\n\n* transition issues\n* delete issues\n\n#### wiki\n\nProvides access to wikis. This scope provides both read and write access (wikis are always editable by anyone with access to them).\nThis scope doesn't implicitly grant any other scopes and doesn't give implicit access to the repository.\n\n* view wikis\n* create pages\n* edit pages\n* push to wikis\n* clone wikis\n\n#### webhook\n\nGives access to webhooks. This scope is required for any webhook-related operation.\n\nThis scope gives read access to existing webhook subscriptions on all\nresources the authorization mechanism can access, without needing further scopes. \nFor example:\n\n- A client can list all existing webhook subscriptions on a repository. The [`repository`](#repository) scope is not required.\n- Existing webhook subscriptions for the issue tracker on a repo can be retrieved without the [`issue`](#issue) scope. All that is required is the `webhook` scope.\n\nTo create webhooks, the client will need read access to the resource. Such as: for [`issue:created`](#issue-created), the client will need to\nhave both the `webhook` and the [`issue`](#issue) scope.\n\n* list webhook subscriptions on any accessible repository, user, team, or snippet\n* create/update/delete webhook subscriptions.\n\n#### snippet\n\nProvides read access to snippets.\nNo distinction is made between public and private snippets (public snippets are accessible without any form of authentication).\n\n* view any snippet\n* create snippet comments\n\n#### snippet:write\n\nProvides write access to snippets.\nNo distinction is made between public and private snippets (public snippets are accessible without any form of authentication).\nThis scope implicitly grants the [`snippet`](#snippet) scope which does not need to be requested separately.\n\n* create snippets\n* edit snippets\n* delete snippets\n\n#### email\n\nAbility to see the user's primary email address. This should make it easier to use Bitbucket Cloud as a login provider for apps or external applications.\n\n#### account\n\nAbility to see all the user's account information. Note that this doesn't include any ability to change any of the data.\n\n* see all email addresses\n* language\n* location\n* website\n* full name\n* SSH keys\n* user groups\n\n#### account:write\n\nAbility to change properties on the user's account.\n\n* delete the authorizing user's account\n* manage the user's groups\n* change a user's email addresses\n* change username, display name and avatar\n\n#### pipeline\n\nGives read-only access to pipelines, steps, deployment environments and variables.\n\n#### pipeline:write\n\nGives write access to pipelines. This scope allows a user to:\n* Stop pipelines\n* Rerun failed pipelines\n* Resume halted pipelines\n* Trigger manual pipelines.\n\nThis scope is not needed to trigger a build using a push. Performing a `git push` (or equivalent actions) will trigger the build. The token doing the push only needs the [`repository:write`](#repository-write) scope.\n\nThis doesn't give write access to create variables.\n\n#### pipeline:variable\n\nGives write access to create variables in pipelines at the various levels:\n* Workspace\n* Repository\n* Deployment\n\n#### runner\n\nGives read-only access to pipelines runners setup against a workspace or repository.\n\n#### runner:write\n\nGives write access to create/edit/disable/delete pipelines runners setup against a workspace or repository.\n\n### Basic auth\n\nBasic HTTP Authentication as per [RFC-2617](https://tools.ietf.org/html/rfc2617) (Digest not supported). Note that Basic Auth is available only with username and [app password](https://bitbucket.org/account/settings/app-passwords/) as credentials.\n\n### Repository Access Tokens\n\nRepository Access Tokens are passwords (or tokens) that provide access to\n_a single repository_. These tokens can authenticate with Bitbucket APIs for\nscripting, CI/CD tools, Bitbucket Cloud-connected apps, and Bitbucket Cloud\nintegrations. The level of access provided by the token is set when a repository\nadmin creates it, by setting permission scopes. Repository Access Tokens are\nlinked to their repository, not a user or a workspace, preventing them from\nbeing used to access any other repositories or workspaces.\n\nWhen using Bitbucket APIs with a Repository Access Token, the token will be\ntreated as the \"user\" in the Bitbucket UI and Bitbucket logs. This includes\nusing the Repository Access Token to leave a comment on a pull request, push a\ncommit, or merge a pull request. The Bitbucket UI and API responses will show\nthe Repository Access Token as a user. This user uses the Repository Access\nToken name and a custom icon to differentiate it from a regular user in the UI.\n\nFor details on creating, managing, and using Repository Access Tokens, visit\n[Repository Access Tokens](https://support.atlassian.com/bitbucket-cloud/docs/repository-access-tokens/).\n\n#### Considerations for using Repository Access Tokens\n\n* After creation, a Repository Access Token can't be viewed or modified. The\ntoken's name, created date, last accessed date, and scopes are visible on the\nRepository Access Token page.\n* Repository Access Tokens can only be granted a limited set of Bitbucket's \npermission scopes.\n* Provided you set the correct permission scopes, you can use a Repository Access\nToken to clone (`repository`) and push (`repository:write`) code to the\ntoken's corresponding repository.\n* You can't use a Repository Access Token to log into the Bitbucket website.\n* Repository Access Tokens don't require two-step verification.\n* You can set permission scopes (specific access rights) for each Repository\nAccess Token.\n* You can't use a Repository Access Token to manipulate or query repository\npermissions.\n* Repository Access Tokens will not be listed in any repository or workspace \npermission API response.\n* Repository Access Tokens are deactivated when a repository is transferred or deleted.\n* Any content created by the Repository Access Token will persist after the\nRepository Access Token has been revoked.\n\n#### Available permissions scopes\n\nThe available scopes for Repository Access Tokens are:\n\n- [repository](#repository)\n- [repository:write](#repository-write)\n- [repository:admin](#repository-admin)\n- [repository:delete](#repository-delete)\n- [pullrequest](#pullrequest)\n- [pullrequest:write](#pullrequest-write)\n- [webhook](#webhook)\n- [pipeline](#pipeline)\n- [pipeline:write](#pipeline-write)\n- [pipeline:variable](#pipeline-variable)\n- [runner](#runner)\n- [runner:write](#runner-write)\n\nThere are some APIs which are inaccessible for Repository Access Tokens, these are: \n\n* [Add a repository deploy key](/cloud/bitbucket/rest/api-group-deployments/#api-repositories-workspace-repo-slug-deploy-keys-post)\n* [Update a repository deploy key](/cloud/bitbucket/rest/api-group-deployments/#api-repositories-workspace-repo-slug-deploy-keys-key-id-put)\n* [Delete a repository deploy key](/cloud/bitbucket/rest/api-group-deployments/#api-repositories-workspace-repo-slug-deploy-keys-key-id-delete)\n\n### App passwords\n\nApp passwords allow users to make API calls to their Bitbucket account through apps such as Sourcetree.\n\nSome important points about app passwords:\n\n* You cannot view an app password or adjust permissions after you create the app password. Because app passwords are encrypted on our database and cannot be viewed by anyone. They are essentially designed to be disposable. If you need to change the scopes or lost the password just create a new one.\n* You cannot use them to log into your Bitbucket account.\n* You cannot use app passwords to manage team actions.\n\n App passwords are tied to an individual account's credentials and should not be shared. If you're sharing your app password you're essentially giving direct, authenticated, access to everything that password has been scoped to do with the Bitbucket API's.\n\n* You can use them for API call authentication, even if you don't have two-step verification enabled.\n* You can set permission scopes (specific access rights) for each app password.\n\n#### Create an app password\n\nTo create an app password:\n\n1. Select **Avatar > Bitbucket settings**.\n2. [Click **App passwords** in the Access management section.](https://bitbucket.org/account/settings/app-passwords/)\n3. Click **Create app password**.\n4. Give the app password a name related to the application that will use the password.\n5. Select the specific access and permissions you want this application password to have.\n6. Copy the generated password and either record or paste it into the application you want to give access. The password is only displayed this one time.\n\nThat's all there is to creating an app password. See your applications documentation for how to apply the app password for a specific application."
},
{
"anchor": "filtering",
@@ -19723,7 +19809,7 @@
"state": {
"type": "string",
"description": "Provides some indication of the status of this commit",
- "enum": ["FAILED", "SUCCESSFUL", "INPROGRESS", "STOPPED"]
+ "enum": ["INPROGRESS", "STOPPED", "FAILED", "SUCCESSFUL"]
},
"updated_on": {
"type": "string",
@@ -20589,29 +20675,29 @@
"type": "string",
"description": "The event identifier.",
"enum": [
- "pullrequest:updated",
- "issue:comment_created",
- "issue:updated",
- "repo:fork",
- "pullrequest:changes_request_created",
- "pullrequest:comment_created",
- "repo:created",
- "repo:updated",
- "pullrequest:comment_deleted",
- "pullrequest:rejected",
"issue:created",
- "repo:imported",
- "pullrequest:unapproved",
- "pullrequest:approved",
- "pullrequest:comment_updated",
- "project:updated",
- "pullrequest:created",
- "pullrequest:fulfilled",
- "repo:commit_status_created",
- "pullrequest:changes_request_removed",
- "repo:push",
- "repo:commit_comment_created",
"repo:commit_status_updated",
+ "pullrequest:comment_created",
+ "pullrequest:created",
+ "pullrequest:unapproved",
+ "repo:commit_status_created",
+ "repo:created",
+ "pullrequest:changes_request_created",
+ "pullrequest:comment_updated",
+ "pullrequest:changes_request_removed",
+ "pullrequest:comment_deleted",
+ "repo:imported",
+ "repo:commit_comment_created",
+ "project:updated",
+ "repo:updated",
+ "issue:updated",
+ "pullrequest:rejected",
+ "pullrequest:fulfilled",
+ "issue:comment_created",
+ "repo:fork",
+ "pullrequest:updated",
+ "repo:push",
+ "pullrequest:approved",
"repo:deleted",
"repo:transfer"
]
@@ -25356,29 +25442,29 @@
"items": {
"type": "string",
"enum": [
- "pullrequest:updated",
- "issue:comment_created",
- "issue:updated",
- "repo:fork",
- "pullrequest:changes_request_created",
- "pullrequest:comment_created",
- "repo:created",
- "repo:updated",
- "pullrequest:comment_deleted",
- "pullrequest:rejected",
"issue:created",
- "repo:imported",
- "pullrequest:unapproved",
- "pullrequest:approved",
- "pullrequest:comment_updated",
- "project:updated",
- "pullrequest:created",
- "pullrequest:fulfilled",
- "repo:commit_status_created",
- "pullrequest:changes_request_removed",
- "repo:push",
- "repo:commit_comment_created",
"repo:commit_status_updated",
+ "pullrequest:comment_created",
+ "pullrequest:created",
+ "pullrequest:unapproved",
+ "repo:commit_status_created",
+ "repo:created",
+ "pullrequest:changes_request_created",
+ "pullrequest:comment_updated",
+ "pullrequest:changes_request_removed",
+ "pullrequest:comment_deleted",
+ "repo:imported",
+ "repo:commit_comment_created",
+ "project:updated",
+ "repo:updated",
+ "issue:updated",
+ "pullrequest:rejected",
+ "pullrequest:fulfilled",
+ "issue:comment_created",
+ "repo:fork",
+ "pullrequest:updated",
+ "repo:push",
+ "pullrequest:approved",
"repo:deleted",
"repo:transfer"
]
diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md
index 25f7480156..fc2c4802d0 100644
--- a/plugins/bitrise/CHANGELOG.md
+++ b/plugins/bitrise/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-bitrise
+## 0.1.39-next.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.12.1-next.4
+ - @backstage/plugin-catalog-react@1.2.2-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/core-plugin-api@1.2.0-next.2
+ - @backstage/theme@0.2.16
+
## 0.1.39-next.3
### Patch Changes
diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json
index 42415ad743..47af82bf51 100644
--- a/plugins/bitrise/package.json
+++ b/plugins/bitrise/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-bitrise",
"description": "A Backstage plugin that integrates towards Bitrise",
- "version": "0.1.39-next.3",
+ "version": "0.1.39-next.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md
index 0b8b33ec92..0078f38f95 100644
--- a/plugins/catalog-backend-module-aws/CHANGELOG.md
+++ b/plugins/catalog-backend-module-aws/CHANGELOG.md
@@ -1,5 +1,21 @@
# @backstage/plugin-catalog-backend-module-aws
+## 0.1.12-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
## 0.1.12-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json
index d2161eb02f..b929300b1f 100644
--- a/plugins/catalog-backend-module-aws/package.json
+++ b/plugins/catalog-backend-module-aws/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-aws",
"description": "A Backstage catalog backend module that helps integrate towards AWS",
- "version": "0.1.12-next.2",
+ "version": "0.1.12-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md
index 9a85995cd7..57457ee462 100644
--- a/plugins/catalog-backend-module-azure/CHANGELOG.md
+++ b/plugins/catalog-backend-module-azure/CHANGELOG.md
@@ -1,5 +1,21 @@
# @backstage/plugin-catalog-backend-module-azure
+## 0.1.10-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
## 0.1.10-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json
index 8a27ef8fae..1170fe3b9a 100644
--- a/plugins/catalog-backend-module-azure/package.json
+++ b/plugins/catalog-backend-module-azure/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-azure",
"description": "A Backstage catalog backend module that helps integrate towards Azure",
- "version": "0.1.10-next.2",
+ "version": "0.1.10-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md
index 3571832c60..27b7356712 100644
--- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md
+++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md
@@ -1,5 +1,23 @@
# @backstage/plugin-catalog-backend-module-bitbucket-cloud
+## 0.1.6-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-bitbucket-cloud-common@0.2.2-next.1
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+ - @backstage/plugin-events-node@0.2.0-next.3
+
## 0.1.6-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json
index 2ddf990448..469d2b0914 100644
--- a/plugins/catalog-backend-module-bitbucket-cloud/package.json
+++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud",
"description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud",
- "version": "0.1.6-next.2",
+ "version": "0.1.6-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md
index 496c6cde5a..117be6acb2 100644
--- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md
+++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md
@@ -1,5 +1,20 @@
# @backstage/plugin-catalog-backend-module-bitbucket-server
+## 0.1.4-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
## 0.1.4-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json
index 67eb48180a..df84c523fc 100644
--- a/plugins/catalog-backend-module-bitbucket-server/package.json
+++ b/plugins/catalog-backend-module-bitbucket-server/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-backend-module-bitbucket-server",
- "version": "0.1.4-next.2",
+ "version": "0.1.4-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md
index df447cef57..7a95b37a5c 100644
--- a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md
+++ b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/plugin-catalog-backend-module-bitbucket
+## 0.2.6-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-bitbucket-cloud-common@0.2.2-next.1
+
## 0.2.6-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json
index 33da24c9d5..3c93b66d02 100644
--- a/plugins/catalog-backend-module-bitbucket/package.json
+++ b/plugins/catalog-backend-module-bitbucket/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-bitbucket",
"description": "A Backstage catalog backend module that helps integrate towards Bitbucket",
- "version": "0.2.6-next.2",
+ "version": "0.2.6-next.3",
"deprecated": true,
"main": "src/index.ts",
"types": "src/index.ts",
diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md
index 5b3995adf8..27eca385b3 100644
--- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md
+++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md
@@ -1,5 +1,20 @@
# @backstage/plugin-catalog-backend-module-gerrit
+## 0.1.7-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
## 0.1.7-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json
index e20b049fbe..eaa9980507 100644
--- a/plugins/catalog-backend-module-gerrit/package.json
+++ b/plugins/catalog-backend-module-gerrit/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-backend-module-gerrit",
- "version": "0.1.7-next.2",
+ "version": "0.1.7-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md
index 25839df3d4..e71ab6ecc1 100644
--- a/plugins/catalog-backend-module-github/CHANGELOG.md
+++ b/plugins/catalog-backend-module-github/CHANGELOG.md
@@ -1,5 +1,24 @@
# @backstage/plugin-catalog-backend-module-github
+## 0.2.2-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+ - @backstage/plugin-events-node@0.2.0-next.3
+
## 0.2.2-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json
index ce25e99420..88c9d8f738 100644
--- a/plugins/catalog-backend-module-github/package.json
+++ b/plugins/catalog-backend-module-github/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-github",
"description": "A Backstage catalog backend module that helps integrate towards GitHub",
- "version": "0.2.2-next.2",
+ "version": "0.2.2-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md
index 3f7a2e7f1f..ade90d90a2 100644
--- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md
+++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md
@@ -1,5 +1,21 @@
# @backstage/plugin-catalog-backend-module-gitlab
+## 0.1.10-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
## 0.1.10-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json
index 57aeba228b..ac0ac4aa1d 100644
--- a/plugins/catalog-backend-module-gitlab/package.json
+++ b/plugins/catalog-backend-module-gitlab/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-gitlab",
"description": "A Backstage catalog backend module that helps integrate towards GitLab",
- "version": "0.1.10-next.2",
+ "version": "0.1.10-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md
index 9b80fce23c..8b246385bd 100644
--- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md
+++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md
@@ -1,5 +1,21 @@
# @backstage/plugin-catalog-backend-module-incremental-ingestion
+## 0.1.0-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/backend-test-utils@0.1.31-next.4
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
## 0.1.0-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json
index 15826cd65a..d7a5ae7470 100644
--- a/plugins/catalog-backend-module-incremental-ingestion/package.json
+++ b/plugins/catalog-backend-module-incremental-ingestion/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-incremental-ingestion",
"description": "An entity provider for streaming large asset sources into the catalog",
- "version": "0.1.0-next.2",
+ "version": "0.1.0-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.ts b/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.ts
index 44da5067fd..a6cfe14df2 100644
--- a/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.ts
+++ b/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.ts
@@ -14,9 +14,12 @@
* limitations under the License.
*/
-import { Logger, loggerToWinstonLogger } from '@backstage/backend-plugin-api';
-import { PluginTaskScheduler } from '@backstage/backend-tasks';
-import { Config } from '@backstage/config';
+import {
+ ConfigService,
+ LoggerService,
+ SchedulerService,
+ loggerToWinstonLogger,
+} from '@backstage/backend-plugin-api';
import { stringifyError } from '@backstage/errors';
import {
EntityProvider,
@@ -46,10 +49,10 @@ export class WrapperProviders {
constructor(
private readonly options: {
- config: Config;
- logger: Logger;
+ config: ConfigService;
+ logger: LoggerService;
client: Knex;
- scheduler: PluginTaskScheduler;
+ scheduler: SchedulerService;
applyDatabaseMigrations?: typeof applyDatabaseMigrations;
},
) {}
diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md
index 4ad3ad72e7..aa2d15b1ce 100644
--- a/plugins/catalog-backend-module-ldap/CHANGELOG.md
+++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-catalog-backend-module-ldap
+## 0.5.6-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/types@1.0.2-next.1
+
## 0.5.6-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json
index eb75e4b35b..68268f657f 100644
--- a/plugins/catalog-backend-module-ldap/package.json
+++ b/plugins/catalog-backend-module-ldap/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-ldap",
"description": "A Backstage catalog backend module that helps integrate towards LDAP",
- "version": "0.5.6-next.2",
+ "version": "0.5.6-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md
index b7388fab71..e26b6801c0 100644
--- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md
+++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-catalog-backend-module-msgraph
+## 0.4.5-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-tasks@0.4.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
## 0.4.5-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json
index 95fc9f33a8..e38a1c3a09 100644
--- a/plugins/catalog-backend-module-msgraph/package.json
+++ b/plugins/catalog-backend-module-msgraph/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-msgraph",
"description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph",
- "version": "0.4.5-next.2",
+ "version": "0.4.5-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md
index beb20a2118..c087d239dd 100644
--- a/plugins/catalog-backend-module-openapi/CHANGELOG.md
+++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md
@@ -1,5 +1,18 @@
# @backstage/plugin-catalog-backend-module-openapi
+## 0.1.5-next.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@1.6.0-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+
## 0.1.5-next.2
### Patch Changes
diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json
index 868f201a51..2791f54678 100644
--- a/plugins/catalog-backend-module-openapi/package.json
+++ b/plugins/catalog-backend-module-openapi/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-openapi",
"description": "A Backstage catalog backend module that helps with OpenAPI specifications",
- "version": "0.1.5-next.2",
+ "version": "0.1.5-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md
index bcfc66db88..8fc297e1b8 100644
--- a/plugins/catalog-backend/CHANGELOG.md
+++ b/plugins/catalog-backend/CHANGELOG.md
@@ -1,5 +1,28 @@
# @backstage/plugin-catalog-backend
+## 1.6.0-next.3
+
+### Patch Changes
+
+- ba13ff663c: Added a new `catalog.rules[].location` configuration that makes it possible to configure catalog rules to only apply to specific locations, either via exact match or a glob pattern.
+- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries
+- 71147d5c16: Internal code reorganization.
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.7.2-next.2
+ - @backstage/plugin-permission-node@0.7.2-next.3
+ - @backstage/backend-common@0.17.0-next.3
+ - @backstage/backend-plugin-api@0.2.0-next.3
+ - @backstage/catalog-client@1.2.0-next.1
+ - @backstage/catalog-model@1.1.4-next.1
+ - @backstage/config@1.0.5-next.1
+ - @backstage/errors@1.1.4-next.1
+ - @backstage/integration@1.4.1-next.1
+ - @backstage/types@1.0.2-next.1
+ - @backstage/plugin-catalog-common@1.0.9-next.3
+ - @backstage/plugin-catalog-node@1.3.0-next.3
+ - @backstage/plugin-scaffolder-common@1.2.3-next.1
+ - @backstage/plugin-search-common@1.2.0-next.3
+
## 1.6.0-next.2
### Minor Changes
diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md
index a46abda5d3..3e6c5ef676 100644
--- a/plugins/catalog-backend/api-report.md
+++ b/plugins/catalog-backend/api-report.md
@@ -239,7 +239,7 @@ export type CatalogPermissionRule<
// @alpha
export const catalogPlugin: (options?: undefined) => BackendFeature;
-// @public (undocumented)
+// @public
export interface CatalogProcessingEngine {
// (undocumented)
start(): Promise;
diff --git a/plugins/catalog-backend/config.d.ts b/plugins/catalog-backend/config.d.ts
index daa70656bc..5c5bfea753 100644
--- a/plugins/catalog-backend/config.d.ts
+++ b/plugins/catalog-backend/config.d.ts
@@ -38,6 +38,37 @@ export interface Config {
* E.g. ["Component", "API", "Template", "Location"]
*/
allow: Array;
+ /**
+ * Limit this rule to a specific location
+ *
+ * Example with a fixed location
+ * { "type": "url", "exact": "https://github.com/a/b/blob/file.yaml"}
+ *
+ * Example using a Regex
+ * { "type": "url", "pattern": "https://github.com/org/*\/blob/master/*.yaml"}
+ *
+ * Using both exact and pattern will result in an error starting the application
+ */
+ locations?: Array<{
+ /**
+ * The type of location, e.g. "url".
+ */
+ type: string;
+ /**
+ * The exact location, e.g.
+ * "https://github.com/org/repo/blob/master/users.yaml".
+ *
+ * The exact location can also be used to match on locations
+ * that contain glob characters themselves, e.g.
+ * "https://github.com/org/*\/blob/master/*.yaml".
+ */
+ exact?: string;
+ /**
+ * The pattern allowed for the location, e.g.
+ * "https://github.com/org/*\/blob/master/*.yaml".
+ */
+ pattern?: string;
+ }>;
}>;
/**
diff --git a/plugins/catalog-backend/migrations/20221201085245_add_last_updated_at_in_final_entities.js b/plugins/catalog-backend/migrations/20221201085245_add_last_updated_at_in_final_entities.js
new file mode 100644
index 0000000000..44fcf30ba4
--- /dev/null
+++ b/plugins/catalog-backend/migrations/20221201085245_add_last_updated_at_in_final_entities.js
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// @ts-check
+
+/**
+ * @param { import("knex").Knex } knex
+ */
+exports.up = async function up(knex) {
+ await knex.schema.table('final_entities', table => {
+ table
+ .dateTime('last_updated_at')
+ .nullable()
+ .comment('The time when final_entity changed');
+ });
+};
+
+/**
+ * @param { import("knex").Knex } knex
+ * @returns { Promise }
+ */
+exports.down = async function down(knex) {
+ await knex.schema.table('final_entities', table => {
+ table.dropColumn('last_updated_at');
+ });
+};
diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json
index fe8ccc609d..2bae86b38a 100644
--- a/plugins/catalog-backend/package.json
+++ b/plugins/catalog-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend",
"description": "The Backstage backend plugin that provides the Backstage catalog",
- "version": "1.6.0-next.2",
+ "version": "1.6.0-next.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -47,6 +47,7 @@
"@backstage/plugin-scaffolder-common": "workspace:^",
"@backstage/plugin-search-common": "workspace:^",
"@backstage/types": "workspace:^",
+ "@opentelemetry/api": "^1.3.0",
"@types/express": "^4.17.6",
"codeowners-utils": "^1.0.2",
"core-js": "^3.6.5",
@@ -59,6 +60,7 @@
"knex": "^2.0.0",
"lodash": "^4.17.21",
"luxon": "^3.0.0",
+ "minimatch": "^5.0.0",
"node-fetch": "^2.6.7",
"p-limit": "^3.0.2",
"prom-client": "^14.0.1",
@@ -66,7 +68,7 @@
"winston": "^3.2.1",
"yaml": "^2.0.0",
"yn": "^4.0.0",
- "zod": "^3.11.6"
+ "zod": "~3.18.0"
},
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
diff --git a/plugins/catalog-backend/src/database/DefaultCatalogDatabase.test.ts b/plugins/catalog-backend/src/database/DefaultCatalogDatabase.test.ts
new file mode 100644
index 0000000000..b873f6a985
--- /dev/null
+++ b/plugins/catalog-backend/src/database/DefaultCatalogDatabase.test.ts
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { getVoidLogger } from '@backstage/backend-common';
+import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils';
+import { Logger } from 'winston';
+import { DefaultCatalogDatabase } from './DefaultCatalogDatabase';
+import { applyDatabaseMigrations } from './migrations';
+import { DbRefreshStateReferencesRow, DbRefreshStateRow } from './tables';
+
+describe('DefaultCatalogDatabase', () => {
+ const defaultLogger = getVoidLogger();
+ const databases = TestDatabases.create({
+ ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'],
+ });
+
+ async function createDatabase(
+ databaseId: TestDatabaseId,
+ logger: Logger = defaultLogger,
+ ) {
+ const knex = await databases.init(databaseId);
+ await applyDatabaseMigrations(knex);
+ return {
+ knex,
+ db: new DefaultCatalogDatabase({
+ database: knex,
+ logger,
+ }),
+ };
+ }
+
+ describe('listAncestors', () => {
+ let nextId = 1;
+ function makeEntity(ref: string) {
+ return {
+ entity_id: String(nextId++),
+ entity_ref: ref,
+ unprocessed_entity: JSON.stringify({
+ kind: 'Location',
+ apiVersion: '1.0.0',
+ metadata: {
+ name: 'xyz',
+ },
+ }),
+ errors: '[]',
+ next_update_at: '2019-01-01 23:00:00',
+ last_discovery_at: '2021-04-01 13:37:00',
+ };
+ }
+
+ it.each(databases.eachSupportedId())(
+ 'should return ancestors, %p',
+ async databaseId => {
+ const { knex, db } = await createDatabase(databaseId);
+
+ await knex('refresh_state').insert(
+ makeEntity('location:default/root-1'),
+ );
+ await knex('refresh_state').insert(
+ makeEntity('location:default/root-2'),
+ );
+ await knex('refresh_state').insert(
+ makeEntity('component:default/foobar'),
+ );
+
+ await knex(
+ 'refresh_state_references',
+ ).insert({
+ source_key: 'source',
+ target_entity_ref: 'location:default/root-2',
+ });
+ await knex(
+ 'refresh_state_references',
+ ).insert({
+ source_entity_ref: 'location:default/root-2',
+ target_entity_ref: 'location:default/root-1',
+ });
+ await knex(
+ 'refresh_state_references',
+ ).insert({
+ source_entity_ref: 'location:default/root-1',
+ target_entity_ref: 'component:default/foobar',
+ });
+
+ const result = await db.transaction(tx =>
+ db.listAncestors(tx, {
+ entityRef: 'component:default/foobar',
+ }),
+ );
+ expect(result.entityRefs).toEqual([
+ 'location:default/root-1',
+ 'location:default/root-2',
+ ]);
+ },
+ );
+ });
+});
diff --git a/plugins/catalog-backend/src/database/DefaultCatalogDatabase.ts b/plugins/catalog-backend/src/database/DefaultCatalogDatabase.ts
new file mode 100644
index 0000000000..98b100c91e
--- /dev/null
+++ b/plugins/catalog-backend/src/database/DefaultCatalogDatabase.ts
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2020 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { NotFoundError } from '@backstage/errors';
+import { Knex } from 'knex';
+import type { Logger } from 'winston';
+import {
+ CatalogDatabase,
+ ListAncestorsOptions,
+ ListAncestorsResult,
+ RefreshOptions,
+} from './types';
+import { DbRefreshStateReferencesRow, DbRefreshStateRow } from './tables';
+import { rethrowError } from './conversion';
+import { Transaction } from './types';
+
+const MAX_ANCESTOR_DEPTH = 32;
+
+export class DefaultCatalogDatabase implements CatalogDatabase {
+ constructor(
+ private readonly options: {
+ database: Knex;
+ logger: Logger;
+ },
+ ) {}
+
+ async transaction(fn: (tx: Transaction) => Promise): Promise {
+ try {
+ let result: T | undefined = undefined;
+
+ await this.options.database.transaction(
+ async tx => {
+ // We can't return here, as knex swallows the return type in case the transaction is rolled back:
+ // https://github.com/knex/knex/blob/e37aeaa31c8ef9c1b07d2e4d3ec6607e557d800d/lib/transaction.js#L136
+ result = await fn(tx);
+ },
+ {
+ // If we explicitly trigger a rollback, don't fail.
+ doNotRejectOnRollback: true,
+ },
+ );
+
+ return result!;
+ } catch (e) {
+ this.options.logger.debug(`Error during transaction, ${e}`);
+ throw rethrowError(e);
+ }
+ }
+
+ async listAncestors(
+ txOpaque: Transaction,
+ options: ListAncestorsOptions,
+ ): Promise {
+ const tx = txOpaque as Knex.Transaction;
+ const { entityRef } = options;
+ const entityRefs = new Array();
+
+ let currentRef = entityRef.toLocaleLowerCase('en-US');
+ for (let depth = 1; depth <= MAX_ANCESTOR_DEPTH; depth += 1) {
+ const rows = await tx(
+ 'refresh_state_references',
+ )
+ .where({ target_entity_ref: currentRef })
+ .select();
+
+ if (rows.length === 0) {
+ if (depth === 1) {
+ throw new NotFoundError(`Entity ${currentRef} not found`);
+ }
+ throw new NotFoundError(
+ `Entity ${entityRef} has a broken parent reference chain at ${currentRef}`,
+ );
+ }
+
+ const parentRef = rows.find(r => r.source_entity_ref)?.source_entity_ref;
+ if (!parentRef) {
+ // We've reached the top of the tree which is the entityProvider.
+ // In this case we refresh the entity itself.
+ return { entityRefs };
+ }
+ entityRefs.push(parentRef);
+ currentRef = parentRef;
+ }
+ throw new Error(
+ `Unable receive ancestors for ${entityRef}, reached maximum depth of ${MAX_ANCESTOR_DEPTH}`,
+ );
+ }
+
+ async refresh(txOpaque: Transaction, options: RefreshOptions): Promise {
+ const tx = txOpaque as Knex.Transaction;
+ const { entityRef } = options;
+
+ const updateResult = await tx('refresh_state')
+ .where({ entity_ref: entityRef.toLocaleLowerCase('en-US') })
+ .update({ next_update_at: tx.fn.now() });
+ if (updateResult === 0) {
+ throw new NotFoundError(`Failed to schedule ${entityRef} for refresh`);
+ }
+ }
+}
diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts
index 1056557706..4fbb38b4fc 100644
--- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts
+++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts
@@ -33,7 +33,7 @@ import { createRandomProcessingInterval } from '../processing/refresh';
import { timestampToDateTime } from './conversion';
import { generateStableHash } from './util';
-describe('Default Processing Database', () => {
+describe('DefaultProcessingDatabase', () => {
const defaultLogger = getVoidLogger();
const databases = TestDatabases.create({
ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'],
@@ -582,664 +582,6 @@ describe('Default Processing Database', () => {
);
});
- describe('replaceUnprocessedEntities', () => {
- const createLocations = async (db: Knex, entityRefs: string[]) => {
- for (const ref of entityRefs) {
- await insertRefreshStateRow(db, {
- entity_id: uuid.v4(),
- entity_ref: ref,
- unprocessed_entity: '{}',
- processed_entity: '{}',
- errors: '[]',
- next_update_at: '2021-04-01 13:37:00',
- last_discovery_at: '2021-04-01 13:37:00',
- });
- }
- };
-
- it.each(databases.eachSupportedId())(
- 'replaces all existing state correctly for simple dependency chains, %p',
- async databaseId => {
- const { knex, db } = await createDatabase(databaseId);
- /*
- config -> location:default/root -> location:default/root-1 -> location:default/root-2
- database -> location:default/second -> location:default/root-2
- */
- await createLocations(knex, [
- 'location:default/root',
- 'location:default/root-1',
- 'location:default/root-2',
- 'location:default/second',
- ]);
-
- await insertRefRow(knex, {
- source_key: 'config',
- target_entity_ref: 'location:default/root',
- });
-
- await insertRefRow(knex, {
- source_key: 'database',
- target_entity_ref: 'location:default/second',
- });
-
- await insertRefRow(knex, {
- source_entity_ref: 'location:default/root',
- target_entity_ref: 'location:default/root-1',
- });
-
- await insertRefRow(knex, {
- source_entity_ref: 'location:default/root-1',
- target_entity_ref: 'location:default/root-2',
- });
-
- await insertRefRow(knex, {
- source_entity_ref: 'location:default/second',
- target_entity_ref: 'location:default/root-2',
- });
-
- await db.transaction(tx =>
- db.replaceUnprocessedEntities(tx, {
- type: 'full',
- sourceKey: 'config',
- items: [
- {
- entity: {
- apiVersion: '1.0.0',
- metadata: {
- name: 'new-root',
- },
- kind: 'Location',
- } as Entity,
- locationKey: 'file:///tmp/foobar',
- },
- ],
- }),
- );
-
- const currentRefreshState = await knex(
- 'refresh_state',
- ).select();
-
- const currentRefRowState = await knex(
- 'refresh_state_references',
- ).select();
-
- for (const ref of [
- 'location:default/root',
- 'location:default/root-1',
- ]) {
- expect(
- currentRefreshState.some(t => t.entity_ref === ref),
- ).toBeFalsy();
- }
-
- expect(
- currentRefreshState.some(
- t => t.entity_ref === 'location:default/new-root',
- ),
- ).toBeTruthy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_entity_ref === 'location:default/root' &&
- t.target_entity_ref === 'location:default/root-1',
- ),
- ).toBeFalsy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_entity_ref === 'location:default/root-1' &&
- t.target_entity_ref === 'location:default/root-2',
- ),
- ).toBeFalsy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.target_entity_ref === 'location:default/root-1' &&
- t.source_key === 'config',
- ),
- ).toBeFalsy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.target_entity_ref === 'location:default/new-root' &&
- t.source_key === 'config',
- ),
- ).toBeTruthy();
- },
- 60_000,
- );
-
- it.each(databases.eachSupportedId())(
- 'should work for more complex chains, %p',
- async databaseId => {
- const { knex, db } = await createDatabase(databaseId);
- /*
- config -> location:default/root -> location:default/root-1 -> location:default/root-2
- config -> location:default/root -> location:default/root-1a -> location:default/root-2
- */
- await createLocations(knex, [
- 'location:default/root',
- 'location:default/root-1',
- 'location:default/root-2',
- 'location:default/root-1a',
- ]);
-
- await insertRefRow(knex, {
- source_key: 'config',
- target_entity_ref: 'location:default/root',
- });
-
- await insertRefRow(knex, {
- source_entity_ref: 'location:default/root',
- target_entity_ref: 'location:default/root-1',
- });
-
- await insertRefRow(knex, {
- source_entity_ref: 'location:default/root',
- target_entity_ref: 'location:default/root-1a',
- });
-
- await insertRefRow(knex, {
- source_entity_ref: 'location:default/root-1',
- target_entity_ref: 'location:default/root-2',
- });
-
- await insertRefRow(knex, {
- source_entity_ref: 'location:default/root-1a',
- target_entity_ref: 'location:default/root-2',
- });
-
- await db.transaction(async tx => {
- await db.replaceUnprocessedEntities(tx, {
- type: 'full',
- sourceKey: 'config',
- items: [
- {
- entity: {
- apiVersion: '1.0.0',
- metadata: {
- name: 'new-root',
- },
- kind: 'Location',
- } as Entity,
- locationKey: 'file:/tmp/foobar',
- },
- ],
- });
- });
-
- const currentRefreshState = await knex(
- 'refresh_state',
- ).select();
-
- const currentRefRowState = await knex(
- 'refresh_state_references',
- ).select();
-
- const deletedRefs = [
- 'location:default/root',
- 'location:default/root-1',
- 'location:default/root-1a',
- 'location:default/root-2',
- ];
-
- for (const ref of deletedRefs) {
- expect(
- currentRefreshState.some(t => t.entity_ref === ref),
- ).toBeFalsy();
- }
-
- expect(
- currentRefreshState.some(
- t => t.entity_ref === 'location:default/new-root',
- ),
- ).toBeTruthy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_key === 'config' &&
- t.target_entity_ref === 'location:default/new-root',
- ),
- ).toBeTruthy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_key === 'config' &&
- t.target_entity_ref === 'location:default/root',
- ),
- ).toBeFalsy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_entity_ref === 'location:default/root' &&
- t.target_entity_ref === 'location:default/root-1',
- ),
- ).toBeFalsy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_entity_ref === 'location:default/root' &&
- t.target_entity_ref === 'location:default/root-1a',
- ),
- ).toBeFalsy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_entity_ref === 'location:default/root-1' &&
- t.target_entity_ref === 'location:default/root-2',
- ),
- ).toBeFalsy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_entity_ref === 'location:default/root-1a' &&
- t.target_entity_ref === 'location:default/root-2',
- ),
- ).toBeFalsy();
- },
- 60_000,
- );
-
- it.each(databases.eachSupportedId())(
- 'should add new locations using the delta options, %p',
- async databaseId => {
- const { knex, db } = await createDatabase(databaseId);
-
- // Existing state and references should stay
- await createLocations(knex, ['location:default/existing']);
- await insertRefRow(knex, {
- source_key: 'lols',
- target_entity_ref: 'location:default/existing',
- });
-
- await db.transaction(async tx => {
- await db.replaceUnprocessedEntities(tx, {
- type: 'delta',
- sourceKey: 'lols',
- removed: [],
- added: [
- {
- entity: {
- apiVersion: '1.0.0',
- metadata: {
- name: 'new-root',
- },
- kind: 'Location',
- } as Entity,
- locationKey: 'file:///tmp/foobar',
- },
- ],
- });
- });
-
- const currentRefreshState = await knex(
- 'refresh_state',
- ).select();
-
- const currentRefRowState = await knex(
- 'refresh_state_references',
- ).select();
-
- expect(
- currentRefreshState.some(
- t => t.entity_ref === 'location:default/new-root',
- ),
- ).toBeTruthy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_key === 'lols' &&
- t.target_entity_ref === 'location:default/new-root',
- ),
- ).toBeTruthy();
-
- expect(
- currentRefreshState.some(
- t => t.entity_ref === 'location:default/existing',
- ),
- ).toBeTruthy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_key === 'lols' &&
- t.target_entity_ref === 'location:default/existing',
- ),
- ).toBeTruthy();
- },
- 60_000,
- );
-
- it.each(databases.eachSupportedId())(
- 'should not remove locations that are referenced elsewhere, %p',
- async databaseId => {
- const { knex, db } = await createDatabase(databaseId);
- /*
- config-1 -> location:default/root
- config-2 -> location:default/root
- */
- await createLocations(knex, ['location:default/root']);
-
- await insertRefRow(knex, {
- source_key: 'config-1',
- target_entity_ref: 'location:default/root',
- });
- await insertRefRow(knex, {
- source_key: 'config-2',
- target_entity_ref: 'location:default/root',
- });
-
- await db.transaction(async tx => {
- await db.replaceUnprocessedEntities(tx, {
- type: 'full',
- sourceKey: 'config-1',
- items: [],
- });
- });
-
- const currentRefreshState = await knex(
- 'refresh_state',
- ).select();
-
- const currentRefRowState = await knex(
- 'refresh_state_references',
- ).select();
-
- expect(currentRefRowState).toEqual([
- expect.objectContaining({
- source_key: 'config-2',
- target_entity_ref: 'location:default/root',
- }),
- ]);
-
- expect(currentRefreshState).toEqual([
- expect.objectContaining({
- entity_ref: 'location:default/root',
- }),
- ]);
- },
- 60_000,
- );
-
- it.each(databases.eachSupportedId())(
- 'should remove old locations using the delta options, %p',
- async databaseId => {
- const { knex, db } = await createDatabase(databaseId);
- await createLocations(knex, ['location:default/new-root']);
-
- await insertRefRow(knex, {
- source_key: 'lols',
- target_entity_ref: 'location:default/new-root',
- });
-
- await db.transaction(async tx => {
- await db.replaceUnprocessedEntities(tx, {
- type: 'delta',
- sourceKey: 'lols',
- added: [],
- removed: [
- {
- entityRef: 'location:default/new-root',
- locationKey: 'file:/tmp/foobar',
- },
- ],
- });
- });
-
- const currentRefreshState = await knex(
- 'refresh_state',
- ).select();
-
- const currentRefRowState = await knex(
- 'refresh_state_references',
- ).select();
-
- expect(
- currentRefreshState.some(
- t => t.entity_ref === 'location:default/new-root',
- ),
- ).toBeFalsy();
-
- expect(
- currentRefRowState.some(
- t =>
- t.source_key === 'lols' &&
- t.target_entity_ref === 'location:default/new-root',
- ),
- ).toBeFalsy();
- },
- 60_000,
- );
-
- it.each(databases.eachSupportedId())(
- 'should update the location key during full replace, %p',
- async databaseId => {
- const { knex, db } = await createDatabase(databaseId);
- await createLocations(knex, ['location:default/removed']);
- await insertRefreshStateRow(knex, {
- entity_id: uuid.v4(),
- entity_ref: 'location:default/replaced',
- unprocessed_entity: '{}',
- processed_entity: '{}',
- errors: '[]',
- next_update_at: '2021-04-01 13:37:00',
- last_discovery_at: '2021-04-01 13:37:00',
- location_key: 'file:///tmp/old',
- });
-
- await insertRefRow(knex, {
- source_key: 'lols',
- target_entity_ref: 'location:default/removed',
- });
- await insertRefRow(knex, {
- source_key: 'lols',
- target_entity_ref: 'location:default/replaced',
- });
-
- await db.transaction(async tx => {
- await db.replaceUnprocessedEntities(tx, {
- type: 'full',
- sourceKey: 'lols',
- items: [
- {
- entity: {
- apiVersion: '1.0.0',
- metadata: {
- name: 'replaced',
- },
- kind: 'Location',
- } as Entity,
- locationKey: 'file:///tmp/foobar',
- },
- ],
- });
- });
-
- const currentRefreshState = await knex(
- 'refresh_state',
- ).select();
- expect(currentRefreshState).toEqual([
- expect.objectContaining({
- entity_ref: 'location:default/replaced',
- location_key: 'file:///tmp/foobar',
- }),
- ]);
-
- const currentRefRowState = await knex(
- 'refresh_state_references',
- ).select();
- expect(currentRefRowState).toEqual([
- expect.objectContaining({
- source_key: 'lols',
- target_entity_ref: 'location:default/replaced',
- }),
- ]);
- },
- 60_000,
- );
-
- it.each(databases.eachSupportedId())(
- 'should support replacing modified entities during a full update, %p',
- async databaseId => {
- const { knex, db } = await createDatabase(databaseId);
-
- await db.transaction(async tx => {
- await db.replaceUnprocessedEntities(tx, {
- type: 'full',
- sourceKey: 'lols',
- items: [
- {
- entity: {
- apiVersion: '1',
- kind: 'Component',
- metadata: { name: 'a' },
- spec: { marker: 'WILL_CHANGE' },
- } as Entity,
- locationKey: 'file:///tmp/a',
- },
- {
- entity: {
- apiVersion: '1',
- kind: 'Component',
- metadata: { name: 'b' },
- spec: { marker: 'NEVER_CHANGES' },
- } as Entity,
- locationKey: 'file:///tmp/b',
- },
- ],
- });
- });
-
- let state = await knex('refresh_state').select();
- expect(state).toEqual(
- expect.arrayContaining([
- expect.objectContaining({
- entity_ref: 'component:default/a',
- location_key: 'file:///tmp/a',
- unprocessed_entity: expect.stringContaining('WILL_CHANGE'),
- }),
- expect.objectContaining({
- entity_ref: 'component:default/b',
- location_key: 'file:///tmp/b',
- unprocessed_entity: expect.stringContaining('NEVER_CHANGES'),
- }),
- ]),
- );
-
- await db.transaction(async tx => {
- await db.replaceUnprocessedEntities(tx, {
- type: 'full',
- sourceKey: 'lols',
- items: [
- {
- entity: {
- apiVersion: '1',
- kind: 'Component',
- metadata: { name: 'a' },
- spec: { marker: 'HAS_CHANGED' },
- } as Entity,
- locationKey: 'file:///tmp/a',
- },
- {
- entity: {
- apiVersion: '1',
- kind: 'Component',
- metadata: { name: 'b' },
- spec: { marker: 'NEVER_CHANGES' },
- } as Entity,
- locationKey: 'file:///tmp/b',
- },
- ],
- });
- });
-
- state = await knex('refresh_state').select();
- expect(state).toEqual(
- expect.arrayContaining([
- expect.objectContaining({
- entity_ref: 'component:default/a',
- location_key: 'file:///tmp/a',
- unprocessed_entity: expect.stringContaining('HAS_CHANGED'),
- }),
- expect.objectContaining({
- entity_ref: 'component:default/b',
- location_key: 'file:///tmp/b',
- unprocessed_entity: expect.stringContaining('NEVER_CHANGES'),
- }),
- ]),
- );
- },
- 60_000,
- );
-
- it.each(databases.eachSupportedId())(
- 'should successfully fall back from batch to individual mode on conflicts, %p',
- async databaseId => {
- const fakeLogger = {
- debug: jest.fn(),
- };
- const { knex, db } = await createDatabase(
- databaseId,
- fakeLogger as any,
- );
-
- await createLocations(knex, ['component:default/a']);
-
- await insertRefRow(knex, {
- source_key: undefined,
- target_entity_ref: 'component:default/a',
- });
-
- await db.transaction(async tx => {
- await db.replaceUnprocessedEntities(tx, {
- type: 'full',
- sourceKey: 'lols',
- items: [
- {
- entity: {
- apiVersion: '1',
- kind: 'Component',
- metadata: { name: 'a' },
- spec: { marker: 'WILL_CHANGE' },
- } as Entity,
- locationKey: 'file:///tmp/a',
- },
- ],
- });
- });
- expect(fakeLogger.debug).toHaveBeenCalledWith(
- expect.stringMatching(
- /Fast insert path failed, falling back to slow path/,
- ),
- );
-
- const state = await knex('refresh_state').select();
- expect(state).toEqual(
- expect.arrayContaining([
- expect.objectContaining({
- entity_ref: 'component:default/a',
- location_key: 'file:///tmp/a',
- unprocessed_entity: expect.stringContaining('WILL_CHANGE'),
- }),
- ]),
- );
- },
- 60_000,
- );
- });
-
describe('getProcessableEntities', () => {
it.each(databases.eachSupportedId())(
'should return entities to process, %p',
@@ -1329,64 +671,6 @@ describe('Default Processing Database', () => {
);
});
- describe('listAncestors', () => {
- let nextId = 1;
- function makeEntity(ref: string) {
- return {
- entity_id: String(nextId++),
- entity_ref: ref,
- unprocessed_entity: JSON.stringify({
- kind: 'Location',
- apiVersion: '1.0.0',
- metadata: {
- name: 'xyz',
- },
- }),
- errors: '[]',
- next_update_at: '2019-01-01 23:00:00',
- last_discovery_at: '2021-04-01 13:37:00',
- };
- }
-
- it.each(databases.eachSupportedId())(
- 'should return ancestors, %p',
- async databaseId => {
- const { knex, db } = await createDatabase(databaseId);
-
- await knex('refresh_state').insert(
- makeEntity('location:default/root-1'),
- );
- await knex('refresh_state').insert(
- makeEntity('location:default/root-2'),
- );
- await knex('refresh_state').insert(
- makeEntity('component:default/foobar'),
- );
-
- await insertRefRow(knex, {
- source_key: 'source',
- target_entity_ref: 'location:default/root-2',
- });
- await insertRefRow(knex, {
- source_entity_ref: 'location:default/root-2',
- target_entity_ref: 'location:default/root-1',
- });
- await insertRefRow(knex, {
- source_entity_ref: 'location:default/root-1',
- target_entity_ref: 'component:default/foobar',
- });
-
- const result = await db.transaction(async tx =>
- db.listAncestors(tx, { entityRef: 'component:default/foobar' }),
- );
- expect(result.entityRefs).toEqual([
- 'location:default/root-1',
- 'location:default/root-2',
- ]);
- },
- );
- });
-
describe('listParents', () => {
let nextId = 1;
function makeEntity(ref: string) {
diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts
index 97259bce29..1127deed7e 100644
--- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts
+++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts
@@ -15,26 +15,10 @@
*/
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
-import { ConflictError, NotFoundError } from '@backstage/errors';
+import { ConflictError } from '@backstage/errors';
import { Knex } from 'knex';
import lodash from 'lodash';
-import { v4 as uuid } from 'uuid';
import type { Logger } from 'winston';
-import {
- Transaction,
- GetProcessableEntitiesResult,
- ProcessingDatabase,
- RefreshStateItem,
- RefreshOptions,
- ReplaceUnprocessedEntitiesOptions,
- UpdateProcessedEntityOptions,
- ListAncestorsOptions,
- ListAncestorsResult,
- UpdateEntityCacheOptions,
- ListParentsOptions,
- ListParentsResult,
- RefreshByKeyOptions,
-} from './types';
import { ProcessingIntervalFunction } from '../processing/refresh';
import { rethrowError, timestampToDateTime } from './conversion';
import { initDatabaseMetrics } from './metrics';
@@ -44,17 +28,28 @@ import {
DbRefreshStateRow,
DbRelationsRow,
} from './tables';
+import {
+ GetProcessableEntitiesResult,
+ ListParentsOptions,
+ ListParentsResult,
+ ProcessingDatabase,
+ RefreshStateItem,
+ Transaction,
+ UpdateEntityCacheOptions,
+ UpdateProcessedEntityOptions,
+} from './types';
-import { generateStableHash } from './util';
-import { isDatabaseConflictError } from '@backstage/backend-common';
import { DeferredEntity } from '@backstage/plugin-catalog-node';
+import { checkLocationKeyConflict } from './operations/refreshState/checkLocationKeyConflict';
+import { insertUnprocessedEntity } from './operations/refreshState/insertUnprocessedEntity';
+import { updateUnprocessedEntity } from './operations/refreshState/updateUnprocessedEntity';
+import { generateStableHash } from './util';
// The number of items that are sent per batch to the database layer, when
// doing .batchInsert calls to knex. This needs to be low enough to not cause
// errors in the underlying engine due to exceeding query limits, but large
// enough to get the speed benefits.
const BATCH_SIZE = 50;
-const MAX_ANCESTOR_DEPTH = 32;
export class DefaultProcessingDatabase implements ProcessingDatabase {
constructor(
@@ -193,236 +188,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase {
.where('entity_id', id);
}
- async replaceUnprocessedEntities(
- txOpaque: Transaction,
- options: ReplaceUnprocessedEntitiesOptions,
- ): Promise {
- const tx = txOpaque as Knex.Transaction;
-
- const { toAdd, toUpsert, toRemove } = await this.createDelta(tx, options);
-
- if (toRemove.length) {
- let removedCount = 0;
- const rootId = () => {
- if (tx.client.config.client.includes('mysql')) {
- return tx.raw('CAST(NULL as UNSIGNED INT)', []);
- }
-
- return tx.raw('CAST(NULL as INT)', []);
- };
- for (const refs of lodash.chunk(toRemove, 1000)) {
- /*
- WITH RECURSIVE
- -- All the nodes that can be reached downwards from our root
- descendants(root_id, entity_ref) AS (
- SELECT id, target_entity_ref
- FROM refresh_state_references
- WHERE source_key = "R1" AND target_entity_ref = "A"
- UNION
- SELECT descendants.root_id, target_entity_ref
- FROM descendants
- JOIN refresh_state_references ON source_entity_ref = descendants.entity_ref
- ),
- -- All the nodes that can be reached upwards from the descendants
- ancestors(root_id, via_entity_ref, to_entity_ref) AS (
- SELECT CAST(NULL as INT), entity_ref, entity_ref
- FROM descendants
- UNION
- SELECT
- CASE WHEN source_key IS NOT NULL THEN id ELSE NULL END,
- source_entity_ref,
- ancestors.to_entity_ref
- FROM ancestors
- JOIN refresh_state_references ON target_entity_ref = ancestors.via_entity_ref
- )
- -- Start out with all of the descendants
- SELECT descendants.entity_ref
- FROM descendants
- -- Expand with all ancestors that point to those, but aren't the current root
- LEFT OUTER JOIN ancestors
- ON ancestors.to_entity_ref = descendants.entity_ref
- AND ancestors.root_id IS NOT NULL
- AND ancestors.root_id != descendants.root_id
- -- Exclude all lines that had such a foreign ancestor
- WHERE ancestors.root_id IS NULL;
- */
- removedCount += await tx('refresh_state')
- .whereIn('entity_ref', function orphanedEntityRefs(orphans) {
- return (
- orphans
- // All the nodes that can be reached downwards from our root
- .withRecursive('descendants', function descendants(outer) {
- return outer
- .select({ root_id: 'id', entity_ref: 'target_entity_ref' })
- .from('refresh_state_references')
- .where('source_key', options.sourceKey)
- .whereIn('target_entity_ref', refs)
- .union(function recursive(inner) {
- return inner
- .select({
- root_id: 'descendants.root_id',
- entity_ref:
- 'refresh_state_references.target_entity_ref',
- })
- .from('descendants')
- .join('refresh_state_references', {
- 'descendants.entity_ref':
- 'refresh_state_references.source_entity_ref',
- });
- });
- })
- // All the nodes that can be reached upwards from the descendants
- .withRecursive('ancestors', function ancestors(outer) {
- return outer
- .select({
- root_id: rootId(),
- via_entity_ref: 'entity_ref',
- to_entity_ref: 'entity_ref',
- })
- .from('descendants')
- .union(function recursive(inner) {
- return inner
- .select({
- root_id: tx.raw(
- 'CASE WHEN source_key IS NOT NULL THEN id ELSE NULL END',
- [],
- ),
- via_entity_ref: 'source_entity_ref',
- to_entity_ref: 'ancestors.to_entity_ref',
- })
- .from('ancestors')
- .join('refresh_state_references', {
- target_entity_ref: 'ancestors.via_entity_ref',
- });
- });
- })
- // Start out with all of the descendants
- .select('descendants.entity_ref')
- .from('descendants')
- // Expand with all ancestors that point to those, but aren't the current root
- .leftOuterJoin('ancestors', function keepaliveRoots() {
- this.on(
- 'ancestors.to_entity_ref',
- '=',
- 'descendants.entity_ref',
- );
- this.andOnNotNull('ancestors.root_id');
- this.andOn('ancestors.root_id', '!=', 'descendants.root_id');
- })
- .whereNull('ancestors.root_id')
- );
- })
- .delete();
-
- await tx('refresh_state_references')
- .where('source_key', '=', options.sourceKey)
- .whereIn('target_entity_ref', refs)
- .delete();
- }
-
- this.options.logger.debug(
- `removed, ${removedCount} entities: ${JSON.stringify(toRemove)}`,
- );
- }
-
- if (toAdd.length) {
- // The reason for this chunking, rather than just massively batch
- // inserting the entire payload, is that we fall back to the individual
- // upsert mechanism below on conflicts. That path is massively slower than
- // the fast batch path, so we don't want to end up accidentally having to
- // for example item-by-item upsert tens of thousands of entities in a
- // large initial delivery dump. The implication is that the size of these
- // chunks needs to weigh the benefit of fast successful inserts, against
- // the drawback of super slow but more rare fallbacks. There's quickly
- // diminishing returns though with turning up this value way high.
- for (const chunk of lodash.chunk(toAdd, 50)) {
- try {
- await tx.batchInsert(
- 'refresh_state',
- chunk.map(item => ({
- entity_id: uuid(),
- entity_ref: stringifyEntityRef(item.deferred.entity),
- unprocessed_entity: JSON.stringify(item.deferred.entity),
- unprocessed_hash: item.hash,
- errors: '',
- location_key: item.deferred.locationKey,
- next_update_at: tx.fn.now(),
- last_discovery_at: tx.fn.now(),
- })),
- BATCH_SIZE,
- );
- await tx.batchInsert(
- 'refresh_state_references',
- chunk.map(item => ({
- source_key: options.sourceKey,
- target_entity_ref: stringifyEntityRef(item.deferred.entity),
- })),
- BATCH_SIZE,
- );
- } catch (error) {
- if (!isDatabaseConflictError(error)) {
- throw error;
- } else {
- this.options.logger.debug(
- `Fast insert path failed, falling back to slow path, ${error}`,
- );
- toUpsert.push(...chunk);
- }
- }
- }
- }
-
- if (toUpsert.length) {
- for (const {
- deferred: { entity, locationKey },
- hash,
- } of toUpsert) {
- const entityRef = stringifyEntityRef(entity);
-
- try {
- let ok = await this.updateUnprocessedEntity(
- tx,
- entity,
- hash,
- locationKey,
- );
- if (!ok) {
- ok = await this.insertUnprocessedEntity(
- tx,
- entity,
- hash,
- locationKey,
- );
- }
-
- if (ok) {
- await tx(
- 'refresh_state_references',
- ).insert({
- source_key: options.sourceKey,
- target_entity_ref: entityRef,
- });
- } else {
- const conflictingKey = await this.checkLocationKeyConflict(
- tx,
- entityRef,
- locationKey,
- );
- if (conflictingKey) {
- this.options.logger.warn(
- `Source ${options.sourceKey} detected conflicting entityRef ${entityRef} already referenced by ${conflictingKey} and now also ${locationKey}`,
- );
- }
- }
- } catch (error) {
- this.options.logger.error(
- `Failed to add '${entityRef}' from source '${options.sourceKey}', ${error}`,
- );
- }
- }
- }
- }
-
async getProcessableEntities(
txOpaque: Transaction,
request: { processBatchSize: number },
@@ -487,45 +252,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase {
};
}
- async listAncestors(
- txOpaque: Transaction,
- options: ListAncestorsOptions,
- ): Promise {
- const tx = txOpaque as Knex.Transaction;
- const { entityRef } = options;
- const entityRefs = new Array();
-
- let currentRef = entityRef.toLocaleLowerCase('en-US');
- for (let depth = 1; depth <= MAX_ANCESTOR_DEPTH; depth += 1) {
- const rows = await tx(
- 'refresh_state_references',
- )
- .where({ target_entity_ref: currentRef })
- .select();
-
- if (rows.length === 0) {
- if (depth === 1) {
- throw new NotFoundError(`Entity ${currentRef} not found`);
- }
- throw new NotFoundError(
- `Entity ${entityRef} has a broken parent reference chain at ${currentRef}`,
- );
- }
-
- const parentRef = rows.find(r => r.source_entity_ref)?.source_entity_ref;
- if (!parentRef) {
- // We've reached the top of the tree which is the entityProvider.
- // In this case we refresh the entity itself.
- return { entityRefs };
- }
- entityRefs.push(parentRef);
- currentRef = parentRef;
- }
- throw new Error(
- `Unable receive ancestors for ${entityRef}, reached maximum depth of ${MAX_ANCESTOR_DEPTH}`,
- );
- }
-
async listParents(
txOpaque: Transaction,
options: ListParentsOptions,
@@ -543,37 +269,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase {
return { entityRefs };
}
- async refresh(txOpaque: Transaction, options: RefreshOptions): Promise {
- const tx = txOpaque as Knex.Transaction;
- const { entityRef } = options;
-
- const updateResult = await tx('refresh_state')
- .where({ entity_ref: entityRef.toLocaleLowerCase('en-US') })
- .update({ next_update_at: tx.fn.now() });
- if (updateResult === 0) {
- throw new NotFoundError(`Failed to schedule ${entityRef} for refresh`);
- }
- }
-
- async refreshByRefreshKeys(
- txOpaque: Transaction,
- options: RefreshByKeyOptions,
- ) {
- const tx = txOpaque as Knex.Transaction;
- const { keys } = options;
-
- await tx('refresh_state')
- .whereIn('entity_id', function selectEntityRefs(tx2) {
- tx2
- .whereIn('key', keys)
- .select({
- entity_id: 'refresh_keys.entity_id',
- })
- .from('refresh_keys');
- })
- .update({ next_update_at: tx.fn.now() });
- }
-
async transaction(fn: (tx: Transaction) => Promise): Promise {
try {
let result: T | undefined = undefined;
@@ -597,123 +292,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase {
}
}
- /**
- * Attempts to update an existing refresh state row, returning true if it was
- * updated and false if there was no entity with a matching ref and location key.
- *
- * Updating the entity will also cause it to be scheduled for immediate processing.
- */
- private async updateUnprocessedEntity(
- tx: Knex.Transaction,
- entity: Entity,
- hash: string,
- locationKey?: string,
- ): Promise {
- const entityRef = stringifyEntityRef(entity);
- const serializedEntity = JSON.stringify(entity);
-
- const refreshResult = await tx('refresh_state')
- .update({
- unprocessed_entity: serializedEntity,
- unprocessed_hash: hash,
- location_key: locationKey,
- last_discovery_at: tx.fn.now(),
- // We only get to this point if a processed entity actually had any changes, or
- // if an entity provider requested this mutation, meaning that we can safely
- // bump the deferred entities to the front of the queue for immediate processing.
- next_update_at: tx.fn.now(),
- })
- .where('entity_ref', entityRef)
- .andWhere(inner => {
- if (!locationKey) {
- return inner.whereNull('location_key');
- }
- return inner
- .where('location_key', locationKey)
- .orWhereNull('location_key');
- });
-
- return refreshResult === 1;
- }
-
- /**
- * Attempts to insert a new refresh state row for the given entity, returning
- * true if successful and false if there was a conflict.
- */
- private async insertUnprocessedEntity(
- tx: Knex.Transaction,
- entity: Entity,
- hash: string,
- locationKey?: string,
- ): Promise {
- const entityRef = stringifyEntityRef(entity);
- const serializedEntity = JSON.stringify(entity);
-
- try {
- let query = tx('refresh_state').insert({
- entity_id: uuid(),
- entity_ref: entityRef,
- unprocessed_entity: serializedEntity,
- unprocessed_hash: hash,
- errors: '',
- location_key: locationKey,
- next_update_at: tx.fn.now(),
- last_discovery_at: tx.fn.now(),
- });
-
- // TODO(Rugvip): only tested towards MySQL, Postgres and SQLite.
- // We have to do this because the only way to detect if there was a conflict with
- // SQLite is to catch the error, while Postgres needs to ignore the conflict to not
- // break the ongoing transaction.
- if (tx.client.config.client.includes('pg')) {
- query = query.onConflict('entity_ref').ignore() as any; // type here does not match runtime
- }
-
- // Postgres gives as an object with rowCount, SQLite gives us an array
- const result: { rowCount?: number; length?: number } = await query;
- return result.rowCount === 1 || result.length === 1;
- } catch (error) {
- // SQLite, or MySQL reached this rather than the rowCount check above
- if (!isDatabaseConflictError(error)) {
- throw error;
- } else {
- this.options.logger.debug(
- `Unable to insert a new refresh state row, ${error}`,
- );
- return false;
- }
- }
- }
-
- /**
- * Checks whether a refresh state exists for the given entity that has a
- * location key that does not match the provided location key.
- *
- * @returns The conflicting key if there is one.
- */
- private async checkLocationKeyConflict(
- tx: Knex.Transaction,
- entityRef: string,
- locationKey?: string,
- ): Promise {
- const row = await tx('refresh_state')
- .select('location_key')
- .where('entity_ref', entityRef)
- .first();
-
- const conflictingKey = row?.location_key;
-
- // If there's no existing key we can't have a conflict
- if (!conflictingKey) {
- return undefined;
- }
-
- if (conflictingKey !== locationKey) {
- return conflictingKey;
- }
- return undefined;
- }
-
private deduplicateRelations(rows: DbRelationsRow[]): DbRelationsRow[] {
return lodash.uniqBy(
rows,
@@ -721,84 +299,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase {
);
}
- private async createDelta(
- tx: Knex.Transaction,
- options: ReplaceUnprocessedEntitiesOptions,
- ): Promise<{
- toAdd: { deferred: DeferredEntity; hash: string }[];
- toUpsert: { deferred: DeferredEntity; hash: string }[];
- toRemove: string[];
- }> {
- if (options.type === 'delta') {
- return {
- toAdd: [],
- toUpsert: options.added.map(e => ({
- deferred: e,
- hash: generateStableHash(e.entity),
- })),
- toRemove: options.removed.map(e => e.entityRef),
- };
- }
-
- // Grab all of the existing references from the same source, and their locationKeys as well
- const oldRefs = await tx(
- 'refresh_state_references',
- )
- .leftJoin('refresh_state', {
- target_entity_ref: 'entity_ref',
- })
- .where({ source_key: options.sourceKey })
- .select({
- target_entity_ref: 'refresh_state_references.target_entity_ref',
- location_key: 'refresh_state.location_key',
- unprocessed_hash: 'refresh_state.unprocessed_hash',
- });
-
- const items = options.items.map(deferred => ({
- deferred,
- ref: stringifyEntityRef(deferred.entity),
- hash: generateStableHash(deferred.entity),
- }));
-
- const oldRefsSet = new Map(
- oldRefs.map(r => [
- r.target_entity_ref,
- {
- locationKey: r.location_key,
- oldEntityHash: r.unprocessed_hash,
- },
- ]),
- );
- const newRefsSet = new Set(items.map(item => item.ref));
-
- const toAdd = new Array<{ deferred: DeferredEntity; hash: string }>();
- const toUpsert = new Array<{ deferred: DeferredEntity; hash: string }>();
- const toRemove = oldRefs
- .map(row => row.target_entity_ref)
- .filter(ref => !newRefsSet.has(ref));
-
- for (const item of items) {
- const oldRef = oldRefsSet.get(item.ref);
- const upsertItem = { deferred: item.deferred, hash: item.hash };
- if (!oldRef) {
- // Add any entity that does not exist in the database
- toAdd.push(upsertItem);
- } else if (
- (oldRef?.locationKey ?? undefined) !==
- (item.deferred.locationKey ?? undefined)
- ) {
- // Remove and then re-add any entity that exists, but with a different location key
- toRemove.push(item.ref);
- toAdd.push(upsertItem);
- } else if (oldRef.oldEntityHash !== item.hash) {
- // Entities with modifications should be pushed through too
- toUpsert.push(upsertItem);
- }
- }
-
- return { toAdd, toUpsert, toRemove };
- }
-
/**
* Add a set of deferred entities for processing.
* The entities will be added at the front of the processing queue.
@@ -822,23 +322,24 @@ export class DefaultProcessingDatabase implements ProcessingDatabase {
const entityRef = stringifyEntityRef(entity);
const hash = generateStableHash(entity);
- const updated = await this.updateUnprocessedEntity(
+ const updated = await updateUnprocessedEntity({
tx,
entity,
hash,
locationKey,
- );
+ });
if (updated) {
stateReferences.push(entityRef);
continue;
}
- const inserted = await this.insertUnprocessedEntity(
+ const inserted = await insertUnprocessedEntity({
tx,
entity,
hash,
locationKey,
- );
+ logger: this.options.logger,
+ });
if (inserted) {
stateReferences.push(entityRef);
continue;
@@ -847,11 +348,11 @@ export class DefaultProcessingDatabase implements ProcessingDatabase {
// If the row can't be inserted, we have a conflict, but it could be either
// because of a conflicting locationKey or a race with another instance, so check
// whether the conflicting entity has the same entityRef but a different locationKey
- const conflictingKey = await this.checkLocationKeyConflict(
+ const conflictingKey = await checkLocationKeyConflict({
tx,
entityRef,
locationKey,
- );
+ });
if (conflictingKey) {
this.options.logger.warn(
`Detected conflicting entityRef ${entityRef} already referenced by ${conflictingKey} and now also ${locationKey}`,
diff --git a/plugins/catalog-backend/src/database/DefaultProviderDatabase.test.ts b/plugins/catalog-backend/src/database/DefaultProviderDatabase.test.ts
new file mode 100644
index 0000000000..43f2209b60
--- /dev/null
+++ b/plugins/catalog-backend/src/database/DefaultProviderDatabase.test.ts
@@ -0,0 +1,715 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { getVoidLogger } from '@backstage/backend-common';
+import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils';
+import { Entity } from '@backstage/catalog-model';
+import { Knex } from 'knex';
+import * as uuid from 'uuid';
+import { Logger } from 'winston';
+import { DefaultProviderDatabase } from './DefaultProviderDatabase';
+import { applyDatabaseMigrations } from './migrations';
+import { DbRefreshStateReferencesRow, DbRefreshStateRow } from './tables';
+
+describe('DefaultProviderDatabase', () => {
+ const defaultLogger = getVoidLogger();
+ const databases = TestDatabases.create({
+ ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'],
+ });
+
+ async function createDatabase(
+ databaseId: TestDatabaseId,
+ logger: Logger = defaultLogger,
+ ) {
+ const knex = await databases.init(databaseId);
+ await applyDatabaseMigrations(knex);
+ return {
+ knex,
+ db: new DefaultProviderDatabase({
+ database: knex,
+ logger,
+ }),
+ };
+ }
+
+ const insertRefRow = async (db: Knex, ref: DbRefreshStateReferencesRow) => {
+ return db('refresh_state_references').insert(
+ ref,
+ );
+ };
+
+ const insertRefreshStateRow = async (db: Knex, ref: DbRefreshStateRow) => {
+ await db('refresh_state').insert(ref);
+ };
+
+ describe('replaceUnprocessedEntities', () => {
+ const createLocations = async (db: Knex, entityRefs: string[]) => {
+ for (const ref of entityRefs) {
+ await insertRefreshStateRow(db, {
+ entity_id: uuid.v4(),
+ entity_ref: ref,
+ unprocessed_entity: '{}',
+ processed_entity: '{}',
+ errors: '[]',
+ next_update_at: '2021-04-01 13:37:00',
+ last_discovery_at: '2021-04-01 13:37:00',
+ });
+ }
+ };
+
+ it.each(databases.eachSupportedId())(
+ 'replaces all existing state correctly for simple dependency chains, %p',
+ async databaseId => {
+ const { knex, db } = await createDatabase(databaseId);
+ /*
+ config -> location:default/root -> location:default/root-1 -> location:default/root-2
+ database -> location:default/second -> location:default/root-2
+ */
+ await createLocations(knex, [
+ 'location:default/root',
+ 'location:default/root-1',
+ 'location:default/root-2',
+ 'location:default/second',
+ ]);
+
+ await insertRefRow(knex, {
+ source_key: 'config',
+ target_entity_ref: 'location:default/root',
+ });
+
+ await insertRefRow(knex, {
+ source_key: 'database',
+ target_entity_ref: 'location:default/second',
+ });
+
+ await insertRefRow(knex, {
+ source_entity_ref: 'location:default/root',
+ target_entity_ref: 'location:default/root-1',
+ });
+
+ await insertRefRow(knex, {
+ source_entity_ref: 'location:default/root-1',
+ target_entity_ref: 'location:default/root-2',
+ });
+
+ await insertRefRow(knex, {
+ source_entity_ref: 'location:default/second',
+ target_entity_ref: 'location:default/root-2',
+ });
+
+ await db.transaction(tx =>
+ db.replaceUnprocessedEntities(tx, {
+ type: 'full',
+ sourceKey: 'config',
+ items: [
+ {
+ entity: {
+ apiVersion: '1.0.0',
+ metadata: {
+ name: 'new-root',
+ },
+ kind: 'Location',
+ } as Entity,
+ locationKey: 'file:///tmp/foobar',
+ },
+ ],
+ }),
+ );
+
+ const currentRefreshState = await knex(
+ 'refresh_state',
+ ).select();
+
+ const currentRefRowState = await knex(
+ 'refresh_state_references',
+ ).select();
+
+ for (const ref of [
+ 'location:default/root',
+ 'location:default/root-1',
+ ]) {
+ expect(
+ currentRefreshState.some(t => t.entity_ref === ref),
+ ).toBeFalsy();
+ }
+
+ expect(
+ currentRefreshState.some(
+ t => t.entity_ref === 'location:default/new-root',
+ ),
+ ).toBeTruthy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_entity_ref === 'location:default/root' &&
+ t.target_entity_ref === 'location:default/root-1',
+ ),
+ ).toBeFalsy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_entity_ref === 'location:default/root-1' &&
+ t.target_entity_ref === 'location:default/root-2',
+ ),
+ ).toBeFalsy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.target_entity_ref === 'location:default/root-1' &&
+ t.source_key === 'config',
+ ),
+ ).toBeFalsy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.target_entity_ref === 'location:default/new-root' &&
+ t.source_key === 'config',
+ ),
+ ).toBeTruthy();
+ },
+ 60_000,
+ );
+
+ it.each(databases.eachSupportedId())(
+ 'should work for more complex chains, %p',
+ async databaseId => {
+ const { knex, db } = await createDatabase(databaseId);
+ /*
+ config -> location:default/root -> location:default/root-1 -> location:default/root-2
+ config -> location:default/root -> location:default/root-1a -> location:default/root-2
+ */
+ await createLocations(knex, [
+ 'location:default/root',
+ 'location:default/root-1',
+ 'location:default/root-2',
+ 'location:default/root-1a',
+ ]);
+
+ await insertRefRow(knex, {
+ source_key: 'config',
+ target_entity_ref: 'location:default/root',
+ });
+
+ await insertRefRow(knex, {
+ source_entity_ref: 'location:default/root',
+ target_entity_ref: 'location:default/root-1',
+ });
+
+ await insertRefRow(knex, {
+ source_entity_ref: 'location:default/root',
+ target_entity_ref: 'location:default/root-1a',
+ });
+
+ await insertRefRow(knex, {
+ source_entity_ref: 'location:default/root-1',
+ target_entity_ref: 'location:default/root-2',
+ });
+
+ await insertRefRow(knex, {
+ source_entity_ref: 'location:default/root-1a',
+ target_entity_ref: 'location:default/root-2',
+ });
+
+ await db.transaction(async tx => {
+ await db.replaceUnprocessedEntities(tx, {
+ type: 'full',
+ sourceKey: 'config',
+ items: [
+ {
+ entity: {
+ apiVersion: '1.0.0',
+ metadata: {
+ name: 'new-root',
+ },
+ kind: 'Location',
+ } as Entity,
+ locationKey: 'file:/tmp/foobar',
+ },
+ ],
+ });
+ });
+
+ const currentRefreshState = await knex(
+ 'refresh_state',
+ ).select();
+
+ const currentRefRowState = await knex(
+ 'refresh_state_references',
+ ).select();
+
+ const deletedRefs = [
+ 'location:default/root',
+ 'location:default/root-1',
+ 'location:default/root-1a',
+ 'location:default/root-2',
+ ];
+
+ for (const ref of deletedRefs) {
+ expect(
+ currentRefreshState.some(t => t.entity_ref === ref),
+ ).toBeFalsy();
+ }
+
+ expect(
+ currentRefreshState.some(
+ t => t.entity_ref === 'location:default/new-root',
+ ),
+ ).toBeTruthy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_key === 'config' &&
+ t.target_entity_ref === 'location:default/new-root',
+ ),
+ ).toBeTruthy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_key === 'config' &&
+ t.target_entity_ref === 'location:default/root',
+ ),
+ ).toBeFalsy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_entity_ref === 'location:default/root' &&
+ t.target_entity_ref === 'location:default/root-1',
+ ),
+ ).toBeFalsy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_entity_ref === 'location:default/root' &&
+ t.target_entity_ref === 'location:default/root-1a',
+ ),
+ ).toBeFalsy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_entity_ref === 'location:default/root-1' &&
+ t.target_entity_ref === 'location:default/root-2',
+ ),
+ ).toBeFalsy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_entity_ref === 'location:default/root-1a' &&
+ t.target_entity_ref === 'location:default/root-2',
+ ),
+ ).toBeFalsy();
+ },
+ 60_000,
+ );
+
+ it.each(databases.eachSupportedId())(
+ 'should add new locations using the delta options, %p',
+ async databaseId => {
+ const { knex, db } = await createDatabase(databaseId);
+
+ // Existing state and references should stay
+ await createLocations(knex, ['location:default/existing']);
+ await insertRefRow(knex, {
+ source_key: 'lols',
+ target_entity_ref: 'location:default/existing',
+ });
+
+ await db.transaction(async tx => {
+ await db.replaceUnprocessedEntities(tx, {
+ type: 'delta',
+ sourceKey: 'lols',
+ removed: [],
+ added: [
+ {
+ entity: {
+ apiVersion: '1.0.0',
+ metadata: {
+ name: 'new-root',
+ },
+ kind: 'Location',
+ } as Entity,
+ locationKey: 'file:///tmp/foobar',
+ },
+ ],
+ });
+ });
+
+ const currentRefreshState = await knex(
+ 'refresh_state',
+ ).select();
+
+ const currentRefRowState = await knex(
+ 'refresh_state_references',
+ ).select();
+
+ expect(
+ currentRefreshState.some(
+ t => t.entity_ref === 'location:default/new-root',
+ ),
+ ).toBeTruthy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_key === 'lols' &&
+ t.target_entity_ref === 'location:default/new-root',
+ ),
+ ).toBeTruthy();
+
+ expect(
+ currentRefreshState.some(
+ t => t.entity_ref === 'location:default/existing',
+ ),
+ ).toBeTruthy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_key === 'lols' &&
+ t.target_entity_ref === 'location:default/existing',
+ ),
+ ).toBeTruthy();
+ },
+ 60_000,
+ );
+
+ it.each(databases.eachSupportedId())(
+ 'should not remove locations that are referenced elsewhere, %p',
+ async databaseId => {
+ const { knex, db } = await createDatabase(databaseId);
+ /*
+ config-1 -> location:default/root
+ config-2 -> location:default/root
+ */
+ await createLocations(knex, ['location:default/root']);
+
+ await insertRefRow(knex, {
+ source_key: 'config-1',
+ target_entity_ref: 'location:default/root',
+ });
+ await insertRefRow(knex, {
+ source_key: 'config-2',
+ target_entity_ref: 'location:default/root',
+ });
+
+ await db.transaction(async tx => {
+ await db.replaceUnprocessedEntities(tx, {
+ type: 'full',
+ sourceKey: 'config-1',
+ items: [],
+ });
+ });
+
+ const currentRefreshState = await knex(
+ 'refresh_state',
+ ).select();
+
+ const currentRefRowState = await knex(
+ 'refresh_state_references',
+ ).select();
+
+ expect(currentRefRowState).toEqual([
+ expect.objectContaining({
+ source_key: 'config-2',
+ target_entity_ref: 'location:default/root',
+ }),
+ ]);
+
+ expect(currentRefreshState).toEqual([
+ expect.objectContaining({
+ entity_ref: 'location:default/root',
+ }),
+ ]);
+ },
+ 60_000,
+ );
+
+ it.each(databases.eachSupportedId())(
+ 'should remove old locations using the delta options, %p',
+ async databaseId => {
+ const { knex, db } = await createDatabase(databaseId);
+ await createLocations(knex, ['location:default/new-root']);
+
+ await insertRefRow(knex, {
+ source_key: 'lols',
+ target_entity_ref: 'location:default/new-root',
+ });
+
+ await db.transaction(async tx => {
+ await db.replaceUnprocessedEntities(tx, {
+ type: 'delta',
+ sourceKey: 'lols',
+ added: [],
+ removed: [
+ {
+ entityRef: 'location:default/new-root',
+ locationKey: 'file:/tmp/foobar',
+ },
+ ],
+ });
+ });
+
+ const currentRefreshState = await knex(
+ 'refresh_state',
+ ).select();
+
+ const currentRefRowState = await knex(
+ 'refresh_state_references',
+ ).select();
+
+ expect(
+ currentRefreshState.some(
+ t => t.entity_ref === 'location:default/new-root',
+ ),
+ ).toBeFalsy();
+
+ expect(
+ currentRefRowState.some(
+ t =>
+ t.source_key === 'lols' &&
+ t.target_entity_ref === 'location:default/new-root',
+ ),
+ ).toBeFalsy();
+ },
+ 60_000,
+ );
+
+ it.each(databases.eachSupportedId())(
+ 'should update the location key during full replace, %p',
+ async databaseId => {
+ const { knex, db } = await createDatabase(databaseId);
+ await createLocations(knex, ['location:default/removed']);
+ await insertRefreshStateRow(knex, {
+ entity_id: uuid.v4(),
+ entity_ref: 'location:default/replaced',
+ unprocessed_entity: '{}',
+ processed_entity: '{}',
+ errors: '[]',
+ next_update_at: '2021-04-01 13:37:00',
+ last_discovery_at: '2021-04-01 13:37:00',
+ location_key: 'file:///tmp/old',
+ });
+
+ await insertRefRow(knex, {
+ source_key: 'lols',
+ target_entity_ref: 'location:default/removed',
+ });
+ await insertRefRow(knex, {
+ source_key: 'lols',
+ target_entity_ref: 'location:default/replaced',
+ });
+
+ await db.transaction(async tx => {
+ await db.replaceUnprocessedEntities(tx, {
+ type: 'full',
+ sourceKey: 'lols',
+ items: [
+ {
+ entity: {
+ apiVersion: '1.0.0',
+ metadata: {
+ name: 'replaced',
+ },
+ kind: 'Location',
+ } as Entity,
+ locationKey: 'file:///tmp/foobar',
+ },
+ ],
+ });
+ });
+
+ const currentRefreshState = await knex(
+ 'refresh_state',
+ ).select();
+ expect(currentRefreshState).toEqual([
+ expect.objectContaining({
+ entity_ref: 'location:default/replaced',
+ location_key: 'file:///tmp/foobar',
+ }),
+ ]);
+
+ const currentRefRowState = await knex(
+ 'refresh_state_references',
+ ).select();
+ expect(currentRefRowState).toEqual([
+ expect.objectContaining({
+ source_key: 'lols',
+ target_entity_ref: 'location:default/replaced',
+ }),
+ ]);
+ },
+ 60_000,
+ );
+
+ it.each(databases.eachSupportedId())(
+ 'should support replacing modified entities during a full update, %p',
+ async databaseId => {
+ const { knex, db } = await createDatabase(databaseId);
+
+ await db.transaction(async tx => {
+ await db.replaceUnprocessedEntities(tx, {
+ type: 'full',
+ sourceKey: 'lols',
+ items: [
+ {
+ entity: {
+ apiVersion: '1',
+ kind: 'Component',
+ metadata: { name: 'a' },
+ spec: { marker: 'WILL_CHANGE' },
+ } as Entity,
+ locationKey: 'file:///tmp/a',
+ },
+ {
+ entity: {
+ apiVersion: '1',
+ kind: 'Component',
+ metadata: { name: 'b' },
+ spec: { marker: 'NEVER_CHANGES' },
+ } as Entity,
+ locationKey: 'file:///tmp/b',
+ },
+ ],
+ });
+ });
+
+ let state = await knex('refresh_state').select();
+ expect(state).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ entity_ref: 'component:default/a',
+ location_key: 'file:///tmp/a',
+ unprocessed_entity: expect.stringContaining('WILL_CHANGE'),
+ }),
+ expect.objectContaining({
+ entity_ref: 'component:default/b',
+ location_key: 'file:///tmp/b',
+ unprocessed_entity: expect.stringContaining('NEVER_CHANGES'),
+ }),
+ ]),
+ );
+
+ await db.transaction(async tx => {
+ await db.replaceUnprocessedEntities(tx, {
+ type: 'full',
+ sourceKey: 'lols',
+ items: [
+ {
+ entity: {
+ apiVersion: '1',
+ kind: 'Component',
+ metadata: { name: 'a' },
+ spec: { marker: 'HAS_CHANGED' },
+ } as Entity,
+ locationKey: 'file:///tmp/a',
+ },
+ {
+ entity: {
+ apiVersion: '1',
+ kind: 'Component',
+ metadata: { name: 'b' },
+ spec: { marker: 'NEVER_CHANGES' },
+ } as Entity,
+ locationKey: 'file:///tmp/b',
+ },
+ ],
+ });
+ });
+
+ state = await knex('refresh_state').select();
+ expect(state).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ entity_ref: 'component:default/a',
+ location_key: 'file:///tmp/a',
+ unprocessed_entity: expect.stringContaining('HAS_CHANGED'),
+ }),
+ expect.objectContaining({
+ entity_ref: 'component:default/b',
+ location_key: 'file:///tmp/b',
+ unprocessed_entity: expect.stringContaining('NEVER_CHANGES'),
+ }),
+ ]),
+ );
+ },
+ 60_000,
+ );
+
+ it.each(databases.eachSupportedId())(
+ 'should successfully fall back from batch to individual mode on conflicts, %p',
+ async databaseId => {
+ const fakeLogger = {
+ debug: jest.fn(),
+ };
+ const { knex, db } = await createDatabase(
+ databaseId,
+ fakeLogger as any,
+ );
+
+ await createLocations(knex, ['component:default/a']);
+
+ await insertRefRow(knex, {
+ source_key: undefined,
+ target_entity_ref: 'component:default/a',
+ });
+
+ await db.transaction(async tx => {
+ await db.replaceUnprocessedEntities(tx, {
+ type: 'full',
+ sourceKey: 'lols',
+ items: [
+ {
+ entity: {
+ apiVersion: '1',
+ kind: 'Component',
+ metadata: { name: 'a' },
+ spec: { marker: 'WILL_CHANGE' },
+ } as Entity,
+ locationKey: 'file:///tmp/a',
+ },
+ ],
+ });
+ });
+ expect(fakeLogger.debug).toHaveBeenCalledWith(
+ expect.stringMatching(
+ /Fast insert path failed, falling back to slow path/,
+ ),
+ );
+
+ const state = await knex('refresh_state').select();
+ expect(state).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ entity_ref: 'component:default/a',
+ location_key: 'file:///tmp/a',
+ unprocessed_entity: expect.stringContaining('WILL_CHANGE'),
+ }),
+ ]),
+ );
+ },
+ 60_000,
+ );
+ });
+});
diff --git a/plugins/catalog-backend/src/database/DefaultProviderDatabase.ts b/plugins/catalog-backend/src/database/DefaultProviderDatabase.ts
new file mode 100644
index 0000000000..f1073fd984
--- /dev/null
+++ b/plugins/catalog-backend/src/database/DefaultProviderDatabase.ts
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { isDatabaseConflictError } from '@backstage/backend-common';
+import { stringifyEntityRef } from '@backstage/catalog-model';
+import { DeferredEntity } from '@backstage/plugin-catalog-node';
+import { Knex } from 'knex';
+import lodash from 'lodash';
+import { v4 as uuid } from 'uuid';
+import type { Logger } from 'winston';
+import { rethrowError } from './conversion';
+import { deleteWithEagerPruningOfChildren } from './operations/provider/deleteWithEagerPruningOfChildren';
+import { refreshByRefreshKeys } from './operations/provider/refreshByRefreshKeys';
+import { checkLocationKeyConflict } from './operations/refreshState/checkLocationKeyConflict';
+import { insertUnprocessedEntity } from './operations/refreshState/insertUnprocessedEntity';
+import { updateUnprocessedEntity } from './operations/refreshState/updateUnprocessedEntity';
+import { DbRefreshStateReferencesRow, DbRefreshStateRow } from './tables';
+import {
+ ProviderDatabase,
+ RefreshByKeyOptions,
+ ReplaceUnprocessedEntitiesOptions,
+ Transaction,
+} from './types';
+import { generateStableHash } from './util';
+
+// The number of items that are sent per batch to the database layer, when
+// doing .batchInsert calls to knex. This needs to be low enough to not cause
+// errors in the underlying engine due to exceeding query limits, but large
+// enough to get the speed benefits.
+const BATCH_SIZE = 50;
+
+export class DefaultProviderDatabase implements ProviderDatabase {
+ constructor(
+ private readonly options: {
+ database: Knex;
+ logger: Logger;
+ },
+ ) {}
+
+ async transaction(fn: (tx: Transaction) => Promise): Promise {
+ try {
+ let result: T | undefined = undefined;
+ await this.options.database.transaction(
+ async tx => {
+ // We can't return here, as knex swallows the return type in case the
+ // transaction is rolled back:
+ // https://github.com/knex/knex/blob/e37aeaa31c8ef9c1b07d2e4d3ec6607e557d800d/lib/transaction.js#L136
+ result = await fn(tx);
+ },
+ {
+ // If we explicitly trigger a rollback, don't fail.
+ doNotRejectOnRollback: true,
+ },
+ );
+ return result!;
+ } catch (e) {
+ this.options.logger.debug(`Error during transaction, ${e}`);
+ throw rethrowError(e);
+ }
+ }
+
+ async replaceUnprocessedEntities(
+ txOpaque: Transaction,
+ options: ReplaceUnprocessedEntitiesOptions,
+ ): Promise {
+ const tx = txOpaque as Knex.Transaction;
+ const { toAdd, toUpsert, toRemove } = await this.createDelta(tx, options);
+
+ if (toRemove.length) {
+ const removedCount = await deleteWithEagerPruningOfChildren({
+ tx,
+ entityRefs: toRemove,
+ sourceKey: options.sourceKey,
+ });
+ this.options.logger.debug(
+ `removed, ${removedCount} entities: ${JSON.stringify(toRemove)}`,
+ );
+ }
+
+ if (toAdd.length) {
+ // The reason for this chunking, rather than just massively batch
+ // inserting the entire payload, is that we fall back to the individual
+ // upsert mechanism below on conflicts. That path is massively slower than
+ // the fast batch path, so we don't want to end up accidentally having to
+ // for example item-by-item upsert tens of thousands of entities in a
+ // large initial delivery dump. The implication is that the size of these
+ // chunks needs to weigh the benefit of fast successful inserts, against
+ // the drawback of super slow but more rare fallbacks. There's quickly
+ // diminishing returns though with turning up this value way high.
+ for (const chunk of lodash.chunk(toAdd, 50)) {
+ try {
+ await tx.batchInsert(
+ 'refresh_state',
+ chunk.map(item => ({
+ entity_id: uuid(),
+ entity_ref: stringifyEntityRef(item.deferred.entity),
+ unprocessed_entity: JSON.stringify(item.deferred.entity),
+ unprocessed_hash: item.hash,
+ errors: '',
+ location_key: item.deferred.locationKey,
+ next_update_at: tx.fn.now(),
+ last_discovery_at: tx.fn.now(),
+ })),
+ BATCH_SIZE,
+ );
+ await tx.batchInsert(
+ 'refresh_state_references',
+ chunk.map(item => ({
+ source_key: options.sourceKey,
+ target_entity_ref: stringifyEntityRef(item.deferred.entity),
+ })),
+ BATCH_SIZE,
+ );
+ } catch (error) {
+ if (!isDatabaseConflictError(error)) {
+ throw error;
+ } else {
+ this.options.logger.debug(
+ `Fast insert path failed, falling back to slow path, ${error}`,
+ );
+ toUpsert.push(...chunk);
+ }
+ }
+ }
+ }
+
+ if (toUpsert.length) {
+ for (const {
+ deferred: { entity, locationKey },
+ hash,
+ } of toUpsert) {
+ const entityRef = stringifyEntityRef(entity);
+
+ try {
+ let ok = await updateUnprocessedEntity({
+ tx,
+ entity,
+ hash,
+ locationKey,
+ });
+ if (!ok) {
+ ok = await insertUnprocessedEntity({
+ tx,
+ entity,
+ hash,
+ locationKey,
+ logger: this.options.logger,
+ });
+ }
+
+ if (ok) {
+ await tx(
+ 'refresh_state_references',
+ ).insert({
+ source_key: options.sourceKey,
+ target_entity_ref: entityRef,
+ });
+ } else {
+ const conflictingKey = await checkLocationKeyConflict({
+ tx,
+ entityRef,
+ locationKey,
+ });
+ if (conflictingKey) {
+ this.options.logger.warn(
+ `Source ${options.sourceKey} detected conflicting entityRef ${entityRef} already referenced by ${conflictingKey} and now also ${locationKey}`,
+ );
+ }
+ }
+ } catch (error) {
+ this.options.logger.error(
+ `Failed to add '${entityRef}' from source '${options.sourceKey}', ${error}`,
+ );
+ }
+ }
+ }
+ }
+
+ async refreshByRefreshKeys(
+ txOpaque: Transaction,
+ options: RefreshByKeyOptions,
+ ) {
+ const tx = txOpaque as Knex.Transaction;
+ await refreshByRefreshKeys({ tx, keys: options.keys });
+ }
+
+ private async createDelta(
+ tx: Knex.Transaction,
+ options: ReplaceUnprocessedEntitiesOptions,
+ ): Promise<{
+ toAdd: { deferred: DeferredEntity; hash: string }[];
+ toUpsert: { deferred: DeferredEntity; hash: string }[];
+ toRemove: string[];
+ }> {
+ if (options.type === 'delta') {
+ return {
+ toAdd: [],
+ toUpsert: options.added.map(e => ({
+ deferred: e,
+ hash: generateStableHash(e.entity),
+ })),
+ toRemove: options.removed.map(e => e.entityRef),
+ };
+ }
+
+ // Grab all of the existing references from the same source, and their locationKeys as well
+ const oldRefs = await tx(
+ 'refresh_state_references',
+ )
+ .leftJoin('refresh_state', {
+ target_entity_ref: 'entity_ref',
+ })
+ .where({ source_key: options.sourceKey })
+ .select({
+ target_entity_ref: 'refresh_state_references.target_entity_ref',
+ location_key: 'refresh_state.location_key',
+ unprocessed_hash: 'refresh_state.unprocessed_hash',
+ });
+
+ const items = options.items.map(deferred => ({
+ deferred,
+ ref: stringifyEntityRef(deferred.entity),
+ hash: generateStableHash(deferred.entity),
+ }));
+
+ const oldRefsSet = new Map(
+ oldRefs.map(r => [
+ r.target_entity_ref,
+ {
+ locationKey: r.location_key,
+ oldEntityHash: r.unprocessed_hash,
+ },
+ ]),
+ );
+ const newRefsSet = new Set(items.map(item => item.ref));
+
+ const toAdd = new Array<{ deferred: DeferredEntity; hash: string }>();
+ const toUpsert = new Array<{ deferred: DeferredEntity; hash: string }>();
+ const toRemove = oldRefs
+ .map(row => row.target_entity_ref)
+ .filter(ref => !newRefsSet.has(ref));
+
+ for (const item of items) {
+ const oldRef = oldRefsSet.get(item.ref);
+ const upsertItem = { deferred: item.deferred, hash: item.hash };
+ if (!oldRef) {
+ // Add any entity that does not exist in the database
+ toAdd.push(upsertItem);
+ } else if (
+ (oldRef?.locationKey ?? undefined) !==
+ (item.deferred.locationKey ?? undefined)
+ ) {
+ // Remove and then re-add any entity that exists, but with a different location key
+ toRemove.push(item.ref);
+ toAdd.push(upsertItem);
+ } else if (oldRef.oldEntityHash !== item.hash) {
+ // Entities with modifications should be pushed through too
+ toUpsert.push(upsertItem);
+ }
+ }
+
+ return { toAdd, toUpsert, toRemove };
+ }
+}
diff --git a/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.ts b/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.ts
new file mode 100644
index 0000000000..3d642cbf3a
--- /dev/null
+++ b/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.ts
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Knex } from 'knex';
+import lodash from 'lodash';
+import { DbRefreshStateReferencesRow, DbRefreshStateRow } from '../../tables';
+
+/**
+ * Given a number of entity refs originally created by a given entity provider
+ * (source key), remove those entities from the refresh state, and at the same
+ * time recursively remove every child that is a direct or indirect result of
+ * processing those entities, if they would have otherwise become orphaned by
+ * the removal of their parents.
+ */
+export async function deleteWithEagerPruningOfChildren(options: {
+ tx: Knex.Transaction;
+ entityRefs: string[];
+ sourceKey: string;
+}): Promise {
+ const { tx, entityRefs, sourceKey } = options;
+ let removedCount = 0;
+
+ const rootId = () =>
+ tx.raw(
+ tx.client.config.client.includes('mysql')
+ ? 'CAST(NULL as UNSIGNED INT)'
+ : 'CAST(NULL as INT)',
+ [],
+ );
+
+ // Split up the operation by (large) chunks, so that we do not hit database
+ // limits for the number of permitted bindings on a precompiled statement
+ for (const refs of lodash.chunk(entityRefs, 1000)) {
+ /*
+ WITH RECURSIVE
+ -- All the nodes that can be reached downwards from our root
+ descendants(root_id, entity_ref) AS (
+ SELECT id, target_entity_ref
+ FROM refresh_state_references
+ WHERE source_key = "R1" AND target_entity_ref = "A"
+ UNION
+ SELECT descendants.root_id, target_entity_ref
+ FROM descendants
+ JOIN refresh_state_references ON source_entity_ref = descendants.entity_ref
+ ),
+ -- All the nodes that can be reached upwards from the descendants
+ ancestors(root_id, via_entity_ref, to_entity_ref) AS (
+ SELECT CAST(NULL as INT), entity_ref, entity_ref
+ FROM descendants
+ UNION
+ SELECT
+ CASE WHEN source_key IS NOT NULL THEN id ELSE NULL END,
+ source_entity_ref,
+ ancestors.to_entity_ref
+ FROM ancestors
+ JOIN refresh_state_references ON target_entity_ref = ancestors.via_entity_ref
+ )
+ -- Start out with all of the descendants
+ SELECT descendants.entity_ref
+ FROM descendants
+ -- Expand with all ancestors that point to those, but aren't the current root
+ LEFT OUTER JOIN ancestors
+ ON ancestors.to_entity_ref = descendants.entity_ref
+ AND ancestors.root_id IS NOT NULL
+ AND ancestors.root_id != descendants.root_id
+ -- Exclude all lines that had such a foreign ancestor
+ WHERE ancestors.root_id IS NULL;
+ */
+ removedCount += await tx('refresh_state')
+ .whereIn('entity_ref', function orphanedEntityRefs(orphans) {
+ return (
+ orphans
+ // All the nodes that can be reached downwards from our root
+ .withRecursive('descendants', function descendants(outer) {
+ return outer
+ .select({ root_id: 'id', entity_ref: 'target_entity_ref' })
+ .from('refresh_state_references')
+ .where('source_key', sourceKey)
+ .whereIn('target_entity_ref', refs)
+ .union(function recursive(inner) {
+ return inner
+ .select({
+ root_id: 'descendants.root_id',
+ entity_ref: 'refresh_state_references.target_entity_ref',
+ })
+ .from('descendants')
+ .join('refresh_state_references', {
+ 'descendants.entity_ref':
+ 'refresh_state_references.source_entity_ref',
+ });
+ });
+ })
+ // All the nodes that can be reached upwards from the descendants
+ .withRecursive('ancestors', function ancestors(outer) {
+ return outer
+ .select({
+ root_id: rootId(),
+ via_entity_ref: 'entity_ref',
+ to_entity_ref: 'entity_ref',
+ })
+ .from('descendants')
+ .union(function recursive(inner) {
+ return inner
+ .select({
+ root_id: tx.raw(
+ 'CASE WHEN source_key IS NOT NULL THEN id ELSE NULL END',
+ [],
+ ),
+ via_entity_ref: 'source_entity_ref',
+ to_entity_ref: 'ancestors.to_entity_ref',
+ })
+ .from('ancestors')
+ .join('refresh_state_references', {
+ target_entity_ref: 'ancestors.via_entity_ref',
+ });
+ });
+ })
+ // Start out with all of the descendants
+ .select('descendants.entity_ref')
+ .from('descendants')
+ // Expand with all ancestors that point to those, but aren't the current root
+ .leftOuterJoin('ancestors', function keepaliveRoots() {
+ this.on('ancestors.to_entity_ref', '=', 'descendants.entity_ref');
+ this.andOnNotNull('ancestors.root_id');
+ this.andOn('ancestors.root_id', '!=', 'descendants.root_id');
+ })
+ .whereNull('ancestors.root_id')
+ );
+ })
+ .delete();
+
+ // Delete the references that originate only from this entity provider. Note
+ // that there may be more than one entity provider making a "claim" for a
+ // given root entity, if they emit with the same location key.
+ await tx('refresh_state_references')
+ .where('source_key', '=', sourceKey)
+ .whereIn('target_entity_ref', refs)
+ .delete();
+ }
+
+ return removedCount;
+}
diff --git a/plugins/catalog-backend/src/database/operations/provider/refreshByRefreshKeys.ts b/plugins/catalog-backend/src/database/operations/provider/refreshByRefreshKeys.ts
new file mode 100644
index 0000000000..dc34c9cdf0
--- /dev/null
+++ b/plugins/catalog-backend/src/database/operations/provider/refreshByRefreshKeys.ts
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Knex } from 'knex';
+import { DbRefreshStateRow } from '../../tables';
+
+/**
+ * Schedules a future refresh of entities, by so called "refresh keys" that may
+ * be associated with one or more entities. Note that this does not mean that
+ * the refresh happens immediately, but rather that their scheduling time gets
+ * moved up the queue and will get picked up eventually by the regular
+ * processing loop.
+ */
+export async function refreshByRefreshKeys(options: {
+ tx: Knex.Transaction;
+ keys: string[];
+}): Promise {
+ const { tx, keys } = options;
+
+ await tx('refresh_state')
+ .whereIn('entity_id', function selectEntityRefs(inner) {
+ inner
+ .whereIn('key', keys)
+ .select({
+ entity_id: 'refresh_keys.entity_id',
+ })
+ .from('refresh_keys');
+ })
+ .update({ next_update_at: tx.fn.now() });
+}
diff --git a/plugins/catalog-backend/src/database/operations/refreshState/checkLocationKeyConflict.ts b/plugins/catalog-backend/src/database/operations/refreshState/checkLocationKeyConflict.ts
new file mode 100644
index 0000000000..97d376f9a4
--- /dev/null
+++ b/plugins/catalog-backend/src/database/operations/refreshState/checkLocationKeyConflict.ts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Knex } from 'knex';
+import { DbRefreshStateRow } from '../../tables';
+
+/**
+ * Checks whether a refresh state exists for the given entity that has a
+ * location key that does not match the provided location key.
+ *
+ * @returns The conflicting key if there is one.
+ */
+export async function checkLocationKeyConflict(options: {
+ tx: Knex.Transaction;
+ entityRef: string;
+ locationKey?: string;
+}): Promise {
+ const { tx, entityRef, locationKey } = options;
+
+ const row = await tx('refresh_state')
+ .select('location_key')
+ .where('entity_ref', entityRef)
+ .first();
+
+ const conflictingKey = row?.location_key;
+
+ // If there's no existing key we can't have a conflict
+ if (!conflictingKey) {
+ return undefined;
+ }
+
+ if (conflictingKey !== locationKey) {
+ return conflictingKey;
+ }
+ return undefined;
+}
diff --git a/plugins/catalog-backend/src/database/operations/refreshState/insertUnprocessedEntity.ts b/plugins/catalog-backend/src/database/operations/refreshState/insertUnprocessedEntity.ts
new file mode 100644
index 0000000000..8e1c6edc87
--- /dev/null
+++ b/plugins/catalog-backend/src/database/operations/refreshState/insertUnprocessedEntity.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
+import { Knex } from 'knex';
+import { DbRefreshStateRow } from '../../tables';
+import { v4 as uuid } from 'uuid';
+import type { Logger } from 'winston';
+import { isDatabaseConflictError } from '@backstage/backend-common';
+
+/**
+ * Attempts to insert a new refresh state row for the given entity, returning
+ * true if successful and false if there was a conflict.
+ */
+export async function insertUnprocessedEntity(options: {
+ tx: Knex.Transaction;
+ entity: Entity;
+ hash: string;
+ locationKey?: string;
+ logger: Logger;
+}): Promise {
+ const { tx, entity, hash, logger, locationKey } = options;
+
+ const entityRef = stringifyEntityRef(entity);
+ const serializedEntity = JSON.stringify(entity);
+
+ try {
+ let query = tx('refresh_state').insert({
+ entity_id: uuid(),
+ entity_ref: entityRef,
+ unprocessed_entity: serializedEntity,
+ unprocessed_hash: hash,
+ errors: '',
+ location_key: locationKey,
+ next_update_at: tx.fn.now(),
+ last_discovery_at: tx.fn.now(),
+ });
+
+ // TODO(Rugvip): only tested towards MySQL, Postgres and SQLite.
+ // We have to do this because the only way to detect if there was a conflict with
+ // SQLite is to catch the error, while Postgres needs to ignore the conflict to not
+ // break the ongoing transaction.
+ if (tx.client.config.client.includes('pg')) {
+ query = query.onConflict('entity_ref').ignore() as any; // type here does not match runtime
+ }
+
+ // Postgres gives as an object with rowCount, SQLite gives us an array
+ const result: { rowCount?: number; length?: number } = await query;
+ return result.rowCount === 1 || result.length === 1;
+ } catch (error) {
+ // SQLite, or MySQL reached this rather than the rowCount check above
+ if (!isDatabaseConflictError(error)) {
+ throw error;
+ } else {
+ logger.debug(`Unable to insert a new refresh state row, ${error}`);
+ return false;
+ }
+ }
+}
diff --git a/plugins/catalog-backend/src/database/operations/refreshState/updateUnprocessedEntity.ts b/plugins/catalog-backend/src/database/operations/refreshState/updateUnprocessedEntity.ts
new file mode 100644
index 0000000000..e26db4429b
--- /dev/null
+++ b/plugins/catalog-backend/src/database/operations/refreshState/updateUnprocessedEntity.ts
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
+import { Knex } from 'knex';
+import { DbRefreshStateRow } from '../../tables';
+
+/**
+ * Attempts to update an existing refresh state row, returning true if it was
+ * updated and false if there was no entity with a matching ref and location key.
+ *
+ * Updating the entity will also cause it to be scheduled for immediate processing.
+ */
+export async function updateUnprocessedEntity(options: {
+ tx: Knex.Transaction;
+ entity: Entity;
+ hash: string;
+ locationKey?: string;
+}): Promise {
+ const { tx, entity, hash, locationKey } = options;
+
+ const entityRef = stringifyEntityRef(entity);
+ const serializedEntity = JSON.stringify(entity);
+
+ const refreshResult = await tx('refresh_state')
+ .update({
+ unprocessed_entity: serializedEntity,
+ unprocessed_hash: hash,
+ location_key: locationKey,
+ last_discovery_at: tx.fn.now(),
+ // We only get to this point if a processed entity actually had any changes, or
+ // if an entity provider requested this mutation, meaning that we can safely
+ // bump the deferred entities to the front of the queue for immediate processing.
+ next_update_at: tx.fn.now(),
+ })
+ .where('entity_ref', entityRef)
+ .andWhere(inner => {
+ if (!locationKey) {
+ return inner.whereNull('location_key');
+ }
+ return inner
+ .where('location_key', locationKey)
+ .orWhereNull('location_key');
+ });
+
+ return refreshResult === 1;
+}
diff --git a/plugins/catalog-backend/src/database/tables.ts b/plugins/catalog-backend/src/database/tables.ts
index c23753b267..e3f3efd1bb 100644
--- a/plugins/catalog-backend/src/database/tables.ts
+++ b/plugins/catalog-backend/src/database/tables.ts
@@ -66,6 +66,7 @@ export type DbFinalEntitiesRow = {
hash: string;
stitch_ticket: string;
final_entity?: string;
+ last_updated_at?: string | Date;
};
export type DbSearchRow = {
diff --git a/plugins/catalog-backend/src/database/types.ts b/plugins/catalog-backend/src/database/types.ts
index 345aee6ebd..56e5f48f14 100644
--- a/plugins/catalog-backend/src/database/types.ts
+++ b/plugins/catalog-backend/src/database/types.ts
@@ -109,17 +109,12 @@ export type ListParentsResult = {
entityRefs: string[];
};
+/**
+ * The database abstraction layer for Entity Processor interactions.
+ */
export interface ProcessingDatabase {
transaction(fn: (tx: Transaction) => Promise