diff --git a/.changeset/afraid-numbers-invite.md b/.changeset/afraid-numbers-invite.md new file mode 100644 index 0000000000..ee81341d3a --- /dev/null +++ b/.changeset/afraid-numbers-invite.md @@ -0,0 +1,15 @@ +--- +'@backstage/repo-tools': minor +--- + +Updates the OpenAPI client template to support the new format for identifying plugin ID. You should now use `info.title` like so, + +```diff +info: ++ title: yourPluginId +- title: @internal/plugin-*-backend + +servers: + - / +- - yourPluginId +``` diff --git a/.changeset/brown-items-hammer.md b/.changeset/brown-items-hammer.md new file mode 100644 index 0000000000..fa023a026b --- /dev/null +++ b/.changeset/brown-items-hammer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-okta-provider': patch +--- + +Added missing `additionalScopes` option to configuration schema. diff --git a/.changeset/cyan-icons-rest.md b/.changeset/cyan-icons-rest.md new file mode 100644 index 0000000000..3092c1bc90 --- /dev/null +++ b/.changeset/cyan-icons-rest.md @@ -0,0 +1,14 @@ +--- +'@backstage/plugin-explore-backend': patch +--- + +Add support for the new backend system. + +A new backend plugin for the explore backend +was added and exported as `default`. + +You can use it with the new backend system like + +```ts title="packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-explore-backend')); +``` diff --git a/.changeset/dry-lizards-taste.md b/.changeset/dry-lizards-taste.md new file mode 100644 index 0000000000..90e4c9f659 --- /dev/null +++ b/.changeset/dry-lizards-taste.md @@ -0,0 +1,6 @@ +--- +'@backstage/app-defaults': patch +'@backstage/plugin-catalog': patch +--- + +Change default icon for `kind:resource` to the storage icon. diff --git a/.changeset/dull-fireants-repeat.md b/.changeset/dull-fireants-repeat.md new file mode 100644 index 0000000000..4e849bfbaf --- /dev/null +++ b/.changeset/dull-fireants-repeat.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Use the externalized `auth-backend-module-microsoft-provider` again. diff --git a/.changeset/empty-ligers-hang.md b/.changeset/empty-ligers-hang.md new file mode 100644 index 0000000000..c17609712a --- /dev/null +++ b/.changeset/empty-ligers-hang.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Overflowing labels in OwnerPicker (Catalog) are now truncated. Hovering over them shows the full label diff --git a/.changeset/fast-jeans-walk.md b/.changeset/fast-jeans-walk.md new file mode 100644 index 0000000000..f733c9f464 --- /dev/null +++ b/.changeset/fast-jeans-walk.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-react': minor +'@backstage/plugin-scaffolder': minor +--- + +Remove the old legacy exports from `/alpha` diff --git a/.changeset/hot-pillows-poke.md b/.changeset/hot-pillows-poke.md new file mode 100644 index 0000000000..8060e7121f --- /dev/null +++ b/.changeset/hot-pillows-poke.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-user-settings': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-tech-radar': patch +'@backstage/plugin-graphiql': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-search': patch +--- + +Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. diff --git a/.changeset/hot-tips-doubt.md b/.changeset/hot-tips-doubt.md new file mode 100644 index 0000000000..464ddec302 --- /dev/null +++ b/.changeset/hot-tips-doubt.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-openapi-utils': patch +--- + +Internal updates due to `json-schema-to-ts` diff --git a/.changeset/lemon-cameras-remember.md b/.changeset/lemon-cameras-remember.md new file mode 100644 index 0000000000..29cd88602f --- /dev/null +++ b/.changeset/lemon-cameras-remember.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Migrated oidc auth provider to new `@backstage/plugin-auth-backend-module-oidc-provider` module package. diff --git a/.changeset/long-suns-bow.md b/.changeset/long-suns-bow.md new file mode 100644 index 0000000000..81fafa8dae --- /dev/null +++ b/.changeset/long-suns-bow.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog-backend': minor +'@backstage/plugin-search-backend': minor +'@backstage/plugin-todo-backend': patch +--- + +Updates the OpenAPI spec to use plugin as `info.title` instead of package name. diff --git a/.changeset/loud-walls-compare.md b/.changeset/loud-walls-compare.md new file mode 100644 index 0000000000..495ad933d9 --- /dev/null +++ b/.changeset/loud-walls-compare.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Fixed inconsistencies in icons used for System and Template diff --git a/.changeset/lovely-starfishes-remain.md b/.changeset/lovely-starfishes-remain.md new file mode 100644 index 0000000000..c57bfa0aaa --- /dev/null +++ b/.changeset/lovely-starfishes-remain.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Removed alpha symbol from Task List header diff --git a/.changeset/nine-bulldogs-camp.md b/.changeset/nine-bulldogs-camp.md new file mode 100644 index 0000000000..b6612b9948 --- /dev/null +++ b/.changeset/nine-bulldogs-camp.md @@ -0,0 +1,8 @@ +--- +'@backstage/catalog-client': minor +'@backstage/plugin-catalog-backend': minor +'@backstage/plugin-search-backend': minor +'@backstage/plugin-todo-backend': patch +--- + +Updates the OpenAPI specification title to plugin ID instead of package name. diff --git a/.changeset/old-students-smoke.md b/.changeset/old-students-smoke.md new file mode 100644 index 0000000000..8e072c5203 --- /dev/null +++ b/.changeset/old-students-smoke.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-oidc-provider': minor +--- + +Created new `@backstage/plugin-auth-backend-module-oidc-provider` module package to house oidc auth provider migration. diff --git a/.changeset/olive-singers-accept.md b/.changeset/olive-singers-accept.md new file mode 100644 index 0000000000..7e8cf7ae8d --- /dev/null +++ b/.changeset/olive-singers-accept.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': patch +--- + +Added `convertLegacyRouteRefs` for bulk conversion of plugin routes. diff --git a/.changeset/rotten-lemons-cry.md b/.changeset/rotten-lemons-cry.md new file mode 100644 index 0000000000..2bcc4c2ea7 --- /dev/null +++ b/.changeset/rotten-lemons-cry.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-microsoft-provider': patch +--- + +Added the possibility to use custom scopes for performing login with Microsoft EntraID. diff --git a/.changeset/seven-dots-serve.md b/.changeset/seven-dots-serve.md new file mode 100644 index 0000000000..80919b5d28 --- /dev/null +++ b/.changeset/seven-dots-serve.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': minor +--- + +Exported `CatalogTable.defaultColumnsFunc` for defining the columns in `` of some Kinds while using the default columns for the others. diff --git a/.changeset/silent-hotels-knock.md b/.changeset/silent-hotels-knock.md new file mode 100644 index 0000000000..7ff5d978d2 --- /dev/null +++ b/.changeset/silent-hotels-knock.md @@ -0,0 +1,25 @@ +--- +'@backstage/frontend-app-api': minor +--- + +**BREAKING**: The `app.routes.bindings` app-config mapping has been simplified. You now only need to specify the plugin ID and route ID on both sides of the mapping. + +Old form: + +```yaml +app: + routes: + bindings: + plugin.catalog.externalRoutes.viewTechDoc: plugin.techdocs.routes.docRoot + plugin.catalog.externalRoutes.createComponent: plugin.catalog-import.routes.importPage +``` + +New form: + +```yaml +app: + routes: + bindings: + catalog.viewTechDoc: techdocs.docRoot + catalog.createComponent: catalog-import.importPage +``` diff --git a/.changeset/silent-poets-grab.md b/.changeset/silent-poets-grab.md new file mode 100644 index 0000000000..0d76e263d2 --- /dev/null +++ b/.changeset/silent-poets-grab.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': patch +--- + +Improved the error message when data input/output shapes do not match diff --git a/.changeset/tame-rockets-sin.md b/.changeset/tame-rockets-sin.md new file mode 100644 index 0000000000..30c7289871 --- /dev/null +++ b/.changeset/tame-rockets-sin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-module-addons-contrib': patch +--- + +Fix position of the ReportIssue component when is displaying at the top of the container. diff --git a/.changeset/ten-planets-guess.md b/.changeset/ten-planets-guess.md new file mode 100644 index 0000000000..c8510dc6b2 --- /dev/null +++ b/.changeset/ten-planets-guess.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': patch +--- + +Fix typo in VisitsStorageApi diff --git a/.changeset/tiny-kiwis-know.md b/.changeset/tiny-kiwis-know.md new file mode 100644 index 0000000000..add4736527 --- /dev/null +++ b/.changeset/tiny-kiwis-know.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Updated dependencies in frontend plugin templates diff --git a/.changeset/tough-drinks-scream.md b/.changeset/tough-drinks-scream.md new file mode 100644 index 0000000000..3d2f154016 --- /dev/null +++ b/.changeset/tough-drinks-scream.md @@ -0,0 +1,12 @@ +--- +'@backstage/plugin-cloudbuild': minor +--- + +Changed build list view to automatically filter builds based on repository name matching component-info's metadata.name. +Added optional `google.com/cloudbuild-repo-name` annotation which allows you to specify a different repository to filter on. +Added optional `google.com/cloudbuild-trigger-name` annotation which allows you to filter based on a trigger name instead of a repo name. +Updated the ReadMe with information about the filtering and some other minor verbiage updates. +Changed `substitutions.BRANCH_NAME` to `substitutions.REF_NAME` so that the Ref field is populated properly. +Added optional `google.com/cloudbuild-location` annotation which allows you to specify the Cloud Build location of your builds. Default is global scope. +Changed build list view to show builds in a specific location if the location annotation is used. +Updated ReadMe with information about the use of the location filtering. diff --git a/.changeset/twenty-taxis-mate.md b/.changeset/twenty-taxis-mate.md new file mode 100644 index 0000000000..65ed158e9b --- /dev/null +++ b/.changeset/twenty-taxis-mate.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': patch +--- + +Plugins converted by `convertLegacyApp` now have their `routes` and `externalRoutes` included as well, allowing them to be used to bind external routes in configuration. diff --git a/.changeset/two-coats-smile.md b/.changeset/two-coats-smile.md new file mode 100644 index 0000000000..65abb7a1eb --- /dev/null +++ b/.changeset/two-coats-smile.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Updated the backend module template to make the module instance the package default export. diff --git a/.changeset/two-singers-learn.md b/.changeset/two-singers-learn.md new file mode 100644 index 0000000000..f5c2a78ab0 --- /dev/null +++ b/.changeset/two-singers-learn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-devtools': patch +--- + +Added alpha support for the New Frontend System (Declarative Integration) diff --git a/.changeset/wicked-elephants-scream.md b/.changeset/wicked-elephants-scream.md new file mode 100644 index 0000000000..f002a48ba8 --- /dev/null +++ b/.changeset/wicked-elephants-scream.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-azure-devops': patch +--- + +Prefer `dev.azure.com/build-definition` annotation when it is provided, as it is more specific than `dev.azure.com/project-repo`. This can also be used as a filter for mono-repos. diff --git a/.github/labeler.yml b/.github/labeler.yml index add66d7b28..5066ebaf05 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -2,34 +2,37 @@ area:catalog: - plugins/catalog/**/* - plugins/catalog-*/**/* - packages/catalog-*/**/* -area:scaffolder: - - plugins/scaffolder/**/* - - plugins/scaffolder-*/**/* -search: - - plugins/search/**/* - - plugins/search-*/**/* - - packages/search-*/**/* -homepage: - - plugins/home/**/* area:discoverability: # search + home - plugins/search/**/* - plugins/search-*/**/* - packages/search-*/**/* - plugins/home/**/* +area:kubernetes: + - plugins/kubernetes/**/* + - plugins/kubernetes-*/**/* +area:permission: + - plugins/permission-*/**/* +area:scaffolder: + - plugins/scaffolder/**/* + - plugins/scaffolder-*/**/* area:techdocs: - plugins/techdocs/**/* - plugins/techdocs-*/**/* - packages/techdocs-*/**/* -documentation: - - docs/**/* -microsite: - - microsite/**/* -storybook: - - storybook/**/* auth: - - plugins/auth-backend/**/* + - plugins/auth-*/**/* - packages/core-app-api/src/apis/implementations/auth/**/* - packages/core-app-api/src/lib/Auth*/**/* - packages/core-plugin-api/src/apis/definitions/auth.ts -area:permission: - - plugins/permission-*/**/* +documentation: + - docs/**/* +homepage: + - plugins/home/**/* +microsite: + - microsite/**/* +search: + - plugins/search/**/* + - plugins/search-*/**/* + - packages/search-*/**/* +storybook: + - storybook/**/* diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c46380fef..fd6e2edbc3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -216,7 +216,7 @@ jobs: run: yarn backstage-cli repo lint --since origin/master - name: test changed packages - run: yarn backstage-cli repo test --maxWorkers=4 --workerIdleMemoryLimit=1300M --since origin/master + run: yarn backstage-cli repo test --maxWorkers=3 --workerIdleMemoryLimit=1300M --since origin/master env: BACKSTAGE_TEST_DISABLE_DOCKER: 1 BACKSTAGE_TEST_DATABASE_POSTGRES16_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres16.ports[5432] }} diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index cd7ca23a86..6cd6caecf9 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -98,7 +98,7 @@ jobs: - name: test (and upload coverage) run: | - yarn backstage-cli repo test --maxWorkers=4 --workerIdleMemoryLimit=1300M --coverage + yarn backstage-cli repo test --maxWorkers=3 --workerIdleMemoryLimit=1300M --coverage bash <(curl -s https://codecov.io/bash) # Upload code coverage for some specific flags. Also see .codecov.yml bash <(curl -s https://codecov.io/bash) -f packages/core-app-api/coverage/* -F core-app-api diff --git a/.github/workflows/uffizzi-preview.yaml b/.github/workflows/uffizzi-preview.yaml index 2c1c353847..47029df5e0 100644 --- a/.github/workflows/uffizzi-preview.yaml +++ b/.github/workflows/uffizzi-preview.yaml @@ -76,7 +76,7 @@ jobs: - name: Cache Manifests File if: ${{ steps.event.outputs.ACTION != 'closed' }} - uses: actions/cache@v3.3.3 + uses: actions/cache@v4.0.0 with: path: manifests.rendered.yml key: ${{ steps.hash.outputs.MANIFESTS_FILE_HASH }} @@ -140,7 +140,7 @@ jobs: - name: Fetch cached Manifests File id: cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: manifests.rendered.yml key: ${{ needs.cache-manifests-file.outputs.manifests-cache-key }} diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index 0acf1cc1ef..143b22c8b6 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -55,7 +55,7 @@ jobs: run: yarn lint:type-deps - name: test - run: yarn backstage-cli repo test --maxWorkers=4 --workerIdleMemoryLimit=1300M + run: yarn backstage-cli repo test --maxWorkers=3 --workerIdleMemoryLimit=1300M env: BACKSTAGE_TEST_DISABLE_DOCKER: 1 diff --git a/contrib/terraform/techdocs-s3-storage/readme.md b/contrib/terraform/techdocs-s3-storage/readme.md index 9615cc8d13..b4968f7c09 100644 --- a/contrib/terraform/techdocs-s3-storage/readme.md +++ b/contrib/terraform/techdocs-s3-storage/readme.md @@ -1 +1 @@ -This terraform file should create a S3 bucket and setup IAM with a user with an inline policy which gives the user access to the bucket. After you have created the bucket, user and policy you should go to the user in the AWS console and create an access key. This access key should be used as the env variables in step 3a [here](https://backstage.io/docs/features/techdocs/using-cloud-storage#configuring-aws-s3-bucket-with-techdocs). +This Terraform file should create an S3 bucket and set up IAM with a user and an inline policy that authorises access to the bucket. After you've set up the bucket, user, and policy, go to the user's AWS dashboard and create an access key. This access key should be used to configure the environment variables in step 3a [here](https://backstage.io/docs/features/techdocs/using-cloud-storage#configuring-aws-s3-bucket-with-techdocs). diff --git a/docs/auth/microsoft/provider.md b/docs/auth/microsoft/provider.md index 999e1f40d2..bb8a7db6e4 100644 --- a/docs/auth/microsoft/provider.md +++ b/docs/auth/microsoft/provider.md @@ -28,6 +28,7 @@ On the **API permissions** tab, click on `Add Permission`, then add the followin - `openid` - `profile` - `User.Read` +- Optional custom scopes of the `Microsoft Graph` API defined in the app-config.yaml file. Your company may require you to grant [admin consent](https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/user-admin-consent-overview) for these permissions. Even if your company doesn't require admin consent, you may wish to do so as it means users don't need to individually consent the first time they access backstage. @@ -54,6 +55,8 @@ auth: clientSecret: ${AZURE_CLIENT_SECRET} tenantId: ${AZURE_TENANT_ID} domainHint: ${AZURE_TENANT_ID} + additionalScopes: + - Mail.Send ``` The Microsoft provider is a structure with three mandatory configuration keys: @@ -65,6 +68,7 @@ The Microsoft provider is a structure with three mandatory configuration keys: Leave blank if your app registration is multi tenant. When specified, this reduces login friction for users with accounts in multiple tenants by automatically filtering away accounts from other tenants. For more details, see [Home Realm Discovery](https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/home-realm-discovery-policy) +- `additionalScopes` (optional): List of scopes for the App Registration. The default and mandatory value is ['user.read']. ## Adding the provider to the Backstage frontend diff --git a/docs/faq/index.md b/docs/faq/index.md new file mode 100644 index 0000000000..93e3e90fbe --- /dev/null +++ b/docs/faq/index.md @@ -0,0 +1,15 @@ +--- +id: index +title: Overview +description: FAQ Overview +--- + +This section contains answers to frequently asked questions about Backstage. + +### [Product FAQ](../faq/product.md) + +Questions related to product and design. + +### [Technical FAQ](../faq/technical.md) + +General technical questions about Backstage. diff --git a/docs/faq/product.md b/docs/faq/product.md new file mode 100644 index 0000000000..9d2a32f33e --- /dev/null +++ b/docs/faq/product.md @@ -0,0 +1,66 @@ +--- +id: product +title: Product FAQ +description: Questions related to product and design. +--- + +### Can we call Backstage something different? So that it fits our company better? + +Yes, Backstage is just a platform for building your own developer portal. We +happen to call our internal version Backstage, as well, as a reference to our +music roots. You can call your version whatever suits your team, company, or +brand. + +### Is Backstage a monitoring platform? + +No, but it can be! Backstage is designed to be a developer portal for all your +infrastructure tooling, services, and documentation. So, it's not a monitoring +platform — but that doesn't mean you can't integrate a monitoring tool into +Backstage by writing [a plugin](#what-is-a-plugin-in-backstage). + +### How is Backstage licensed? + +Backstage was released as open source software by Spotify and is licensed under +[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +### Why did we open source Backstage? + +We hope to see Backstage become the infrastructure standard everywhere. When we +saw how much Backstage improved developer experience and productivity +internally, we wanted to share those gains. After all, if Backstage can create +order in an engineering environment as open and diverse as ours, then we're +pretty sure it can create order (and boost productivity) anywhere. To learn +more, read our blog post, +"[What the heck is Backstage anyway?](https://backstage.io/blog/2020/03/18/what-is-backstage)" + +### Will Spotify's internal plugins be open sourced, too? + +Yes, we've already started releasing open source versions of some of the plugins +we use here, and we'll continue to do so. +[Plugins](#what-is-a-plugin-in-backstage) are the building blocks of +functionality in Backstage. We have over 120 plugins inside Spotify — many of +those are specialized for our use, so will remain internal and proprietary to +us. But we estimate that about a third of our existing plugins make good open +source candidates. (And we'll probably end up writing some brand new ones, too.) + +### What's the roadmap for Backstage? + +We envision three phases, which you can learn about in +[our project roadmap](../overview/roadmap.md). Even though the open source version +of Backstage is relatively new compared to our internal version, we have already +begun work on various aspects of all three phases. Looking at the +[milestones for active issues](https://github.com/backstage/backstage/milestones) +will also give you a sense of our progress. + +### My company doesn't have thousands of developers or services. Is using Backstage excessive for our needs? + +Not at all! A core reason to adopt Backstage is to standardize how software is +built at your company. It's easier to decide on those standards as a small +company, and grows in importance as the company grows. Backstage sets a +foundation, and an early investment in your infrastructure becomes even more +valuable as you grow. + +### Our company has a strong design language system/brand that we want to incorporate. Does Backstage support this? + +Yes! The Backstage UI is built using Material UI. With the theming capabilities +of Material UI, you are able to adapt the interface to your brand guidelines. diff --git a/docs/FAQ.md b/docs/faq/technical.md similarity index 74% rename from docs/FAQ.md rename to docs/faq/technical.md index 7b935140e6..55bb1af615 100644 --- a/docs/FAQ.md +++ b/docs/faq/technical.md @@ -1,74 +1,9 @@ --- -id: FAQ -title: FAQ -description: All FAQ related to Backstage +id: technical +title: Technical FAQ +description: General technical questions about Backstage. --- -## Product FAQ - -### Can we call Backstage something different? So that it fits our company better? - -Yes, Backstage is just a platform for building your own developer portal. We -happen to call our internal version Backstage, as well, as a reference to our -music roots. You can call your version whatever suits your team, company, or -brand. - -### Is Backstage a monitoring platform? - -No, but it can be! Backstage is designed to be a developer portal for all your -infrastructure tooling, services, and documentation. So, it's not a monitoring -platform — but that doesn't mean you can't integrate a monitoring tool into -Backstage by writing [a plugin](#what-is-a-plugin-in-backstage). - -### How is Backstage licensed? - -Backstage was released as open source software by Spotify and is licensed under -[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0). - -### Why did we open source Backstage? - -We hope to see Backstage become the infrastructure standard everywhere. When we -saw how much Backstage improved developer experience and productivity -internally, we wanted to share those gains. After all, if Backstage can create -order in an engineering environment as open and diverse as ours, then we're -pretty sure it can create order (and boost productivity) anywhere. To learn -more, read our blog post, -"[What the heck is Backstage anyway?](https://backstage.io/blog/2020/03/18/what-is-backstage)" - -### Will Spotify's internal plugins be open sourced, too? - -Yes, we've already started releasing open source versions of some of the plugins -we use here, and we'll continue to do so. -[Plugins](#what-is-a-plugin-in-backstage) are the building blocks of -functionality in Backstage. We have over 120 plugins inside Spotify — many of -those are specialized for our use, so will remain internal and proprietary to -us. But we estimate that about a third of our existing plugins make good open -source candidates. (And we'll probably end up writing some brand new ones, too.) - -### What's the roadmap for Backstage? - -We envision three phases, which you can learn about in -[our project roadmap](overview/roadmap.md). Even though the open source version -of Backstage is relatively new compared to our internal version, we have already -begun work on various aspects of all three phases. Looking at the -[milestones for active issues](https://github.com/backstage/backstage/milestones) -will also give you a sense of our progress. - -### My company doesn't have thousands of developers or services. Is using Backstage excessive for our needs? - -Not at all! A core reason to adopt Backstage is to standardize how software is -built at your company. It's easier to decide on those standards as a small -company, and grows in importance as the company grows. Backstage sets a -foundation, and an early investment in your infrastructure becomes even more -valuable as you grow. - -### Our company has a strong design language system/brand that we want to incorporate. Does Backstage support this? - -Yes! The Backstage UI is built using Material UI. With the theming capabilities -of Material UI, you are able to adapt the interface to your brand guidelines. - -## Technical FAQ - ### What technology does Backstage use? Backstage is a large scale [TypeScript](https://www.typescriptlang.org/) @@ -116,7 +51,7 @@ type of content. Plugins all use a common set of platform APIs and reusable UI components. Plugins can fetch data either from the backend or an API exposed through the proxy. -Learn more about [the different components](overview/what-is-backstage.md) that +Learn more about [the different components](../overview/what-is-backstage.md) that make up Backstage. ### Why can't I dynamically install plugins without modifications to the app? @@ -253,7 +188,7 @@ data is shared with. Yes. The core frontend framework could be used for building any large-scale web application where (1) multiple teams are building separate parts of the app, and (2) you want the overall experience to be consistent. That being said, in -[Phase 2](overview/roadmap.md) of the project we will add features that are +[Phase 2](../overview/roadmap.md) of the project we will add features that are needed for developer portals and systems for managing software ecosystems. Our ambition will be to keep Backstage modular. diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 8351a864ba..11586573be 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -241,10 +241,10 @@ app: bindings: # point to the Scaffolder create component page when the Catalog create component ref is used # highlight-next-line - plugin.catalog.externalRoutes.createComponent: plugin.scaffolder.routes.index + catalog.createComponent: scaffolder.index # point to the Catalog details page when the Scaffolder component details ref is used # highlight-next-line - plugin.scaffolder.externalRoutes.componentDetails: plugin.catalog.routes.details + scaffolder.componentDetails: catalog.details ``` We also have the ability to express this in code as an option to `createApp`, but you of course only need to use one of these two methods: diff --git a/docs/integrations/github/github-apps.md b/docs/integrations/github/github-apps.md index cc84704799..96363bc719 100644 --- a/docs/integrations/github/github-apps.md +++ b/docs/integrations/github/github-apps.md @@ -139,3 +139,13 @@ integration: - `Variables`: `Read & write` (if templates include GitHub Action Repository Variables) - `Secrets`: `Read & write` (if templates include GitHub Action Repository Secrets) - `Environments`: `Read & write` (if templates include GitHub Environments) + +### Troubleshooting + +`HttpError: This endpoint requires you to be authenticated.` + +This message tends to wrap a `NotFoundError: No app installation found` under the hood, which +is the result of not installing the app in your organization. Even if created via the `backstage-cli` +as a member and app manager of your organization, the app will not automatically install. You +must possess the `Owner` role in the organization to see the `Install` menu under your +app settings, then manually press `Install` to authorize the application. diff --git a/docs/openapi/generate-client.md b/docs/openapi/generate-client.md index 4afa7d64d7..f2c7c64574 100644 --- a/docs/openapi/generate-client.md +++ b/docs/openapi/generate-client.md @@ -8,15 +8,12 @@ description: Documentation on how to create a client for a given OpenAPI spec ### Prerequisites -1. Add your plugin ID as the last `servers` item, like this, +1. Set your OpenAPI file's `info.title` to your pluginID like so, ```yaml -servers: - # first value, used for OpenAPI router validation. - - url: / - - # final value, pluginId. - - url: catalog +info: + # your pluginId + title: catalog ``` 2. Find or create a new plugin to house your new generated client. Currently, we do not support generating an entirely new plugin and instead just generate client files. diff --git a/docs/overview/support.md b/docs/overview/support.md index c968405a99..38bb60784f 100644 --- a/docs/overview/support.md +++ b/docs/overview/support.md @@ -11,7 +11,7 @@ description: Support and Community Details and Links here if you want to contribute. - [RFCs](https://github.com/backstage/backstage/labels/rfc) - Help shape the technical direction by reviewing _Request for Comments_ issues. -- [FAQ](../FAQ.md) - Frequently Asked Questions. +- [FAQ](../faq/index.md) - Frequently Asked Questions. - [Code of Conduct](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md) - This is how we roll. - [Blog](https://backstage.io/blog/) - Announcements and updates. diff --git a/microsite/data/plugins/aws-app-development.yaml b/microsite/data/plugins/aws-app-development.yaml index 3944bbb4e0..47b40b8b3b 100644 --- a/microsite/data/plugins/aws-app-development.yaml +++ b/microsite/data/plugins/aws-app-development.yaml @@ -1,10 +1,10 @@ --- -title: AWS App Developer Tools +title: OPA on AWS author: Amazon Web Services authorUrl: https://aws.amazon.com/ category: Infrastructure -description: Create and manage AWS Apps within Backstage -documentation: https://github.com/awslabs/app-development-for-backstage-io-on-aws#readme -iconUrl: https://github.com/awslabs/app-development-for-backstage-io-on-aws/blob/main/docs/images/AWS_logo.png?raw=true +description: Orchestrate Platforms and Applications (OPA) allows customers to build and manage AWS Apps & Environments within Backstage +documentation: https://opaonaws.io +iconUrl: https://github.com/awslabs/app-development-for-backstage-io-on-aws/blob/main/website/static/img/white_OPA_text02.png?raw=true npmPackageName: '@aws/plugin-aws-apps-for-backstage' addedDate: '2023-05-10' diff --git a/microsite/data/plugins/backchat.yaml b/microsite/data/plugins/backchat.yaml new file mode 100644 index 0000000000..b375ad26bc --- /dev/null +++ b/microsite/data/plugins/backchat.yaml @@ -0,0 +1,10 @@ +--- +title: Backchat GenAI +author: benwilcock +authorUrl: https://github.com/benwilcock +category: Services +description: Access your favorite open source GenAI GUIs privately from Backstage. Chat wth large language models in your portal. Choose from hundreds of LLMs. Run inferencing wherever you like - local or remote, CPU or GPU - it's up to you! +documentation: https://github.com/benwilcock/backstage-plugin-backchat +iconUrl: /img/backchat-logo.png +npmPackageName: '@benbravo73/backstage-plugin-backchat' +addedDate: '2024-01-12' diff --git a/microsite/data/plugins/end-of-life.yaml b/microsite/data/plugins/end-of-life.yaml new file mode 100644 index 0000000000..d54a6bc5f9 --- /dev/null +++ b/microsite/data/plugins/end-of-life.yaml @@ -0,0 +1,10 @@ +--- +title: End of life +author: dweber019 +authorUrl: https://github.com/dweber019 +category: Quality +description: Display end of life data for entities from endoflife.data +documentation: https://github.com/dweber019/backstage-plugin-endoflife +iconUrl: https://raw.githubusercontent.com/dweber019/backstage-plugin-endoflife/main/plugins/endoflife/docs/pluginIcon.png +npmPackageName: '@dweber019/backstage-plugin-endoflife' +addedDate: '2024-01-18' diff --git a/microsite/data/plugins/github-codespaces.yaml b/microsite/data/plugins/github-codespaces.yaml new file mode 100644 index 0000000000..de2659c1e1 --- /dev/null +++ b/microsite/data/plugins/github-codespaces.yaml @@ -0,0 +1,15 @@ +--- +title: GitHub Codespaces +author: Aditya Singhal +authorUrl: https://github.com/adityasinghal26 +category: Development +description: Integrates GitHub Codespaces for a Backstage component with the Authenticated User. +documentation: https://github.com/adityasinghal26/backstage-plugins/tree/main/plugins/github-codespaces +iconUrl: https://github.com/adityasinghal26/backstage-plugins/blob/00c9c00ba9acc3135014d6454ccf04f573195eef/plugins/github-codespaces/images/GitHubLogo.png +npmPackageName: '@adityasinghal26/plugin-github-codespaces' +tags: + - github + - codespaces + - development + - devcontainers +addedDate: '2023-12-30' diff --git a/microsite/package.json b/microsite/package.json index 53309fb358..637327f83e 100644 --- a/microsite/package.json +++ b/microsite/package.json @@ -18,7 +18,7 @@ "docusaurus": "docusaurus" }, "devDependencies": { - "@docusaurus/module-type-aliases": "0.0.0-5703", + "@docusaurus/module-type-aliases": "0.0.0-5809", "@spotify/prettier-config": "^14.0.0", "@tsconfig/docusaurus": "^2.0.0", "@types/luxon": "^3.0.0", @@ -30,9 +30,9 @@ }, "prettier": "@spotify/prettier-config", "dependencies": { - "@docusaurus/core": "0.0.0-5703", - "@docusaurus/plugin-client-redirects": "0.0.0-5703", - "@docusaurus/preset-classic": "0.0.0-5703", + "@docusaurus/core": "0.0.0-5809", + "@docusaurus/plugin-client-redirects": "0.0.0-5809", + "@docusaurus/preset-classic": "0.0.0-5809", "@swc/core": "^1.3.46", "clsx": "^2.0.0", "docusaurus-plugin-sass": "^0.2.3", diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 187c41ad75..e32e027807 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -478,7 +478,7 @@ "architecture-decisions/adrs-adr012", "architecture-decisions/adrs-adr013" ], - "FAQ": ["FAQ"], + "FAQ": ["faq/index", "faq/product", "faq/technical"], "Accessibility": ["accessibility/index"] } } diff --git a/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss b/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss index 77e1a87a53..9533890660 100644 --- a/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss +++ b/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss @@ -1,9 +1,13 @@ +$page-header-height: 44px; + .hubSpotNewAdopterFormContainer { top: 50%; right: 0; display: flex; position: fixed; transform: translateY(-50%); + margin-top: $page-header-height; + max-height: calc(100% - $page-header-height); transition: all 250ms ease-in-out; @@ -22,9 +26,7 @@ } .hubSpotNewAdopterFormContent { - height: 600px; max-width: 500px; - overflow-y: hidden; border-radius: 8px 0 0 8px; background-color: var(--ifm-color-white); diff --git a/microsite/static/img/backchat-logo.png b/microsite/static/img/backchat-logo.png new file mode 100644 index 0000000000..2d58948007 Binary files /dev/null and b/microsite/static/img/backchat-logo.png differ diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 5e976cce69..1841fcb678 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -197,55 +197,55 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.8.3": - version: 7.22.13 - resolution: "@babel/code-frame@npm:7.22.13" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.8.3": + version: 7.23.5 + resolution: "@babel/code-frame@npm:7.23.5" dependencies: - "@babel/highlight": ^7.22.13 + "@babel/highlight": ^7.23.4 chalk: ^2.4.2 - checksum: 22e342c8077c8b77eeb11f554ecca2ba14153f707b85294fcf6070b6f6150aae88a7b7436dd88d8c9289970585f3fe5b9b941c5aa3aa26a6d5a8ef3f292da058 + checksum: d90981fdf56a2824a9b14d19a4c0e8db93633fd488c772624b4e83e0ceac6039a27cd298a247c3214faa952bf803ba23696172ae7e7235f3b97f43ba278c569a languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.20, @babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9": - version: 7.22.20 - resolution: "@babel/compat-data@npm:7.22.20" - checksum: efedd1d18878c10fde95e4d82b1236a9aba41395ef798cbb651f58dbf5632dbff475736c507b8d13d4c8f44809d41c0eb2ef0d694283af9ba5dd8339b6dab451 +"@babel/compat-data@npm:^7.22.20, @babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.5": + version: 7.23.5 + resolution: "@babel/compat-data@npm:7.23.5" + checksum: 06ce244cda5763295a0ea924728c09bae57d35713b675175227278896946f922a63edf803c322f855a3878323d48d0255a2a3023409d2a123483c8a69ebb4744 languageName: node linkType: hard -"@babel/core@npm:^7.19.6, @babel/core@npm:^7.22.9": - version: 7.23.0 - resolution: "@babel/core@npm:7.23.0" +"@babel/core@npm:^7.19.6, @babel/core@npm:^7.23.3": + version: 7.23.7 + resolution: "@babel/core@npm:7.23.7" dependencies: "@ampproject/remapping": ^2.2.0 - "@babel/code-frame": ^7.22.13 - "@babel/generator": ^7.23.0 - "@babel/helper-compilation-targets": ^7.22.15 - "@babel/helper-module-transforms": ^7.23.0 - "@babel/helpers": ^7.23.0 - "@babel/parser": ^7.23.0 + "@babel/code-frame": ^7.23.5 + "@babel/generator": ^7.23.6 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helpers": ^7.23.7 + "@babel/parser": ^7.23.6 "@babel/template": ^7.22.15 - "@babel/traverse": ^7.23.0 - "@babel/types": ^7.23.0 + "@babel/traverse": ^7.23.7 + "@babel/types": ^7.23.6 convert-source-map: ^2.0.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.3 semver: ^6.3.1 - checksum: cebd9b48dbc970a7548522f207f245c69567e5ea17ebb1a4e4de563823cf20a01177fe8d2fe19b6e1461361f92fa169fd0b29f8ee9d44eeec84842be1feee5f2 + checksum: 32d5bf73372a47429afaae9adb0af39e47bcea6a831c4b5dcbb4791380cda6949cb8cb1a2fea8b60bb1ebe189209c80e333903df1fa8e9dcb04798c0ce5bf59e languageName: node linkType: hard -"@babel/generator@npm:^7.22.9, @babel/generator@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/generator@npm:7.23.0" +"@babel/generator@npm:^7.23.3, @babel/generator@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/generator@npm:7.23.6" dependencies: - "@babel/types": ^7.23.0 + "@babel/types": ^7.23.6 "@jridgewell/gen-mapping": ^0.3.2 "@jridgewell/trace-mapping": ^0.3.17 jsesc: ^2.5.1 - checksum: 8efe24adad34300f1f8ea2add420b28171a646edc70f2a1b3e1683842f23b8b7ffa7e35ef0119294e1901f45bfea5b3dc70abe1f10a1917ccdfb41bed69be5f1 + checksum: 1a1a1c4eac210f174cd108d479464d053930a812798e09fee069377de39a893422df5b5b146199ead7239ae6d3a04697b45fc9ac6e38e0f6b76374390f91fc6c languageName: node linkType: hard @@ -267,16 +267,16 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.15, @babel/helper-compilation-targets@npm:^7.22.5, @babel/helper-compilation-targets@npm:^7.22.6": - version: 7.22.15 - resolution: "@babel/helper-compilation-targets@npm:7.22.15" +"@babel/helper-compilation-targets@npm:^7.22.15, @babel/helper-compilation-targets@npm:^7.22.5, @babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/helper-compilation-targets@npm:7.23.6" dependencies: - "@babel/compat-data": ^7.22.9 - "@babel/helper-validator-option": ^7.22.15 - browserslist: ^4.21.9 + "@babel/compat-data": ^7.23.5 + "@babel/helper-validator-option": ^7.23.5 + browserslist: ^4.22.2 lru-cache: ^5.1.1 semver: ^6.3.1 - checksum: ce85196769e091ae54dd39e4a80c2a9df1793da8588e335c383d536d54f06baf648d0a08fc873044f226398c4ded15c4ae9120ee18e7dfd7c639a68e3cdc9980 + checksum: c630b98d4527ac8fe2c58d9a06e785dfb2b73ec71b7c4f2ddf90f814b5f75b547f3c015f110a010fd31f76e3864daaf09f3adcd2f6acdbfb18a8de3a48717590 languageName: node linkType: hard @@ -371,9 +371,9 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.22.5, @babel/helper-module-transforms@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/helper-module-transforms@npm:7.23.0" +"@babel/helper-module-transforms@npm:^7.22.5, @babel/helper-module-transforms@npm:^7.23.0, @babel/helper-module-transforms@npm:^7.23.3": + version: 7.23.3 + resolution: "@babel/helper-module-transforms@npm:7.23.3" dependencies: "@babel/helper-environment-visitor": ^7.22.20 "@babel/helper-module-imports": ^7.22.15 @@ -382,7 +382,7 @@ __metadata: "@babel/helper-validator-identifier": ^7.22.20 peerDependencies: "@babel/core": ^7.0.0 - checksum: 6e2afffb058cf3f8ce92f5116f710dda4341c81cfcd872f9a0197ea594f7ce0ab3cb940b0590af2fe99e60d2e5448bfba6bca8156ed70a2ed4be2adc8586c891 + checksum: 5d0895cfba0e16ae16f3aa92fee108517023ad89a855289c4eb1d46f7aef4519adf8e6f971e1d55ac20c5461610e17213f1144097a8f932e768a9132e2278d71 languageName: node linkType: hard @@ -455,10 +455,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-string-parser@npm:7.22.5" - checksum: 836851ca5ec813077bbb303acc992d75a360267aa3b5de7134d220411c852a6f17de7c0d0b8c8dcc0f567f67874c00f4528672b2a4f1bc978a3ada64c8c78467 +"@babel/helper-string-parser@npm:^7.23.4": + version: 7.23.4 + resolution: "@babel/helper-string-parser@npm:7.23.4" + checksum: c0641144cf1a7e7dc93f3d5f16d5327465b6cf5d036b48be61ecba41e1eece161b48f46b7f960951b67f8c3533ce506b16dece576baef4d8b3b49f8c65410f90 languageName: node linkType: hard @@ -469,10 +469,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/helper-validator-option@npm:7.22.15" - checksum: 68da52b1e10002a543161494c4bc0f4d0398c8fdf361d5f7f4272e95c45d5b32d974896d44f6a0ea7378c9204988879d73613ca683e13bd1304e46d25ff67a8d +"@babel/helper-validator-option@npm:^7.22.15, @babel/helper-validator-option@npm:^7.23.5": + version: 7.23.5 + resolution: "@babel/helper-validator-option@npm:7.23.5" + checksum: 537cde2330a8aede223552510e8a13e9c1c8798afee3757995a7d4acae564124fe2bf7e7c3d90d62d3657434a74340a274b3b3b1c6f17e9a2be1f48af29cb09e languageName: node linkType: hard @@ -487,34 +487,34 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.23.0": - version: 7.23.1 - resolution: "@babel/helpers@npm:7.23.1" +"@babel/helpers@npm:^7.23.7": + version: 7.23.8 + resolution: "@babel/helpers@npm:7.23.8" dependencies: "@babel/template": ^7.22.15 - "@babel/traverse": ^7.23.0 - "@babel/types": ^7.23.0 - checksum: acfc345102045c24ea2a4d60e00dcf8220e215af3add4520e2167700661338e6a80bd56baf44bb764af05ec6621101c9afc315dc107e18c61fa6da8acbdbb893 + "@babel/traverse": ^7.23.7 + "@babel/types": ^7.23.6 + checksum: 8b522d527921f8df45a983dc7b8e790c021250addf81ba7900ba016e165442a527348f6f877aa55e1debb3eef9e860a334b4e8d834e6c9b438ed61a63d9a7ad4 languageName: node linkType: hard -"@babel/highlight@npm:^7.22.13": - version: 7.22.20 - resolution: "@babel/highlight@npm:7.22.20" +"@babel/highlight@npm:^7.23.4": + version: 7.23.4 + resolution: "@babel/highlight@npm:7.23.4" dependencies: "@babel/helper-validator-identifier": ^7.22.20 chalk: ^2.4.2 js-tokens: ^4.0.0 - checksum: 84bd034dca309a5e680083cd827a766780ca63cef37308404f17653d32366ea76262bd2364b2d38776232f2d01b649f26721417d507e8b4b6da3e4e739f6d134 + checksum: 643acecdc235f87d925979a979b539a5d7d1f31ae7db8d89047269082694122d11aa85351304c9c978ceeb6d250591ccadb06c366f358ccee08bb9c122476b89 languageName: node linkType: hard -"@babel/parser@npm:^7.22.15, @babel/parser@npm:^7.22.7, @babel/parser@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/parser@npm:7.23.0" +"@babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/parser@npm:7.23.6" bin: parser: ./bin/babel-parser.js - checksum: 453fdf8b9e2c2b7d7b02139e0ce003d1af21947bbc03eb350fb248ee335c9b85e4ab41697ddbdd97079698de825a265e45a0846bb2ed47a2c7c1df833f42a354 + checksum: 140801c43731a6c41fd193f5c02bc71fd647a0360ca616b23d2db8be4b9739b9f951a03fc7c2db4f9b9214f4b27c1074db0f18bc3fa653783082d5af7c8860d5 languageName: node linkType: hard @@ -1593,7 +1593,7 @@ __metadata: 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.22.6, @babel/runtime@npm:^7.8.4": +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.3, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.8.4": version: 7.23.1 resolution: "@babel/runtime@npm:7.23.1" dependencies: @@ -1613,32 +1613,32 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.23.0": - version: 7.23.2 - resolution: "@babel/traverse@npm:7.23.2" +"@babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.23.7": + version: 7.23.7 + resolution: "@babel/traverse@npm:7.23.7" dependencies: - "@babel/code-frame": ^7.22.13 - "@babel/generator": ^7.23.0 + "@babel/code-frame": ^7.23.5 + "@babel/generator": ^7.23.6 "@babel/helper-environment-visitor": ^7.22.20 "@babel/helper-function-name": ^7.23.0 "@babel/helper-hoist-variables": ^7.22.5 "@babel/helper-split-export-declaration": ^7.22.6 - "@babel/parser": ^7.23.0 - "@babel/types": ^7.23.0 - debug: ^4.1.0 + "@babel/parser": ^7.23.6 + "@babel/types": ^7.23.6 + debug: ^4.3.1 globals: ^11.1.0 - checksum: 26a1eea0dde41ab99dde8b9773a013a0dc50324e5110a049f5d634e721ff08afffd54940b3974a20308d7952085ac769689369e9127dea655f868c0f6e1ab35d + checksum: d4a7afb922361f710efc97b1e25ec343fab8b2a4ddc81ca84f9a153f22d4482112cba8f263774be8d297918b6c4767c7a98988ab4e53ac73686c986711dd002e languageName: node linkType: hard -"@babel/types@npm:^7.20.0, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": - version: 7.23.0 - resolution: "@babel/types@npm:7.23.0" +"@babel/types@npm:^7.20.0, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.6, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": + version: 7.23.6 + resolution: "@babel/types@npm:7.23.6" dependencies: - "@babel/helper-string-parser": ^7.22.5 + "@babel/helper-string-parser": ^7.23.4 "@babel/helper-validator-identifier": ^7.22.20 to-fast-properties: ^2.0.0 - checksum: 215fe04bd7feef79eeb4d33374b39909ce9cad1611c4135a4f7fdf41fe3280594105af6d7094354751514625ea92d0875aba355f53e86a92600f290e77b0e604 + checksum: 68187dbec0d637f79bc96263ac95ec8b06d424396678e7e225492be866414ce28ebc918a75354d4c28659be6efe30020b4f0f6df81cc418a2d30645b690a8de0 languageName: node linkType: hard @@ -1689,12 +1689,12 @@ __metadata: languageName: node linkType: hard -"@docusaurus/core@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/core@npm:0.0.0-5703" +"@docusaurus/core@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/core@npm:0.0.0-5809" dependencies: - "@babel/core": ^7.22.9 - "@babel/generator": ^7.22.9 + "@babel/core": ^7.23.3 + "@babel/generator": ^7.23.3 "@babel/plugin-syntax-dynamic-import": ^7.8.3 "@babel/plugin-transform-runtime": ^7.22.9 "@babel/preset-env": ^7.22.9 @@ -1703,13 +1703,13 @@ __metadata: "@babel/runtime": ^7.22.6 "@babel/runtime-corejs3": ^7.22.6 "@babel/traverse": ^7.22.8 - "@docusaurus/cssnano-preset": 0.0.0-5703 - "@docusaurus/logger": 0.0.0-5703 - "@docusaurus/mdx-loader": 0.0.0-5703 + "@docusaurus/cssnano-preset": 0.0.0-5809 + "@docusaurus/logger": 0.0.0-5809 + "@docusaurus/mdx-loader": 0.0.0-5809 "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/utils": 0.0.0-5703 - "@docusaurus/utils-common": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 + "@docusaurus/utils": 0.0.0-5809 + "@docusaurus/utils-common": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 "@slorber/static-site-generator-webpack-plugin": ^4.0.7 "@svgr/webpack": ^6.5.1 autoprefixer: ^10.4.14 @@ -1736,7 +1736,6 @@ __metadata: html-minifier-terser: ^7.2.0 html-tags: ^3.3.1 html-webpack-plugin: ^5.5.3 - import-fresh: ^3.3.0 leven: ^3.1.0 lodash: ^4.17.21 mini-css-extract-plugin: ^2.7.6 @@ -1758,7 +1757,6 @@ __metadata: tslib: ^2.6.0 update-notifier: ^6.0.2 url-loader: ^4.1.1 - wait-on: ^7.0.1 webpack: ^5.88.1 webpack-bundle-analyzer: ^4.9.0 webpack-dev-server: ^4.15.1 @@ -1769,76 +1767,73 @@ __metadata: react-dom: ^18.0.0 bin: docusaurus: bin/docusaurus.mjs - checksum: 0e2912a09964778db626dc190317badb074f2f5e09157b8070f281eff69ce2e89846529584ce9bf6e6898293409c353adc80572484aceda1d2136aa2b0b334ca + checksum: 4b448bc4fc5df42de82afb7fd6e05aa1faec9edd4b534f982bd36efadc75e10f5fd94275286ee28be0c849f22504f4441a9918d179bfe1a0783f341bb6ccac3e languageName: node linkType: hard -"@docusaurus/cssnano-preset@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/cssnano-preset@npm:0.0.0-5703" +"@docusaurus/cssnano-preset@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/cssnano-preset@npm:0.0.0-5809" dependencies: cssnano-preset-advanced: ^5.3.10 postcss: ^8.4.26 postcss-sort-media-queries: ^4.4.1 tslib: ^2.6.0 - checksum: 5f6e2a69765fb18de7d8f5e3037bf4f08695034762fca092229ae0ba9a40e9b76048914ffbf6b1d339d496e23580f47aa419f51f446c98fca0ba8d500a06e396 + checksum: 92ec22fb1dfcc8d85cd55f9f365a22809ea65d2181ace4610889e804a322c9fccf983eacbf56b8d848515d505eb1cdc9a8ac6d8d0409dd764d6cd784d029826e languageName: node linkType: hard -"@docusaurus/logger@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/logger@npm:0.0.0-5703" +"@docusaurus/logger@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/logger@npm:0.0.0-5809" dependencies: chalk: ^4.1.2 tslib: ^2.6.0 - checksum: 9ee30b054388e5a618876316df50b73a7c4c8300ce205ace3c09f689a1a38b85d51891a1f0613341fd038a0d06290f0675d64c3e9e5b87f1eee3cb76fd45b55c + checksum: 818f0493308a3261efbd098ca7b37cc76b15280e133f5aa7d8e344e8e39b54e8d07cd011f494b964be6ef39740ec0edf3d4829361e40fb1dbb3027599fc08fdd languageName: node linkType: hard -"@docusaurus/mdx-loader@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/mdx-loader@npm:0.0.0-5703" +"@docusaurus/mdx-loader@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/mdx-loader@npm:0.0.0-5809" dependencies: - "@babel/parser": ^7.22.7 - "@babel/traverse": ^7.22.8 - "@docusaurus/logger": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 - "@mdx-js/mdx": ^2.1.5 + "@docusaurus/logger": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 + "@mdx-js/mdx": ^3.0.0 "@slorber/remark-comment": ^1.0.0 escape-html: ^1.0.3 - estree-util-value-to-estree: ^2.1.0 + estree-util-value-to-estree: ^3.0.1 file-loader: ^6.2.0 fs-extra: ^11.1.1 - hastscript: ^7.1.0 image-size: ^1.0.2 - mdast-util-mdx: ^2.0.0 - mdast-util-to-string: ^3.2.0 - rehype-raw: ^6.1.1 - remark-directive: ^2.0.1 - remark-emoji: ^2.2.0 + mdast-util-mdx: ^3.0.0 + mdast-util-to-string: ^4.0.0 + rehype-raw: ^7.0.0 + remark-directive: ^3.0.0 + remark-emoji: ^4.0.0 remark-frontmatter: ^5.0.0 - remark-gfm: ^3.0.1 + remark-gfm: ^4.0.0 stringify-object: ^3.3.0 tslib: ^2.6.0 - unified: ^10.1.2 - unist-util-visit: ^2.0.3 + unified: ^11.0.3 + unist-util-visit: ^5.0.0 url-loader: ^4.1.1 - vfile: ^5.3.7 + vfile: ^6.0.1 webpack: ^5.88.1 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: d57b08d7d676b9246be129af06a803fc55162359578e486456cb96a2372809c2093ef4115c926cf8e8be35e285b35d3ea444d808d46afb78edf66b49f58474fb + checksum: d92126b7b32aa5b73c9556e9e04ddf4055992301d4df0cc0d1de5a618fa48e9133038ef8ee15395bbc1fa1c66552bd5cb8c901a2239130e1ee6499d679f0eae5 languageName: node linkType: hard -"@docusaurus/module-type-aliases@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/module-type-aliases@npm:0.0.0-5703" +"@docusaurus/module-type-aliases@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/module-type-aliases@npm:0.0.0-5809" dependencies: "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/types": 0.0.0-5703 + "@docusaurus/types": 0.0.0-5809 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -1848,19 +1843,19 @@ __metadata: peerDependencies: react: "*" react-dom: "*" - checksum: b0dbf719f3c6510b6706f36310b185bdf8a8a2ab5d3b0b76f8962b08d3b1a86783c3f4c23455c03d528500871f0a18ede4e03a0df8c7a44096b91097a5ffda7d + checksum: 3bd545d550989111b00274f3f06df9367895688060afb08b6c7ec3b4967768a78f5d2e1bf7a1b43d77276b116e62f077f0131cc8f1b7e4acbc1db9d3d49471aa languageName: node linkType: hard -"@docusaurus/plugin-client-redirects@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/plugin-client-redirects@npm:0.0.0-5703" +"@docusaurus/plugin-client-redirects@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/plugin-client-redirects@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/logger": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 - "@docusaurus/utils-common": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/logger": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 + "@docusaurus/utils-common": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 eta: ^2.2.0 fs-extra: ^11.1.1 lodash: ^4.17.21 @@ -1868,21 +1863,21 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: ac246eeb75028acd6a1d8804572fb89bac5575facf82c35ca3c8441d916980c183f5342a768d31cccc95f2034657bd25cfda24d480a2b8b4abdd693a51d9754e + checksum: d0b9b842f184e0b21ae9fcb718b8eccb7d0103ed847c7e27b782ba67b6eaba1875f3de796823363ccfbc648d6721a5d8ac1512ffc61e55e9c1d9a47bc7ad1646 languageName: node linkType: hard -"@docusaurus/plugin-content-blog@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/plugin-content-blog@npm:0.0.0-5703" +"@docusaurus/plugin-content-blog@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/plugin-content-blog@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/logger": 0.0.0-5703 - "@docusaurus/mdx-loader": 0.0.0-5703 - "@docusaurus/types": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 - "@docusaurus/utils-common": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/logger": 0.0.0-5809 + "@docusaurus/mdx-loader": 0.0.0-5809 + "@docusaurus/types": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 + "@docusaurus/utils-common": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 cheerio: ^1.0.0-rc.12 feed: ^4.2.2 fs-extra: ^11.1.1 @@ -1890,31 +1885,30 @@ __metadata: reading-time: ^1.5.0 srcset: ^4.0.0 tslib: ^2.6.0 - unist-util-visit: ^2.0.3 + unist-util-visit: ^5.0.0 utility-types: ^3.10.0 webpack: ^5.88.1 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 46e4a4fac407a8014ce0918933a476b03adca3d3b7e76b27a87bf0eeeb446f20e25db60b292f743652f3ad88232824f7a1541fcb7d27bcdbf9cb6d1c94e9a1b5 + checksum: 40981493af1fd0f835e3a5cf42c56718bc41feb73af36a8641c425875cd366e1e0c44841469649f55a014bfb5d1782d459a6ad8876849b12ee73e97b3f3b73cc languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/plugin-content-docs@npm:0.0.0-5703" +"@docusaurus/plugin-content-docs@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/plugin-content-docs@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/logger": 0.0.0-5703 - "@docusaurus/mdx-loader": 0.0.0-5703 - "@docusaurus/module-type-aliases": 0.0.0-5703 - "@docusaurus/types": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/logger": 0.0.0-5809 + "@docusaurus/mdx-loader": 0.0.0-5809 + "@docusaurus/module-type-aliases": 0.0.0-5809 + "@docusaurus/types": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 "@types/react-router-config": ^5.0.7 combine-promises: ^1.1.0 fs-extra: ^11.1.1 - import-fresh: ^3.3.0 js-yaml: ^4.1.0 lodash: ^4.17.21 tslib: ^2.6.0 @@ -1923,133 +1917,133 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: b08fbbac78f76ca68fc4a8ba488f41709733727e073d5f2d1e671dab484c4d37729a657305b315052369292ec7ae83c32992e551eda1d0990c035aa84fecbac6 + checksum: 1ce8c1e1783d08e41172d0db0e858847c2de4c9a750fc2206f7344bfa9186fdc1d818ad0f28542b109b0cb5d45a5ddfb9145014555225198f41881f57fb9df83 languageName: node linkType: hard -"@docusaurus/plugin-content-pages@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/plugin-content-pages@npm:0.0.0-5703" +"@docusaurus/plugin-content-pages@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/plugin-content-pages@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/mdx-loader": 0.0.0-5703 - "@docusaurus/types": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/mdx-loader": 0.0.0-5809 + "@docusaurus/types": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 fs-extra: ^11.1.1 tslib: ^2.6.0 webpack: ^5.88.1 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 9d0b904259c625d82175fa3fdeae89de8503f409a7dc47c9077f35d25f72fcf76a0a6392f5e790c3bf2604896e1aa0fced00386b9df553f6ba01247ccadd6503 + checksum: 362fa40e3c92b8637ed13f67ce244306e668484e985e2e1267c92ea0506a742c0d3b552ed508d3bd77259cfca0fb7ebc7722df9434e8d819c93c8a4edd546b1b languageName: node linkType: hard -"@docusaurus/plugin-debug@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/plugin-debug@npm:0.0.0-5703" +"@docusaurus/plugin-debug@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/plugin-debug@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/types": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 - "@microlink/react-json-view": ^1.22.2 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/types": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 fs-extra: ^11.1.1 + react-json-view-lite: ^1.2.0 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: b9bf04c27144dc797fa25cae6df95f5a8b15c888993194bf1b0fae06ce6ae55cf338270b7a914ef07d6551addd6261e628a465c4f277a4e13753c207e533557d + checksum: 7dcb4ae3fff5352b9080b4fda26c834907bcafb230201154d1e13cefc9dbaafc0f9013bdd485f247cf390a084154695f6b9ef589936c66c30fa66b02f774a775 languageName: node linkType: hard -"@docusaurus/plugin-google-analytics@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/plugin-google-analytics@npm:0.0.0-5703" +"@docusaurus/plugin-google-analytics@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/plugin-google-analytics@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/types": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/types": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: ad98ea301caa4908197a3c460ae88dd5598c1485d8643708e8fb3f757ae3bf854efc1b5a1ab9c8ba15371c3a989704d7f9fdb55dd25d1d1b81936526068a877b + checksum: b7a6d4ea53098db90602d5359d807c3b7d164c335294155538565be29cb85b2853a8e5b7c76d57efb0b50901d0beb60689116933ab4940fc370ff6f194acd675 languageName: node linkType: hard -"@docusaurus/plugin-google-gtag@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/plugin-google-gtag@npm:0.0.0-5703" +"@docusaurus/plugin-google-gtag@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/plugin-google-gtag@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/types": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/types": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 "@types/gtag.js": ^0.0.12 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 9fbdbc0569f1ff634c357d197c1442da17c4a09c03163640db1d1bde0be8612dd432e494a4f02eb43ac58dd7df2cbd335911fdb7fa315a9de95e173090daf5dc + checksum: 0ce11539963fb62dc417bcd704bcdf3b5fab46f2e035286187d44bc5d9bc5f8238541e1da0cf3a9ab930871d21d08681fd3ec1291c1f0e088a70d85bf704579a languageName: node linkType: hard -"@docusaurus/plugin-google-tag-manager@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/plugin-google-tag-manager@npm:0.0.0-5703" +"@docusaurus/plugin-google-tag-manager@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/plugin-google-tag-manager@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/types": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/types": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 3ed2c6eb05087db3877ffe98cc6eca59be80889411e3cdbd981ac4d951a5efa269a1011a39a94c997d93474fd916e3634905a6537e10575e5d5a954a9bb00c5d + checksum: 7041f2b5574b6b77300ea3082a090057d389e1059d45d4ff2d87386d362f55f00cc26d329b8cdeec4fb10c9fcfe4702823c3f4f2ceef29b557086c4c20819ab3 languageName: node linkType: hard -"@docusaurus/plugin-sitemap@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/plugin-sitemap@npm:0.0.0-5703" +"@docusaurus/plugin-sitemap@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/plugin-sitemap@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/logger": 0.0.0-5703 - "@docusaurus/types": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 - "@docusaurus/utils-common": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/logger": 0.0.0-5809 + "@docusaurus/types": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 + "@docusaurus/utils-common": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 fs-extra: ^11.1.1 sitemap: ^7.1.1 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 1afbd2e3575ae09428fb4c53a2563e313c3e1a2323c79bdc256779c56f8d796c2c94473d055d6d7a97d477f06e35f0922bed441f7c3e1467feeb5329e1f7761b + checksum: cdb41c318786913923b1381882d7f5c956dba98f958f14cfd27fb962c540732b940ab7c01d04a97e30c229b98637d57fa3897dd0bdd738ac68ba55e27080bb08 languageName: node linkType: hard -"@docusaurus/preset-classic@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/preset-classic@npm:0.0.0-5703" +"@docusaurus/preset-classic@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/preset-classic@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/plugin-content-blog": 0.0.0-5703 - "@docusaurus/plugin-content-docs": 0.0.0-5703 - "@docusaurus/plugin-content-pages": 0.0.0-5703 - "@docusaurus/plugin-debug": 0.0.0-5703 - "@docusaurus/plugin-google-analytics": 0.0.0-5703 - "@docusaurus/plugin-google-gtag": 0.0.0-5703 - "@docusaurus/plugin-google-tag-manager": 0.0.0-5703 - "@docusaurus/plugin-sitemap": 0.0.0-5703 - "@docusaurus/theme-classic": 0.0.0-5703 - "@docusaurus/theme-common": 0.0.0-5703 - "@docusaurus/theme-search-algolia": 0.0.0-5703 - "@docusaurus/types": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/plugin-content-blog": 0.0.0-5809 + "@docusaurus/plugin-content-docs": 0.0.0-5809 + "@docusaurus/plugin-content-pages": 0.0.0-5809 + "@docusaurus/plugin-debug": 0.0.0-5809 + "@docusaurus/plugin-google-analytics": 0.0.0-5809 + "@docusaurus/plugin-google-gtag": 0.0.0-5809 + "@docusaurus/plugin-google-tag-manager": 0.0.0-5809 + "@docusaurus/plugin-sitemap": 0.0.0-5809 + "@docusaurus/theme-classic": 0.0.0-5809 + "@docusaurus/theme-common": 0.0.0-5809 + "@docusaurus/theme-search-algolia": 0.0.0-5809 + "@docusaurus/types": 0.0.0-5809 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: d4c2e6e02b828b248351819410fe03e94a4b4fd8489e398b60d128ba8f173548f8353a3875ff0347179ee59e84df7e3e9e1e5b0be24b84f015c8c02b650eb80c + checksum: 425337b7d91c761919cd1c7f6d7845932c78c1df7b86647b1129f122502798505577f4be87b243f4ff58fff55c71ab20ee49ae6015b3aba09c644a7154a0b9b9 languageName: node linkType: hard @@ -2065,30 +2059,30 @@ __metadata: languageName: node linkType: hard -"@docusaurus/theme-classic@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/theme-classic@npm:0.0.0-5703" +"@docusaurus/theme-classic@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/theme-classic@npm:0.0.0-5809" dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/mdx-loader": 0.0.0-5703 - "@docusaurus/module-type-aliases": 0.0.0-5703 - "@docusaurus/plugin-content-blog": 0.0.0-5703 - "@docusaurus/plugin-content-docs": 0.0.0-5703 - "@docusaurus/plugin-content-pages": 0.0.0-5703 - "@docusaurus/theme-common": 0.0.0-5703 - "@docusaurus/theme-translations": 0.0.0-5703 - "@docusaurus/types": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 - "@docusaurus/utils-common": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 - "@mdx-js/react": ^2.1.5 - clsx: ^1.2.1 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/mdx-loader": 0.0.0-5809 + "@docusaurus/module-type-aliases": 0.0.0-5809 + "@docusaurus/plugin-content-blog": 0.0.0-5809 + "@docusaurus/plugin-content-docs": 0.0.0-5809 + "@docusaurus/plugin-content-pages": 0.0.0-5809 + "@docusaurus/theme-common": 0.0.0-5809 + "@docusaurus/theme-translations": 0.0.0-5809 + "@docusaurus/types": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 + "@docusaurus/utils-common": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 + "@mdx-js/react": ^3.0.0 + clsx: ^2.0.0 copy-text-to-clipboard: ^3.2.0 infima: 0.2.0-alpha.43 lodash: ^4.17.21 nprogress: ^0.2.0 postcss: ^8.4.26 - prism-react-renderer: ^2.1.0 + prism-react-renderer: ^2.3.0 prismjs: ^1.29.0 react-router-dom: ^5.3.4 rtlcss: ^4.1.0 @@ -2097,51 +2091,51 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: ba078e06a07bbcc4a474f67938760852146e0cb612e44bc81b22879d374372eeea076de6e46e9f955dd351f37dadd98ced2e70b6b8a476b88684fae40855ecb9 + checksum: 9df071f67a7048e7a33ec2b0d627c8c342574ac8fd4596d108b88c3d6fe9b454cbc84a558aaa09a0ef4d7d6887c0bb75bc60d3ec1182ee69b7de87c035cee843 languageName: node linkType: hard -"@docusaurus/theme-common@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/theme-common@npm:0.0.0-5703" +"@docusaurus/theme-common@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/theme-common@npm:0.0.0-5809" dependencies: - "@docusaurus/mdx-loader": 0.0.0-5703 - "@docusaurus/module-type-aliases": 0.0.0-5703 - "@docusaurus/plugin-content-blog": 0.0.0-5703 - "@docusaurus/plugin-content-docs": 0.0.0-5703 - "@docusaurus/plugin-content-pages": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 - "@docusaurus/utils-common": 0.0.0-5703 + "@docusaurus/mdx-loader": 0.0.0-5809 + "@docusaurus/module-type-aliases": 0.0.0-5809 + "@docusaurus/plugin-content-blog": 0.0.0-5809 + "@docusaurus/plugin-content-docs": 0.0.0-5809 + "@docusaurus/plugin-content-pages": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 + "@docusaurus/utils-common": 0.0.0-5809 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" - clsx: ^1.2.1 + clsx: ^2.0.0 parse-numeric-range: ^1.3.0 - prism-react-renderer: ^2.1.0 + prism-react-renderer: ^2.3.0 tslib: ^2.6.0 utility-types: ^3.10.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: f9b23318dbb504bcce0992de475f1ab32860620523dfe749bfdb00ac8e7fc75be705fd5177db2ce893ed269de40cef7f6a7290d44a12c6a160d9461bbca05552 + checksum: 6561d5526ac8d0e818fa5d9eaf1b1969d8f2623b8b6358d0360c3808da49798f4bdbe07f97af56bd69f2604f158e62bf454c8f4e6a9c0233f57c3a81ddafec5c languageName: node linkType: hard -"@docusaurus/theme-search-algolia@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/theme-search-algolia@npm:0.0.0-5703" +"@docusaurus/theme-search-algolia@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/theme-search-algolia@npm:0.0.0-5809" dependencies: "@docsearch/react": ^3.5.2 - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/logger": 0.0.0-5703 - "@docusaurus/plugin-content-docs": 0.0.0-5703 - "@docusaurus/theme-common": 0.0.0-5703 - "@docusaurus/theme-translations": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 - "@docusaurus/utils-validation": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/logger": 0.0.0-5809 + "@docusaurus/plugin-content-docs": 0.0.0-5809 + "@docusaurus/theme-common": 0.0.0-5809 + "@docusaurus/theme-translations": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 + "@docusaurus/utils-validation": 0.0.0-5809 algoliasearch: ^4.18.0 algoliasearch-helper: ^3.13.3 - clsx: ^1.2.1 + clsx: ^2.0.0 eta: ^2.2.0 fs-extra: ^11.1.1 lodash: ^4.17.21 @@ -2150,24 +2144,25 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 2e8ccc603126634488332ae108f9ac9ad3d2e1e46b5abef48720f2a25ae5cfc93850301d4ea30a6dc66034877b6abedd31229f622c6fd181347c3c14f7ba3c66 + checksum: 7fb83216b8d091dd108c13b7af86b59f26d3772ad0e0d0e8b5493c4c547dd9554b3184d6e4574e456cc6bb5a598a1dae8929453f4a94dffc7ae1da0665968ddf languageName: node linkType: hard -"@docusaurus/theme-translations@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/theme-translations@npm:0.0.0-5703" +"@docusaurus/theme-translations@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/theme-translations@npm:0.0.0-5809" dependencies: fs-extra: ^11.1.1 tslib: ^2.6.0 - checksum: 1f952386982008e2e7b07d6b95b1a902a57891321ae2670f13f391a541944ec2c82f5e03d3ed2c459a17113387a51cb5efe824d03037a3cc0b25251451287d1d + checksum: 8ca34bb5e02f021995bea8213f1ed0bb2c9493156b9495ab94a437d3d893a5a970dad871d07d2a80b003ba28c1fd5bd39e175c766884cb2ea442c226400091cf languageName: node linkType: hard -"@docusaurus/types@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/types@npm:0.0.0-5703" +"@docusaurus/types@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/types@npm:0.0.0-5809" dependencies: + "@mdx-js/mdx": ^3.0.0 "@types/history": ^4.7.11 "@types/react": "*" commander: ^5.1.0 @@ -2179,13 +2174,13 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 46ca6a27c8a0d1b69f744375ee2c24be2deed20c2801231a462b2e37b7a6e1f73ab17b6a5506e05f628957be8be74e4cd960780b9986c8fa4ac1757bd8c74231 + checksum: 97800e1b3f52ed167b78c812c2c652fe84308fc033f057b81043d485f3afb935dd5c30761c9ed7868fcf5ee0728fe3a841edd745285793167d0d1d48a298f5cd languageName: node linkType: hard -"@docusaurus/utils-common@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/utils-common@npm:0.0.0-5703" +"@docusaurus/utils-common@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/utils-common@npm:0.0.0-5809" dependencies: tslib: ^2.6.0 peerDependencies: @@ -2193,28 +2188,28 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 8f70f176a99bcbbde22abd759621087ad555e7967cddf85662402f6d55c84d5f44cc1a90bf4e64670fc75b6db646dca4f573b3656a1718d1596d60e0e6c2d23a + checksum: 4cab3b5aa8b2ddbcfa5245f628fd84257f39312301b9813e36d616996a43dfe4f77abb26907271480128ce983125b4d20837c42e94d18875e6d07edcd4daaef7 languageName: node linkType: hard -"@docusaurus/utils-validation@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/utils-validation@npm:0.0.0-5703" +"@docusaurus/utils-validation@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/utils-validation@npm:0.0.0-5809" dependencies: - "@docusaurus/logger": 0.0.0-5703 - "@docusaurus/utils": 0.0.0-5703 + "@docusaurus/logger": 0.0.0-5809 + "@docusaurus/utils": 0.0.0-5809 joi: ^17.9.2 js-yaml: ^4.1.0 tslib: ^2.6.0 - checksum: e0d6df549644d8e732daf5407ce110dbccba17dcf84fe1a80091119675d2ce515e26bf6612fefa60b7df2c65dbaeee7ceb1a9f2b947a3705fe1efc7c229794e2 + checksum: 2ed6483a1e752a9c291d9ee607cfc3fc9f906cd6fa85687cc2e951cf0400264578e6f2b6bc282ee44eef52ed4c7503896f43e52f18d96064e37f5cb53096dbc4 languageName: node linkType: hard -"@docusaurus/utils@npm:0.0.0-5703": - version: 0.0.0-5703 - resolution: "@docusaurus/utils@npm:0.0.0-5703" +"@docusaurus/utils@npm:0.0.0-5809": + version: 0.0.0-5809 + resolution: "@docusaurus/utils@npm:0.0.0-5809" dependencies: - "@docusaurus/logger": 0.0.0-5703 + "@docusaurus/logger": 0.0.0-5809 "@svgr/webpack": ^6.5.1 escape-string-regexp: ^4.0.0 file-loader: ^6.2.0 @@ -2222,6 +2217,7 @@ __metadata: github-slugger: ^1.5.0 globby: ^11.1.0 gray-matter: ^4.0.3 + jiti: ^1.20.0 js-yaml: ^4.1.0 lodash: ^4.17.21 micromatch: ^4.0.5 @@ -2235,7 +2231,7 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 91f53b17393e29fadb01c039f5394fc257c54bd7d80068f3a3e8a5e52d635d2e3de9fe781340de2ff4eaf691a2d4104865291c05c22ffc8b48a0894f588f3a9e + checksum: 408969f77fddf7fd621e3025927db7766a6513fa01a2c357cbcd57d1cd41db0abf72282bdb3e94cf6a6ad1b03138e48833c65da84c1c67b917e5660491ce40b6 languageName: node linkType: hard @@ -2344,55 +2340,46 @@ __metadata: languageName: node linkType: hard -"@mdx-js/mdx@npm:^2.1.5": - version: 2.3.0 - resolution: "@mdx-js/mdx@npm:2.3.0" +"@mdx-js/mdx@npm:^3.0.0": + version: 3.0.0 + resolution: "@mdx-js/mdx@npm:3.0.0" dependencies: + "@types/estree": ^1.0.0 "@types/estree-jsx": ^1.0.0 + "@types/hast": ^3.0.0 "@types/mdx": ^2.0.0 - estree-util-build-jsx: ^2.0.0 - estree-util-is-identifier-name: ^2.0.0 - estree-util-to-js: ^1.1.0 + collapse-white-space: ^2.0.0 + devlop: ^1.0.0 + estree-util-build-jsx: ^3.0.0 + estree-util-is-identifier-name: ^3.0.0 + estree-util-to-js: ^2.0.0 estree-walker: ^3.0.0 - hast-util-to-estree: ^2.0.0 - markdown-extensions: ^1.0.0 + hast-util-to-estree: ^3.0.0 + hast-util-to-jsx-runtime: ^2.0.0 + markdown-extensions: ^2.0.0 periscopic: ^3.0.0 - remark-mdx: ^2.0.0 - remark-parse: ^10.0.0 - remark-rehype: ^10.0.0 - unified: ^10.0.0 - unist-util-position-from-estree: ^1.0.0 - unist-util-stringify-position: ^3.0.0 - unist-util-visit: ^4.0.0 - vfile: ^5.0.0 - checksum: d918766a326502ec0b54adee61dc2930daf5b748acb9107f9bfd1ab0dbc4d7b1a4d0dbb9e21da9dd2a9fc2f9950b2973a43c6ba62d3a72eb67a30f6c953e5be8 + remark-mdx: ^3.0.0 + remark-parse: ^11.0.0 + remark-rehype: ^11.0.0 + source-map: ^0.7.0 + unified: ^11.0.0 + unist-util-position-from-estree: ^2.0.0 + unist-util-stringify-position: ^4.0.0 + unist-util-visit: ^5.0.0 + vfile: ^6.0.0 + checksum: da4305dcfd9012521170e0ed439eb336900fb84a5784e5e3dac2144855fa603325477855e17a04b7c673cc24699cf2bfd611c958f591bb3a9afb5608c259bbd3 languageName: node linkType: hard -"@mdx-js/react@npm:^2.1.5": - version: 2.3.0 - resolution: "@mdx-js/react@npm:2.3.0" +"@mdx-js/react@npm:^3.0.0": + version: 3.0.0 + resolution: "@mdx-js/react@npm:3.0.0" dependencies: "@types/mdx": ^2.0.0 + peerDependencies: "@types/react": ">=16" - peerDependencies: react: ">=16" - checksum: f45fe779556e6cd9a787f711274480e0638b63c460f192ebdcd77cc07ffa61e23c98cb46dd46e577093e1cb4997a232a848d1fb0ba850ae204422cf603add524 - languageName: node - linkType: hard - -"@microlink/react-json-view@npm:^1.22.2": - version: 1.22.2 - resolution: "@microlink/react-json-view@npm:1.22.2" - 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: ">= 15" - react-dom: ">= 15" - checksum: 7cc31fcc06f6bac2062aedda565e55a03e1275f5b810f0efee27de8ea60967713f3a13859a16ba775b9b3e8782c044928cf3faee48902a19ce1c58d7ecc6e8d0 + checksum: a780cff9d7f7639d6fc21c9d4e0a6ac1370c3209ea0db176923df7f9145785309591cf871f227f5135d1fe2accce0d5df9a22fc0530e5dda0c7b4b105705f20d languageName: node linkType: hard @@ -2507,6 +2494,13 @@ __metadata: languageName: node linkType: hard +"@sindresorhus/is@npm:^4.6.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: 83839f13da2c29d55c97abc3bc2c55b250d33a0447554997a85c539e058e57b8da092da396e252b11ec24a0279a0bed1f537fa26302209327060643e327f81d2 + languageName: node + linkType: hard + "@sindresorhus/is@npm:^5.2.0": version: 5.3.0 resolution: "@sindresorhus/is@npm:5.3.0" @@ -2983,12 +2977,12 @@ __metadata: languageName: node linkType: hard -"@types/hast@npm:^2.0.0": - version: 2.3.4 - resolution: "@types/hast@npm:2.3.4" +"@types/hast@npm:^3.0.0": + version: 3.0.3 + resolution: "@types/hast@npm:3.0.3" dependencies: "@types/unist": "*" - checksum: fff47998f4c11e21a7454b58673f70478740ecdafd95aaf50b70a3daa7da9cdc57315545bf9c039613732c40b7b0e9e49d11d03fe9a4304721cdc3b29a88141e + checksum: ca204207550fd6848ee20b5ba2018fd54f515d59a8b80375cdbe392ba2b4b130dac25fdfbaf9f2a70d2aec9d074a34dc14d4d59d31fa3ede80ef9850afad5d3c languageName: node linkType: hard @@ -3061,21 +3055,12 @@ __metadata: languageName: node linkType: hard -"@types/mdast@npm:^3.0.0": - version: 3.0.10 - resolution: "@types/mdast@npm:3.0.10" +"@types/mdast@npm:^4.0.0, @types/mdast@npm:^4.0.2": + version: 4.0.3 + resolution: "@types/mdast@npm:4.0.3" dependencies: "@types/unist": "*" - checksum: 3f587bfc0a9a2403ecadc220e61031b01734fedaf82e27eb4d5ba039c0eb54db8c85681ccc070ab4df3f7ec711b736a82b990e69caa14c74bf7ac0ccf2ac7313 - languageName: node - linkType: hard - -"@types/mdast@npm:^4.0.0": - version: 4.0.1 - resolution: "@types/mdast@npm:4.0.1" - dependencies: - "@types/unist": "*" - checksum: 3d8fe54a6fb747376c4cc2f05c319730a5737b77844d8ea58d2d696417fa933cd270c20e197f531fc1b4be5e340dc416129f8b4f5fa2f0d2d0cf51850928340a + checksum: 345c5a22fccf05f35239ea6313ee4aaf6ebed5927c03ac79744abccb69b9ba5e692f9b771e36a012b79e17429082cada30f579e9c43b8a54e0ffb365431498b6 languageName: node linkType: hard @@ -3121,13 +3106,6 @@ __metadata: languageName: node linkType: hard -"@types/parse5@npm:^6.0.0": - version: 6.0.3 - resolution: "@types/parse5@npm:6.0.3" - checksum: ddb59ee4144af5dfcc508a8dcf32f37879d11e12559561e65788756b95b33e6f03ea027d88e1f5408f9b7bfb656bf630ace31a2169edf44151daaf8dd58df1b7 - languageName: node - linkType: hard - "@types/prismjs@npm:^1.26.0": version: 1.26.1 resolution: "@types/prismjs@npm:1.26.1" @@ -3188,7 +3166,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:>=16": +"@types/react@npm:*": version: 18.2.0 resolution: "@types/react@npm:18.2.0" dependencies: @@ -3296,6 +3274,13 @@ __metadata: languageName: node linkType: hard +"@ungap/structured-clone@npm:^1.0.0": + version: 1.2.0 + resolution: "@ungap/structured-clone@npm:1.2.0" + checksum: 4f656b7b4672f2ce6e272f2427d8b0824ed11546a601d8d5412b9d7704e83db38a8d9f402ecdf2b9063fc164af842ad0ec4a55819f621ed7e7ea4d1efcc74524 + languageName: node + linkType: hard + "@webassemblyjs/ast@npm:1.11.5, @webassemblyjs/ast@npm:^1.11.5": version: 1.11.5 resolution: "@webassemblyjs/ast@npm:1.11.5" @@ -3768,13 +3753,6 @@ __metadata: 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 - "astring@npm:^1.8.0": version: 1.8.4 resolution: "astring@npm:1.8.4" @@ -3784,13 +3762,6 @@ __metadata: languageName: node linkType: hard -"asynckit@npm:^0.4.0": - version: 0.4.0 - resolution: "asynckit@npm:0.4.0" - checksum: 7b78c451df768adba04e2d02e63e2d0bf3b07adcd6e42b4cf665cb7ce899bedd344c69a1dcbce355b5f972d597b25aaa1c1742b52cffd9caccb22f348114f6be - languageName: node - linkType: hard - "at-least-node@npm:^1.0.0": version: 1.0.0 resolution: "at-least-node@npm:1.0.0" @@ -3816,16 +3787,6 @@ __metadata: languageName: node linkType: hard -"axios@npm:^0.27.2": - version: 0.27.2 - resolution: "axios@npm:0.27.2" - dependencies: - follow-redirects: ^1.14.9 - form-data: ^4.0.0 - checksum: 38cb7540465fe8c4102850c4368053c21683af85c5fdf0ea619f9628abbcb59415d1e22ebc8a6390d2bbc9b58a9806c874f139767389c862ec9b772235f06854 - languageName: node - linkType: hard - "babel-loader@npm:^9.1.3": version: 9.1.3 resolution: "babel-loader@npm:9.1.3" @@ -3888,10 +3849,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-microsite@workspace:." dependencies: - "@docusaurus/core": 0.0.0-5703 - "@docusaurus/module-type-aliases": 0.0.0-5703 - "@docusaurus/plugin-client-redirects": 0.0.0-5703 - "@docusaurus/preset-classic": 0.0.0-5703 + "@docusaurus/core": 0.0.0-5809 + "@docusaurus/module-type-aliases": 0.0.0-5809 + "@docusaurus/plugin-client-redirects": 0.0.0-5809 + "@docusaurus/preset-classic": 0.0.0-5809 "@spotify/prettier-config": ^14.0.0 "@swc/core": ^1.3.46 "@tsconfig/docusaurus": ^2.0.0 @@ -3926,13 +3887,6 @@ __metadata: 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" @@ -4053,17 +4007,17 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.14.5, browserslist@npm:^4.18.1, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.21.9, browserslist@npm:^4.22.1": - version: 4.22.1 - resolution: "browserslist@npm:4.22.1" +"browserslist@npm:^4.0.0, browserslist@npm:^4.14.5, browserslist@npm:^4.18.1, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.22.1, browserslist@npm:^4.22.2": + version: 4.22.2 + resolution: "browserslist@npm:4.22.2" dependencies: - caniuse-lite: ^1.0.30001541 - electron-to-chromium: ^1.4.535 - node-releases: ^2.0.13 + caniuse-lite: ^1.0.30001565 + electron-to-chromium: ^1.4.601 + node-releases: ^2.0.14 update-browserslist-db: ^1.0.13 bin: browserslist: cli.js - checksum: 7e6b10c53f7dd5d83fd2b95b00518889096382539fed6403829d447e05df4744088de46a571071afb447046abc3c66ad06fbc790e70234ec2517452e32ffd862 + checksum: 33ddfcd9145220099a7a1ac533cecfe5b7548ffeb29b313e1b57be6459000a1f8fa67e781cf4abee97268ac594d44134fcc4a6b2b4750ceddc9796e3a22076d9 languageName: node linkType: hard @@ -4189,10 +4143,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001538, caniuse-lite@npm:^1.0.30001541": - version: 1.0.30001546 - resolution: "caniuse-lite@npm:1.0.30001546" - checksum: d3ef82f5ee94743002c5b2dd61c84342debcc94b2d5907b64ade3514ecfc4f20bbe86a6bc453fd6436d5fbcf6582e07405d7c2077565675a71c83adc238a11fa +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001538, caniuse-lite@npm:^1.0.30001565": + version: 1.0.30001579 + resolution: "caniuse-lite@npm:1.0.30001579" + checksum: 7539dcff74d2243a30c428393dc690c87fa34d7da36434731853e9bcfe783757763b2971f5cc878e25242a93e184e53f167d11bd74955af956579f7af71cc764 languageName: node linkType: hard @@ -4231,6 +4185,13 @@ __metadata: languageName: node linkType: hard +"char-regex@npm:^1.0.2": + version: 1.0.2 + resolution: "char-regex@npm:1.0.2" + checksum: b563e4b6039b15213114626621e7a3d12f31008bdce20f9c741d69987f62aeaace7ec30f6018890ad77b2e9b4d95324c9f5acfca58a9441e3b1dcdd1e2525d17 + languageName: node + linkType: hard + "character-entities-html4@npm:^2.0.0": version: 2.1.0 resolution: "character-entities-html4@npm:2.1.0" @@ -4375,17 +4336,17 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^1.2.1": - version: 1.2.1 - resolution: "clsx@npm:1.2.1" - checksum: 30befca8019b2eb7dbad38cff6266cf543091dae2825c856a62a8ccf2c3ab9c2907c4d12b288b73101196767f66812365400a227581484a05f968b0307cfaf12 +"clsx@npm:^2.0.0": + version: 2.1.0 + resolution: "clsx@npm:2.1.0" + checksum: 43fefc29b6b49c9476fbce4f8b1cc75c27b67747738e598e6651dd40d63692135dc60b18fa1c5b78a2a9ba8ae6fd2055a068924b94e20b42039bd53b78b98e1d languageName: node linkType: hard -"clsx@npm:^2.0.0": - version: 2.0.0 - resolution: "clsx@npm:2.0.0" - checksum: a2cfb2351b254611acf92faa0daf15220f4cd648bdf96ce369d729813b85336993871a4bf6978ddea2b81b5a130478339c20d9d0b5c6fc287e5147f0c059276e +"collapse-white-space@npm:^2.0.0": + version: 2.1.0 + resolution: "collapse-white-space@npm:2.1.0" + checksum: c8978b1f4e7d68bf846cfdba6c6689ce8910511df7d331eb6e6757e51ceffb52768d59a28db26186c91dcf9594955b59be9f8ccd473c485790f5d8b90dc6726f languageName: node linkType: hard @@ -4451,15 +4412,6 @@ __metadata: languageName: node linkType: hard -"combined-stream@npm:^1.0.8": - version: 1.0.8 - resolution: "combined-stream@npm:1.0.8" - dependencies: - delayed-stream: ~1.0.0 - checksum: 49fa4aeb4916567e33ea81d088f6584749fc90c7abec76fd516bf1c5aa5c79f3584b5ba3de6b86d26ddd64bae5329c4c7479343250cfe71c75bb366eae53bb7c - languageName: node - linkType: hard - "comma-separated-tokens@npm:^2.0.0": version: 2.0.3 resolution: "comma-separated-tokens@npm:2.0.3" @@ -4724,15 +4676,6 @@ __metadata: 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" @@ -4963,7 +4906,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.3": +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3": version: 4.3.4 resolution: "debug@npm:4.3.4" dependencies: @@ -5056,13 +4999,6 @@ __metadata: languageName: node linkType: hard -"delayed-stream@npm:~1.0.0": - version: 1.0.0 - resolution: "delayed-stream@npm:1.0.0" - checksum: 46fe6e83e2cb1d85ba50bd52803c68be9bd953282fa7096f51fc29edd5d67ff84ff753c51966061e5ba7cb5e47ef6d36a91924eddb7f3f3483b1c560f77a0020 - languageName: node - linkType: hard - "delegates@npm:^1.0.0": version: 1.0.0 resolution: "delegates@npm:1.0.0" @@ -5131,7 +5067,7 @@ __metadata: languageName: node linkType: hard -"devlop@npm:^1.0.0": +"devlop@npm:^1.0.0, devlop@npm:^1.1.0": version: 1.1.0 resolution: "devlop@npm:1.1.0" dependencies: @@ -5140,13 +5076,6 @@ __metadata: languageName: node linkType: hard -"diff@npm:^5.0.0": - version: 5.1.0 - resolution: "diff@npm:5.1.0" - checksum: c7bf0df7c9bfbe1cf8a678fd1b2137c4fb11be117a67bc18a0e03ae75105e8533dbfb1cda6b46beb3586ef5aed22143ef9d70713977d5fb1f9114e21455fba90 - languageName: node - linkType: hard - "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -5302,10 +5231,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.535": - version: 1.4.544 - resolution: "electron-to-chromium@npm:1.4.544" - checksum: 78e88e4c56fc4faaa9a405de5e0b51305531e9cdf2c71bcc9296c2c59fb68001472e5b924f8701c873bc855ab5174cf0340642712d7af05c1d8e92356529397e +"electron-to-chromium@npm:^1.4.601": + version: 1.4.639 + resolution: "electron-to-chromium@npm:1.4.639" + checksum: f16293e69c5c31d836d1a3fdafb07f7a19a0f9a1137893aea879758f6de7d212480f4204e14f0669e653a5a3a1c35f6d1cbd54d4dd9e6ace7e22638270c9984e languageName: node linkType: hard @@ -5323,6 +5252,13 @@ __metadata: languageName: node linkType: hard +"emojilib@npm:^2.4.0": + version: 2.4.0 + resolution: "emojilib@npm:2.4.0" + checksum: ea241c342abda5a86ffd3a15d8f4871a616d485f700e03daea38c6ce38205847cea9f6ff8d5e962c00516b004949cc96c6e37b05559ea71a0a496faba53b56da + languageName: node + linkType: hard + "emojis-list@npm:^3.0.0": version: 3.0.0 resolution: "emojis-list@npm:3.0.0" @@ -5330,10 +5266,10 @@ __metadata: languageName: node linkType: hard -"emoticon@npm:^3.2.0": - version: 3.2.0 - resolution: "emoticon@npm:3.2.0" - checksum: f30649d18b672ab3139e95cb04f77b2442feb95c99dc59372ff80fbfd639b2bf4018bc68ab0b549bd765aecf8230d7899c43f86cfcc7b6370c06c3232783e24f +"emoticon@npm:^4.0.1": + version: 4.0.1 + resolution: "emoticon@npm:4.0.1" + checksum: 991ab6421927601af4eb44036b60e3125759a4d81f32d2ad96b66e3491e2fdb6a026eeb6bffbfa66724592dca95235570785963607d16961ea73a62ecce715e2 languageName: node linkType: hard @@ -5492,61 +5428,62 @@ __metadata: languageName: node linkType: hard -"estree-util-attach-comments@npm:^2.0.0": - version: 2.1.1 - resolution: "estree-util-attach-comments@npm:2.1.1" +"estree-util-attach-comments@npm:^3.0.0": + version: 3.0.0 + resolution: "estree-util-attach-comments@npm:3.0.0" dependencies: "@types/estree": ^1.0.0 - checksum: c5c2c41c9a55a169fb4fba9627057843f0d2e21e47a2e3e24318a11ffcf6bc704c0f96f405a529bddac7969b7c44f6cf86711505faaf0c5862c2024419b19704 + checksum: 56254eaef39659e6351919ebc2ae53a37a09290a14571c19e373e9d5fad343a3403d9ad0c23ae465d6e7d08c3e572fd56fb8c793efe6434a261bf1489932dbd5 languageName: node linkType: hard -"estree-util-build-jsx@npm:^2.0.0": - version: 2.2.2 - resolution: "estree-util-build-jsx@npm:2.2.2" +"estree-util-build-jsx@npm:^3.0.0": + version: 3.0.1 + resolution: "estree-util-build-jsx@npm:3.0.1" dependencies: "@types/estree-jsx": ^1.0.0 - estree-util-is-identifier-name: ^2.0.0 + devlop: ^1.0.0 + estree-util-is-identifier-name: ^3.0.0 estree-walker: ^3.0.0 - checksum: d008ac36a45d797eadca696f41b4c1ac0587ec0e0b52560cfb0e76d14ef15fc18e526f9023b6e5457dafa9cf3f010c9bb1dfc9c727ebd7cf0ba2ebbaa43919ac + checksum: 185eff060eda2ba32cecd15904db4f5ba0681159fbdf54f0f6586cd9411e77e733861a833d0aee3415e1d1fd4b17edf08bc9e9872cee98e6ec7b0800e1a85064 languageName: node linkType: hard -"estree-util-is-identifier-name@npm:^2.0.0": - version: 2.1.0 - resolution: "estree-util-is-identifier-name@npm:2.1.0" - checksum: cab317a071fafb99cf83b57df7924bccd2e6ab4e252688739e49f00b16cefd168e279c171442b0557c80a1c80ffaa927d670dadea65bb3c9b151efb8e772e89d +"estree-util-is-identifier-name@npm:^3.0.0": + version: 3.0.0 + resolution: "estree-util-is-identifier-name@npm:3.0.0" + checksum: ea3909f0188ea164af0aadeca87c087e3e5da78d76da5ae9c7954ff1340ea3e4679c4653bbf4299ffb70caa9b322218cc1128db2541f3d2976eb9704f9857787 languageName: node linkType: hard -"estree-util-to-js@npm:^1.1.0": - version: 1.2.0 - resolution: "estree-util-to-js@npm:1.2.0" +"estree-util-to-js@npm:^2.0.0": + version: 2.0.0 + resolution: "estree-util-to-js@npm:2.0.0" dependencies: "@types/estree-jsx": ^1.0.0 astring: ^1.8.0 source-map: ^0.7.0 - checksum: 93a75e1051a6a4f5c631597ecd2ed95129fadbc80a58a10475d6d6b1b076a69393ba4a8d2bb71f698401f64ccca47e3f3828dd0042cac81439b988fae0f5f8e0 + checksum: 833edc94ab9978e0918f90261e0a3361bf4564fec4901f326d2237a9235d3f5fc6482da3be5acc545e702c8c7cb8bc5de5c7c71ba3b080eb1975bcfdf3923d79 languageName: node linkType: hard -"estree-util-value-to-estree@npm:^2.1.0": - version: 2.1.0 - resolution: "estree-util-value-to-estree@npm:2.1.0" +"estree-util-value-to-estree@npm:^3.0.1": + version: 3.0.1 + resolution: "estree-util-value-to-estree@npm:3.0.1" dependencies: "@types/estree": ^1.0.0 is-plain-obj: ^4.0.0 - checksum: 6a930e9c8b85c27845ecca010b5b6b64d3b3a4e7d61117d8342fad7b2b595d7052c671616d1c2269e0954a200666834227ce0abb8488ded49700dfde54167ebb + checksum: 7ab89084aa2c5677aeb0d7350ff21e71c9bbc424dc872a55bb4f25f63a7fd99fc7861626dd89b5544db3d3696212154bcf2b12b63ecd5a59dbfd07915c88aee4 languageName: node linkType: hard -"estree-util-visit@npm:^1.0.0": - version: 1.2.1 - resolution: "estree-util-visit@npm:1.2.1" +"estree-util-visit@npm:^2.0.0": + version: 2.0.0 + resolution: "estree-util-visit@npm:2.0.0" dependencies: "@types/estree-jsx": ^1.0.0 - "@types/unist": ^2.0.0 - checksum: 6feea4fdc43b0ba0f79faf1d57cf32373007e146d4810c7c09c13f5a9c1b8600c1ac57a8d949967cedd2a9a91dddd246e19b59bacfc01e417168b4ebf220f691 + "@types/unist": ^3.0.0 + checksum: 6444b38f224322945a6d19ea81a8828a0eec64aefb2bf1ea791fe20df496f7b7c543408d637df899e6a8e318b638f66226f16378a33c4c2b192ba5c3f891121f languageName: node linkType: hard @@ -5739,37 +5676,6 @@ __metadata: 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" @@ -5861,19 +5767,7 @@ __metadata: languageName: node linkType: hard -"flux@npm:~4.0.1": - version: 4.0.4 - resolution: "flux@npm:4.0.4" - dependencies: - fbemitter: ^3.0.0 - fbjs: ^3.0.1 - peerDependencies: - react: ^15.0.2 || ^16.0.0 || ^17.0.0 - checksum: 8fa5c2f9322258de3e331f67c6f1078a7f91c4dec9dbe8a54c4b8a80eed19a4f91889028b768668af4a796e8f2ee75e461e1571b8615432a3920ae95cc4ff794 - languageName: node - linkType: hard - -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.9": +"follow-redirects@npm:^1.0.0": version: 1.15.4 resolution: "follow-redirects@npm:1.15.4" peerDependenciesMeta: @@ -5921,17 +5815,6 @@ __metadata: languageName: node linkType: hard -"form-data@npm:^4.0.0": - version: 4.0.0 - resolution: "form-data@npm:4.0.0" - dependencies: - asynckit: ^0.4.0 - combined-stream: ^1.0.8 - mime-types: ^2.1.12 - checksum: 01135bf8675f9d5c61ff18e2e2932f719ca4de964e3be90ef4c36aacfc7b9cb2fceb5eca0b7e0190e3383fe51c5b37f4cb80b62ca06a99aaabfcfd6ac7c9328c - languageName: node - linkType: hard - "format@npm:^0.2.0": version: 0.2.2 resolution: "format@npm:0.2.2" @@ -6309,103 +6192,133 @@ __metadata: languageName: node linkType: hard -"hast-util-from-parse5@npm:^7.0.0": - version: 7.1.2 - resolution: "hast-util-from-parse5@npm:7.1.2" +"hast-util-from-parse5@npm:^8.0.0": + version: 8.0.1 + resolution: "hast-util-from-parse5@npm:8.0.1" dependencies: - "@types/hast": ^2.0.0 - "@types/unist": ^2.0.0 - hastscript: ^7.0.0 + "@types/hast": ^3.0.0 + "@types/unist": ^3.0.0 + devlop: ^1.0.0 + hastscript: ^8.0.0 property-information: ^6.0.0 - vfile: ^5.0.0 - vfile-location: ^4.0.0 + vfile: ^6.0.0 + vfile-location: ^5.0.0 web-namespaces: ^2.0.0 - checksum: 7b4ed5b508b1352127c6719f7b0c0880190cf9859fe54ccaf7c9228ecf623d36cef3097910b3874d2fe1aac6bf4cf45d3cc2303daac3135a05e9ade6534ddddb + checksum: fdd1ab8b03af13778ecb94ef9a58b1e3528410cdfceb3d6bb7600508967d0d836b451bc7bc3baf66efb7c730d3d395eea4bb1b30352b0162823d9f0de976774b languageName: node linkType: hard -"hast-util-parse-selector@npm:^3.0.0": - version: 3.1.1 - resolution: "hast-util-parse-selector@npm:3.1.1" +"hast-util-parse-selector@npm:^4.0.0": + version: 4.0.0 + resolution: "hast-util-parse-selector@npm:4.0.0" dependencies: - "@types/hast": ^2.0.0 - checksum: 511d373465f60dd65e924f88bf0954085f4fb6e3a2b062a4b5ac43b93cbfd36a8dce6234b5d1e3e63499d936375687e83fc5da55628b22bd6b581b5ee167d1c4 + "@types/hast": ^3.0.0 + checksum: 76087670d3b0b50b23a6cb70bca53a6176d6608307ccdbb3ed18b650b82e7c3513bfc40348f1389dc0c5ae872b9a768851f4335f44654abd7deafd6974c52402 languageName: node linkType: hard -"hast-util-raw@npm:^7.2.0": - version: 7.2.3 - resolution: "hast-util-raw@npm:7.2.3" +"hast-util-raw@npm:^9.0.0": + version: 9.0.1 + resolution: "hast-util-raw@npm:9.0.1" dependencies: - "@types/hast": ^2.0.0 - "@types/parse5": ^6.0.0 - hast-util-from-parse5: ^7.0.0 - hast-util-to-parse5: ^7.0.0 - html-void-elements: ^2.0.0 - parse5: ^6.0.0 - unist-util-position: ^4.0.0 - unist-util-visit: ^4.0.0 - vfile: ^5.0.0 + "@types/hast": ^3.0.0 + "@types/unist": ^3.0.0 + "@ungap/structured-clone": ^1.0.0 + hast-util-from-parse5: ^8.0.0 + hast-util-to-parse5: ^8.0.0 + html-void-elements: ^3.0.0 + mdast-util-to-hast: ^13.0.0 + parse5: ^7.0.0 + unist-util-position: ^5.0.0 + unist-util-visit: ^5.0.0 + vfile: ^6.0.0 web-namespaces: ^2.0.0 zwitch: ^2.0.0 - checksum: 21857eea3ffb8fd92d2d9be7793b56d0b2c40db03c4cfa14828855ae41d7c584917aa83efb7157220b2e41e25e95f81f24679ac342c35145e5f1c1d39015f81f + checksum: 4b486eb4782eafb471ae639d45c14ac8797676518cf5da16adc973f52d7b8e1075a1451558c023b390820bd9fd213213e6248a2dae71b68ac5040b277509b8d9 languageName: node linkType: hard -"hast-util-to-estree@npm:^2.0.0": - version: 2.3.2 - resolution: "hast-util-to-estree@npm:2.3.2" +"hast-util-to-estree@npm:^3.0.0": + version: 3.1.0 + resolution: "hast-util-to-estree@npm:3.1.0" dependencies: "@types/estree": ^1.0.0 "@types/estree-jsx": ^1.0.0 - "@types/hast": ^2.0.0 - "@types/unist": ^2.0.0 + "@types/hast": ^3.0.0 comma-separated-tokens: ^2.0.0 - estree-util-attach-comments: ^2.0.0 - estree-util-is-identifier-name: ^2.0.0 - hast-util-whitespace: ^2.0.0 - mdast-util-mdx-expression: ^1.0.0 - mdast-util-mdxjs-esm: ^1.0.0 + devlop: ^1.0.0 + estree-util-attach-comments: ^3.0.0 + estree-util-is-identifier-name: ^3.0.0 + hast-util-whitespace: ^3.0.0 + mdast-util-mdx-expression: ^2.0.0 + mdast-util-mdx-jsx: ^3.0.0 + mdast-util-mdxjs-esm: ^2.0.0 property-information: ^6.0.0 space-separated-tokens: ^2.0.0 - style-to-object: ^0.4.1 - unist-util-position: ^4.0.0 + style-to-object: ^0.4.0 + unist-util-position: ^5.0.0 zwitch: ^2.0.0 - checksum: 721167e275c1b0b9b1dcb35964a39f6180e22983ee7b56748ecab9f6cc35fe5229fd6e30a8eb4826caeee7eed88014ce4710bd79146c080d4dd281058ba09a39 + checksum: 61272f7c18c9d2a5e34df7cfd2c97cbf12f6e9d05114d60e4dedd64e5576565eb1e35c78b9213c909bb8f984f0f8e9c49b568f04bdb444b83d0bca9159e14f3c languageName: node linkType: hard -"hast-util-to-parse5@npm:^7.0.0": - version: 7.1.0 - resolution: "hast-util-to-parse5@npm:7.1.0" +"hast-util-to-jsx-runtime@npm:^2.0.0": + version: 2.3.0 + resolution: "hast-util-to-jsx-runtime@npm:2.3.0" dependencies: - "@types/hast": ^2.0.0 + "@types/estree": ^1.0.0 + "@types/hast": ^3.0.0 + "@types/unist": ^3.0.0 comma-separated-tokens: ^2.0.0 + devlop: ^1.0.0 + estree-util-is-identifier-name: ^3.0.0 + hast-util-whitespace: ^3.0.0 + mdast-util-mdx-expression: ^2.0.0 + mdast-util-mdx-jsx: ^3.0.0 + mdast-util-mdxjs-esm: ^2.0.0 + property-information: ^6.0.0 + space-separated-tokens: ^2.0.0 + style-to-object: ^1.0.0 + unist-util-position: ^5.0.0 + vfile-message: ^4.0.0 + checksum: 599a97c6ec61c1430776813d7fb42e6f96032bf4a04dfcbb8eceef3bc8d1845ecf242387a4426b9d3f52320dbbfa26450643b81124b3d6a0b9bbb0fff4d0ba83 + languageName: node + linkType: hard + +"hast-util-to-parse5@npm:^8.0.0": + version: 8.0.0 + resolution: "hast-util-to-parse5@npm:8.0.0" + dependencies: + "@types/hast": ^3.0.0 + comma-separated-tokens: ^2.0.0 + devlop: ^1.0.0 property-information: ^6.0.0 space-separated-tokens: ^2.0.0 web-namespaces: ^2.0.0 zwitch: ^2.0.0 - checksum: 3a7f2175a3db599bbae7e49ba73d3e5e688e5efca7590ff50130ba108ad649f728402815d47db49146f6b94c14c934bf119915da9f6964e38802c122bcc8af6b + checksum: 137469209cb2b32b57387928878dc85310fbd5afa4807a8da69529199bb1d19044bfc95b50c3dc68d4fb2b6cb8bf99b899285597ab6ab318f50422eefd5599dd languageName: node linkType: hard -"hast-util-whitespace@npm:^2.0.0": - version: 2.0.1 - resolution: "hast-util-whitespace@npm:2.0.1" - checksum: 431be6b2f35472f951615540d7a53f69f39461e5e080c0190268bdeb2be9ab9b1dddfd1f467dd26c1de7e7952df67beb1307b6ee940baf78b24a71b5e0663868 - languageName: node - linkType: hard - -"hastscript@npm:^7.0.0, hastscript@npm:^7.1.0": - version: 7.2.0 - resolution: "hastscript@npm:7.2.0" +"hast-util-whitespace@npm:^3.0.0": + version: 3.0.0 + resolution: "hast-util-whitespace@npm:3.0.0" dependencies: - "@types/hast": ^2.0.0 + "@types/hast": ^3.0.0 + checksum: 41d93ccce218ba935dc3c12acdf586193c35069489c8c8f50c2aa824c00dec94a3c78b03d1db40fa75381942a189161922e4b7bca700b3a2cc779634c351a1e4 + languageName: node + linkType: hard + +"hastscript@npm:^8.0.0": + version: 8.0.0 + resolution: "hastscript@npm:8.0.0" + dependencies: + "@types/hast": ^3.0.0 comma-separated-tokens: ^2.0.0 - hast-util-parse-selector: ^3.0.0 + hast-util-parse-selector: ^4.0.0 property-information: ^6.0.0 space-separated-tokens: ^2.0.0 - checksum: 928a21576ff7b9a8c945e7940bcbf2d27f770edb4279d4d04b33dc90753e26ca35c1172d626f54afebd377b2afa32331e399feb3eb0f7b91a399dca5927078ae + checksum: ae3c20223e7b847320c0f98b6fb3c763ebe1bf3913c5805fbc176cf84553a9db1117ca34cf842a5235890b4b9ae0e94501bfdc9a9b870a5dbf5fc52426db1097 languageName: node linkType: hard @@ -6501,10 +6414,10 @@ __metadata: languageName: node linkType: hard -"html-void-elements@npm:^2.0.0": - version: 2.0.1 - resolution: "html-void-elements@npm:2.0.1" - checksum: 06d41f13b9d5d6e0f39861c4bec9a9196fa4906d56cd5cf6cf54ad2e52a85bf960cca2bf9600026bde16c8331db171bedba5e5a35e2e43630c8f1d497b2fb658 +"html-void-elements@npm:^3.0.0": + version: 3.0.0 + resolution: "html-void-elements@npm:3.0.0" + checksum: 59be397525465a7489028afa064c55763d9cccd1d7d9f630cca47137317f0e897a9ca26cef7e745e7cff1abc44260cfa407742b243a54261dfacd42230e94fce languageName: node linkType: hard @@ -6818,6 +6731,13 @@ __metadata: languageName: node linkType: hard +"inline-style-parser@npm:0.2.2": + version: 0.2.2 + resolution: "inline-style-parser@npm:0.2.2" + checksum: 698893d6542d4e7c0377936a1c7daec34a197765bd77c5599384756a95ce8804e6b79347b783aa591d5e9c6f3d33dae74c6d4cad3a94647eb05f3a785e927a3f + languageName: node + linkType: hard + "interpret@npm:^1.0.0": version: 1.4.0 resolution: "interpret@npm:1.4.0" @@ -6888,13 +6808,6 @@ __metadata: 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:^3.0.1": version: 3.0.1 resolution: "is-ci@npm:3.0.1" @@ -7182,16 +7095,16 @@ __metadata: languageName: node linkType: hard -"jiti@npm:^1.18.2": - version: 1.20.0 - resolution: "jiti@npm:1.20.0" +"jiti@npm:^1.18.2, jiti@npm:^1.20.0": + version: 1.21.0 + resolution: "jiti@npm:1.21.0" bin: jiti: bin/jiti.js - checksum: 7924062b5675142e3e272a27735be84b7bfc0a0eb73217fc2dcafa034f37c4f7b4b9ffc07dd98bcff0f739a8811ce1544db205ae7e97b1c86f0df92c65ce3c72 + checksum: a7bd5d63921c170eaec91eecd686388181c7828e1fa0657ab374b9372bfc1f383cf4b039e6b272383d5cb25607509880af814a39abdff967322459cca41f2961 languageName: node linkType: hard -"joi@npm:^17.7.0, joi@npm:^17.9.2": +"joi@npm:^17.9.2": version: 17.11.0 resolution: "joi@npm:17.11.0" dependencies: @@ -7325,13 +7238,6 @@ __metadata: languageName: node linkType: hard -"kleur@npm:^4.0.3": - version: 4.1.5 - resolution: "kleur@npm:4.1.5" - checksum: 1dc476e32741acf0b1b5b0627ffd0d722e342c1b0da14de3e8ae97821327ca08f9fb944542fb3c126d90ac5f27f9d804edbe7c585bf7d12ef495d115e0f22c12 - languageName: node - linkType: hard - "klona@npm:^2.0.4": version: 2.0.6 resolution: "klona@npm:2.0.6" @@ -7432,13 +7338,6 @@ __metadata: 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" @@ -7460,13 +7359,6 @@ __metadata: 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.invokemap@npm:^4.6.0": version: 4.6.0 resolution: "lodash.invokemap@npm:4.6.0" @@ -7599,10 +7491,10 @@ __metadata: languageName: node linkType: hard -"markdown-extensions@npm:^1.0.0": - version: 1.1.1 - resolution: "markdown-extensions@npm:1.1.1" - checksum: 8a6dd128be1c524049ea6a41a9193715c2835d3d706af4b8b714ff2043a82786dbcd4a8f1fa9ddd28facbc444426c97515aef2d1f3dd11d5e2d63749ba577b1e +"markdown-extensions@npm:^2.0.0": + version: 2.0.0 + resolution: "markdown-extensions@npm:2.0.0" + checksum: ec4ffcb0768f112e778e7ac74cb8ef22a966c168c3e6c29829f007f015b0a0b5c79c73ee8599a0c72e440e7f5cfdbf19e80e2d77b9a313b8f66e180a330cf1b2 languageName: node linkType: hard @@ -7613,61 +7505,31 @@ __metadata: languageName: node linkType: hard -"mdast-util-definitions@npm:^5.0.0": - version: 5.1.2 - resolution: "mdast-util-definitions@npm:5.1.2" +"mdast-util-directive@npm:^3.0.0": + version: 3.0.0 + resolution: "mdast-util-directive@npm:3.0.0" dependencies: - "@types/mdast": ^3.0.0 - "@types/unist": ^2.0.0 - unist-util-visit: ^4.0.0 - checksum: 2544daccab744ea1ede76045c2577ae4f1cc1b9eb1ea51ab273fe1dca8db5a8d6f50f87759c0ce6484975914b144b7f40316f805cb9c86223a78db8de0b77bae - languageName: node - linkType: hard - -"mdast-util-directive@npm:^2.0.0": - version: 2.2.4 - resolution: "mdast-util-directive@npm:2.2.4" - dependencies: - "@types/mdast": ^3.0.0 - "@types/unist": ^2.0.0 - mdast-util-from-markdown: ^1.3.0 - mdast-util-to-markdown: ^1.5.0 + "@types/mdast": ^4.0.0 + "@types/unist": ^3.0.0 + devlop: ^1.0.0 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 parse-entities: ^4.0.0 stringify-entities: ^4.0.0 - unist-util-visit-parents: ^5.1.3 - checksum: d04112761659c912b5d7db8f8c035918da52e79ce8cb598c7c270c6f678db0c22f3dea7894b30dec46852409f926306b84ca95683dd1e28731835eb5cb4fbda4 + unist-util-visit-parents: ^6.0.0 + checksum: 593afdc4f39f99bb198f3774bf4648cb546cb99a055e40c82262a7faab10926d2529a725d0d3945300ed0a1f07c6c84215a3f76b899a89b3f410ec7375bbab17 languageName: node linkType: hard -"mdast-util-find-and-replace@npm:^2.0.0": - version: 2.2.2 - resolution: "mdast-util-find-and-replace@npm:2.2.2" +"mdast-util-find-and-replace@npm:^3.0.0, mdast-util-find-and-replace@npm:^3.0.1": + version: 3.0.1 + resolution: "mdast-util-find-and-replace@npm:3.0.1" dependencies: - "@types/mdast": ^3.0.0 + "@types/mdast": ^4.0.0 escape-string-regexp: ^5.0.0 - unist-util-is: ^5.0.0 - unist-util-visit-parents: ^5.0.0 - checksum: b4ce463c43fe6e1c38a53a89703f755c84ab5437f49bff9a0ac751279733332ca11c85ed0262aa6c17481f77b555d26ca6d64e70d6814f5b8d12d34a3e53a60b - languageName: node - linkType: hard - -"mdast-util-from-markdown@npm:^1.0.0, mdast-util-from-markdown@npm:^1.1.0, mdast-util-from-markdown@npm:^1.3.0": - version: 1.3.0 - resolution: "mdast-util-from-markdown@npm:1.3.0" - dependencies: - "@types/mdast": ^3.0.0 - "@types/unist": ^2.0.0 - decode-named-character-reference: ^1.0.0 - mdast-util-to-string: ^3.1.0 - micromark: ^3.0.0 - micromark-util-decode-numeric-character-reference: ^1.0.0 - micromark-util-decode-string: ^1.0.0 - micromark-util-normalize-identifier: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - unist-util-stringify-position: ^3.0.0 - uvu: ^0.5.0 - checksum: cc971d1ad381150f6504fd753fbcffcc64c0abb527540ce343625c2bba76104505262122ef63d14ab66eb47203f323267017c6d09abfa8535ee6a8e14069595f + unist-util-is: ^6.0.0 + unist-util-visit-parents: ^6.0.0 + checksum: 05d5c4ff02e31db2f8a685a13bcb6c3f44e040bd9dfa54c19a232af8de5268334c8755d79cb456ed4cced1300c4fb83e88444c7ae8ee9ff16869a580f29d08cd languageName: node linkType: hard @@ -7705,142 +7567,142 @@ __metadata: languageName: node linkType: hard -"mdast-util-gfm-autolink-literal@npm:^1.0.0": - version: 1.0.3 - resolution: "mdast-util-gfm-autolink-literal@npm:1.0.3" +"mdast-util-gfm-autolink-literal@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-gfm-autolink-literal@npm:2.0.0" dependencies: - "@types/mdast": ^3.0.0 + "@types/mdast": ^4.0.0 ccount: ^2.0.0 - mdast-util-find-and-replace: ^2.0.0 - micromark-util-character: ^1.0.0 - checksum: 1748a8727cfc533bac0c287d6e72d571d165bfa77ae0418be4828177a3ec73c02c3f2ee534d87eb75cbaffa00c0866853bbcc60ae2255babb8210f7636ec2ce2 + devlop: ^1.0.0 + mdast-util-find-and-replace: ^3.0.0 + micromark-util-character: ^2.0.0 + checksum: 10322662e5302964bed7c9829c5fd3b0c9899d4f03e63fb8620ab141cf4f3de9e61fcb4b44d46aacc8a23f82bcd5d900980a211825dfe026b1dab5fdbc3e8742 languageName: node linkType: hard -"mdast-util-gfm-footnote@npm:^1.0.0": - version: 1.0.2 - resolution: "mdast-util-gfm-footnote@npm:1.0.2" +"mdast-util-gfm-footnote@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-gfm-footnote@npm:2.0.0" dependencies: - "@types/mdast": ^3.0.0 - mdast-util-to-markdown: ^1.3.0 - micromark-util-normalize-identifier: ^1.0.0 - checksum: 2d77505f9377ed7e14472ef5e6b8366c3fec2cf5f936bb36f9fbe5b97ccb7cce0464d9313c236fa86fb844206fd585db05707e4fcfb755e4fc1864194845f1f6 + "@types/mdast": ^4.0.0 + devlop: ^1.1.0 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + micromark-util-normalize-identifier: ^2.0.0 + checksum: 45d26b40e7a093712e023105791129d76e164e2168d5268e113298a22de30c018162683fb7893cdc04ab246dac0087eed708b2a136d1d18ed2b32b3e0cae4a79 languageName: node linkType: hard -"mdast-util-gfm-strikethrough@npm:^1.0.0": - version: 1.0.3 - resolution: "mdast-util-gfm-strikethrough@npm:1.0.3" +"mdast-util-gfm-strikethrough@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-gfm-strikethrough@npm:2.0.0" dependencies: - "@types/mdast": ^3.0.0 - mdast-util-to-markdown: ^1.3.0 - checksum: 17003340ff1bba643ec4a59fd4370fc6a32885cab2d9750a508afa7225ea71449fb05acaef60faa89c6378b8bcfbd86a9d94b05f3c6651ff27a60e3ddefc2549 + "@types/mdast": ^4.0.0 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + checksum: fe9b1d0eba9b791ff9001c008744eafe3dd7a81b085f2bf521595ce4a8e8b1b44764ad9361761ad4533af3e5d913d8ad053abec38172031d9ee32a8ebd1c7dbd languageName: node linkType: hard -"mdast-util-gfm-table@npm:^1.0.0": - version: 1.0.7 - resolution: "mdast-util-gfm-table@npm:1.0.7" +"mdast-util-gfm-table@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-gfm-table@npm:2.0.0" dependencies: - "@types/mdast": ^3.0.0 + "@types/mdast": ^4.0.0 + devlop: ^1.0.0 markdown-table: ^3.0.0 - mdast-util-from-markdown: ^1.0.0 - mdast-util-to-markdown: ^1.3.0 - checksum: 8b8c401bb4162e53f072a2dff8efbca880fd78d55af30601c791315ab6722cb2918176e8585792469a0c530cebb9df9b4e7fede75fdc4d83df2839e238836692 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + checksum: 063a627fd0993548fd63ca0c24c437baf91ba7d51d0a38820bd459bc20bf3d13d7365ef8d28dca99176dd5eb26058f7dde51190479c186dfe6af2e11202957c9 languageName: node linkType: hard -"mdast-util-gfm-task-list-item@npm:^1.0.0": - version: 1.0.2 - resolution: "mdast-util-gfm-task-list-item@npm:1.0.2" +"mdast-util-gfm-task-list-item@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-gfm-task-list-item@npm:2.0.0" dependencies: - "@types/mdast": ^3.0.0 - mdast-util-to-markdown: ^1.3.0 - checksum: c9b86037d6953b84f11fb2fc3aa23d5b8e14ca0dfcb0eb2fb289200e172bb9d5647bfceb4f86606dc6d935e8d58f6a458c04d3e55e87ff8513c7d4ade976200b + "@types/mdast": ^4.0.0 + devlop: ^1.0.0 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + checksum: 37db90c59b15330fc54d790404abf5ef9f2f83e8961c53666fe7de4aab8dd5e6b3c296b6be19797456711a89a27840291d8871ff0438e9b4e15c89d170efe072 languageName: node linkType: hard -"mdast-util-gfm@npm:^2.0.0": - version: 2.0.2 - resolution: "mdast-util-gfm@npm:2.0.2" +"mdast-util-gfm@npm:^3.0.0": + version: 3.0.0 + resolution: "mdast-util-gfm@npm:3.0.0" dependencies: - mdast-util-from-markdown: ^1.0.0 - mdast-util-gfm-autolink-literal: ^1.0.0 - mdast-util-gfm-footnote: ^1.0.0 - mdast-util-gfm-strikethrough: ^1.0.0 - mdast-util-gfm-table: ^1.0.0 - mdast-util-gfm-task-list-item: ^1.0.0 - mdast-util-to-markdown: ^1.0.0 - checksum: 7078cb985255208bcbce94a121906417d38353c6b1a9acbe56ee8888010d3500608b5d51c16b0999ac63ca58848fb13012d55f26930ff6c6f3450f053d56514e + mdast-util-from-markdown: ^2.0.0 + mdast-util-gfm-autolink-literal: ^2.0.0 + mdast-util-gfm-footnote: ^2.0.0 + mdast-util-gfm-strikethrough: ^2.0.0 + mdast-util-gfm-table: ^2.0.0 + mdast-util-gfm-task-list-item: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + checksum: 62039d2f682ae3821ea1c999454863d31faf94d67eb9b746589c7e136076d7fb35fabc67e02f025c7c26fd7919331a0ee1aabfae24f565d9a6a9ebab3371c626 languageName: node linkType: hard -"mdast-util-mdx-expression@npm:^1.0.0": - version: 1.3.2 - resolution: "mdast-util-mdx-expression@npm:1.3.2" +"mdast-util-mdx-expression@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-mdx-expression@npm:2.0.0" dependencies: "@types/estree-jsx": ^1.0.0 - "@types/hast": ^2.0.0 - "@types/mdast": ^3.0.0 - mdast-util-from-markdown: ^1.0.0 - mdast-util-to-markdown: ^1.0.0 - checksum: e4c90f26deaa5eb6217b0a9af559a80de41da02ab3bcd864c56bed3304b056ae703896e9876bc6ded500f4aff59f4de5cbf6a4b109a5ba408f2342805fe6dc05 + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + devlop: ^1.0.0 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + checksum: 4e1183000e183e07a7264e192889b4fd57372806103031c71b9318967f85fd50a5dd0f92ef14f42c331e77410808f5de3341d7bc8ad4ee91b7fa8f0a30043a8a languageName: node linkType: hard -"mdast-util-mdx-jsx@npm:^2.0.0": - version: 2.1.2 - resolution: "mdast-util-mdx-jsx@npm:2.1.2" +"mdast-util-mdx-jsx@npm:^3.0.0": + version: 3.0.0 + resolution: "mdast-util-mdx-jsx@npm:3.0.0" dependencies: "@types/estree-jsx": ^1.0.0 - "@types/hast": ^2.0.0 - "@types/mdast": ^3.0.0 - "@types/unist": ^2.0.0 + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + "@types/unist": ^3.0.0 ccount: ^2.0.0 - mdast-util-from-markdown: ^1.1.0 - mdast-util-to-markdown: ^1.3.0 + devlop: ^1.1.0 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 parse-entities: ^4.0.0 stringify-entities: ^4.0.0 - unist-util-remove-position: ^4.0.0 - unist-util-stringify-position: ^3.0.0 - vfile-message: ^3.0.0 - checksum: 637e0bbd97c0c783f6b12bb05ccb1edaec076c5aa6d349147d77b8e6e10677f1be8e2870c05b1896f69095c9bc527f34be72b349b30737ab2e499bfc579b3a28 + unist-util-remove-position: ^5.0.0 + unist-util-stringify-position: ^4.0.0 + vfile-message: ^4.0.0 + checksum: 48fe1ba617205f3776ca2030d195adbdb42bb6c53326534db3f5bdd28abe7895103af8c4dfda7cbe2911e8cd71921bc8a82fe40856565e57af8b4f8a79c8c126 languageName: node linkType: hard -"mdast-util-mdx@npm:^2.0.0": - version: 2.0.1 - resolution: "mdast-util-mdx@npm:2.0.1" +"mdast-util-mdx@npm:^3.0.0": + version: 3.0.0 + resolution: "mdast-util-mdx@npm:3.0.0" dependencies: - mdast-util-from-markdown: ^1.0.0 - mdast-util-mdx-expression: ^1.0.0 - mdast-util-mdx-jsx: ^2.0.0 - mdast-util-mdxjs-esm: ^1.0.0 - mdast-util-to-markdown: ^1.0.0 - checksum: 7303149230a26e524e319833b782bffca94e49cdab012996618701259bd056e014ca22a35d25ffa8880ba9064ee126a2a002f01e5c90a31ca726339ed775875e + mdast-util-from-markdown: ^2.0.0 + mdast-util-mdx-expression: ^2.0.0 + mdast-util-mdx-jsx: ^3.0.0 + mdast-util-mdxjs-esm: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + checksum: e2b007d826fcd49fd57ed03e190753c8b0f7d9eff6c7cb26ba609cde15cd3a472c0cd5e4a1ee3e39a40f14be22fdb57de243e093cea0c064d6f3366cff3e3af2 languageName: node linkType: hard -"mdast-util-mdxjs-esm@npm:^1.0.0": - version: 1.3.1 - resolution: "mdast-util-mdxjs-esm@npm:1.3.1" +"mdast-util-mdxjs-esm@npm:^2.0.0": + version: 2.0.1 + resolution: "mdast-util-mdxjs-esm@npm:2.0.1" dependencies: "@types/estree-jsx": ^1.0.0 - "@types/hast": ^2.0.0 - "@types/mdast": ^3.0.0 - mdast-util-from-markdown: ^1.0.0 - mdast-util-to-markdown: ^1.0.0 - checksum: ee78a4f58adfec38723cbc920f05481201ebb001eff3982f2d0e5f5ce5c75685e732e9d361ad4a1be8b936b4e5de0f2599cb96b92ad4bd92698ac0c4a09bbec3 - languageName: node - linkType: hard - -"mdast-util-phrasing@npm:^3.0.0": - version: 3.0.1 - resolution: "mdast-util-phrasing@npm:3.0.1" - dependencies: - "@types/mdast": ^3.0.0 - unist-util-is: ^5.0.0 - checksum: c5b616d9b1eb76a6b351d195d94318494722525a12a89d9c8a3b091af7db3dd1fc55d294f9d29266d8159a8267b0df4a7a133bda8a3909d5331c383e1e1ff328 + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + devlop: ^1.0.0 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + checksum: 1f9dad04d31d59005332e9157ea9510dc1d03092aadbc607a10475c7eec1c158b475aa0601a3a4f74e13097ca735deb8c2d9d37928ddef25d3029fd7c9e14dc3 languageName: node linkType: hard @@ -7854,35 +7716,20 @@ __metadata: languageName: node linkType: hard -"mdast-util-to-hast@npm:^12.1.0": - version: 12.3.0 - resolution: "mdast-util-to-hast@npm:12.3.0" +"mdast-util-to-hast@npm:^13.0.0": + version: 13.1.0 + resolution: "mdast-util-to-hast@npm:13.1.0" dependencies: - "@types/hast": ^2.0.0 - "@types/mdast": ^3.0.0 - mdast-util-definitions: ^5.0.0 - micromark-util-sanitize-uri: ^1.1.0 + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + "@ungap/structured-clone": ^1.0.0 + devlop: ^1.0.0 + micromark-util-sanitize-uri: ^2.0.0 trim-lines: ^3.0.0 - unist-util-generated: ^2.0.0 - unist-util-position: ^4.0.0 - unist-util-visit: ^4.0.0 - checksum: ea40c9f07dd0b731754434e81c913590c611b1fd753fa02550a1492aadfc30fb3adecaf62345ebb03cea2ddd250c15ab6e578fffde69c19955c9b87b10f2a9bb - languageName: node - linkType: hard - -"mdast-util-to-markdown@npm:^1.0.0, mdast-util-to-markdown@npm:^1.3.0, mdast-util-to-markdown@npm:^1.5.0": - version: 1.5.0 - resolution: "mdast-util-to-markdown@npm:1.5.0" - dependencies: - "@types/mdast": ^3.0.0 - "@types/unist": ^2.0.0 - longest-streak: ^3.0.0 - mdast-util-phrasing: ^3.0.0 - mdast-util-to-string: ^3.0.0 - micromark-util-decode-string: ^1.0.0 - unist-util-visit: ^4.0.0 - zwitch: ^2.0.0 - checksum: 64338eb33e49bb0aea417591fd986f72fdd39205052563bb7ce9eb9ecc160824509bfacd740086a05af355c6d5c36353aafe95cab9e6927d674478757cee6259 + unist-util-position: ^5.0.0 + unist-util-visit: ^5.0.0 + vfile: ^6.0.0 + checksum: 640bc897286af8fe760cd477fb04bbf544a5a897cdc2220ce36fe2f892f067b483334610387aeb969511bd78a2d841a54851079cd676ac513d6a5ff75852514e languageName: node linkType: hard @@ -7902,15 +7749,6 @@ __metadata: languageName: node linkType: hard -"mdast-util-to-string@npm:^3.0.0, mdast-util-to-string@npm:^3.1.0, mdast-util-to-string@npm:^3.2.0": - version: 3.2.0 - resolution: "mdast-util-to-string@npm:3.2.0" - dependencies: - "@types/mdast": ^3.0.0 - checksum: dc40b544d54339878ae2c9f2b3198c029e1e07291d2126bd00ca28272ee6616d0d2194eb1c9828a7c34d412a79a7e73b26512a734698d891c710a1e73db1e848 - languageName: node - linkType: hard - "mdast-util-to-string@npm:^4.0.0": version: 4.0.0 resolution: "mdast-util-to-string@npm:4.0.0" @@ -7971,30 +7809,6 @@ __metadata: languageName: node linkType: hard -"micromark-core-commonmark@npm:^1.0.0, micromark-core-commonmark@npm:^1.0.1": - version: 1.0.6 - resolution: "micromark-core-commonmark@npm:1.0.6" - dependencies: - decode-named-character-reference: ^1.0.0 - micromark-factory-destination: ^1.0.0 - micromark-factory-label: ^1.0.0 - micromark-factory-space: ^1.0.0 - micromark-factory-title: ^1.0.0 - micromark-factory-whitespace: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-chunked: ^1.0.0 - micromark-util-classify-character: ^1.0.0 - micromark-util-html-tag-name: ^1.0.0 - micromark-util-normalize-identifier: ^1.0.0 - micromark-util-resolve-all: ^1.0.0 - micromark-util-subtokenize: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.1 - uvu: ^0.5.0 - checksum: 4b483c46077f696ed310f6d709bb9547434c218ceb5c1220fde1707175f6f68b44da15ab8668f9c801e1a123210071e3af883a7d1215122c913fd626f122bfc2 - languageName: node - linkType: hard - "micromark-core-commonmark@npm:^2.0.0": version: 2.0.0 resolution: "micromark-core-commonmark@npm:2.0.0" @@ -8019,18 +7833,18 @@ __metadata: languageName: node linkType: hard -"micromark-extension-directive@npm:^2.0.0": - version: 2.2.0 - resolution: "micromark-extension-directive@npm:2.2.0" +"micromark-extension-directive@npm:^3.0.0": + version: 3.0.0 + resolution: "micromark-extension-directive@npm:3.0.0" dependencies: - micromark-factory-space: ^1.0.0 - micromark-factory-whitespace: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 + devlop: ^1.0.0 + micromark-factory-space: ^2.0.0 + micromark-factory-whitespace: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 parse-entities: ^4.0.0 - uvu: ^0.5.0 - checksum: 1256374a1327c2aecd4b3592de2c62ddf4798441d3a953f8414ecde05da2595a47428d94959b0bdb67605d4e195b95eb0b6e18ece44a50cbdf5a9c2c25d21905 + checksum: 8350106bdf039a544cba64cf7932261a710e07d73d43d6c645dd2b16577f30ebd04abf762e8ca74266f5de19938e1eeff6c237d79f8244dea23aef7f90df2c31 languageName: node linkType: hard @@ -8046,181 +7860,172 @@ __metadata: languageName: node linkType: hard -"micromark-extension-gfm-autolink-literal@npm:^1.0.0": - version: 1.0.3 - resolution: "micromark-extension-gfm-autolink-literal@npm:1.0.3" +"micromark-extension-gfm-autolink-literal@npm:^2.0.0": + version: 2.0.0 + resolution: "micromark-extension-gfm-autolink-literal@npm:2.0.0" dependencies: - micromark-util-character: ^1.0.0 - micromark-util-sanitize-uri: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - checksum: bb181972ac346ca73ca1ab0b80b80c9d6509ed149799d2217d5442670f499c38a94edff73d32fa52b390d89640974cfbd7f29e4ad7d599581d5e1cabcae636a2 + micromark-util-character: ^2.0.0 + micromark-util-sanitize-uri: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: fa16d59528239262d6d04d539a052baf1f81275954ec8bfadea40d81bfc25667d5c8e68b225a5358626df5e30a3933173a67fdad2fed011d37810a10b770b0b2 languageName: node linkType: hard -"micromark-extension-gfm-footnote@npm:^1.0.0": - version: 1.1.0 - resolution: "micromark-extension-gfm-footnote@npm:1.1.0" +"micromark-extension-gfm-footnote@npm:^2.0.0": + version: 2.0.0 + resolution: "micromark-extension-gfm-footnote@npm:2.0.0" dependencies: - micromark-core-commonmark: ^1.0.0 - micromark-factory-space: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-normalize-identifier: ^1.0.0 - micromark-util-sanitize-uri: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - checksum: 7a5408625ef2cca5cc18e6591c2522a8a409f466a6fbc0ed938950aafe5fc9bf1eada65e1a4dd4e36ec3e7b24920de1f4b3e2c365d8f5cd2d6ccb1f8c2377c49 + devlop: ^1.0.0 + micromark-core-commonmark: ^2.0.0 + micromark-factory-space: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-normalize-identifier: ^2.0.0 + micromark-util-sanitize-uri: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: a426fddecfac6144fc622b845cd2dc09d46faa75be5b76ff022cb76a03301b1d4929a5e5e41e071491787936be65e03d0b03c7aebc0e0136b3cdbfadadd6632c languageName: node linkType: hard -"micromark-extension-gfm-strikethrough@npm:^1.0.0": - version: 1.0.5 - resolution: "micromark-extension-gfm-strikethrough@npm:1.0.5" +"micromark-extension-gfm-strikethrough@npm:^2.0.0": + version: 2.0.0 + resolution: "micromark-extension-gfm-strikethrough@npm:2.0.0" dependencies: - micromark-util-chunked: ^1.0.0 - micromark-util-classify-character: ^1.0.0 - micromark-util-resolve-all: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - checksum: 548c0f257753d735c741533411957f04253da53db31e1f398dc5dc1de9f398c45586baad5223dce8f3b55f9433c255e6eb695fc3104256b8c332dd8737136882 + devlop: ^1.0.0 + micromark-util-chunked: ^2.0.0 + micromark-util-classify-character: ^2.0.0 + micromark-util-resolve-all: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 4e35fbbf364bfce08066b70acd94b9d393a8fd09a5afbe0bae70d0c8a174640b1ba86ab6b78ee38f411a813e2a718b07959216cf0063d823ba1c569a7694e5ad languageName: node linkType: hard -"micromark-extension-gfm-table@npm:^1.0.0": - version: 1.0.5 - resolution: "micromark-extension-gfm-table@npm:1.0.5" +"micromark-extension-gfm-table@npm:^2.0.0": + version: 2.0.0 + resolution: "micromark-extension-gfm-table@npm:2.0.0" dependencies: - micromark-factory-space: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - checksum: f0aab3b4333cc24b1534b08dc4cce986dd606df8b7ed913e5a1de9fe2d3ae67b2435663c0bc271b528874af4928e580e1ad540ea9117d7f2d74edb28859c97ef + devlop: ^1.0.0 + micromark-factory-space: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 71484dcf8db7b189da0528f472cc81e4d6d1a64ae43bbe7fcb7e2e1dba758a0a4f785f9f1afb9459fe5b4a02bbe023d78c95c05204414a14083052eb8219e5eb languageName: node linkType: hard -"micromark-extension-gfm-tagfilter@npm:^1.0.0": - version: 1.0.2 - resolution: "micromark-extension-gfm-tagfilter@npm:1.0.2" +"micromark-extension-gfm-tagfilter@npm:^2.0.0": + version: 2.0.0 + resolution: "micromark-extension-gfm-tagfilter@npm:2.0.0" dependencies: - micromark-util-types: ^1.0.0 - checksum: 7d2441df51f890c86f8e7cf7d331a570b69c8105fa1c2fc5b737cb739502c16c8ee01cf35550a8a78f89497c5dfacc97cf82d55de6274e8320f3aec25e2b0dd2 + micromark-util-types: ^2.0.0 + checksum: cf21552f4a63592bfd6c96ae5d64a5f22bda4e77814e3f0501bfe80e7a49378ad140f827007f36044666f176b3a0d5fea7c2e8e7973ce4b4579b77789f01ae95 languageName: node linkType: hard -"micromark-extension-gfm-task-list-item@npm:^1.0.0": - version: 1.0.4 - resolution: "micromark-extension-gfm-task-list-item@npm:1.0.4" - dependencies: - micromark-factory-space: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - checksum: 2575bb47b320f2479d3cc2492ba7cf79d6baa9cd0200c0ed120fd0e318e64e8ebab4a93a056a3781cb5107193f3b36ebd2d86a5928308bef45fc121291f97eb5 - languageName: node - linkType: hard - -"micromark-extension-gfm@npm:^2.0.0": +"micromark-extension-gfm-task-list-item@npm:^2.0.0": version: 2.0.1 - resolution: "micromark-extension-gfm@npm:2.0.1" + resolution: "micromark-extension-gfm-task-list-item@npm:2.0.1" dependencies: - micromark-extension-gfm-autolink-literal: ^1.0.0 - micromark-extension-gfm-footnote: ^1.0.0 - micromark-extension-gfm-strikethrough: ^1.0.0 - micromark-extension-gfm-table: ^1.0.0 - micromark-extension-gfm-tagfilter: ^1.0.0 - micromark-extension-gfm-task-list-item: ^1.0.0 - micromark-util-combine-extensions: ^1.0.0 - micromark-util-types: ^1.0.0 - checksum: b181479c87be38d5ae8d28e6dc52fab73c894fd2706876746f27a91fb186644ce03532a9c35dca2186327a0e2285cd5242ad0361dc89adedd4a50376ffd94e22 + devlop: ^1.0.0 + micromark-factory-space: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 80e569ab1a1d1f89d86af91482e9629e24b7e3f019c9d7989190f36a9367c6de723b2af48e908c1b73479f35b2215d3d38c1fdbf02ab01eb2fc90a59d1cf4465 languageName: node linkType: hard -"micromark-extension-mdx-expression@npm:^1.0.0": - version: 1.0.4 - resolution: "micromark-extension-mdx-expression@npm:1.0.4" +"micromark-extension-gfm@npm:^3.0.0": + version: 3.0.0 + resolution: "micromark-extension-gfm@npm:3.0.0" dependencies: - micromark-factory-mdx-expression: ^1.0.0 - micromark-factory-space: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-events-to-acorn: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - checksum: d19a31f9813dd5d4ad96b99e35b7c48067e69d75f92ec670dad5242857fb7688ba8b7c6a15616797b5df25dd89fd3b54916f93cb60ce2cfe97aca84739b45954 + micromark-extension-gfm-autolink-literal: ^2.0.0 + micromark-extension-gfm-footnote: ^2.0.0 + micromark-extension-gfm-strikethrough: ^2.0.0 + micromark-extension-gfm-table: ^2.0.0 + micromark-extension-gfm-tagfilter: ^2.0.0 + micromark-extension-gfm-task-list-item: ^2.0.0 + micromark-util-combine-extensions: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 2060fa62666a09532d6b3a272d413bc1b25bbb262f921d7402795ac021e1362c8913727e33d7528d5b4ccaf26922ec51208c43f795a702964817bc986de886c9 languageName: node linkType: hard -"micromark-extension-mdx-jsx@npm:^1.0.0": - version: 1.0.3 - resolution: "micromark-extension-mdx-jsx@npm:1.0.3" +"micromark-extension-mdx-expression@npm:^3.0.0": + version: 3.0.0 + resolution: "micromark-extension-mdx-expression@npm:3.0.0" + dependencies: + "@types/estree": ^1.0.0 + devlop: ^1.0.0 + micromark-factory-mdx-expression: ^2.0.0 + micromark-factory-space: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-events-to-acorn: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: abd6ba0acdebc03bc0836c51a1ec4ca28e0be86f10420dd8cfbcd6c10dd37cd3f31e7c8b9792e9276e7526748883f4a30d0803d72b6285dae47d4e5348c23a10 + languageName: node + linkType: hard + +"micromark-extension-mdx-jsx@npm:^3.0.0": + version: 3.0.0 + resolution: "micromark-extension-mdx-jsx@npm:3.0.0" dependencies: "@types/acorn": ^4.0.0 - estree-util-is-identifier-name: ^2.0.0 - micromark-factory-mdx-expression: ^1.0.0 - micromark-factory-space: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - vfile-message: ^3.0.0 - checksum: 1a5566890aabc52fe96b78e3a3a507dee03a2232e44b9360b00617734e156f934e85bc6a477fbb856c793fe33c9fb7d2207a4f50e680168c0d04ba9c9336d960 + "@types/estree": ^1.0.0 + devlop: ^1.0.0 + estree-util-is-identifier-name: ^3.0.0 + micromark-factory-mdx-expression: ^2.0.0 + micromark-factory-space: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + vfile-message: ^4.0.0 + checksum: 5e2f45d381d1ce43afadc5376427b42ef8cd2a574ca3658473254eabe84db99ef1abc03055b3d86728fac7f1edfb1076e6f2f322ed8bfb1f2f14cafc2c8f0d0e languageName: node linkType: hard -"micromark-extension-mdx-md@npm:^1.0.0": - version: 1.0.0 - resolution: "micromark-extension-mdx-md@npm:1.0.0" +"micromark-extension-mdx-md@npm:^2.0.0": + version: 2.0.0 + resolution: "micromark-extension-mdx-md@npm:2.0.0" dependencies: - micromark-util-types: ^1.0.0 - checksum: b4f205e1d5f0946b4755541ef44ffd0b3be8c7ecfc08d8b139b6a21fbd3ff62d8fdb6b7e6d17bd9a3b610450267f43a41703dc48b341da9addd743a28cdefa64 + micromark-util-types: ^2.0.0 + checksum: 7daf03372fd7faddf3f0ac87bdb0debb0bb770f33b586f72251e1072b222ceee75400ab6194c0e130dbf1e077369a5b627be6e9130d7a2e9e6b849f0d18ff246 languageName: node linkType: hard -"micromark-extension-mdxjs-esm@npm:^1.0.0": - version: 1.0.3 - resolution: "micromark-extension-mdxjs-esm@npm:1.0.3" +"micromark-extension-mdxjs-esm@npm:^3.0.0": + version: 3.0.0 + resolution: "micromark-extension-mdxjs-esm@npm:3.0.0" dependencies: - micromark-core-commonmark: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-events-to-acorn: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - unist-util-position-from-estree: ^1.1.0 - uvu: ^0.5.0 - vfile-message: ^3.0.0 - checksum: 756074656391a5e5bb96bc8a0e9c1df7d9f7be5299847c9719e6a90552e1c76a11876aa89986ad5da89ab485f776a4a43a61ea3acddd4f865a5cee43ac523ffd + "@types/estree": ^1.0.0 + devlop: ^1.0.0 + micromark-core-commonmark: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-events-to-acorn: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + unist-util-position-from-estree: ^2.0.0 + vfile-message: ^4.0.0 + checksum: fb33d850200afce567b95c90f2f7d42259bd33eea16154349e4fa77c3ec934f46c8e5c111acea16321dce3d9f85aaa4c49afe8b810e31b34effc11617aeee8f6 languageName: node linkType: hard -"micromark-extension-mdxjs@npm:^1.0.0": - version: 1.0.0 - resolution: "micromark-extension-mdxjs@npm:1.0.0" +"micromark-extension-mdxjs@npm:^3.0.0": + version: 3.0.0 + resolution: "micromark-extension-mdxjs@npm:3.0.0" dependencies: acorn: ^8.0.0 acorn-jsx: ^5.0.0 - micromark-extension-mdx-expression: ^1.0.0 - micromark-extension-mdx-jsx: ^1.0.0 - micromark-extension-mdx-md: ^1.0.0 - micromark-extension-mdxjs-esm: ^1.0.0 - micromark-util-combine-extensions: ^1.0.0 - micromark-util-types: ^1.0.0 - checksum: ba836c6d2dfc67597886e88f533ffa02f2029dbe216a0651f1066e70f8529a700bcc7fa2bc4201ee12fd3d1cd7da7093d5a442442daeb84b27df96aaffb7699c - languageName: node - linkType: hard - -"micromark-factory-destination@npm:^1.0.0": - version: 1.0.0 - resolution: "micromark-factory-destination@npm:1.0.0" - dependencies: - micromark-util-character: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - checksum: 8e733ae9c1c2342f14ff290bf09946e20f6f540117d80342377a765cac48df2ea5e748f33c8b07501ad7a43414b1a6597c8510ede2052b6bf1251fab89748e20 + micromark-extension-mdx-expression: ^3.0.0 + micromark-extension-mdx-jsx: ^3.0.0 + micromark-extension-mdx-md: ^2.0.0 + micromark-extension-mdxjs-esm: ^3.0.0 + micromark-util-combine-extensions: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 7da6f0fb0e1e0270a2f5ad257e7422cc16e68efa7b8214c63c9d55bc264cb872e9ca4ac9a71b9dfd13daf52e010f730bac316086f4340e4fcc6569ec699915bf languageName: node linkType: hard @@ -8235,18 +8040,6 @@ __metadata: languageName: node linkType: hard -"micromark-factory-label@npm:^1.0.0": - version: 1.0.2 - resolution: "micromark-factory-label@npm:1.0.2" - dependencies: - micromark-util-character: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - checksum: 957e9366bdc8dbc1437c0706ff96972fa985ab4b1274abcae12f6094f527cbf5c69e7f2304c23c7f4b96e311ff7911d226563b8b43dcfcd4091e8c985fb97ce6 - languageName: node - linkType: hard - "micromark-factory-label@npm:^2.0.0": version: 2.0.0 resolution: "micromark-factory-label@npm:2.0.0" @@ -8259,19 +8052,19 @@ __metadata: languageName: node linkType: hard -"micromark-factory-mdx-expression@npm:^1.0.0": - version: 1.0.7 - resolution: "micromark-factory-mdx-expression@npm:1.0.7" +"micromark-factory-mdx-expression@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-factory-mdx-expression@npm:2.0.1" dependencies: - micromark-factory-space: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-events-to-acorn: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - unist-util-position-from-estree: ^1.0.0 - uvu: ^0.5.0 - vfile-message: ^3.0.0 - checksum: e7893f21576bcb7755d341e45d3ff202ba466fa2278c6f31ae4db4002a28d6d13a4efad331ef46223372ec2010d9bc2ff27e2cd57a4580be6491e59ca21ba59d + "@types/estree": ^1.0.0 + devlop: ^1.0.0 + micromark-util-character: ^2.0.0 + micromark-util-events-to-acorn: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + unist-util-position-from-estree: ^2.0.0 + vfile-message: ^4.0.0 + checksum: 2ba0ae939d0174a5e5331b1a4c203b96862ccf06e8903d6bdcc2d51f75515e52d407cd394afcd182f9ff0e877dc2a14e3fa430ced0131e156650d45104de8311 languageName: node linkType: hard @@ -8295,19 +8088,6 @@ __metadata: languageName: node linkType: hard -"micromark-factory-title@npm:^1.0.0": - version: 1.0.2 - resolution: "micromark-factory-title@npm:1.0.2" - dependencies: - micromark-factory-space: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - checksum: 9a9cf66babde0bad1e25d6c1087082bfde6dfc319a36cab67c89651cc1a53d0e21cdec83262b5a4c33bff49f0e3c8dc2a7bd464e991d40dbea166a8f9b37e5b2 - languageName: node - linkType: hard - "micromark-factory-title@npm:^2.0.0": version: 2.0.0 resolution: "micromark-factory-title@npm:2.0.0" @@ -8320,18 +8100,6 @@ __metadata: languageName: node linkType: hard -"micromark-factory-whitespace@npm:^1.0.0": - version: 1.0.0 - resolution: "micromark-factory-whitespace@npm:1.0.0" - dependencies: - micromark-factory-space: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - checksum: 0888386e6ea2dd665a5182c570d9b3d0a172d3f11694ca5a2a84e552149c9f1429f5b975ec26e1f0fa4388c55a656c9f359ce5e0603aff6175ba3e255076f20b - languageName: node - linkType: hard - "micromark-factory-whitespace@npm:^2.0.0": version: 2.0.0 resolution: "micromark-factory-whitespace@npm:2.0.0" @@ -8364,15 +8132,6 @@ __metadata: languageName: node linkType: hard -"micromark-util-chunked@npm:^1.0.0": - version: 1.0.0 - resolution: "micromark-util-chunked@npm:1.0.0" - dependencies: - micromark-util-symbol: ^1.0.0 - checksum: c1efd56e8c4217bcf1c6f1a9fb9912b4a2a5503b00d031da902be922fb3fee60409ac53f11739991291357b2784fb0647ddfc74c94753a068646c0cb0fd71421 - languageName: node - linkType: hard - "micromark-util-chunked@npm:^2.0.0": version: 2.0.0 resolution: "micromark-util-chunked@npm:2.0.0" @@ -8382,17 +8141,6 @@ __metadata: languageName: node linkType: hard -"micromark-util-classify-character@npm:^1.0.0": - version: 1.0.0 - resolution: "micromark-util-classify-character@npm:1.0.0" - dependencies: - micromark-util-character: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - checksum: 180446e6a1dec653f625ded028f244784e1db8d10ad05c5d70f08af9de393b4a03dc6cf6fa5ed8ccc9c24bbece7837abf3bf66681c0b4adf159364b7d5236dfd - languageName: node - linkType: hard - "micromark-util-classify-character@npm:^2.0.0": version: 2.0.0 resolution: "micromark-util-classify-character@npm:2.0.0" @@ -8404,16 +8152,6 @@ __metadata: languageName: node linkType: hard -"micromark-util-combine-extensions@npm:^1.0.0": - version: 1.0.0 - resolution: "micromark-util-combine-extensions@npm:1.0.0" - dependencies: - micromark-util-chunked: ^1.0.0 - micromark-util-types: ^1.0.0 - checksum: 5304a820ef75340e1be69d6ad167055b6ba9a3bafe8171e5945a935752f462415a9dd61eb3490220c055a8a11167209a45bfa73f278338b7d3d61fa1464d3f35 - languageName: node - linkType: hard - "micromark-util-combine-extensions@npm:^2.0.0": version: 2.0.0 resolution: "micromark-util-combine-extensions@npm:2.0.0" @@ -8424,15 +8162,6 @@ __metadata: languageName: node linkType: hard -"micromark-util-decode-numeric-character-reference@npm:^1.0.0": - version: 1.0.0 - resolution: "micromark-util-decode-numeric-character-reference@npm:1.0.0" - dependencies: - micromark-util-symbol: ^1.0.0 - checksum: f3ae2bb582a80f1e9d3face026f585c0c472335c064bd850bde152376f0394cb2831746749b6be6e0160f7d73626f67d10716026c04c87f402c0dd45a1a28633 - languageName: node - linkType: hard - "micromark-util-decode-numeric-character-reference@npm:^2.0.0": version: 2.0.0 resolution: "micromark-util-decode-numeric-character-reference@npm:2.0.0" @@ -8442,18 +8171,6 @@ __metadata: languageName: node linkType: hard -"micromark-util-decode-string@npm:^1.0.0": - version: 1.0.2 - resolution: "micromark-util-decode-string@npm:1.0.2" - dependencies: - decode-named-character-reference: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-decode-numeric-character-reference: ^1.0.0 - micromark-util-symbol: ^1.0.0 - checksum: 2dbb41c9691cc71505d39706405139fb7d6699429d577a524c7c248ac0cfd09d3dd212ad8e91c143a00b2896f26f81136edc67c5bda32d20446f0834d261b17a - languageName: node - linkType: hard - "micromark-util-decode-string@npm:^2.0.0": version: 2.0.0 resolution: "micromark-util-decode-string@npm:2.0.0" @@ -8466,13 +8183,6 @@ __metadata: languageName: node linkType: hard -"micromark-util-encode@npm:^1.0.0": - version: 1.0.1 - resolution: "micromark-util-encode@npm:1.0.1" - checksum: 9290583abfdc79ea3e7eb92c012c47a0e14327888f8aaa6f57ff79b3058d8e7743716b9d91abca3646f15ab3d78fdad9779fdb4ccf13349cd53309dfc845253a - languageName: node - linkType: hard - "micromark-util-encode@npm:^2.0.0": version: 2.0.0 resolution: "micromark-util-encode@npm:2.0.0" @@ -8480,25 +8190,19 @@ __metadata: languageName: node linkType: hard -"micromark-util-events-to-acorn@npm:^1.0.0": - version: 1.2.1 - resolution: "micromark-util-events-to-acorn@npm:1.2.1" +"micromark-util-events-to-acorn@npm:^2.0.0": + version: 2.0.2 + resolution: "micromark-util-events-to-acorn@npm:2.0.2" dependencies: "@types/acorn": ^4.0.0 "@types/estree": ^1.0.0 - estree-util-visit: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - vfile-location: ^4.0.0 - vfile-message: ^3.0.0 - checksum: baf1cad66d860980cf20963f641c48c434e5be5802beabefdda21be136ae037845dd236b5e9ce5cf9409bf1b9ba8b4131a396d3a5bfa12098dae13e4a9724f2b - languageName: node - linkType: hard - -"micromark-util-html-tag-name@npm:^1.0.0": - version: 1.1.0 - resolution: "micromark-util-html-tag-name@npm:1.1.0" - checksum: a9b783cec89ec813648d59799464c1950fe281ae797b2a965f98ad0167d7fa1a247718eff023b4c015f47211a172f9446b8e6b98aad50e3cd44a3337317dad2c + "@types/unist": ^3.0.0 + devlop: ^1.0.0 + estree-util-visit: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + vfile-message: ^4.0.0 + checksum: bcb3eeac52a4ae5c3ca3d8cff514de3a7d1f272d9a94cce26a08c578bef64df4d61820874c01207e92fcace9eae5c9a7ecdddef0c6e10014b255a07b7880bf94 languageName: node linkType: hard @@ -8509,15 +8213,6 @@ __metadata: languageName: node linkType: hard -"micromark-util-normalize-identifier@npm:^1.0.0": - version: 1.0.0 - resolution: "micromark-util-normalize-identifier@npm:1.0.0" - dependencies: - micromark-util-symbol: ^1.0.0 - checksum: d7c09d5e8318fb72f194af72664bd84a48a2928e3550b2b21c8fbc0ec22524f2a72e0f6663d2b95dc189a6957d3d7759b60716e888909710767cd557be821f8b - languageName: node - linkType: hard - "micromark-util-normalize-identifier@npm:^2.0.0": version: 2.0.0 resolution: "micromark-util-normalize-identifier@npm:2.0.0" @@ -8527,15 +8222,6 @@ __metadata: languageName: node linkType: hard -"micromark-util-resolve-all@npm:^1.0.0": - version: 1.0.0 - resolution: "micromark-util-resolve-all@npm:1.0.0" - dependencies: - micromark-util-types: ^1.0.0 - checksum: 409667f2bd126ef8acce009270d2aecaaa5584c5807672bc657b09e50aa91bd2e552cf41e5be1e6469244a83349cbb71daf6059b746b1c44e3f35446fef63e50 - languageName: node - linkType: hard - "micromark-util-resolve-all@npm:^2.0.0": version: 2.0.0 resolution: "micromark-util-resolve-all@npm:2.0.0" @@ -8545,17 +8231,6 @@ __metadata: languageName: node linkType: hard -"micromark-util-sanitize-uri@npm:^1.0.0, micromark-util-sanitize-uri@npm:^1.1.0": - version: 1.1.0 - resolution: "micromark-util-sanitize-uri@npm:1.1.0" - dependencies: - micromark-util-character: ^1.0.0 - micromark-util-encode: ^1.0.0 - micromark-util-symbol: ^1.0.0 - checksum: fe6093faa0adeb8fad606184d927ce37f207dcc2ec7256438e7f273c8829686245dd6161b597913ef25a3c4fb61863d3612a40cb04cf15f83ba1b4087099996b - languageName: node - linkType: hard - "micromark-util-sanitize-uri@npm:^2.0.0": version: 2.0.0 resolution: "micromark-util-sanitize-uri@npm:2.0.0" @@ -8567,18 +8242,6 @@ __metadata: languageName: node linkType: hard -"micromark-util-subtokenize@npm:^1.0.0": - version: 1.0.2 - resolution: "micromark-util-subtokenize@npm:1.0.2" - dependencies: - micromark-util-chunked: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.0 - uvu: ^0.5.0 - checksum: c32ee58a7e1384ab1161a9ee02fbb04ad7b6e96d0b8c93dba9803c329a53d07f22ab394c7a96b2e30d6b8fbe3585b85817dba07277b1317111fc234e166bd2d1 - languageName: node - linkType: hard - "micromark-util-subtokenize@npm:^2.0.0": version: 2.0.0 resolution: "micromark-util-subtokenize@npm:2.0.0" @@ -8605,7 +8268,7 @@ __metadata: languageName: node linkType: hard -"micromark-util-types@npm:^1.0.0, micromark-util-types@npm:^1.0.1": +"micromark-util-types@npm:^1.0.0": version: 1.0.2 resolution: "micromark-util-types@npm:1.0.2" checksum: 08dc901b7c06ee3dfeb54befca05cbdab9525c1cf1c1080967c3878c9e72cb9856c7e8ff6112816e18ead36ce6f99d55aaa91560768f2f6417b415dcba1244df @@ -8619,31 +8282,6 @@ __metadata: languageName: node linkType: hard -"micromark@npm:^3.0.0": - version: 3.1.0 - resolution: "micromark@npm:3.1.0" - dependencies: - "@types/debug": ^4.0.0 - debug: ^4.0.0 - decode-named-character-reference: ^1.0.0 - micromark-core-commonmark: ^1.0.1 - micromark-factory-space: ^1.0.0 - micromark-util-character: ^1.0.0 - micromark-util-chunked: ^1.0.0 - micromark-util-combine-extensions: ^1.0.0 - micromark-util-decode-numeric-character-reference: ^1.0.0 - micromark-util-encode: ^1.0.0 - micromark-util-normalize-identifier: ^1.0.0 - micromark-util-resolve-all: ^1.0.0 - micromark-util-sanitize-uri: ^1.0.0 - micromark-util-subtokenize: ^1.0.0 - micromark-util-symbol: ^1.0.0 - micromark-util-types: ^1.0.1 - uvu: ^0.5.0 - checksum: 5fe5bc3bf92e2ddd37b5f0034080fc3a4d4b3c1130dd5e435bb96ec75e9453091272852e71a4d74906a8fcf992d6f79d794607657c534bda49941e9950a92e28 - languageName: node - linkType: hard - "micromark@npm:^4.0.0": version: 4.0.0 resolution: "micromark@npm:4.0.0" @@ -8702,7 +8340,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, 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": +"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: @@ -8777,7 +8415,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.7": +"minimist@npm:^1.2.0": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -8872,13 +8510,6 @@ __metadata: languageName: node linkType: hard -"mri@npm:^1.1.0": - version: 1.2.0 - resolution: "mri@npm:1.2.0" - checksum: 83f515abbcff60150873e424894a2f65d68037e5a7fcde8a9e2b285ee9c13ac581b63cfc1e6826c4732de3aeb84902f7c1e16b7aff46cd3f897a0f757a894e85 - languageName: node - linkType: hard - "mrmime@npm:^1.0.0": version: 1.0.1 resolution: "mrmime@npm:1.0.1" @@ -8952,26 +8583,15 @@ __metadata: languageName: node linkType: hard -"node-emoji@npm:^1.10.0": - version: 1.11.0 - resolution: "node-emoji@npm:1.11.0" +"node-emoji@npm:^2.1.0": + version: 2.1.3 + resolution: "node-emoji@npm:2.1.3" 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 + "@sindresorhus/is": ^4.6.0 + char-regex: ^1.0.2 + emojilib: ^2.4.0 + skin-tone: ^2.0.0 + checksum: 9ae5a1fb12fd5ce6885f251f345986115de4bb82e7d06fdc943845fb19260d89d0aaaccbaf85cae39fe7aaa1fc391640558865ba690c9bb8a7236c3ac10bbab0 languageName: node linkType: hard @@ -9002,10 +8622,10 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.13": - version: 2.0.13 - resolution: "node-releases@npm:2.0.13" - checksum: 17ec8f315dba62710cae71a8dad3cd0288ba943d2ece43504b3b1aa8625bf138637798ab470b1d9035b0545996f63000a8a926e0f6d35d0996424f8b6d36dda3 +"node-releases@npm:^2.0.14": + version: 2.0.14 + resolution: "node-releases@npm:2.0.14" + checksum: 59443a2f77acac854c42d321bf1b43dea0aef55cd544c6a686e9816a697300458d4e82239e2d794ea05f7bbbc8a94500332e2d3ac3f11f52e4b16cbe638b3c41 languageName: node linkType: hard @@ -9085,7 +8705,7 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": +"object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f @@ -9342,13 +8962,6 @@ __metadata: 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" @@ -9977,15 +9590,15 @@ __metadata: languageName: node linkType: hard -"prism-react-renderer@npm:^2.1.0": - version: 2.1.0 - resolution: "prism-react-renderer@npm:2.1.0" +"prism-react-renderer@npm:^2.3.0": + version: 2.3.1 + resolution: "prism-react-renderer@npm:2.3.1" dependencies: "@types/prismjs": ^1.26.0 - clsx: ^1.2.1 + clsx: ^2.0.0 peerDependencies: react: ">=16.0.0" - checksum: 61b4eb22bdbf01005a0d7ec2a24a27b69e28f124a1fbbfc2adb4d7d41a7929ea94d5ce506a361dd5a230728402f02595d521d9a5286d74ec9b34be0896c513a5 + checksum: b12a7d502c1e764d94f7d3c84aee9cd6fccc676bb7e21dee94d37eb2e7e62e097a343999e1979887cb83a57cbdea48d2046aa74d07bce05caa25f4c296df30b6 languageName: node linkType: hard @@ -10020,15 +9633,6 @@ __metadata: 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" @@ -10097,13 +9701,6 @@ __metadata: 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" @@ -10185,18 +9782,6 @@ __metadata: 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" @@ -10278,10 +9863,12 @@ __metadata: 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 +"react-json-view-lite@npm:^1.2.0": + version: 1.2.1 + resolution: "react-json-view-lite@npm:1.2.1" + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + checksum: 9441260033ec07991b0121281d846f9d3e8db9061ea0dc3938f7003630f515d47870a465d90f1f9300ebe406679986657a4062c009c2a2084e2e145e6fa05a47 languageName: node linkType: hard @@ -10345,19 +9932,6 @@ __metadata: languageName: node linkType: hard -"react-textarea-autosize@npm:~8.3.2": - version: 8.3.4 - resolution: "react-textarea-autosize@npm:8.3.4" - 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: 87360d4392276d4e87511a73be9b0634b8bcce8f4f648cf659334d993f25ad3d4062f468f1e1944fc614123acae4299580aad00b760c6a96cec190e076f847f5 - languageName: node - linkType: hard - "react@npm:^18.0.0": version: 18.2.0 resolution: "react@npm:18.2.0" @@ -10502,14 +10076,14 @@ __metadata: languageName: node linkType: hard -"rehype-raw@npm:^6.1.1": - version: 6.1.1 - resolution: "rehype-raw@npm:6.1.1" +"rehype-raw@npm:^7.0.0": + version: 7.0.0 + resolution: "rehype-raw@npm:7.0.0" dependencies: - "@types/hast": ^2.0.0 - hast-util-raw: ^7.2.0 - unified: ^10.0.0 - checksum: a1f9d309e609f49fb1f1e06e722705f4dd2e569653a89f756eaccb33b612cf1bb511216a81d10a619d11d047afc161e4b3cb99b957df05a8ba8fdbd5843f949a + "@types/hast": ^3.0.0 + hast-util-raw: ^9.0.0 + vfile: ^6.0.0 + checksum: f9e28dcbf4c6c7d91a97c10a840310f18ef3268aa45abb3e0428b6b191ff3c4fa8f753b910d768588a2dac5c7da7e557b4ddc3f1b6cd252e8d20cb62d60c65ed languageName: node linkType: hard @@ -10520,26 +10094,28 @@ __metadata: languageName: node linkType: hard -"remark-directive@npm:^2.0.1": - version: 2.0.1 - resolution: "remark-directive@npm:2.0.1" +"remark-directive@npm:^3.0.0": + version: 3.0.0 + resolution: "remark-directive@npm:3.0.0" dependencies: - "@types/mdast": ^3.0.0 - mdast-util-directive: ^2.0.0 - micromark-extension-directive: ^2.0.0 - unified: ^10.0.0 - checksum: 61539926813654011431cc34e3d6c5ba702a6b610a0e8210b4748828809e86614bbb3e2de5fdee59eed24501f95c41665b175b852cc26544079789db10ac6cd7 + "@types/mdast": ^4.0.0 + mdast-util-directive: ^3.0.0 + micromark-extension-directive: ^3.0.0 + unified: ^11.0.0 + checksum: 744d12bbe924bd0492a2481cbaf9250aa6622c0d2cc090bb7bc39975e355c8a46ae13cc4793204ada39f0af64c953f6b730a55420a50375e0f74a5dd5d201089 languageName: node linkType: hard -"remark-emoji@npm:^2.2.0": - version: 2.2.0 - resolution: "remark-emoji@npm:2.2.0" +"remark-emoji@npm:^4.0.0": + version: 4.0.1 + resolution: "remark-emoji@npm:4.0.1" dependencies: - emoticon: ^3.2.0 - node-emoji: ^1.10.0 - unist-util-visit: ^2.0.3 - checksum: 638d4be72eb4110a447f389d4b8c454921f188c0acabf1b6579f3ddaa301ee91010173d6eebd975ea622ae3de7ed4531c0315a4ffd4f9653d80c599ef9ec21a8 + "@types/mdast": ^4.0.2 + emoticon: ^4.0.1 + mdast-util-find-and-replace: ^3.0.1 + node-emoji: ^2.1.0 + unified: ^11.0.4 + checksum: 2c02d8c0b694535a9f0c4fe39180cb89a8fbd07eb873c94842c34dfde566b8a6703df9d28fe175a8c28584f96252121de722862baa756f2d875f2f1a4352c1f4 languageName: node linkType: hard @@ -10555,48 +10131,63 @@ __metadata: languageName: node linkType: hard -"remark-gfm@npm:^3.0.1": - version: 3.0.1 - resolution: "remark-gfm@npm:3.0.1" +"remark-gfm@npm:^4.0.0": + version: 4.0.0 + resolution: "remark-gfm@npm:4.0.0" dependencies: - "@types/mdast": ^3.0.0 - mdast-util-gfm: ^2.0.0 - micromark-extension-gfm: ^2.0.0 - unified: ^10.0.0 - checksum: 02254f74d67b3419c2c9cf62d799ec35f6c6cd74db25c001361751991552a7ce86049a972107bff8122d85d15ae4a8d1a0618f3bc01a7df837af021ae9b2a04e + "@types/mdast": ^4.0.0 + mdast-util-gfm: ^3.0.0 + micromark-extension-gfm: ^3.0.0 + remark-parse: ^11.0.0 + remark-stringify: ^11.0.0 + unified: ^11.0.0 + checksum: 84bea84e388061fbbb697b4b666089f5c328aa04d19dc544c229b607446bc10902e46b67b9594415a1017bbbd7c811c1f0c30d36682c6d1a6718b66a1558261b languageName: node linkType: hard -"remark-mdx@npm:^2.0.0": - version: 2.3.0 - resolution: "remark-mdx@npm:2.3.0" +"remark-mdx@npm:^3.0.0": + version: 3.0.0 + resolution: "remark-mdx@npm:3.0.0" dependencies: - mdast-util-mdx: ^2.0.0 - micromark-extension-mdxjs: ^1.0.0 - checksum: 98486986c5b6f6a8321eb2f3b13c70fcd5644821428c77b7bfeb5ee5d4605b9761b322b2f6b531e83883cd2d5bc7bc4623427149aee00e1eba012f538b3d5627 + mdast-util-mdx: ^3.0.0 + micromark-extension-mdxjs: ^3.0.0 + checksum: 8b9b3e5297e5cb4c312553f42c3720280ada96ae60ede880606924a0aad2e773106aba1ef45a0c179c218f8da6f58dac3c789a9c4f791649ca7a183706cde5b8 languageName: node linkType: hard -"remark-parse@npm:^10.0.0": - version: 10.0.1 - resolution: "remark-parse@npm:10.0.1" +"remark-parse@npm:^11.0.0": + version: 11.0.0 + resolution: "remark-parse@npm:11.0.0" dependencies: - "@types/mdast": ^3.0.0 - mdast-util-from-markdown: ^1.0.0 - unified: ^10.0.0 - checksum: 505088e564ab53ff054433368adbb7b551f69240c7d9768975529837a86f1d0f085e72d6211929c5c42db315273df4afc94f3d3a8662ffdb69468534c6643d29 + "@types/mdast": ^4.0.0 + mdast-util-from-markdown: ^2.0.0 + micromark-util-types: ^2.0.0 + unified: ^11.0.0 + checksum: d83d245290fa84bb04fb3e78111f09c74f7417e7c012a64dd8dc04fccc3699036d828fbd8eeec8944f774b6c30cc1d925c98f8c46495ebcee7c595496342ab7f languageName: node linkType: hard -"remark-rehype@npm:^10.0.0": - version: 10.1.0 - resolution: "remark-rehype@npm:10.1.0" +"remark-rehype@npm:^11.0.0": + version: 11.1.0 + resolution: "remark-rehype@npm:11.1.0" dependencies: - "@types/hast": ^2.0.0 - "@types/mdast": ^3.0.0 - mdast-util-to-hast: ^12.1.0 - unified: ^10.0.0 - checksum: b9ac8acff3383b204dfdc2599d0bdf86e6ca7e837033209584af2e6aaa6a9013e519a379afa3201299798cab7298c8f4b388de118c312c67234c133318aec084 + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + mdast-util-to-hast: ^13.0.0 + unified: ^11.0.0 + vfile: ^6.0.0 + checksum: f0c731f0ab92a122e7f9c9bcbd10d6a31fdb99f0ea3595d232ddd9f9d11a308c4ec0aff4d56e1d0d256042dfad7df23b9941e50b5038da29786959a5926814e1 + languageName: node + linkType: hard + +"remark-stringify@npm:^11.0.0": + version: 11.0.0 + resolution: "remark-stringify@npm:11.0.0" + dependencies: + "@types/mdast": ^4.0.0 + mdast-util-to-markdown: ^2.0.0 + unified: ^11.0.0 + checksum: 59e07460eb629d6c3b3c0f438b0b236e7e6858fd5ab770303078f5a556ec00354d9c7fb9ef6d5f745a4617ac7da1ab618b170fbb4dac120e183fecd9cc86bce6 languageName: node linkType: hard @@ -10752,24 +10343,6 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.8.0": - version: 7.8.1 - resolution: "rxjs@npm:7.8.1" - dependencies: - tslib: ^2.1.0 - checksum: de4b53db1063e618ec2eca0f7965d9137cabe98cf6be9272efe6c86b47c17b987383df8574861bcced18ebd590764125a901d5506082be84a8b8e364bf05f119 - languageName: node - linkType: hard - -"sade@npm:^1.7.3": - version: 1.8.1 - resolution: "sade@npm:1.8.1" - dependencies: - mri: ^1.1.0 - checksum: 0756e5b04c51ccdc8221ebffd1548d0ce5a783a44a0fa9017a026659b97d632913e78f7dca59f2496aa996a0be0b0c322afd87ca72ccd909406f49dbffa0f45d - 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" @@ -10817,15 +10390,15 @@ __metadata: linkType: hard "sass@npm:^1.57.1": - version: 1.69.7 - resolution: "sass@npm:1.69.7" + version: 1.70.0 + resolution: "sass@npm:1.70.0" dependencies: chokidar: ">=3.0.0 <4.0.0" immutable: ^4.0.0 source-map-js: ">=0.6.2 <2.0.0" bin: sass: sass.js - checksum: c67cd32b69fb26a50e4535353e4145de8cbc8187db07c467cc335157fd56d03cae98754f86efe43b880b29f20c0a168ab972c7f74ebfe234e2bd2dfb868890cb + checksum: fd1b622cf9b7fa699a03ec634611997552ece45eb98ac365fef22f42bdcb8ed63b326b64173379c966830c8551ae801e44e4a00d2de16fdadda2dc8f35400bbb languageName: node linkType: hard @@ -11014,13 +10587,6 @@ __metadata: 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" @@ -11137,6 +10703,15 @@ __metadata: languageName: node linkType: hard +"skin-tone@npm:^2.0.0": + version: 2.0.0 + resolution: "skin-tone@npm:2.0.0" + dependencies: + unicode-emoji-modifier-base: ^1.0.0 + checksum: 19de157586b8019cacc55eb25d9d640f00fc02415761f3e41a4527142970fd4e7f6af0333bc90e879858766c20a976107bb386ffd4c812289c01d51f2c8d182c + languageName: node + linkType: hard + "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0" @@ -11420,12 +10995,21 @@ __metadata: languageName: node linkType: hard -"style-to-object@npm:^0.4.1": - version: 0.4.1 - resolution: "style-to-object@npm:0.4.1" +"style-to-object@npm:^0.4.0": + version: 0.4.4 + resolution: "style-to-object@npm:0.4.4" dependencies: inline-style-parser: 0.1.1 - checksum: 2ea213e98eed21764ae1d1dc9359231a9f2d480d6ba55344c4c15eb275f0809f1845786e66d4caf62414a5cc8f112ce9425a58d251c77224060373e0db48f8c2 + checksum: 41656c06f93ac0a7ac260ebc2f9d09a8bd74b8ec1836f358cc58e169235835a3a356977891d2ebbd76f0e08a53616929069199f9cce543214d3dc98346e19c9a + languageName: node + linkType: hard + +"style-to-object@npm:^1.0.0": + version: 1.0.5 + resolution: "style-to-object@npm:1.0.5" + dependencies: + inline-style-parser: 0.2.2 + checksum: 6201063204b6a94645f81b189452b2ca3e63d61867ec48523f4d52609c81e96176739fa12020d97fbbf023efb57a6f7ec3a15fb3a7fb7eb3ffea0b52b9dd6b8c languageName: node linkType: hard @@ -11631,13 +11215,6 @@ __metadata: 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-lines@npm:^3.0.0": version: 3.0.1 resolution: "trim-lines@npm:3.0.1" @@ -11652,7 +11229,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.6.0": +"tslib@npm:^2.0.3, tslib@npm:^2.6.0": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad @@ -11712,13 +11289,6 @@ __metadata: languageName: node linkType: hard -"ua-parser-js@npm:^0.7.30": - version: 0.7.33 - resolution: "ua-parser-js@npm:0.7.33" - checksum: 1510e9ec26fcaf0d8c6ae8f1078a8230e8816f083e1b5f453ea19d06b8ef2b8a596601c92148fd41899e8b3e5f83fa69c42332bd5729b931a721040339831696 - 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" @@ -11726,6 +11296,13 @@ __metadata: languageName: node linkType: hard +"unicode-emoji-modifier-base@npm:^1.0.0": + version: 1.0.0 + resolution: "unicode-emoji-modifier-base@npm:1.0.0" + checksum: 6e1521d35fa69493207eb8b41f8edb95985d8b3faf07c01d820a1830b5e8403e20002563e2f84683e8e962a49beccae789f0879356bf92a4ec7a4dd8e2d16fdb + 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" @@ -11750,24 +11327,9 @@ __metadata: languageName: node linkType: hard -"unified@npm:^10.0.0, unified@npm:^10.1.2": - version: 10.1.2 - resolution: "unified@npm:10.1.2" - dependencies: - "@types/unist": ^2.0.0 - bail: ^2.0.0 - extend: ^3.0.0 - is-buffer: ^2.0.0 - is-plain-obj: ^4.0.0 - trough: ^2.0.0 - vfile: ^5.0.0 - checksum: 053e7c65ede644607f87bd625a299e4b709869d2f76ec8138569e6e886903b6988b21cd9699e471eda42bee189527be0a9dac05936f1d069a5e65d0125d5d756 - languageName: node - linkType: hard - -"unified@npm:^11.0.0": - version: 11.0.3 - resolution: "unified@npm:11.0.3" +"unified@npm:^11.0.0, unified@npm:^11.0.3, unified@npm:^11.0.4": + version: 11.0.4 + resolution: "unified@npm:11.0.4" dependencies: "@types/unist": ^3.0.0 bail: ^2.0.0 @@ -11776,7 +11338,7 @@ __metadata: is-plain-obj: ^4.0.0 trough: ^2.0.0 vfile: ^6.0.0 - checksum: 402d6b397b98f8966993faca0e1480f5f1825cc44df6a5236b75ab099f14b10ed808e578155c3f535e60676c12ee3f52346ca08d64343a72181d7a6b4d32011d + checksum: cfb023913480ac2bd5e787ffb8c27782c43e6be4a55f8f1c288233fce46a7ebe7718ccc5adb80bf8d56b7ef85f5fc32239c7bfccda006f9f2382e0cc2e2a77e4 languageName: node linkType: hard @@ -11807,29 +11369,6 @@ __metadata: languageName: node linkType: hard -"unist-util-generated@npm:^2.0.0": - version: 2.0.1 - resolution: "unist-util-generated@npm:2.0.1" - checksum: 6221ad0571dcc9c8964d6b054f39ef6571ed59cc0ce3e88ae97ea1c70afe76b46412a5ffaa91f96814644ac8477e23fb1b477d71f8d70e625728c5258f5c0d99 - 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-is@npm:^5.0.0": - version: 5.2.1 - resolution: "unist-util-is@npm:5.2.1" - dependencies: - "@types/unist": ^2.0.0 - checksum: ae76fdc3d35352cd92f1bedc3a0d407c3b9c42599a52ab9141fe89bdd786b51f0ec5a2ab68b93fb532e239457cae62f7e39eaa80229e1cb94875da2eafcbe5c4 - languageName: node - linkType: hard - "unist-util-is@npm:^6.0.0": version: 6.0.0 resolution: "unist-util-is@npm:6.0.0" @@ -11839,40 +11378,31 @@ __metadata: languageName: node linkType: hard -"unist-util-position-from-estree@npm:^1.0.0, unist-util-position-from-estree@npm:^1.1.0": - version: 1.1.2 - resolution: "unist-util-position-from-estree@npm:1.1.2" +"unist-util-position-from-estree@npm:^2.0.0": + version: 2.0.0 + resolution: "unist-util-position-from-estree@npm:2.0.0" dependencies: - "@types/unist": ^2.0.0 - checksum: e3f4060e2a9e894c6ed63489c5a7cb58ff282e5dae9497cbc2073033ca74d6e412af4d4d342c97aea08d997c908b8bce2fe43a2062aafc2bb3f266533016588b + "@types/unist": ^3.0.0 + checksum: d3b3048a5727c2367f64ef6dcc5b20c4717215ef8b1372ff9a7c426297c5d1e5776409938acd01531213e2cd2543218d16e73f9f862f318e9496e2c73bb18354 languageName: node linkType: hard -"unist-util-position@npm:^4.0.0": - version: 4.0.4 - resolution: "unist-util-position@npm:4.0.4" +"unist-util-position@npm:^5.0.0": + version: 5.0.0 + resolution: "unist-util-position@npm:5.0.0" dependencies: - "@types/unist": ^2.0.0 - checksum: e7487b6cec9365299695e3379ded270a1717074fa11fd2407c9b934fb08db6fe1d9077ddeaf877ecf1813665f8ccded5171693d3d9a7a01a125ec5cdd5e88691 + "@types/unist": ^3.0.0 + checksum: f89b27989b19f07878de9579cd8db2aa0194c8360db69e2c99bd2124a480d79c08f04b73a64daf01a8fb3af7cba65ff4b45a0b978ca243226084ad5f5d441dde languageName: node linkType: hard -"unist-util-remove-position@npm:^4.0.0": - version: 4.0.2 - resolution: "unist-util-remove-position@npm:4.0.2" +"unist-util-remove-position@npm:^5.0.0": + version: 5.0.0 + resolution: "unist-util-remove-position@npm:5.0.0" dependencies: - "@types/unist": ^2.0.0 - unist-util-visit: ^4.0.0 - checksum: 989831da913d09a82a99ed9b47b78471b6409bde95942cde47e09da54b7736516f17e3c7e026af468684c1efcec5fb52df363381b2f9dc7fd96ce791c5a2fa4a - languageName: node - linkType: hard - -"unist-util-stringify-position@npm:^3.0.0": - version: 3.0.3 - resolution: "unist-util-stringify-position@npm:3.0.3" - dependencies: - "@types/unist": ^2.0.0 - checksum: dbd66c15183607ca942a2b1b7a9f6a5996f91c0d30cf8966fb88955a02349d9eefd3974e9010ee67e71175d784c5a9fea915b0aa0b0df99dcb921b95c4c9e124 + "@types/unist": ^3.0.0 + unist-util-visit: ^5.0.0 + checksum: 8aabdb9d0e3e744141bc123d8f87b90835d521209ad3c6c4619d403b324537152f0b8f20dda839b40c3aa0abfbf1828b3635a7a8bb159c3ed469e743023510ee languageName: node linkType: hard @@ -11885,26 +11415,6 @@ __metadata: 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-parents@npm:^5.0.0, unist-util-visit-parents@npm:^5.1.1, unist-util-visit-parents@npm:^5.1.3": - version: 5.1.3 - resolution: "unist-util-visit-parents@npm:5.1.3" - dependencies: - "@types/unist": ^2.0.0 - unist-util-is: ^5.0.0 - checksum: 8ecada5978994f846b64658cf13b4092cd78dea39e1ba2f5090a5de842ba4852712c02351a8ae95250c64f864635e7b02aedf3b4a093552bb30cf1bd160efbaa - languageName: node - linkType: hard - "unist-util-visit-parents@npm:^6.0.0": version: 6.0.1 resolution: "unist-util-visit-parents@npm:6.0.1" @@ -11915,28 +11425,6 @@ __metadata: languageName: node linkType: hard -"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 - -"unist-util-visit@npm:^4.0.0": - version: 4.1.2 - resolution: "unist-util-visit@npm:4.1.2" - dependencies: - "@types/unist": ^2.0.0 - unist-util-is: ^5.0.0 - unist-util-visit-parents: ^5.1.1 - checksum: 95a34e3f7b5b2d4b68fd722b6229972099eb97b6df18913eda44a5c11df8b1e27efe7206dd7b88c4ed244a48c474a5b2e2629ab79558ff9eb936840295549cee - languageName: node - linkType: hard - "unist-util-visit@npm:^5.0.0": version: 5.0.0 resolution: "unist-util-visit@npm:5.0.0" @@ -12024,41 +11512,6 @@ __metadata: 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" @@ -12096,20 +11549,6 @@ __metadata: languageName: node linkType: hard -"uvu@npm:^0.5.0": - version: 0.5.6 - resolution: "uvu@npm:0.5.6" - dependencies: - dequal: ^2.0.0 - diff: ^5.0.0 - kleur: ^4.0.3 - sade: ^1.7.3 - bin: - uvu: bin.js - checksum: 09460a37975627de9fcad396e5078fb844d01aaf64a6399ebfcfd9e55f1c2037539b47611e8631f89be07656962af0cf48c334993db82b9ae9c3d25ce3862168 - languageName: node - linkType: hard - "value-equal@npm:^1.0.1": version: 1.0.1 resolution: "value-equal@npm:1.0.1" @@ -12124,23 +11563,13 @@ __metadata: languageName: node linkType: hard -"vfile-location@npm:^4.0.0": - version: 4.1.0 - resolution: "vfile-location@npm:4.1.0" +"vfile-location@npm:^5.0.0": + version: 5.0.2 + resolution: "vfile-location@npm:5.0.2" dependencies: - "@types/unist": ^2.0.0 - vfile: ^5.0.0 - checksum: c894e8e5224170d1f85288f4a1d1ebcee0780823ea2b49d881648ab360ebf01b37ecb09b1c4439a75f9a51f31a9f9742cd045e987763e367c352a1ef7c50d446 - languageName: node - linkType: hard - -"vfile-message@npm:^3.0.0": - version: 3.1.4 - resolution: "vfile-message@npm:3.1.4" - dependencies: - "@types/unist": ^2.0.0 - unist-util-stringify-position: ^3.0.0 - checksum: d0ee7da1973ad76513c274e7912adbed4d08d180eaa34e6bd40bc82459f4b7bc50fcaff41556135e3339995575eac5f6f709aba9332b80f775618ea4880a1367 + "@types/unist": ^3.0.0 + vfile: ^6.0.0 + checksum: b61c048cedad3555b4f007f390412c6503f58a6a130b58badf4ee340c87e0d7421e9c86bbc1494c57dedfccadb60f5176cc60ba3098209d99fb3a3d8804e4c38 languageName: node linkType: hard @@ -12154,19 +11583,7 @@ __metadata: languageName: node linkType: hard -"vfile@npm:^5.0.0, vfile@npm:^5.3.7": - version: 5.3.7 - resolution: "vfile@npm:5.3.7" - dependencies: - "@types/unist": ^2.0.0 - is-buffer: ^2.0.0 - unist-util-stringify-position: ^3.0.0 - vfile-message: ^3.0.0 - checksum: 642cce703afc186dbe7cabf698dc954c70146e853491086f5da39e1ce850676fc96b169fcf7898aa3ff245e9313aeec40da93acd1e1fcc0c146dc4f6308b4ef9 - languageName: node - linkType: hard - -"vfile@npm:^6.0.0": +"vfile@npm:^6.0.0, vfile@npm:^6.0.1": version: 6.0.1 resolution: "vfile@npm:6.0.1" dependencies: @@ -12177,21 +11594,6 @@ __metadata: languageName: node linkType: hard -"wait-on@npm:^7.0.1": - version: 7.0.1 - resolution: "wait-on@npm:7.0.1" - dependencies: - axios: ^0.27.2 - joi: ^17.7.0 - lodash: ^4.17.21 - minimist: ^1.2.7 - rxjs: ^7.8.0 - bin: - wait-on: bin/wait-on - checksum: 1e8a17d8ee6436f71d3ab82781ce31267481fcd7bbccde49b0f8124871e6e40a1acac3401f04f775ba6203853a5813352fa131620fc139914351f3b2894d573f - languageName: node - linkType: hard - "watchpack@npm:^2.4.0": version: 2.4.0 resolution: "watchpack@npm:2.4.0" @@ -12218,13 +11620,6 @@ __metadata: 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.9.0": version: 4.9.1 resolution: "webpack-bundle-analyzer@npm:4.9.1" @@ -12400,16 +11795,6 @@ __metadata: 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" diff --git a/mkdocs.yml b/mkdocs.yml index bf4024759b..8c9f84ba81 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -214,4 +214,7 @@ nav: - ADR011 - Plugin Package Structure: 'architecture-decisions/adr011-plugin-package-structure.md' - ADR012 - Plugin Package Structure: 'architecture-decisions/adr012-use-luxon-locale-and-date-presets.md' - ADR013 - Plugin Package Structure: 'architecture-decisions/adr013-use-node-fetch.md' - - FAQ: FAQ.md + - FAQ: + - Overview: 'faq/index.md' + - Product FAQ: 'faq/product.md' + - Technical FAQ: 'faq/technical.md' diff --git a/packages/app-defaults/src/defaults/icons.tsx b/packages/app-defaults/src/defaults/icons.tsx index fbdfb14e5b..1ed5bf03c6 100644 --- a/packages/app-defaults/src/defaults/icons.tsx +++ b/packages/app-defaults/src/defaults/icons.tsx @@ -34,7 +34,7 @@ import MuiMenuBookIcon from '@material-ui/icons/MenuBook'; import MuiPeopleIcon from '@material-ui/icons/People'; import MuiPersonIcon from '@material-ui/icons/Person'; import MuiWarningIcon from '@material-ui/icons/Warning'; -import MuiWorkIcon from '@material-ui/icons/Work'; +import MuiStorageIcon from '@material-ui/icons/Storage'; import MuiFeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList'; export const icons = { @@ -58,7 +58,7 @@ export const icons = { 'kind:location': MuiLocationOnIcon as IconComponent, 'kind:system': MuiCategoryIcon as IconComponent, 'kind:user': MuiPersonIcon as IconComponent, - 'kind:resource': MuiWorkIcon as IconComponent, + 'kind:resource': MuiStorageIcon as IconComponent, 'kind:template': MuiFeaturedPlayListIcon as IconComponent, user: MuiPersonIcon as IconComponent, warning: MuiWarningIcon as IconComponent, diff --git a/packages/app-next/app-config.yaml b/packages/app-next/app-config.yaml index 77f4284455..9cc3507fa4 100644 --- a/packages/app-next/app-config.yaml +++ b/packages/app-next/app-config.yaml @@ -3,8 +3,9 @@ app: packages: 'all' # ✨ routes: bindings: - plugin.pages.externalRoutes.pageX: plugin.pages.routes.pageX - plugin.catalog.externalRoutes.viewTechDoc: plugin.techdocs.routes.docRoot + pages.pageX: pages.pageX + catalog.viewTechDoc: techdocs.docRoot + catalog.createComponent: catalog-import.importPage extensions: # - apis.plugin.graphiql.browse.gitlab: true diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx index ec333ce38f..03a6649c27 100644 --- a/packages/app-next/src/App.tsx +++ b/packages/app-next/src/App.tsx @@ -51,8 +51,6 @@ import { import { createSignInPageExtension } from '@backstage/frontend-plugin-api'; import { SignInPage } from '@backstage/core-components'; -import linguistPlugin from '@backstage/plugin-linguist/alpha'; - /* # Notes @@ -127,7 +125,6 @@ const app = createApp({ userSettingsPlugin, homePlugin, appVisualizerPlugin, - linguistPlugin, ...collectedLegacyPlugins, createExtensionOverrides({ extensions: [ diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index c2296d01e7..d2dde95f68 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -31,7 +31,6 @@ import { AppRouter, ConfigReader, defaultConfigLoader, - FeatureFlagged, FlatRoutes, } from '@backstage/core-app-api'; import { @@ -64,7 +63,6 @@ import { GcpProjectsPage } from '@backstage/plugin-gcp-projects'; import { HomepageCompositionRoot, VisitListener } from '@backstage/plugin-home'; import { LighthousePage } from '@backstage/plugin-lighthouse'; import { NewRelicPage } from '@backstage/plugin-newrelic'; -import { LegacyScaffolderPage } from '@backstage/plugin-scaffolder/alpha'; import { ScaffolderPage, scaffolderPlugin } from '@backstage/plugin-scaffolder'; import { ScaffolderFieldExtensions, @@ -96,10 +94,7 @@ import { apis } from './apis'; import { entityPage } from './components/catalog/EntityPage'; import { homePage } from './components/home/HomePage'; import { Root } from './components/Root'; -import { - DelayingComponentFieldExtension, - LowerCaseValuePickerFieldExtension, -} from './components/scaffolder/customScaffolderExtensions'; +import { DelayingComponentFieldExtension } from './components/scaffolder/customScaffolderExtensions'; import { defaultPreviewTemplate } from './components/scaffolder/defaultPreviewTemplate'; import { searchPage } from './components/search/SearchPage'; import { providers } from './identityProviders'; @@ -236,53 +231,28 @@ const routes = ( - - - entity?.metadata?.tags?.includes('recommended') ?? false, - }, - ]} - /> - } - > - - - - - - - - - - - entity?.metadata?.tags?.includes('recommended') ?? false, - }, - ]} - /> - } - > - - - - - - - - + + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + ]} + /> + } + > + + + + + + + } /> = Extract< // @public (undocumented) type ConvertAll> = { - [Index in keyof T]: T[Index] extends JSONSchema7 + [Index in keyof T]: T[Index] extends JSONSchema ? FromSchema : T[Index]; } & { @@ -463,7 +463,7 @@ type ParameterSchema< Schema extends ImmutableParameterObject['schema'], > = SchemaRef extends infer R ? R extends ImmutableSchemaObject - ? R extends JSONSchema7 + ? R extends JSONSchema ? FromSchema : never : never diff --git a/packages/backend-openapi-utils/src/types/common.ts b/packages/backend-openapi-utils/src/types/common.ts index f9dedf2f84..a43ad4449f 100644 --- a/packages/backend-openapi-utils/src/types/common.ts +++ b/packages/backend-openapi-utils/src/types/common.ts @@ -18,7 +18,7 @@ * Pulled from https://github.com/varanauskas/oatx. */ -import { FromSchema, JSONSchema7 } from 'json-schema-to-ts'; +import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { ImmutableContentObject, ImmutableOpenAPIObject, @@ -221,7 +221,7 @@ export type TuplifyUnion< * @public */ export type ConvertAll> = { - [Index in keyof T]: T[Index] extends JSONSchema7 + [Index in keyof T]: T[Index] extends JSONSchema ? FromSchema : T[Index]; } & { length: T['length'] }; diff --git a/packages/backend-openapi-utils/src/types/params.ts b/packages/backend-openapi-utils/src/types/params.ts index 208cbd4e9a..969657bac7 100644 --- a/packages/backend-openapi-utils/src/types/params.ts +++ b/packages/backend-openapi-utils/src/types/params.ts @@ -36,7 +36,7 @@ import { SchemaRef, ValueOf, } from './common'; -import { FromSchema, JSONSchema7 } from 'json-schema-to-ts'; +import { FromSchema, JSONSchema } from 'json-schema-to-ts'; /** * @public @@ -96,7 +96,7 @@ export type ParameterSchema< Schema extends ImmutableParameterObject['schema'], > = SchemaRef extends infer R ? R extends ImmutableSchemaObject - ? R extends JSONSchema7 + ? R extends JSONSchema ? FromSchema : never : never diff --git a/packages/backend/package.json b/packages/backend/package.json index cdd0a548c8..4223a92a28 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -82,7 +82,7 @@ "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^19.0.3", "@opentelemetry/api": "^1.4.1", - "@opentelemetry/exporter-prometheus": "^0.45.0", + "@opentelemetry/exporter-prometheus": "^0.47.0", "@opentelemetry/sdk-metrics": "^1.13.0", "azure-devops-node-api": "^12.0.0", "better-sqlite3": "^9.0.0", diff --git a/packages/cli/templates/default-backend-module/src/index.ts.hbs b/packages/cli/templates/default-backend-module/src/index.ts.hbs index 0cf1f00d42..7075598e13 100644 --- a/packages/cli/templates/default-backend-module/src/index.ts.hbs +++ b/packages/cli/templates/default-backend-module/src/index.ts.hbs @@ -5,4 +5,4 @@ * @packageDocumentation */ -export { {{moduleVar}} } from './module'; +export { {{moduleVar}} as default } from './module'; diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs index 011a50ba37..15b22bc8e1 100644 --- a/packages/cli/templates/default-plugin/package.json.hbs +++ b/packages/cli/templates/default-plugin/package.json.hbs @@ -45,8 +45,8 @@ "@backstage/core-app-api": "{{versionQuery '@backstage/core-app-api'}}", "@backstage/dev-utils": "{{versionQuery '@backstage/dev-utils'}}", "@backstage/test-utils": "{{versionQuery '@backstage/test-utils'}}", - "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '5.10.1'}}", - "@testing-library/react": "{{versionQuery '@testing-library/react' '12.1.3'}}", + "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '6.0.0'}}", + "@testing-library/react": "{{versionQuery '@testing-library/react' '14.0.0'}}", "@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '14.0.0'}}", "msw": "{{versionQuery 'msw' '1.0.0'}}" }, diff --git a/packages/cli/templates/default-react-plugin-package/package.json.hbs b/packages/cli/templates/default-react-plugin-package/package.json.hbs index 230ecc5f03..f68bd14a1d 100644 --- a/packages/cli/templates/default-react-plugin-package/package.json.hbs +++ b/packages/cli/templates/default-react-plugin-package/package.json.hbs @@ -39,8 +39,8 @@ "devDependencies": { "@backstage/cli": "{{versionQuery '@backstage/cli'}}", "@backstage/test-utils": "{{versionQuery '@backstage/test-utils'}}", - "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '5.10.1'}}", - "@testing-library/react": "{{versionQuery '@testing-library/react' '12.1.3'}}" + "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '6.0.0'}}", + "@testing-library/react": "{{versionQuery '@testing-library/react' '14.0.0'}}" }, "files": [ "dist" diff --git a/packages/cli/templates/web-library-package/package.json.hbs b/packages/cli/templates/web-library-package/package.json.hbs index f9f703f523..271417a525 100644 --- a/packages/cli/templates/web-library-package/package.json.hbs +++ b/packages/cli/templates/web-library-package/package.json.hbs @@ -30,7 +30,7 @@ }, "devDependencies": { "@backstage/cli": "{{versionQuery '@backstage/cli'}}", - "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '5.10.1'}}" + "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '6.0.0'}}" }, "files": [ "dist" diff --git a/packages/core-compat-api/api-report.md b/packages/core-compat-api/api-report.md index 494747be60..a7aae2b5b9 100644 --- a/packages/core-compat-api/api-report.md +++ b/packages/core-compat-api/api-report.md @@ -40,5 +40,26 @@ export function convertLegacyRouteRef< ref: ExternalRouteRef, ): ExternalRouteRef_2; +// @public +export function convertLegacyRouteRefs< + TRefs extends { + [name in string]: RouteRef | SubRouteRef | ExternalRouteRef; + }, +>( + refs: TRefs, +): { + [KName in keyof TRefs]: ToNewRouteRef; +}; + +// @public +export type ToNewRouteRef = + T extends RouteRef + ? RouteRef_2 + : T extends SubRouteRef + ? SubRouteRef_2 + : T extends ExternalRouteRef + ? ExternalRouteRef_2 + : never; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/core-compat-api/src/collectLegacyRoutes.tsx b/packages/core-compat-api/src/collectLegacyRoutes.tsx index 4d560b81d5..7ddb8c4f7e 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.tsx @@ -32,7 +32,10 @@ import { } from '@backstage/frontend-plugin-api'; import React, { Children, ReactNode, isValidElement } from 'react'; import { Route, Routes } from 'react-router-dom'; -import { convertLegacyRouteRef } from './convertLegacyRouteRef'; +import { + convertLegacyRouteRef, + convertLegacyRouteRefs, +} from './convertLegacyRouteRef'; import { compatWrapper } from './compatWrapper'; /* @@ -244,6 +247,8 @@ export function collectLegacyRoutes( createApiExtension({ factory }), ), ], + routes: convertLegacyRouteRefs(plugin.routes ?? {}), + externalRoutes: convertLegacyRouteRefs(plugin.externalRoutes ?? {}), }), ); } diff --git a/packages/core-compat-api/src/convertLegacyRouteRef.ts b/packages/core-compat-api/src/convertLegacyRouteRef.ts index c5ee603722..36311dc081 100644 --- a/packages/core-compat-api/src/convertLegacyRouteRef.ts +++ b/packages/core-compat-api/src/convertLegacyRouteRef.ts @@ -40,6 +40,43 @@ import { toInternalSubRouteRef } from '../../frontend-plugin-api/src/routing/Sub // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalExternalRouteRef } from '../../frontend-plugin-api/src/routing/ExternalRouteRef'; +/** + * Converts a legacy route ref type to the new system. + * + * @public + */ +export type ToNewRouteRef< + T extends LegacyRouteRef | LegacySubRouteRef | LegacyExternalRouteRef, +> = T extends LegacyRouteRef + ? RouteRef + : T extends LegacySubRouteRef + ? SubRouteRef + : T extends LegacyExternalRouteRef + ? ExternalRouteRef + : never; + +/** + * Converts a collection of legacy route refs to the new system. + * This is particularly useful when defining plugin `routes` and `externalRoutes`. + * + * @public + */ +export function convertLegacyRouteRefs< + TRefs extends { + [name in string]: + | LegacyRouteRef + | LegacySubRouteRef + | LegacyExternalRouteRef; + }, +>(refs: TRefs): { [KName in keyof TRefs]: ToNewRouteRef } { + return Object.fromEntries( + Object.entries(refs).map(([name, ref]) => [ + name, + convertLegacyRouteRef(ref as LegacyRouteRef), + ]), + ) as { [KName in keyof TRefs]: ToNewRouteRef }; +} + /** * A temporary helper to convert a legacy route ref to the new system. * diff --git a/packages/core-compat-api/src/index.ts b/packages/core-compat-api/src/index.ts index 68e5d9cf19..b632bf8a57 100644 --- a/packages/core-compat-api/src/index.ts +++ b/packages/core-compat-api/src/index.ts @@ -16,4 +16,8 @@ export * from './compatWrapper'; export { convertLegacyApp } from './convertLegacyApp'; -export { convertLegacyRouteRef } from './convertLegacyRouteRef'; +export { + convertLegacyRouteRef, + convertLegacyRouteRefs, + type ToNewRouteRef, +} from './convertLegacyRouteRef'; diff --git a/packages/frontend-app-api/src/routing/collectRouteIds.test.ts b/packages/frontend-app-api/src/routing/collectRouteIds.test.ts index 95a5afd8cd..6b9fdecf70 100644 --- a/packages/frontend-app-api/src/routing/collectRouteIds.test.ts +++ b/packages/frontend-app-api/src/routing/collectRouteIds.test.ts @@ -37,15 +37,13 @@ describe('collectRouteIds', () => { createPlugin({ id: 'test', routes: { ref }, externalRoutes: { extRef } }), ]); expect(Object.fromEntries(collected.routes)).toEqual({ - 'plugin.test.routes.ref': ref, + 'test.ref': ref, }); expect(Object.fromEntries(collected.externalRoutes)).toEqual({ - 'plugin.test.externalRoutes.extRef': extRef, + 'test.extRef': extRef, }); - expect(String(ref)).toBe('RouteRef{plugin.test.routes.ref}'); - expect(String(extRef)).toBe( - 'ExternalRouteRef{plugin.test.externalRoutes.extRef}', - ); + expect(String(ref)).toBe('RouteRef{test.ref}'); + expect(String(extRef)).toBe('ExternalRouteRef{test.extRef}'); }); }); diff --git a/packages/frontend-app-api/src/routing/collectRouteIds.ts b/packages/frontend-app-api/src/routing/collectRouteIds.ts index 2fbb8b6791..d45871ae89 100644 --- a/packages/frontend-app-api/src/routing/collectRouteIds.ts +++ b/packages/frontend-app-api/src/routing/collectRouteIds.ts @@ -47,7 +47,7 @@ export function collectRouteIds(features: FrontendFeature[]): RouteRefsById { } for (const [name, ref] of Object.entries(feature.routes)) { - const refId = `plugin.${feature.id}.routes.${name}`; + const refId = `${feature.id}.${name}`; if (routesById.has(refId)) { throw new Error(`Unexpected duplicate route '${refId}'`); } @@ -62,7 +62,7 @@ export function collectRouteIds(features: FrontendFeature[]): RouteRefsById { } } for (const [name, ref] of Object.entries(feature.externalRoutes)) { - const refId = `plugin.${feature.id}.externalRoutes.${name}`; + const refId = `${feature.id}.${name}`; if (externalRoutesById.has(refId)) { throw new Error(`Unexpected duplicate external route '${refId}'`); } diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts index 766cb4804e..3330b9add8 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts @@ -615,8 +615,8 @@ describe('createAppNodeInstance', () => { ), ), }), - ).toThrow( - "Failed to instantiate extension 'app/test', input 'singleton' did not receive required extension data 'other' from extension 'app/test'", + ).toThrowErrorMatchingInlineSnapshot( + `"Failed to instantiate extension 'app/test', extension 'app/test' could not be attached because its output data ('test', 'other') does not match what the input 'singleton' requires ('other')"`, ); }); }); diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts index 90a256fea6..63eca749b7 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts @@ -37,8 +37,17 @@ function resolveInputData( return mapValues(dataMap, ref => { const value = attachment.instance?.getData(ref); if (value === undefined && !ref.config.optional) { + const expected = Object.values(dataMap) + .filter(r => !r.config.optional) + .map(r => `'${r.id}'`) + .join(', '); + + const provided = [...(attachment.instance?.getDataRefs() ?? [])] + .map(r => `'${r.id}'`) + .join(', '); + throw new Error( - `input '${inputName}' did not receive required extension data '${ref.id}' from extension '${attachment.spec.id}'`, + `extension '${attachment.spec.id}' could not be attached because its output data (${provided}) does not match what the input '${inputName}' requires (${expected})`, ); } return value; diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx index d53344f7fd..f59d44f6d7 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx @@ -63,8 +63,8 @@ describe('createExtensionTester', () => { factory: () => ({ path: '/foo' }), }); const tester = createExtensionTester(extension); - expect(() => tester.render()).toThrow( - "Failed to instantiate extension 'app/routes', input 'routes' did not receive required extension data 'core.reactElement' from extension 'test'", + expect(() => tester.render()).toThrowErrorMatchingInlineSnapshot( + `"Failed to instantiate extension 'app/routes', extension 'test' could not be attached because its output data ('core.routing.path') does not match what the input 'routes' requires ('core.routing.path', 'core.reactElement')"`, ); }); diff --git a/packages/repo-tools/templates/typescript-backstage/pluginId.mustache b/packages/repo-tools/templates/typescript-backstage/pluginId.mustache index 8bc8461cc9..a71829bb84 100644 --- a/packages/repo-tools/templates/typescript-backstage/pluginId.mustache +++ b/packages/repo-tools/templates/typescript-backstage/pluginId.mustache @@ -1,6 +1,2 @@ -{{#servers}} -{{#-last}} -export const pluginId = "{{url}}"; -{{/-last}} -{{/servers}} \ No newline at end of file +export const pluginId = "{{appName}}"; \ No newline at end of file diff --git a/plugins/auth-backend-module-microsoft-provider/config.d.ts b/plugins/auth-backend-module-microsoft-provider/config.d.ts index aa78f72271..df63e9ccf4 100644 --- a/plugins/auth-backend-module-microsoft-provider/config.d.ts +++ b/plugins/auth-backend-module-microsoft-provider/config.d.ts @@ -28,6 +28,7 @@ export interface Config { clientSecret: string; domainHint?: string; callbackUrl?: string; + additionalScopes?: string[]; }; }; }; diff --git a/plugins/auth-backend-module-microsoft-provider/package.json b/plugins/auth-backend-module-microsoft-provider/package.json index 9412575200..94dddfc7ac 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -27,6 +27,7 @@ "@backstage/plugin-auth-node": "workspace:^", "express": "^4.18.2", "jose": "^4.6.0", + "lodash": "^4.17.21", "node-fetch": "^2.6.7", "passport": "^0.7.0", "passport-microsoft": "^1.0.0" diff --git a/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts b/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts index 35d35c464c..21a60a229b 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts @@ -113,6 +113,7 @@ describe('microsoftAuthenticator', () => { tenantId: 'tenantId', clientId: 'clientId', clientSecret: 'clientSecret', + additionalScopes: ['User.Read.All'], }), }); }); diff --git a/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts b/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts index 52ef1ddd90..1b6eb87fae 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts @@ -21,6 +21,7 @@ import { PassportProfile, } from '@backstage/plugin-auth-node'; import { ExtendedMicrosoftStrategy } from './strategy'; +import { union } from 'lodash'; /** @public */ export const microsoftAuthenticator = createOAuthAuthenticator({ @@ -31,6 +32,10 @@ export const microsoftAuthenticator = createOAuthAuthenticator({ const clientSecret = config.getString('clientSecret'); const tenantId = config.getString('tenantId'); const domainHint = config.getOptionalString('domainHint'); + const scope = union( + ['user.read'], + config.getOptionalStringArray('additionalScopes'), + ); const helper = PassportOAuthAuthenticatorHelper.from( new ExtendedMicrosoftStrategy( @@ -39,7 +44,7 @@ export const microsoftAuthenticator = createOAuthAuthenticator({ clientSecret: clientSecret, callbackURL: callbackUrl, tenant: tenantId, - scope: ['user.read'], + scope: scope, }, ( accessToken: string, diff --git a/plugins/auth-backend-module-microsoft-provider/src/module.test.ts b/plugins/auth-backend-module-microsoft-provider/src/module.test.ts index 21f9a7e845..2ef92c0b44 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/module.test.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/module.test.ts @@ -38,6 +38,7 @@ describe('authModuleMicrosoftProvider', () => { clientId: 'my-client-id', clientSecret: 'my-client-secret', tenantId: 'my-tenant-id', + additionalScopes: ['User.Read.All'], }, }, }, @@ -66,7 +67,7 @@ describe('authModuleMicrosoftProvider', () => { expect(startUrl.pathname).toBe('/my-tenant-id/oauth2/v2.0/authorize'); expect(Object.fromEntries(startUrl.searchParams)).toEqual({ response_type: 'code', - scope: 'user.read', + scope: 'user.read User.Read.All', client_id: 'my-client-id', redirect_uri: `http://localhost:${server.port()}/api/auth/microsoft/handler/frame`, state: expect.any(String), diff --git a/plugins/auth-backend-module-oidc-provider/.eslintrc.js b/plugins/auth-backend-module-oidc-provider/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/auth-backend-module-oidc-provider/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/auth-backend-module-oidc-provider/README.md b/plugins/auth-backend-module-oidc-provider/README.md new file mode 100644 index 0000000000..e586f32fd7 --- /dev/null +++ b/plugins/auth-backend-module-oidc-provider/README.md @@ -0,0 +1,8 @@ +# Auth Module: Oidc Provider + +This module provides an Oidc auth provider implementation for `@backstage/plugin-auth-backend`. + +## Links + +- [Repository](https://oidc.com/backstage/backstage/tree/master/plugins/auth-backend-module-oidc-provider) +- [Backstage Project Homepage](https://backstage.io) diff --git a/plugins/auth-backend-module-oidc-provider/api-report.md b/plugins/auth-backend-module-oidc-provider/api-report.md new file mode 100644 index 0000000000..d96d9952a0 --- /dev/null +++ b/plugins/auth-backend-module-oidc-provider/api-report.md @@ -0,0 +1,50 @@ +## API Report File for "@backstage/plugin-auth-backend-module-oidc-provider" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { BaseClient } from 'openid-client'; +import { OAuthAuthenticator } from '@backstage/plugin-auth-node'; +import { PassportOAuthAuthenticatorHelper } from '@backstage/plugin-auth-node'; +import { SignInResolverFactory } from '@backstage/plugin-auth-node'; +import { Strategy } from 'openid-client'; +import { TokenSet } from 'openid-client'; +import { UserinfoResponse } from 'openid-client'; + +// @public (undocumented) +const authModuleOidcProvider: () => BackendFeature; +export default authModuleOidcProvider; + +// @public (undocumented) +export const oidcAuthenticator: OAuthAuthenticator< + { + initializedScope: string | undefined; + initializedPrompt: string | undefined; + promise: Promise<{ + helper: PassportOAuthAuthenticatorHelper; + client: BaseClient; + strategy: Strategy; + }>; + }, + OidcAuthResult +>; + +// @public +export type OidcAuthResult = { + tokenset: TokenSet; + userinfo: UserinfoResponse; +}; + +// @public +export namespace oidcSignInResolvers { + const emailLocalPartMatchingUserEntityName: SignInResolverFactory< + unknown, + unknown + >; + const emailMatchingUserEntityProfileEmail: SignInResolverFactory< + unknown, + unknown + >; +} +``` diff --git a/plugins/auth-backend-module-oidc-provider/catalog-info.yaml b/plugins/auth-backend-module-oidc-provider/catalog-info.yaml new file mode 100644 index 0000000000..896738898b --- /dev/null +++ b/plugins/auth-backend-module-oidc-provider/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-auth-backend-module-oidc-provider + title: '@backstage/plugin-auth-backend-module-oidc-provider' + description: The oidc-provider backend module for the auth plugin. +spec: + lifecycle: experimental + type: backstage-backend-plugin-module + owner: maintainers diff --git a/plugins/scaffolder/src/legacy/TaskPage/IconLink.test.tsx b/plugins/auth-backend-module-oidc-provider/config.d.ts similarity index 55% rename from plugins/scaffolder/src/legacy/TaskPage/IconLink.test.tsx rename to plugins/auth-backend-module-oidc-provider/config.d.ts index 0b6092c37d..16131c0761 100644 --- a/plugins/scaffolder/src/legacy/TaskPage/IconLink.test.tsx +++ b/plugins/auth-backend-module-oidc-provider/config.d.ts @@ -14,17 +14,25 @@ * limitations under the License. */ -import { renderInTestApp } from '@backstage/test-utils'; -import CloudIcon from '@material-ui/icons/Cloud'; -import React from 'react'; -import { IconLink } from './IconLink'; - -describe('IconLink', () => { - it('should render an icon link', async () => { - const rendered = await renderInTestApp( - , - ); - - expect(rendered.getByText('I am Link')).toBeInTheDocument(); - }); -}); +export interface Config { + auth?: { + providers?: { + /** @visibility frontend */ + oidc?: { + [authEnv: string]: { + clientId: string; + /** + * @visibility secret + */ + clientSecret: string; + metadataUrl: string; + callbackUrl?: string; + tokenEndpointAuthMethod?: string; + tokenSignedResponseAlg?: string; + scope?: string; + prompt?: string; + }; + }; + }; + }; +} diff --git a/plugins/scaffolder/src/legacy/index.ts b/plugins/auth-backend-module-oidc-provider/dev/index.ts similarity index 75% rename from plugins/scaffolder/src/legacy/index.ts rename to plugins/auth-backend-module-oidc-provider/dev/index.ts index 2393be0f69..d3c18c1d48 100644 --- a/plugins/scaffolder/src/legacy/index.ts +++ b/plugins/auth-backend-module-oidc-provider/dev/index.ts @@ -13,5 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { LegacyRouter, type LegacyRouterProps } from './Router'; -export { LegacyScaffolderPage } from '../plugin'; + +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.add(import('@backstage/plugin-auth-backend')); +backend.add(import('../src')); + +backend.start(); diff --git a/plugins/auth-backend-module-oidc-provider/package.json b/plugins/auth-backend-module-oidc-provider/package.json new file mode 100644 index 0000000000..6962c1f340 --- /dev/null +++ b/plugins/auth-backend-module-oidc-provider/package.json @@ -0,0 +1,51 @@ +{ + "name": "@backstage/plugin-auth-backend-module-oidc-provider", + "description": "The oidc-provider backend module for the auth plugin.", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "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" + }, + "dependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/plugin-auth-backend": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", + "express": "^4.18.2", + "openid-client": "^5.5.0", + "passport": "^0.6.0" + }, + "devDependencies": { + "@backstage/backend-defaults": "workspace:^", + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/config": "workspace:^", + "cookie-parser": "^1.4.6", + "express-promise-router": "^4.1.1", + "express-session": "^1.17.3", + "jose": "^4.14.6", + "msw": "^1.3.1", + "supertest": "^6.3.3" + }, + "configSchema": "config.d.ts", + "files": [ + "dist", + "config.d.ts" + ] +} diff --git a/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts b/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts new file mode 100644 index 0000000000..717083562c --- /dev/null +++ b/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts @@ -0,0 +1,437 @@ +/* + * Copyright 2023 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 { + OAuthAuthenticatorAuthenticateInput, + OAuthAuthenticatorRefreshInput, + OAuthAuthenticatorStartInput, + OAuthState, + decodeOAuthState, + encodeOAuthState, +} from '@backstage/plugin-auth-node'; +import { oidcAuthenticator } from './authenticator'; +import { setupServer } from 'msw/node'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { ConfigReader } from '@backstage/config'; +import { JWK, SignJWT, exportJWK, generateKeyPair } from 'jose'; +import { rest } from 'msw'; +import express from 'express'; + +describe('oidcAuthenticator', () => { + let implementation: any; + let oauthState: OAuthState; + let idToken: string; + let publicKey: JWK; + + const mswServer = setupServer(); + setupRequestMockHandlers(mswServer); + + const issuerMetadata = { + issuer: 'https://oidc.test', + authorization_endpoint: 'https://oidc.test/oauth2/authorize', + token_endpoint: 'https://oidc.test/oauth2/token', + revocation_endpoint: 'https://oidc.test/oauth2/revoke_token', + userinfo_endpoint: 'https://oidc.test/idp/userinfo.openid', + introspection_endpoint: 'https://oidc.test/introspect.oauth2', + jwks_uri: 'https://oidc.test/jwks.json', + scopes_supported: [ + 'openid', + 'offline_access', + 'oidc:request-audience', + 'username', + 'groups', + ], + claims_supported: ['email', 'username', 'groups', 'additionalClaims'], + response_types_supported: ['code'], + id_token_signing_alg_values_supported: ['RS256', 'RS512', 'HS256'], + token_endpoint_auth_signing_alg_values_supported: [ + 'RS256', + 'RS512', + 'HS256', + ], + request_object_signing_alg_values_supported: ['RS256', 'RS512', 'HS256'], + }; + + beforeAll(async () => { + const keyPair = await generateKeyPair('RS256'); + const privateKey = await exportJWK(keyPair.privateKey); + publicKey = await exportJWK(keyPair.publicKey); + publicKey.alg = privateKey.alg = 'RS256'; + + idToken = await new SignJWT({ + sub: 'test', + iss: 'https://oidc.test', + iat: Date.now(), + aud: 'clientId', + exp: Date.now() + 10000, + }) + .setProtectedHeader({ alg: privateKey.alg, kid: privateKey.kid }) + .sign(keyPair.privateKey); + }); + + beforeEach(() => { + mswServer.use( + rest.get( + 'https://oidc.test/.well-known/openid-configuration', + (_req, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json(issuerMetadata), + ), + ), + rest.get('https://oidc.test/jwks.json', async (_req, res, ctx) => + res(ctx.status(200), ctx.json({ keys: [{ ...publicKey }] })), + ), + rest.post('https://oidc.test/oauth2/token', async (req, res, ctx) => { + return res( + req.headers.get('Authorization') + ? ctx.json({ + access_token: 'accessToken', + id_token: idToken, + refresh_token: 'refreshToken', + scope: 'testScope', + expires_in: 3600, + }) + : ctx.status(401), + ); + }), + rest.get( + 'https://oidc.test/idp/userinfo.openid', + async (_req, res, ctx) => + res( + ctx.status(200), + ctx.json({ + sub: 'test', + name: 'Alice Adams', + given_name: 'Alice', + family_name: 'Adams', + email: 'alice@test.com', + picture: 'http://testPictureUrl/photo.jpg', + }), + ), + ), + ); + + implementation = oidcAuthenticator.initialize({ + callbackUrl: 'https://backstage.test/callback', + config: new ConfigReader({ + metadataUrl: 'https://oidc.test/.well-known/openid-configuration', + clientId: 'clientId', + clientSecret: 'clientSecret', + }), + }); + + oauthState = { + nonce: 'nonce', + env: 'env', + }; + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('#start', () => { + let fakeSession: Record; + let startRequest: OAuthAuthenticatorStartInput; + + beforeEach(() => { + fakeSession = {}; + startRequest = { + state: encodeOAuthState(oauthState), + req: { + method: 'GET', + url: 'test', + session: fakeSession, + }, + } as unknown as OAuthAuthenticatorStartInput; + }); + + it('redirects to authorization endpoint returned from OIDC metadata endpoint', async () => { + const startResponse = await oidcAuthenticator.start( + startRequest, + implementation, + ); + const url = new URL(startResponse.url); + + expect(url.protocol).toBe('https:'); + expect(url.hostname).toBe('oidc.test'); + expect(url.pathname).toBe('/oauth2/authorize'); + }); + + it('initiates authorization code grant', async () => { + const startResponse = await oidcAuthenticator.start( + startRequest, + implementation, + ); + const { searchParams } = new URL(startResponse.url); + + expect(searchParams.get('response_type')).toBe('code'); + }); + + it('passes client ID from config', async () => { + const startResponse = await oidcAuthenticator.start( + startRequest, + implementation, + ); + const { searchParams } = new URL(startResponse.url); + + expect(searchParams.get('client_id')).toBe('clientId'); + }); + + it('passes callback URL from config', async () => { + const startResponse = await oidcAuthenticator.start( + startRequest, + implementation, + ); + const { searchParams } = new URL(startResponse.url); + + expect(searchParams.get('redirect_uri')).toBe( + 'https://backstage.test/callback', + ); + }); + + it('generates PKCE challenge', async () => { + const startResponse = await oidcAuthenticator.start( + startRequest, + implementation, + ); + const { searchParams } = new URL(startResponse.url); + + expect(searchParams.get('code_challenge_method')).toBe('S256'); + expect(searchParams.get('code_challenge')).not.toBeNull(); + }); + + it('stores PKCE verifier in session', async () => { + await oidcAuthenticator.start(startRequest, implementation); + expect(fakeSession['oidc:oidc.test'].code_verifier).toBeDefined(); + }); + + it('requests default scopes if none are provided in config', async () => { + const startResponse = await oidcAuthenticator.start( + startRequest, + implementation, + ); + const { searchParams } = new URL(startResponse.url); + const scopes = searchParams.get('scope')?.split(' ') ?? []; + + expect(scopes).toEqual( + expect.arrayContaining(['openid', 'profile', 'email']), + ); + }); + + it('encodes OAuth state in query param', async () => { + const startResponse = await oidcAuthenticator.start( + startRequest, + implementation, + ); + const { searchParams } = new URL(startResponse.url); + const stateParam = searchParams.get('state'); + const decodedState = decodeOAuthState(stateParam!); + + expect(decodedState).toMatchObject(oauthState); + }); + + it('fails when request has no session', async () => { + return expect( + oidcAuthenticator.start( + { + state: encodeOAuthState(oauthState), + req: { + method: 'GET', + url: 'test', + }, + } as unknown as OAuthAuthenticatorStartInput, + implementation, + ), + ).rejects.toThrow('authentication requires session support'); + }); + }); + + describe('#authenticate', () => { + let handlerRequest: OAuthAuthenticatorAuthenticateInput; + + beforeEach(() => { + handlerRequest = { + req: { + method: 'GET', + url: `https://test?code=authorization_code&state=${encodeOAuthState( + oauthState, + )}`, + session: { + 'oidc:oidc.test': { + state: encodeOAuthState(oauthState), + }, + }, + } as unknown as express.Request, + }; + }); + + it('exchanges authorization code for access token', async () => { + const authenticatorResult = await oidcAuthenticator.authenticate( + handlerRequest, + implementation, + ); + const accessToken = authenticatorResult.session.accessToken; + + expect(accessToken).toEqual('accessToken'); + }); + + it('exchanges authorization code for refresh token', async () => { + const authenticatorResult = await oidcAuthenticator.authenticate( + handlerRequest, + implementation, + ); + const refreshToken = authenticatorResult.session.refreshToken; + + expect(refreshToken).toEqual('refreshToken'); + }); + + it('returns granted scope', async () => { + const authenticatorResult = await oidcAuthenticator.authenticate( + handlerRequest, + implementation, + ); + const responseScope = authenticatorResult.session.scope; + + expect(responseScope).toEqual('testScope'); + }); + + it('returns a default session.tokentype field', async () => { + const authenticatorResult = await oidcAuthenticator.authenticate( + handlerRequest, + implementation, + ); + const tokenType = authenticatorResult.session.tokenType; + + expect(tokenType).toEqual('bearer'); + }); + + it('returns picture and email', async () => { + const authenticatorResult = await oidcAuthenticator.authenticate( + handlerRequest, + implementation, + ); + + expect(authenticatorResult).toMatchObject({ + fullProfile: { + userinfo: { + email: 'alice@test.com', + picture: 'http://testPictureUrl/photo.jpg', + name: 'Alice Adams', + }, + }, + }); + }); + + it('returns idToken', async () => { + const authenticatorResult = await oidcAuthenticator.authenticate( + handlerRequest, + implementation, + ); + + expect(authenticatorResult).toMatchObject({ + session: { + idToken, + }, + }); + expect( + Math.abs(authenticatorResult.session.expiresInSeconds! - 3600), + ).toBeLessThan(5); + }); + + it('fails without authorization code', async () => { + handlerRequest.req.url = 'https://test.com'; + return expect( + oidcAuthenticator.authenticate(handlerRequest, implementation), + ).rejects.toThrow('Unexpected redirect'); + }); + + it('fails without oauth state', async () => { + return expect( + oidcAuthenticator.authenticate( + { + req: { + method: 'GET', + url: `https://test?code=authorization_code}`, + session: { + ['oidc:pinniped.test']: { + state: { handle: 'sessionid', code_verifier: 'foo' }, + }, + }, + } as unknown as express.Request, + }, + implementation, + ), + ).rejects.toThrow( + 'Authentication failed, did not find expected authorization request details in session, req.session["oidc:oidc.test"] is undefined', + ); + }); + + it('fails when request has no session', async () => { + return expect( + oidcAuthenticator.authenticate( + { + req: { + method: 'GET', + url: 'https://test.com', + } as unknown as express.Request, + }, + implementation, + ), + ).rejects.toThrow('authentication requires session support'); + }); + }); + + describe('#refresh', () => { + let refreshRequest: OAuthAuthenticatorRefreshInput; + + beforeEach(() => { + refreshRequest = { + scope: '', + refreshToken: 'otherRefreshToken', + req: {} as express.Request, + }; + }); + + it('gets new refresh token', async () => { + const refreshResponse = await oidcAuthenticator.refresh( + refreshRequest, + implementation, + ); + + expect(refreshResponse.session.refreshToken).toBe('refreshToken'); + }); + + it('gets access token', async () => { + const refreshResponse = await oidcAuthenticator.refresh( + refreshRequest, + implementation, + ); + + expect(refreshResponse.session.accessToken).toBe('accessToken'); + }); + + it('gets id token', async () => { + const refreshResponse = await oidcAuthenticator.refresh( + refreshRequest, + implementation, + ); + + expect(refreshResponse.session.idToken).toBe(idToken); + }); + }); +}); diff --git a/plugins/auth-backend-module-oidc-provider/src/authenticator.ts b/plugins/auth-backend-module-oidc-provider/src/authenticator.ts new file mode 100644 index 0000000000..ba6bc9d142 --- /dev/null +++ b/plugins/auth-backend-module-oidc-provider/src/authenticator.ts @@ -0,0 +1,187 @@ +/* + * Copyright 2023 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 { + Issuer, + ClientAuthMethod, + TokenSet, + UserinfoResponse, + Strategy as OidcStrategy, +} from 'openid-client'; +import { + createOAuthAuthenticator, + OAuthAuthenticatorResult, + PassportDoneCallback, + PassportHelpers, + PassportOAuthAuthenticatorHelper, + PassportOAuthPrivateInfo, +} from '@backstage/plugin-auth-node'; + +/** + * authentication result for the OIDC which includes the token set and user + * profile response + * @public + */ +export type OidcAuthResult = { + tokenset: TokenSet; + userinfo: UserinfoResponse; +}; + +/** @public */ +export const oidcAuthenticator = createOAuthAuthenticator({ + defaultProfileTransform: async ( + input: OAuthAuthenticatorResult, + ) => ({ + profile: { + email: input.fullProfile.userinfo.email, + picture: input.fullProfile.userinfo.picture, + displayName: input.fullProfile.userinfo.name, + }, + }), + initialize({ callbackUrl, config }) { + const clientId = config.getString('clientId'); + const clientSecret = config.getString('clientSecret'); + const metadataUrl = config.getString('metadataUrl'); + const customCallbackUrl = config.getOptionalString('callbackUrl'); + const tokenEndpointAuthMethod = config.getOptionalString( + 'tokenEndpointAuthMethod', + ) as ClientAuthMethod; + const tokenSignedResponseAlg = config.getOptionalString( + 'tokenSignedResponseAlg', + ); + const initializedScope = config.getOptionalString('scope'); + const initializedPrompt = config.getOptionalString('prompt'); + + const promise = Issuer.discover(metadataUrl).then(issuer => { + const client = new issuer.Client({ + access_type: 'offline', // this option must be passed to provider to receive a refresh token + client_id: clientId, + client_secret: clientSecret, + redirect_uris: [customCallbackUrl || callbackUrl], + response_types: ['code'], + token_endpoint_auth_method: + tokenEndpointAuthMethod || 'client_secret_basic', + id_token_signed_response_alg: tokenSignedResponseAlg || 'RS256', + scope: initializedScope || '', + }); + + const strategy = new OidcStrategy( + { + client, + passReqToCallback: false, + }, + ( + tokenset: TokenSet, + userinfo: UserinfoResponse, + done: PassportDoneCallback, + ) => { + if (typeof done !== 'function') { + throw new Error( + 'OIDC IdP must provide a userinfo_endpoint in the metadata response', + ); + } + + done( + undefined, + { tokenset, userinfo }, + { refreshToken: tokenset.refresh_token }, + ); + }, + ); + + const helper = PassportOAuthAuthenticatorHelper.from(strategy); + return { helper, client, strategy }; + }); + + return { initializedScope, initializedPrompt, promise }; + }, + + async start(input, ctx) { + const { initializedScope, initializedPrompt, promise } = ctx; + const { helper, strategy } = await promise; + const options: Record = { + scope: input.scope || initializedScope || 'openid profile email', + state: input.state, + }; + const prompt = initializedPrompt || 'none'; + if (prompt !== 'auto') { + options.prompt = prompt; + } + + return new Promise((resolve, reject) => { + strategy.error = reject; + + return helper + .start(input, { + ...options, + }) + .then(resolve); + }); + }, + + async authenticate( + input, + ctx, + ): Promise> { + const { strategy } = await ctx.promise; + const { result, privateInfo } = + await PassportHelpers.executeFrameHandlerStrategy< + OidcAuthResult, + PassportOAuthPrivateInfo + >(input.req, strategy); + + return { + fullProfile: result, + session: { + accessToken: result.tokenset.access_token!, + tokenType: result.tokenset.token_type ?? 'bearer', + scope: result.tokenset.scope!, + expiresInSeconds: result.tokenset.expires_in, + idToken: result.tokenset.id_token, + refreshToken: privateInfo.refreshToken, + }, + }; + }, + + async refresh(input, ctx) { + const { client } = await ctx.promise; + const tokenset = await client.refresh(input.refreshToken); + if (!tokenset.access_token) { + throw new Error('Refresh failed'); + } + if (!tokenset.scope) { + tokenset.scope = input.scope; + } + const userinfo = await client.userinfo(tokenset.access_token); + + return new Promise((resolve, reject) => { + if (!tokenset.access_token) { + reject(new Error('Refresh Failed')); + } + resolve({ + fullProfile: { userinfo, tokenset }, + session: { + accessToken: tokenset.access_token!, + tokenType: tokenset.token_type ?? 'bearer', + scope: tokenset.scope!, + expiresInSeconds: tokenset.expires_in, + idToken: tokenset.id_token, + refreshToken: tokenset.refresh_token, + }, + }); + }); + }, +}); diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/DescriptionField.tsx b/plugins/auth-backend-module-oidc-provider/src/index.ts similarity index 61% rename from plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/DescriptionField.tsx rename to plugins/auth-backend-module-oidc-provider/src/index.ts index eded38beee..4e951382bb 100644 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/DescriptionField.tsx +++ b/plugins/auth-backend-module-oidc-provider/src/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * Copyright 2023 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. @@ -14,9 +14,13 @@ * limitations under the License. */ -import React from 'react'; -import { MarkdownContent } from '@backstage/core-components'; -import { FieldProps } from '@rjsf/utils'; +/** + * The oidc-provider backend module for the auth plugin. + * + * @packageDocumentation + */ -export const DescriptionField = ({ description }: FieldProps) => - description && ; +export { oidcAuthenticator } from './authenticator'; +export type { OidcAuthResult } from './authenticator'; +export { authModuleOidcProvider as default } from './module'; +export { oidcSignInResolvers } from './resolvers'; diff --git a/plugins/auth-backend-module-oidc-provider/src/module.test.ts b/plugins/auth-backend-module-oidc-provider/src/module.test.ts new file mode 100644 index 0000000000..216c101049 --- /dev/null +++ b/plugins/auth-backend-module-oidc-provider/src/module.test.ts @@ -0,0 +1,223 @@ +/* + * Copyright 2023 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 request from 'supertest'; +import { decodeOAuthState } from '@backstage/plugin-auth-node'; +import { setupServer } from 'msw/node'; +import { rest } from 'msw'; +import { + mockServices, + setupRequestMockHandlers, + startTestBackend, +} from '@backstage/backend-test-utils'; +import { Server } from 'http'; +import { JWK, SignJWT, exportJWK, generateKeyPair } from 'jose'; +import { authModuleOidcProvider } from './module'; + +describe('authModuleOidcProvider', () => { + let backstageServer: Server; + let appUrl: string; + let idToken: string; + let publicKey: JWK; + + const mswServer = setupServer(); + setupRequestMockHandlers(mswServer); + + const issuerMetadata = { + issuer: 'https://oidc.test', + authorization_endpoint: 'https://oidc.test/oauth2/authorize', + token_endpoint: 'https://oidc.test/oauth2/token', + revocation_endpoint: 'https://oidc.test/oauth2/revoke_token', + userinfo_endpoint: 'https://oidc.test/idp/userinfo.openid', + introspection_endpoint: 'https://oidc.test/as/introspect.oauth2', + jwks_uri: 'https://oidc.test/jwks.json', + scopes_supported: ['openid'], + claims_supported: ['email'], + response_types_supported: ['code'], + id_token_signing_alg_values_supported: ['RS256', 'RS512', 'HS256'], + token_endpoint_auth_signing_alg_values_supported: [ + 'RS256', + 'RS512', + 'HS256', + ], + request_object_signing_alg_values_supported: ['RS256', 'RS512', 'HS256'], + }; + + beforeAll(async () => { + const keyPair = await generateKeyPair('RS256'); + const privateKey = await exportJWK(keyPair.privateKey); + publicKey = await exportJWK(keyPair.publicKey); + publicKey.alg = privateKey.alg = 'RS256'; + + idToken = await new SignJWT({ + sub: 'test', + iss: 'https://oidc.test', + iat: Date.now(), + aud: 'clientId', + exp: Date.now() + 10000, + }) + .setProtectedHeader({ alg: privateKey.alg, kid: privateKey.kid }) + .sign(keyPair.privateKey); + }); + + beforeEach(async () => { + jest.clearAllMocks(); + + mswServer.use( + rest.get( + 'https://oidc.test/.well-known/openid-configuration', + (_req, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json(issuerMetadata), + ), + ), + rest.get('https://oidc.test/oauth2/authorize', async (req, res, ctx) => { + const callbackUrl = new URL(req.url.searchParams.get('redirect_uri')!); + callbackUrl.searchParams.set('code', 'authorization_code'); + callbackUrl.searchParams.set( + 'state', + req.url.searchParams.get('state')!, + ); + callbackUrl.searchParams.set('scope', 'test-scope'); + return res( + ctx.status(302), + ctx.set('Location', callbackUrl.toString()), + ); + }), + rest.get('https://oidc.test/jwks.json', async (_req, res, ctx) => + res(ctx.status(200), ctx.json({ keys: [{ ...publicKey }] })), + ), + rest.post('https://oidc.test/oauth2/token', async (req, res, ctx) => { + return res( + req.headers.get('Authorization') + ? ctx.json({ + access_token: 'accessToken', + id_token: idToken, + refresh_token: 'refreshToken', + scope: 'testScope', + token_type: '', + expires_in: 3600, + }) + : ctx.status(401), + ); + }), + rest.get( + 'https://oidc.test/idp/userinfo.openid', + async (_req, res, ctx) => + res( + ctx.status(200), + ctx.json({ + sub: 'test', + name: 'Alice Adams', + given_name: 'Alice', + family_name: 'Adams', + email: 'alice@test.com', + picture: 'http://testPictureUrl/photo.jpg', + }), + ), + ), + ); + + const backend = await startTestBackend({ + features: [ + authModuleOidcProvider, + import('@backstage/plugin-auth-backend'), + mockServices.rootConfig.factory({ + data: { + app: { baseUrl: 'http://localhost' }, + auth: { + session: { secret: 'test' }, + providers: { + oidc: { + development: { + metadataUrl: + 'https://oidc.test/.well-known/openid-configuration', + clientId: 'clientId', + clientSecret: 'clientSecret', + }, + }, + }, + }, + }, + }), + ], + }); + + backstageServer = backend.server; + const port = backend.server.port(); + appUrl = `http://localhost:${port}`; + mswServer.use(rest.all(`http://*:${port}/*`, req => req.passthrough())); + }); + + afterEach(() => { + backstageServer.close(); + }); + + it('should start', async () => { + const agent = request.agent(backstageServer); + + const startResponse = await agent.get( + `/api/auth/oidc/start?env=development`, + ); + expect(startResponse.status).toEqual(302); + + const nonceCookie = agent.jar.getCookie('oidc-nonce', { + domain: 'localhost', + path: '/api/auth/oidc/handler', + script: false, + secure: false, + }); + expect(nonceCookie).toBeDefined(); + + const startUrl = new URL(startResponse.get('location')); + expect(startUrl.origin).toBe('https://oidc.test'); + expect(startUrl.pathname).toBe('/oauth2/authorize'); + expect(Object.fromEntries(startUrl.searchParams)).toEqual({ + response_type: 'code', + scope: 'openid profile email', + client_id: 'clientId', + redirect_uri: `${appUrl}/api/auth/oidc/handler/frame`, + state: expect.any(String), + prompt: 'none', + code_challenge: expect.any(String), + code_challenge_method: `S256`, + }); + + expect(decodeOAuthState(startUrl.searchParams.get('state')!)).toEqual({ + env: 'development', + nonce: decodeURIComponent(nonceCookie.value), + }); + }); + + it('#authenticate exchanges authorization code for a access_token', async () => { + const agent = request.agent(''); + const startResponse = await agent.get( + `${appUrl}/api/auth/oidc/start?env=development`, + ); + const authorizationResponse = await agent.get( + startResponse.header.location, + ); + const handlerResponse = await agent.get( + authorizationResponse.header.location, + ); + + expect(handlerResponse.text).toContain( + encodeURIComponent(`"accessToken":"accessToken"`), + ); + }); +}); diff --git a/plugins/auth-backend-module-oidc-provider/src/module.ts b/plugins/auth-backend-module-oidc-provider/src/module.ts new file mode 100644 index 0000000000..5680cd8603 --- /dev/null +++ b/plugins/auth-backend-module-oidc-provider/src/module.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2023 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 { createBackendModule } from '@backstage/backend-plugin-api'; +import { + authProvidersExtensionPoint, + commonSignInResolvers, + createOAuthProviderFactory, +} from '@backstage/plugin-auth-node'; +import { oidcAuthenticator } from './authenticator'; +import { oidcSignInResolvers } from './resolvers'; + +/** @public */ +export const authModuleOidcProvider = createBackendModule({ + pluginId: 'auth', + moduleId: 'oidc-provider', + register(reg) { + reg.registerInit({ + deps: { + providers: authProvidersExtensionPoint, + }, + async init({ providers }) { + providers.registerProvider({ + providerId: 'oidc', + factory: createOAuthProviderFactory({ + authenticator: oidcAuthenticator, + signInResolverFactories: { + ...oidcSignInResolvers, + ...commonSignInResolvers, + }, + }), + }); + }, + }); + }, +}); diff --git a/plugins/auth-backend-module-oidc-provider/src/resolvers.ts b/plugins/auth-backend-module-oidc-provider/src/resolvers.ts new file mode 100644 index 0000000000..5367ab5216 --- /dev/null +++ b/plugins/auth-backend-module-oidc-provider/src/resolvers.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2023 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 { commonSignInResolvers } from '@backstage/plugin-auth-node'; + +/** + * Available sign-in resolvers for the Oidc auth provider. + * + * @public + */ +export namespace oidcSignInResolvers { + /** + * A oidc resolver that looks up the user using the local part of + * their email address as the entity name. + */ + export const emailLocalPartMatchingUserEntityName = + commonSignInResolvers.emailLocalPartMatchingUserEntityName; + + /** + * A oidc resolver that looks up the user using their email address + * as email of the entity. + */ + export const emailMatchingUserEntityProfileEmail = + commonSignInResolvers.emailMatchingUserEntityProfileEmail; +} diff --git a/plugins/auth-backend-module-okta-provider/config.d.ts b/plugins/auth-backend-module-okta-provider/config.d.ts index f047c96739..42688528ee 100644 --- a/plugins/auth-backend-module-okta-provider/config.d.ts +++ b/plugins/auth-backend-module-okta-provider/config.d.ts @@ -29,6 +29,7 @@ export interface Config { authServerId?: string; idp?: string; callbackUrl?: string; + additionalScopes?: string; }; }; }; diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index d80648a10f..ef7b7909ba 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -25,6 +25,7 @@ import { LoggerService } from '@backstage/backend-plugin-api'; import { OAuth2ProxyResult as OAuth2ProxyResult_2 } from '@backstage/plugin-auth-backend-module-oauth2-proxy-provider'; import { OAuthEnvironmentHandler as OAuthEnvironmentHandler_2 } from '@backstage/plugin-auth-node'; import { OAuthState as OAuthState_2 } from '@backstage/plugin-auth-node'; +import { OidcAuthResult as OidcAuthResult_2 } from '@backstage/plugin-auth-backend-module-oidc-provider'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { prepareBackstageIdentityResponse as prepareBackstageIdentityResponse_2 } from '@backstage/plugin-auth-node'; @@ -34,9 +35,7 @@ import { SignInInfo as SignInInfo_2 } from '@backstage/plugin-auth-node'; import { SignInResolver as SignInResolver_2 } from '@backstage/plugin-auth-node'; import { TokenManager } from '@backstage/backend-common'; import { TokenParams as TokenParams_2 } from '@backstage/plugin-auth-node'; -import { TokenSet } from 'openid-client'; import { UserEntity } from '@backstage/catalog-model'; -import { UserinfoResponse } from 'openid-client'; import { WebMessageResponse as WebMessageResponse_2 } from '@backstage/plugin-auth-node'; // @public @deprecated @@ -340,11 +339,8 @@ export type OAuthStartResponse = { // @public @deprecated (undocumented) export type OAuthState = OAuthState_2; -// @public -export type OidcAuthResult = { - tokenset: TokenSet; - userinfo: UserinfoResponse; -}; +// @public @deprecated (undocumented) +export type OidcAuthResult = OidcAuthResult_2; // @public @deprecated (undocumented) export const postMessageResponse: ( @@ -531,9 +527,9 @@ export const providers: Readonly<{ | undefined, ) => AuthProviderFactory_2; resolvers: Readonly<{ - emailLocalPartMatchingUserEntityName: () => SignInResolver; - emailMatchingUserEntityProfileEmail: () => SignInResolver; - emailMatchingUserEntityAnnotation(): SignInResolver; + emailMatchingUserEntityProfileEmail: () => SignInResolver_2; + emailLocalPartMatchingUserEntityName: () => SignInResolver_2; + emailMatchingUserEntityAnnotation: () => SignInResolver_2; }>; }>; oauth2: Readonly<{ @@ -564,10 +560,10 @@ export const providers: Readonly<{ create: ( options?: | { - authHandler?: AuthHandler | undefined; + authHandler?: AuthHandler | undefined; signIn?: | { - resolver: SignInResolver; + resolver: SignInResolver; } | undefined; } diff --git a/plugins/auth-backend/config.d.ts b/plugins/auth-backend/config.d.ts index 34139593d3..9dbb89fada 100644 --- a/plugins/auth-backend/config.d.ts +++ b/plugins/auth-backend/config.d.ts @@ -149,22 +149,6 @@ export interface Config { }; }; /** @visibility frontend */ - oidc?: { - [authEnv: string]: { - clientId: string; - /** - * @visibility secret - */ - clientSecret: string; - callbackUrl?: string; - metadataUrl: string; - tokenEndpointAuthMethod?: string; - tokenSignedResponseAlg?: string; - scope?: string; - prompt?: string; - }; - }; - /** @visibility frontend */ auth0?: { [authEnv: string]: { clientId: string; @@ -180,18 +164,6 @@ export interface Config { }; }; /** @visibility frontend */ - microsoft?: { - [authEnv: string]: { - clientId: string; - /** - * @visibility secret - */ - clientSecret: string; - tenantId: string; - callbackUrl?: string; - }; - }; - /** @visibility frontend */ onelogin?: { [authEnv: string]: { clientId: string; diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index a2b4d01b6c..f485f04311 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -43,8 +43,10 @@ "@backstage/plugin-auth-backend-module-github-provider": "workspace:^", "@backstage/plugin-auth-backend-module-gitlab-provider": "workspace:^", "@backstage/plugin-auth-backend-module-google-provider": "workspace:^", + "@backstage/plugin-auth-backend-module-microsoft-provider": "workspace:^", "@backstage/plugin-auth-backend-module-oauth2-provider": "workspace:^", "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "workspace:^", + "@backstage/plugin-auth-backend-module-oidc-provider": "workspace:^", "@backstage/plugin-auth-backend-module-okta-provider": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", @@ -74,7 +76,6 @@ "passport-auth0": "^1.4.3", "passport-bitbucket-oauth2": "^0.1.2", "passport-github2": "^0.1.12", - "passport-gitlab2": "^5.0.0", "passport-google-oauth20": "^2.0.0", "passport-microsoft": "^1.0.0", "passport-oauth2": "^1.6.1", diff --git a/plugins/auth-backend/src/providers/microsoft/__testUtils__/fake.test.ts b/plugins/auth-backend/src/providers/microsoft/__testUtils__/fake.test.ts deleted file mode 100644 index dee37f0f6b..0000000000 --- a/plugins/auth-backend/src/providers/microsoft/__testUtils__/fake.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2023 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 { FakeMicrosoftAPI } from './fake'; - -describe('FakeMicrosoftAPI', () => { - const api = new FakeMicrosoftAPI(); - - describe('#token', () => { - it('exchanges auth codes', () => { - const { access_token } = api.token( - new URLSearchParams({ - grant_type: 'authorization_code', - code: api.generateAuthCode('User.Read'), - }), - ); - - expect(api.tokenHasScope(access_token, 'User.Read')).toBe(true); - }); - - it('supports scopes for the first requested audience only', () => { - const { access_token } = api.token( - new URLSearchParams({ - grant_type: 'authorization_code', - code: api.generateAuthCode('someaudience/somescope User.Read'), - }), - ); - - expect(api.tokenHasScope(access_token, 'User.Read')).toBe(false); - }); - - it('special openid scopes do not count towards the 1-audience limit', () => { - const { access_token } = api.token( - new URLSearchParams({ - grant_type: 'authorization_code', - code: api.generateAuthCode('openid offline_access User.Read'), - }), - ); - - expect(api.tokenHasScope(access_token, 'User.Read')).toBe(true); - }); - - it('refreshes tokens', () => { - const { access_token } = api.token( - new URLSearchParams({ - grant_type: 'refresh_token', - refresh_token: api.generateRefreshToken( - 'email openid profile User.Read', - ), - }), - ); - - expect( - api.tokenHasScope(access_token, 'email openid profile User.Read'), - ).toBe(true); - }); - it('requires `openid` scope for ID token', () => { - const { id_token } = api.token( - new URLSearchParams({ - grant_type: 'authorization_code', - code: api.generateAuthCode('User.Read'), - }), - ); - - expect(id_token).toBeUndefined(); - }); - it('requires `offline_access` scope for refresh token', () => { - const { refresh_token } = api.token( - new URLSearchParams({ - grant_type: 'authorization_code', - code: api.generateAuthCode('User.Read'), - }), - ); - - expect(refresh_token).toBeUndefined(); - }); - }); -}); diff --git a/plugins/auth-backend/src/providers/microsoft/__testUtils__/fake.ts b/plugins/auth-backend/src/providers/microsoft/__testUtils__/fake.ts deleted file mode 100644 index 9b3ca09c57..0000000000 --- a/plugins/auth-backend/src/providers/microsoft/__testUtils__/fake.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2023 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 { decodeJwt } from 'jose'; - -type Claims = { aud: string; scp: string }; - -export class FakeMicrosoftAPI { - generateAccessToken(scope: string): string { - return this.tokenWithClaims(this.allClaimsForScope(scope)).access_token; - } - generateAuthCode(scope: string): string { - return this.encodeClaims(this.allClaimsForScope(scope)); - } - generateRefreshToken(scope: string): string { - return this.encodeClaims(this.allClaimsForScope(scope)); - } - token(formData: URLSearchParams): { - access_token: string; - scope: string; - refresh_token?: string; - id_token?: string; - } { - const scopeParameter = formData.get('scope'); - const claims = - (scopeParameter && this.allClaimsForScope(scopeParameter)) ?? - formData.get('grant_type') === 'refresh_token' - ? this.decodeClaims(formData.get('refresh_token')!) - : this.decodeClaims(formData.get('code')!); - return { - ...this.tokenWithClaims(claims), - ...(this.hasScope(claims, 'offline_access') && { - refresh_token: this.encodeClaims(claims), - }), - ...(this.hasScope(claims, 'openid') && { - id_token: 'header.e30K.microsoft', - }), - }; - } - tokenHasScope(token: string, scope: string): boolean { - const { aud, scp } = decodeJwt(token); - return this.hasScope({ aud: aud as string, scp: scp as string }, scope); - } - private tokenWithClaims(claims: Claims): { - access_token: string; - scope: string; - } { - const filteredClaims = { - ...claims, - scp: claims.scp - .split(' ') - .filter(s => s !== 'offline_access') - .join(' '), - }; - return { - access_token: `header.${Buffer.from( - JSON.stringify(filteredClaims), - ).toString('base64')}.signature`, - scope: this.scopeFromClaims(filteredClaims), - }; - } - private allClaimsForScope(scope: string): Claims { - const scopes = scope.split(' ').map(this.parseScope); - const firstAudience = scopes - .map(({ aud }) => aud) - .find(aud => aud !== 'openid'); - return { - aud: firstAudience ?? '00000003-0000-0000-c000-000000000000', - scp: scopes - .filter(({ aud }) => aud === 'openid' || aud === firstAudience) - .map(({ scp }) => scp) - .join(' '), - }; - } - // auth codes and refresh tokens in this fake system are base64-encoded JSON - // strings of claims - private encodeClaims(claims: Claims): string { - return Buffer.from(JSON.stringify(claims)).toString('base64'); - } - private decodeClaims(encoded: string): Claims { - return JSON.parse(Buffer.from(encoded, 'base64').toString()); - } - private hasScope(claims: Claims, scope: string): boolean { - return this.scopeFromClaims(claims).includes(scope); - } - private parseScope(s: string): Claims { - if (s.includes('/')) { - const [aud, scp] = s.split('/'); - return { aud, scp }; - } - switch (s) { - case 'email': - case 'openid': - case 'offline_access': - case 'profile': { - return { aud: 'openid', scp: s }; - } - default: - return { aud: '00000003-0000-0000-c000-000000000000', scp: s }; - } - } - private scopeFromClaims(claims: Claims): string { - return claims.scp - .split(' ') - .map(this.parseScope) - .map(({ aud, scp }) => - aud === 'openid' || - claims.aud === '00000003-0000-0000-c000-000000000000' - ? scp - : `${claims.aud}/${scp}`, - ) - .join(' '); - } -} diff --git a/plugins/auth-backend/src/providers/microsoft/provider.test.ts b/plugins/auth-backend/src/providers/microsoft/provider.test.ts deleted file mode 100644 index 7bbfd085d6..0000000000 --- a/plugins/auth-backend/src/providers/microsoft/provider.test.ts +++ /dev/null @@ -1,450 +0,0 @@ -/* - * 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 { microsoft } from './provider'; -import { getVoidLogger } from '@backstage/backend-common'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; -import { ConfigReader } from '@backstage/config'; -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; -import { AuthProviderRouteHandlers, AuthResolverContext } from '../types'; -import express from 'express'; -import crypto from 'crypto'; -import { FakeMicrosoftAPI } from './__testUtils__/fake'; - -describe('MicrosoftAuthProvider', () => { - const nonce = 'AAAAAAAAAAAAAAAAAAAAAA=='; // 16 bytes of zeros in base64 - const state = Buffer.from( - `nonce=${encodeURIComponent(nonce)}&env=development`, - ).toString('hex'); - const mockBackstageToken = `header.${Buffer.from( - JSON.stringify({ sub: 'user:default/mock' }), - 'utf8', - ).toString('base64')}.backstage`; - - const server = setupServer(); - const microsoftApi = new FakeMicrosoftAPI(); - let provider: AuthProviderRouteHandlers; - let response: jest.Mocked; - - setupRequestMockHandlers(server); - - beforeEach(() => { - provider = microsoft.create({ - signIn: { - resolver: microsoft.resolvers.emailMatchingUserEntityAnnotation(), - }, - })({ - providerId: 'microsoft', - baseUrl: 'http://backstage.test/api/auth', - appUrl: 'http://backstage.test', - isOriginAllowed: _ => true, - globalConfig: { - baseUrl: 'http://backstage.test/api/auth', - appUrl: 'http://backstage.test', - isOriginAllowed: _ => true, - }, - config: new ConfigReader({ - development: { - tenantId: 'tenantId', - clientId: 'clientId', - clientSecret: 'clientSecret', - }, - }), - logger: getVoidLogger(), - resolverContext: { - issueToken: jest.fn(), - findCatalogUser: jest.fn(), - signInWithCatalogUser: async _ => ({ - token: mockBackstageToken, - }), - } as AuthResolverContext, - }) as AuthProviderRouteHandlers; - - server.use( - rest.post( - 'https://login.microsoftonline.com/tenantId/oauth2/v2.0/token', - async (req, res, ctx) => { - return res( - ctx.json({ - ...microsoftApi.token(new URLSearchParams(await req.text())), - token_type: 'Bearer', - expires_in: 123, - ext_expires_in: 123, - }), - ); - }, - ), - rest.get('https://graph.microsoft.com/v1.0/me/', (req, res, ctx) => { - if ( - !microsoftApi.tokenHasScope( - req.headers.get('authorization')!.replace(/^Bearer /, ''), - 'User.Read', - ) - ) { - return res(ctx.status(403)); - } - return res( - ctx.json({ - id: 'conrad', - displayName: 'Conrad', - surname: 'Ribas', - givenName: 'Francisco', - mail: 'conrad@example.com', - }), - ); - }), - rest.get( - 'https://graph.microsoft.com/v1.0/me/photos/*', - async (req, res, ctx) => { - if ( - !microsoftApi.tokenHasScope( - req.headers.get('authorization')!.replace(/^Bearer /, ''), - 'User.Read', - ) - ) { - return res(ctx.status(403)); - } - const imageBuffer = new Uint8Array([104, 111, 119, 100, 121]).buffer; - return res( - ctx.set('Content-Length', imageBuffer.byteLength.toString()), - ctx.set('Content-Type', 'image/jpeg'), - ctx.body(imageBuffer), - ); - }, - ), - ); - response = { - cookie: jest.fn(), - end: jest.fn(), - json: jest.fn(), - setHeader: jest.fn(), - status: jest.fn(), - } as unknown as jest.Mocked; - response.status.mockReturnValue(response); - }); - - describe('#start', () => { - const randomBytes = jest.spyOn( - crypto, - 'randomBytes', - ) as unknown as jest.MockedFunction<(size: number) => Buffer>; - - afterEach(() => { - randomBytes.mockRestore(); - }); - - it('redirects to authorize URL', async () => { - randomBytes.mockReturnValue(Buffer.from(nonce, 'base64')); - - await provider.start( - { - query: { - env: 'development', - scope: 'email openid profile User.Read', - }, - } as unknown as express.Request, - response, - ); - - expect(response.setHeader).toHaveBeenCalledWith( - 'Location', - 'https://login.microsoftonline.com/tenantId/oauth2/v2.0/authorize' + - '?response_type=code' + - `&redirect_uri=${encodeURIComponent( - 'http://backstage.test/api/auth/microsoft/handler/frame', - )}` + - `&scope=${encodeURIComponent('email openid profile User.Read')}` + - `&state=${state}` + - '&client_id=clientId', - ); - }); - }); - - describe('#handle', () => { - it('returns provider info and profile with photo data', async () => { - await provider.frameHandler( - { - query: { - env: 'development', - code: microsoftApi.generateAuthCode( - 'email openid profile User.Read', - ), - state, - }, - cookies: { - 'microsoft-nonce': nonce, - }, - } as unknown as express.Request, - response, - ); - - expect(response.end).toHaveBeenCalledWith( - expect.stringContaining( - encodeURIComponent( - JSON.stringify({ - type: 'authorization_response', - response: { - providerInfo: { - accessToken: microsoftApi.generateAccessToken( - 'email openid profile User.Read', - ), - scope: 'email openid profile User.Read', - expiresInSeconds: 123, - idToken: 'header.e30K.microsoft', - }, - profile: { - email: 'conrad@example.com', - picture: 'data:image/jpeg;base64,aG93ZHk=', - displayName: 'Conrad', - }, - backstageIdentity: { - token: mockBackstageToken, - identity: { - type: 'user', - userEntityRef: 'user:default/mock', - ownershipEntityRefs: [], - }, - }, - }, - }), - ), - ), - ); - }); - - it('returns access token for non-microsoft graph scope', async () => { - await provider.frameHandler( - { - query: { - env: 'development', - code: microsoftApi.generateAuthCode('aks-audience/user.read'), - state, - }, - cookies: { - 'microsoft-nonce': nonce, - }, - } as unknown as express.Request, - response, - ); - - expect(response.end).toHaveBeenCalledWith( - expect.stringContaining( - encodeURIComponent( - JSON.stringify({ - type: 'authorization_response', - response: { - providerInfo: { - accessToken: microsoftApi.generateAccessToken( - 'aks-audience/user.read', - ), - scope: 'aks-audience/user.read', - expiresInSeconds: 123, - }, - profile: {}, - }, - }), - ), - ), - ); - }); - - it('sets refresh token', async () => { - await provider.frameHandler( - { - query: { - env: 'development', - code: microsoftApi.generateAuthCode( - 'email offline_access openid profile User.Read', - ), - state, - }, - cookies: { - 'microsoft-nonce': nonce, - }, - } as unknown as express.Request, - response, - ); - - expect(response.cookie).toHaveBeenCalledWith( - 'microsoft-refresh-token', - microsoftApi.generateRefreshToken( - 'email offline_access openid profile User.Read', - ), - { - domain: 'backstage.test', - httpOnly: true, - maxAge: 86400000000, - path: '/api/auth/microsoft', - sameSite: 'lax', - secure: false, - }, - ); - }); - - it('omits photo data when fetching it fails', async () => { - server.use( - rest.get('https://graph.microsoft.com/v1.0/me/photos/*', (_, res) => - res.networkError('remote hung up'), - ), - ); - - await provider.frameHandler( - { - query: { - env: 'development', - code: microsoftApi.generateAuthCode( - 'email openid profile User.Read', - ), - state, - }, - cookies: { - 'microsoft-nonce': nonce, - }, - } as unknown as express.Request, - response, - ); - - expect(response.end).toHaveBeenCalledWith( - expect.stringContaining( - encodeURIComponent( - JSON.stringify({ - type: 'authorization_response', - response: { - providerInfo: { - accessToken: microsoftApi.generateAccessToken( - 'email openid profile User.Read', - ), - scope: 'email openid profile User.Read', - expiresInSeconds: 123, - idToken: 'header.e30K.microsoft', - }, - profile: { - email: 'conrad@example.com', - displayName: 'Conrad', - }, - backstageIdentity: { - token: mockBackstageToken, - identity: { - type: 'user', - userEntityRef: 'user:default/mock', - ownershipEntityRefs: [], - }, - }, - }, - }), - ), - ), - ); - }); - }); - - describe('#refresh', () => { - it('returns provider info and profile with photo data', async () => { - await provider.refresh!( - { - query: { - env: 'development', - scope: 'email openid profile User.Read', - }, - header: jest.fn(_ => 'XMLHttpRequest'), - cookies: { - 'microsoft-refresh-token': microsoftApi.generateRefreshToken( - 'email openid profile User.Read', - ), - }, - get: jest.fn(), - } as unknown as express.Request, - response, - ); - - expect(response.json).toHaveBeenCalledWith( - expect.objectContaining({ - providerInfo: { - accessToken: microsoftApi.generateAccessToken( - 'email openid profile User.Read', - ), - scope: 'email openid profile User.Read', - expiresInSeconds: 123, - idToken: 'header.e30K.microsoft', - }, - profile: { - email: 'conrad@example.com', - picture: 'data:image/jpeg;base64,aG93ZHk=', - displayName: 'Conrad', - }, - }), - ); - }); - - it('returns access token for non-microsoft graph scope', async () => { - await provider.refresh!( - { - query: { - env: 'development', - scope: 'aks-audience/user.read', - }, - header: jest.fn(_ => 'XMLHttpRequest'), - cookies: { - 'microsoft-refresh-token': microsoftApi.generateRefreshToken( - 'aks-audience/user.read', - ), - }, - get: jest.fn(), - } as unknown as express.Request, - response, - ); - - expect(response.json).toHaveBeenCalledWith({ - providerInfo: { - accessToken: microsoftApi.generateAccessToken( - 'aks-audience/user.read', - ), - expiresInSeconds: 123, - scope: 'aks-audience/user.read', - }, - profile: {}, - }); - }); - - it('returns backstage identity', async () => { - await provider.refresh!( - { - query: { - env: 'development', - scope: 'email openid profile User.Read', - }, - header: jest.fn(_ => 'XMLHttpRequest'), - cookies: { - 'microsoft-refresh-token': microsoftApi.generateRefreshToken( - 'email openid profile User.Read', - ), - }, - get: jest.fn(), - } as unknown as express.Request, - response, - ); - - expect(response.json).toHaveBeenCalledWith( - expect.objectContaining({ - backstageIdentity: expect.objectContaining({ - token: mockBackstageToken, - }), - }), - ); - }); - }); -}); diff --git a/plugins/auth-backend/src/providers/microsoft/provider.ts b/plugins/auth-backend/src/providers/microsoft/provider.ts index 8fc8459f10..b004cb9651 100644 --- a/plugins/auth-backend/src/providers/microsoft/provider.ts +++ b/plugins/auth-backend/src/providers/microsoft/provider.ts @@ -14,215 +14,22 @@ * limitations under the License. */ -import express from 'express'; -import passport from 'passport'; -import { Strategy as MicrosoftStrategy } from 'passport-microsoft'; -import { - encodeState, - OAuthAdapter, - OAuthEnvironmentHandler, - OAuthHandlers, - OAuthProviderOptions, - OAuthRefreshRequest, - OAuthResponse, - OAuthResult, - OAuthStartRequest, -} from '../../lib/oauth'; -import { - executeFetchUserProfileStrategy, - executeFrameHandlerStrategy, - executeRedirectStrategy, - executeRefreshTokenStrategy, - makeProfileInfo, - PassportDoneCallback, -} from '../../lib/passport'; -import { - AuthHandler, - OAuthStartResponse, - SignInResolver, - AuthResolverContext, -} from '../types'; +import { SignInResolver, AuthHandler } from '../types'; +import { OAuthResult } from '../../lib/oauth'; import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; import { - commonByEmailLocalPartResolver, - commonByEmailResolver, -} from '../resolvers'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import fetch from 'node-fetch'; -import { decodeJwt } from 'jose'; -import { Profile as PassportProfile } from 'passport'; -import { BACKSTAGE_SESSION_EXPIRATION } from '../../lib/session'; - -type PrivateInfo = { - refreshToken: string; -}; - -type Options = OAuthProviderOptions & { - signInResolver?: SignInResolver; - authHandler: AuthHandler; - logger: LoggerService; - resolverContext: AuthResolverContext; - authorizationUrl?: string; - tokenUrl?: string; -}; - -export class MicrosoftAuthProvider implements OAuthHandlers { - private readonly _strategy: MicrosoftStrategy; - private readonly signInResolver?: SignInResolver; - private readonly authHandler: AuthHandler; - private readonly logger: LoggerService; - private readonly resolverContext: AuthResolverContext; - - constructor(options: Options) { - this.signInResolver = options.signInResolver; - this.authHandler = options.authHandler; - this.logger = options.logger; - this.resolverContext = options.resolverContext; - - this._strategy = new MicrosoftStrategy( - { - clientID: options.clientId, - clientSecret: options.clientSecret, - callbackURL: options.callbackUrl, - authorizationURL: options.authorizationUrl, - tokenURL: options.tokenUrl, - passReqToCallback: false, - skipUserProfile: ( - accessToken: string, - done: (err: unknown, skip: boolean) => void, - ) => { - done(null, this.skipUserProfile(accessToken)); - }, - }, - ( - accessToken: any, - refreshToken: any, - params: any, - fullProfile: passport.Profile, - done: PassportDoneCallback, - ) => { - done(undefined, { fullProfile, accessToken, params }, { refreshToken }); - }, - ); - } - - private skipUserProfile = (accessToken: string): boolean => { - const { aud, scp } = decodeJwt(accessToken); - const hasGraphReadScope = - aud === '00000003-0000-0000-c000-000000000000' && - (scp as string) - .split(' ') - .map(s => s.toLowerCase()) - .includes('user.read'); - return !hasGraphReadScope; - }; - - async start(req: OAuthStartRequest): Promise { - return await executeRedirectStrategy(req, this._strategy, { - scope: req.scope, - state: encodeState(req.state), - }); - } - - async handler(req: express.Request) { - const { result, privateInfo } = await executeFrameHandlerStrategy< - OAuthResult, - PrivateInfo - >(req, this._strategy); - - return { - response: await this.handleResult(result), - refreshToken: privateInfo.refreshToken, - }; - } - - async refresh(req: OAuthRefreshRequest) { - const { accessToken, refreshToken, params } = - await executeRefreshTokenStrategy( - this._strategy, - req.refreshToken, - req.scope, - ); - - return { - response: await this.handleResult({ - params, - accessToken, - ...(!this.skipUserProfile(accessToken) && { - fullProfile: await executeFetchUserProfileStrategy( - this._strategy, - accessToken, - ), - }), - }), - refreshToken, - }; - } - - private async handleResult(result: { - fullProfile?: PassportProfile; - params: { - id_token?: string; - scope: string; - expires_in: number; - }; - accessToken: string; - refreshToken?: string; - }): Promise { - let profile = {}; - if (result.fullProfile) { - const photo = await this.getUserPhoto(result.accessToken); - result.fullProfile.photos = photo ? [{ value: photo }] : undefined; - ({ profile } = await this.authHandler( - result as OAuthResult, - this.resolverContext, - )); - } - - const expiresInSeconds = - result.params.expires_in === undefined - ? BACKSTAGE_SESSION_EXPIRATION - : Math.min(result.params.expires_in, BACKSTAGE_SESSION_EXPIRATION); - - return { - providerInfo: { - accessToken: result.accessToken, - scope: result.params.scope, - expiresInSeconds, - ...{ idToken: result.params.id_token }, - }, - profile, - ...(result.fullProfile && - this.signInResolver && { - backstageIdentity: await this.signInResolver( - { result: result as OAuthResult, profile }, - this.resolverContext, - ), - }), - }; - } - - private async getUserPhoto(accessToken: string): Promise { - try { - const res = await fetch( - 'https://graph.microsoft.com/v1.0/me/photos/48x48/$value', - { - headers: { - Authorization: `Bearer ${accessToken}`, - }, - }, - ); - const data = await res.buffer(); - - return `data:image/jpeg;base64,${data.toString('base64')}`; - } catch (error) { - this.logger.warn( - `Could not retrieve user profile photo from Microsoft Graph API: ${error}`, - ); - return undefined; - } - } -} + commonSignInResolvers, + createOAuthProviderFactory, +} from '@backstage/plugin-auth-node'; +import { + adaptLegacyOAuthHandler, + adaptLegacyOAuthSignInResolver, + adaptOAuthSignInResolverToLegacy, +} from '../../lib/legacy'; +import { + microsoftAuthenticator, + microsoftSignInResolvers, +} from '@backstage/plugin-auth-backend-module-microsoft-provider'; /** * Auth provider integration for Microsoft auth @@ -241,75 +48,21 @@ export const microsoft = createAuthProviderIntegration({ * Configure sign-in for this provider, without it the provider can not be used to sign users in. */ signIn?: { - /** - * Maps an auth result to a Backstage identity for the user. - */ resolver: SignInResolver; }; }) { - return ({ providerId, globalConfig, config, logger, resolverContext }) => - OAuthEnvironmentHandler.mapConfig(config, envConfig => { - const clientId = envConfig.getString('clientId'); - const clientSecret = envConfig.getString('clientSecret'); - const tenantId = envConfig.getString('tenantId'); - - const customCallbackUrl = envConfig.getOptionalString('callbackUrl'); - const callbackUrl = - customCallbackUrl || - `${globalConfig.baseUrl}/${providerId}/handler/frame`; - const authorizationUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`; - const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`; - - const authHandler: AuthHandler = options?.authHandler - ? options.authHandler - : async ({ fullProfile, params }) => ({ - profile: makeProfileInfo(fullProfile ?? {}, params.id_token), - }); - - const provider = new MicrosoftAuthProvider({ - clientId, - clientSecret, - callbackUrl, - authorizationUrl, - tokenUrl, - authHandler, - signInResolver: options?.signIn?.resolver, - logger, - resolverContext, - }); - - return OAuthAdapter.fromConfig(globalConfig, provider, { - providerId, - callbackUrl, - }); - }); - }, - resolvers: { - /** - * Looks up the user by matching their email local part to the entity name. - */ - emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver, - /** - * Looks up the user by matching their email to the entity email. - */ - emailMatchingUserEntityProfileEmail: () => commonByEmailResolver, - /** - * Looks up the user by matching their email to the `microsoft.com/email` annotation. - */ - emailMatchingUserEntityAnnotation(): SignInResolver { - return async (info, ctx) => { - const { profile } = info; - - if (!profile.email) { - throw new Error('Microsoft profile contained no email'); - } - - return ctx.signInWithCatalogUser({ - annotations: { - 'microsoft.com/email': profile.email, - }, - }); - }; - }, + return createOAuthProviderFactory({ + authenticator: microsoftAuthenticator, + profileTransform: adaptLegacyOAuthHandler(options?.authHandler), + signInResolver: adaptLegacyOAuthSignInResolver(options?.signIn?.resolver), + }); }, + resolvers: adaptOAuthSignInResolverToLegacy({ + emailLocalPartMatchingUserEntityName: + commonSignInResolvers.emailLocalPartMatchingUserEntityName(), + emailMatchingUserEntityProfileEmail: + commonSignInResolvers.emailMatchingUserEntityProfileEmail(), + emailMatchingUserEntityAnnotation: + microsoftSignInResolvers.emailMatchingUserEntityAnnotation(), + }), }); diff --git a/plugins/auth-backend/src/providers/oidc/index.ts b/plugins/auth-backend/src/providers/oidc/index.ts index 6b2282411c..501f223fb3 100644 --- a/plugins/auth-backend/src/providers/oidc/index.ts +++ b/plugins/auth-backend/src/providers/oidc/index.ts @@ -15,4 +15,11 @@ */ export { oidc } from './provider'; -export type { OidcAuthResult } from './provider'; + +import { OidcAuthResult as OidcAuthResult_ } from '@backstage/plugin-auth-backend-module-oidc-provider'; + +/** + * @public + * @deprecated Use OidcAuthResult from `@backstage/plugin-auth-backend-module-oidc-provider` instead + */ +export type OidcAuthResult = OidcAuthResult_; diff --git a/plugins/auth-backend/src/providers/oidc/provider.test.ts b/plugins/auth-backend/src/providers/oidc/provider.test.ts index 7161ef1d6b..f2172a796d 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.test.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.test.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * Copyright 2024 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. @@ -13,177 +13,157 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -import { Config, ConfigReader } from '@backstage/config'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { getVoidLogger } from '@backstage/backend-common'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { Config, ConfigReader } from '@backstage/config'; +import { + AuthProviderConfig, + AuthResolverContext, + CookieConfigurer, +} from '@backstage/plugin-auth-node'; import express from 'express'; -import { Session } from 'express-session'; -import { UnsecuredJWT } from 'jose'; +import { JWK, SignJWT, exportJWK, generateKeyPair } from 'jose'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { ClientMetadata, IssuerMetadata } from 'openid-client'; -import { OAuthAdapter } from '../../lib/oauth'; -import { oidc, OidcAuthProvider, Options } from './provider'; -import { AuthResolverContext } from '../types'; +import { oidc } from './provider'; -const issuerMetadata = { - issuer: 'https://oidc.test', - authorization_endpoint: 'https://oidc.test/as/authorization.oauth2', - token_endpoint: 'https://oidc.test/as/token.oauth2', - revocation_endpoint: 'https://oidc.test/as/revoke_token.oauth2', - userinfo_endpoint: 'https://oidc.test/idp/userinfo.openid', - introspection_endpoint: 'https://oidc.test/as/introspect.oauth2', - jwks_uri: 'https://oidc.test/pf/JWKS', - scopes_supported: ['openid'], - claims_supported: ['email'], - response_types_supported: ['code'], - id_token_signing_alg_values_supported: ['RS256', 'RS512', 'HS256'], - token_endpoint_auth_signing_alg_values_supported: ['RS256', 'RS512', 'HS256'], - request_object_signing_alg_values_supported: ['RS256', 'RS512', 'HS256'], -}; +describe('oidc.create', () => { + const userinfo = { + sub: 'test', + iss: 'https://oidc.test', + aud: 'clientId', + nonce: 'foo', + }; + const server = setupServer(); + setupRequestMockHandlers(server); -const clientMetadata: Options = { - authHandler: async input => ({ - profile: { - displayName: input.userinfo.email, - }, - }), - resolverContext: {} as AuthResolverContext, - callbackUrl: 'https://oidc.test/callback', - clientId: 'testclientid', - clientSecret: 'testclientsecret', - metadataUrl: 'https://oidc.test/.well-known/openid-configuration', - tokenEndpointAuthMethod: 'none', - tokenSignedResponseAlg: 'none', -}; + let publicKey: JWK; + let tokenset: object; + let providerFactoryOptions: { + providerId: string; + globalConfig: AuthProviderConfig; + config: Config; + logger: LoggerService; + resolverContext: AuthResolverContext; + baseUrl: string; + appUrl: string; + isOriginAllowed: (origin: string) => boolean; + cookieConfigurer?: CookieConfigurer; + }; -describe('OidcAuthProvider', () => { - const worker = setupServer(); - setupRequestMockHandlers(worker); + beforeAll(async () => { + const keyPair = await generateKeyPair('RS256'); + const privateKey = await exportJWK(keyPair.privateKey); + publicKey = await exportJWK(keyPair.publicKey); + publicKey.alg = privateKey.alg = 'RS256'; + + tokenset = { + id_token: await new SignJWT({ + iat: Date.now(), + exp: Date.now() + 10000, + ...userinfo, + }) + .setProtectedHeader({ alg: privateKey.alg, kid: privateKey.kid }) + .sign(keyPair.privateKey), + access_token: 'accessToken', + }; + }); beforeEach(() => { - jest.clearAllMocks(); - }); - - it('hit the metadata url', async () => { - const handler = jest.fn((_req, res, ctx) => { - return res( - ctx.status(200), - ctx.set('Content-Type', 'application/json'), - ctx.json(issuerMetadata), - ); - }); - worker.use( - rest.get('https://oidc.test/.well-known/openid-configuration', handler), + server.use( + rest.get( + 'https://oidc.test/.well-known/openid-configuration', + (_req, res, ctx) => + res( + ctx.json({ + issuer: 'https://oidc.test', + token_endpoint: 'https://oidc.test/oauth2/token', + userinfo_endpoint: 'https://oidc.test/idp/userinfo.openid', + jwks_uri: 'https://oidc.test/jwks.json', + }), + ), + ), + rest.post('https://oidc.test/oauth2/token', (_req, res, ctx) => + res(ctx.json(tokenset)), + ), + rest.get('https://oidc.test/jwks.json', async (_req, res, ctx) => + res(ctx.json({ keys: [{ ...publicKey }] })), + ), + rest.get( + 'https://oidc.test/idp/userinfo.openid', + async (_req, res, ctx) => res(ctx.json(userinfo)), + ), ); - const provider = new OidcAuthProvider(clientMetadata); - const { strategy } = (await (provider as any).implementation) as any as { - strategy: { - _client: ClientMetadata; - _issuer: IssuerMetadata; - }; - }; - // Assert that the expected request to the metadaurl was made. - expect(handler).toHaveBeenCalledTimes(1); - const { _client, _issuer } = strategy; - expect(_client.client_id).toBe(clientMetadata.clientId); - expect(_issuer.token_endpoint).toBe(issuerMetadata.token_endpoint); - }); - - it('OidcAuthProvider#handler successfully invokes the oidc endpoints', async () => { - const sub = 'alice'; - const iss = 'https://oidc.test'; - const iat = Date.now(); - const aud = clientMetadata.clientId; - const exp = Date.now() + 10000; - const jwt = await new UnsecuredJWT({ iss, sub, aud, iat, exp }) - .setIssuer(iss) - .setAudience(aud) - .setSubject(sub) - .setIssuedAt(iat) - .setExpirationTime(exp) - .encode(); - const requestSequence: Array = []; - - // The array of expected requests executed by the provider handler - const requests: Array<{ - method: 'get' | 'post'; - url: string; - payload: object; - }> = [ - { - method: 'get', - url: 'https://oidc.test/.well-known/openid-configuration', - payload: issuerMetadata, - }, - { - method: 'post', - url: 'https://oidc.test/as/token.oauth2', - payload: { - id_token: jwt, - access_token: 'test', - authorization_signed_response_alg: 'HS256', - }, - }, - { - method: 'get', - url: 'https://oidc.test/idp/userinfo.openid', - payload: { - sub: 'alice', - email: 'alice@oidc.test', - }, - }, - ]; - worker.use( - ...requests.map(r => { - return rest[r.method](r.url, (_req, res, ctx) => { - requestSequence.push(r.url); - return res( - ctx.status(200), - ctx.set('Content-Type', 'application/json'), - ctx.json(r.payload), - ); - }); - }), - ); - const provider = new OidcAuthProvider(clientMetadata); - const req = { - method: 'GET', - url: 'https://oidc.test/?code=test2', - session: { 'oidc:oidc.test': 'test' } as any as Session, - } as express.Request; - await provider.handler(req); - expect(requestSequence).toEqual([0, 1, 2].map(i => requests[i].url)); - }); - - it('oidc.create', async () => { - const handler = jest.fn((_req, res, ctx) => { - return res( - ctx.status(200), - ctx.set('Content-Type', 'application/json'), - ctx.json(issuerMetadata), - ); - }); - worker.use( - rest.get('https://oidc.test/.well-known/openid-configuration', handler), - ); - const config: Config = new ConfigReader({ - testEnv: { - ...clientMetadata, - metadataUrl: 'https://oidc.test/.well-known/openid-configuration', - }, - } as any); - const provider = oidc.create()({ + providerFactoryOptions = { + providerId: 'myoidc', + baseUrl: 'http://backstage.test/api/auth', + appUrl: 'http://backstage.test', + isOriginAllowed: _ => true, globalConfig: { - appUrl: 'https://oidc.test', - baseUrl: 'https://oidc.test', + baseUrl: 'http://backstage.test/api/auth', + appUrl: 'http://backstage.test', + isOriginAllowed: _ => true, }, - config, - } as any) as OAuthAdapter; - expect(provider.start).toBeDefined(); - // Cast provider as any here to be able to inspect private members - await (provider as any).handlers.get('testEnv').handlers.implementation; - // Assert that the expected request to the metadaurl was made. - expect(handler).toHaveBeenCalledTimes(1); + config: new ConfigReader({ + development: { + metadataUrl: 'https://oidc.test/.well-known/openid-configuration', + clientId: 'clientId', + clientSecret: 'clientSecret', + }, + }), + logger: getVoidLogger(), + resolverContext: { + issueToken: jest.fn(), + findCatalogUser: jest.fn(), + signInWithCatalogUser: jest.fn(), + }, + }; + }); + + it('invokes authHandler with tokenset and userinfo response', async () => { + const authHandler = jest.fn(); + const provider = oidc.create({ authHandler })(providerFactoryOptions); + const state = Buffer.from('nonce=foo&env=development').toString('hex'); + + await provider.frameHandler( + { + method: 'GET', + url: `http://backstage.test/api/auth/myoidc/handler/frame?code=blahblah&state=${state}`, + query: { state }, + cookies: { 'myoidc-nonce': 'foo' }, + session: { 'oidc:oidc.test': { state, nonce: 'foo' } }, + } as unknown as express.Request, + { setHeader: jest.fn(), end: jest.fn() } as unknown as express.Response, + ); + + expect(authHandler).toHaveBeenCalledWith( + { tokenset, userinfo }, + providerFactoryOptions.resolverContext, + ); + }); + + it('invokes sign-in resolver with tokenset and userinfo response', async () => { + const resolver = jest.fn(); + const provider = oidc.create({ signIn: { resolver } })( + providerFactoryOptions, + ); + const state = Buffer.from('nonce=foo&env=development').toString('hex'); + + await provider.frameHandler( + { + method: 'GET', + url: `http://backstage.test/api/auth/myoidc/handler/frame?code=blahblah&state=${state}`, + query: { state }, + cookies: { 'myoidc-nonce': 'foo' }, + session: { 'oidc:oidc.test': { state, nonce: 'foo' } }, + } as unknown as express.Request, + { setHeader: jest.fn(), end: jest.fn() } as unknown as express.Response, + ); + + expect(resolver).toHaveBeenCalledWith( + expect.objectContaining({ result: { tokenset, userinfo } }), + providerFactoryOptions.resolverContext, + ); }); }); diff --git a/plugins/auth-backend/src/providers/oidc/provider.ts b/plugins/auth-backend/src/providers/oidc/provider.ts index b6608aebbd..9bc78c48d2 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.ts @@ -14,208 +14,23 @@ * limitations under the License. */ -import express from 'express'; -import { - Client, - ClientAuthMethod, - Issuer, - Strategy as OidcStrategy, - TokenSet, - UserinfoResponse, -} from 'openid-client'; -import { - encodeState, - OAuthAdapter, - OAuthEnvironmentHandler, - OAuthHandlers, - OAuthProviderOptions, - OAuthRefreshRequest, - OAuthResponse, - OAuthStartRequest, -} from '../../lib/oauth'; -import { - executeFrameHandlerStrategy, - executeRedirectStrategy, - PassportDoneCallback, -} from '../../lib/passport'; -import { - AuthHandler, - AuthResolverContext, - OAuthStartResponse, - SignInResolver, -} from '../types'; +import { AuthHandler, SignInResolver } from '../types'; import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; +import { + createOAuthProviderFactory, + AuthResolverContext, + BackstageSignInResult, + OAuthAuthenticatorResult, + SignInInfo, +} from '@backstage/plugin-auth-node'; +import { + oidcAuthenticator, + OidcAuthResult, +} from '@backstage/plugin-auth-backend-module-oidc-provider'; import { commonByEmailLocalPartResolver, commonByEmailResolver, } from '../resolvers'; -import { BACKSTAGE_SESSION_EXPIRATION } from '../../lib/session'; - -type PrivateInfo = { - refreshToken?: string; -}; - -type OidcImpl = { - strategy: OidcStrategy; - client: Client; -}; - -/** - * authentication result for the OIDC which includes the token set and user information (a profile response sent by OIDC server) - * @public - */ -export type OidcAuthResult = { - tokenset: TokenSet; - userinfo: UserinfoResponse; -}; - -export type Options = OAuthProviderOptions & { - metadataUrl: string; - scope?: string; - prompt?: string; - tokenEndpointAuthMethod?: ClientAuthMethod; - tokenSignedResponseAlg?: string; - signInResolver?: SignInResolver; - authHandler: AuthHandler; - resolverContext: AuthResolverContext; -}; - -export class OidcAuthProvider implements OAuthHandlers { - private readonly implementation: Promise; - private readonly scope?: string; - private readonly prompt?: string; - - private readonly signInResolver?: SignInResolver; - private readonly authHandler: AuthHandler; - private readonly resolverContext: AuthResolverContext; - - constructor(options: Options) { - this.implementation = this.setupStrategy(options); - this.scope = options.scope; - this.prompt = options.prompt; - this.signInResolver = options.signInResolver; - this.authHandler = options.authHandler; - this.resolverContext = options.resolverContext; - } - - async start(req: OAuthStartRequest): Promise { - const { strategy } = await this.implementation; - const options: Record = { - scope: req.scope || this.scope || 'openid profile email', - state: encodeState(req.state), - }; - const prompt = this.prompt || 'none'; - if (prompt !== 'auto') { - options.prompt = prompt; - } - return await executeRedirectStrategy(req, strategy, options); - } - - async handler(req: express.Request) { - const { strategy } = await this.implementation; - const { result, privateInfo } = await executeFrameHandlerStrategy< - OidcAuthResult, - PrivateInfo - >(req, strategy); - - return { - response: await this.handleResult(result), - refreshToken: privateInfo.refreshToken, - }; - } - - async refresh(req: OAuthRefreshRequest) { - const { client } = await this.implementation; - const tokenset = await client.refresh(req.refreshToken); - if (!tokenset.access_token) { - throw new Error('Refresh failed'); - } - if (!tokenset.scope) { - tokenset.scope = req.scope; - } - const userinfo = await client.userinfo(tokenset.access_token); - - return { - response: await this.handleResult({ tokenset, userinfo }), - refreshToken: tokenset.refresh_token, - }; - } - - private async setupStrategy(options: Options): Promise { - const issuer = await Issuer.discover(options.metadataUrl); - const client = new issuer.Client({ - access_type: 'offline', // this option must be passed to provider to receive a refresh token - client_id: options.clientId, - client_secret: options.clientSecret, - redirect_uris: [options.callbackUrl], - response_types: ['code'], - token_endpoint_auth_method: - options.tokenEndpointAuthMethod || 'client_secret_basic', - id_token_signed_response_alg: options.tokenSignedResponseAlg || 'RS256', - scope: options.scope || '', - }); - - const strategy = new OidcStrategy( - { - client, - passReqToCallback: false, - }, - ( - tokenset: TokenSet, - userinfo: UserinfoResponse, - done: PassportDoneCallback, - ) => { - if (typeof done !== 'function') { - throw new Error( - 'OIDC IdP must provide a userinfo_endpoint in the metadata response', - ); - } - done( - undefined, - { tokenset, userinfo }, - { - refreshToken: tokenset.refresh_token, - }, - ); - }, - ); - strategy.error = console.error; - return { strategy, client }; - } - - // Use this function to grab the user profile info from the token - // Then populate the profile with it - private async handleResult(result: OidcAuthResult): Promise { - const { profile } = await this.authHandler(result, this.resolverContext); - - const expiresInSeconds = - result.tokenset.expires_in === undefined - ? BACKSTAGE_SESSION_EXPIRATION - : Math.min(result.tokenset.expires_in, BACKSTAGE_SESSION_EXPIRATION); - - let backstageIdentity = undefined; - if (this.signInResolver) { - backstageIdentity = await this.signInResolver( - { - result, - profile, - }, - this.resolverContext, - ); - } - - return { - backstageIdentity, - providerInfo: { - idToken: result.tokenset.id_token, - accessToken: result.tokenset.access_token!, - scope: result.tokenset.scope!, - expiresInSeconds, - }, - profile, - }; - } -} /** * Auth provider integration for generic OpenID Connect auth @@ -224,59 +39,44 @@ export class OidcAuthProvider implements OAuthHandlers { */ export const oidc = createAuthProviderIntegration({ create(options?: { + /** + * The profile transformation function used to verify and convert the auth response + * into the profile that will be presented to the user. + */ authHandler?: AuthHandler; + /** + * Configure sign-in for this provider; convert user profile respones into + * Backstage identities. + */ signIn?: { resolver: SignInResolver; }; }) { - return ({ providerId, globalConfig, config, resolverContext }) => - OAuthEnvironmentHandler.mapConfig(config, envConfig => { - const clientId = envConfig.getString('clientId'); - const clientSecret = envConfig.getString('clientSecret'); - const customCallbackUrl = envConfig.getOptionalString('callbackUrl'); - const callbackUrl = - customCallbackUrl || - `${globalConfig.baseUrl}/${providerId}/handler/frame`; - const metadataUrl = envConfig.getString('metadataUrl'); - const tokenEndpointAuthMethod = envConfig.getOptionalString( - 'tokenEndpointAuthMethod', - ) as ClientAuthMethod; - const tokenSignedResponseAlg = envConfig.getOptionalString( - 'tokenSignedResponseAlg', - ); - const scope = envConfig.getOptionalString('scope'); - const prompt = envConfig.getOptionalString('prompt'); - - const authHandler: AuthHandler = options?.authHandler - ? options.authHandler - : async ({ userinfo }) => ({ - profile: { - displayName: userinfo.name, - email: userinfo.email, - picture: userinfo.picture, - }, - }); - - const provider = new OidcAuthProvider({ - clientId, - clientSecret, - callbackUrl, - tokenEndpointAuthMethod, - tokenSignedResponseAlg, - metadataUrl, - scope, - prompt, - signInResolver: options?.signIn?.resolver, - authHandler, - resolverContext, - }); - - return OAuthAdapter.fromConfig(globalConfig, provider, { - providerId, - callbackUrl, - }); - }); + const authHandler = options?.authHandler; + const signInResolver = options?.signIn?.resolver; + return createOAuthProviderFactory({ + authenticator: oidcAuthenticator, + profileTransform: + authHandler && + (( + result: OAuthAuthenticatorResult, + context: AuthResolverContext, + ) => authHandler(result.fullProfile, context)), + signInResolver: + signInResolver && + (( + info: SignInInfo>, + context: AuthResolverContext, + ): Promise => + signInResolver( + { + result: info.result.fullProfile, + profile: info.profile, + }, + context, + )), + }); }, resolvers: { /** diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index d7335e54c8..7119cb0980 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -61,6 +61,25 @@ spec: # ... ``` +#### Mono repos + +If you have multiple entities within a single repo, you will need to specify which pipelines belong to each entity. + +```yaml +dev.azure.com/project-repo: / +dev.azure.com/build-definition: +``` + +#### Pipeline in different project to repo + +If your pipeline is in a different project to the source code, you will need to specify this in the project annotation. + +```yaml +dev.azure.com/project-repo: / +dev.azure.com/build-definition: +dev.azure.com/project: +``` + #### Azure Pipelines Only If you are only using Azure Pipelines along with a different SCM tool then you can use the following two annotations to see Builds: diff --git a/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx b/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx index 409602eec4..e165236fe8 100644 --- a/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx +++ b/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx @@ -99,7 +99,7 @@ describe('useBuildRuns', () => { renderHook(() => useBuildRuns(entity), { wrapper: Wrapper, }), - ).toThrow('Value for annotation "dev.azure.com/project" was not found'); + ).toThrow('Expected "dev.azure.com" annotations were not found'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/hooks/useGitTags.test.tsx b/plugins/azure-devops/src/hooks/useGitTags.test.tsx index 1a5620e16e..1c07b8868e 100644 --- a/plugins/azure-devops/src/hooks/useGitTags.test.tsx +++ b/plugins/azure-devops/src/hooks/useGitTags.test.tsx @@ -103,7 +103,7 @@ describe('useGitTags', () => { renderHook(() => useGitTags(entity), { wrapper: Wrapper, }), - ).toThrow('Value for annotation "dev.azure.com/project" was not found'); + ).toThrow('Expected "dev.azure.com" annotations were not found'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/hooks/usePullRequests.test.tsx b/plugins/azure-devops/src/hooks/usePullRequests.test.tsx index 3e51c003e6..65579a2adf 100644 --- a/plugins/azure-devops/src/hooks/usePullRequests.test.tsx +++ b/plugins/azure-devops/src/hooks/usePullRequests.test.tsx @@ -102,7 +102,7 @@ describe('usePullRequests', () => { renderHook(() => usePullRequests(entity), { wrapper: Wrapper, }), - ).toThrow('Value for annotation "dev.azure.com/project" was not found'); + ).toThrow('Expected "dev.azure.com" annotations were not found'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/hooks/useReadme.test.tsx b/plugins/azure-devops/src/hooks/useReadme.test.tsx index ffc33c136b..fdb9080bba 100644 --- a/plugins/azure-devops/src/hooks/useReadme.test.tsx +++ b/plugins/azure-devops/src/hooks/useReadme.test.tsx @@ -81,7 +81,7 @@ describe('useReadme', () => { renderHook(() => useReadme(entity), { wrapper: Wrapper, }), - ).toThrow('Value for annotation "dev.azure.com/project" was not found'); + ).toThrow('Expected "dev.azure.com" annotations were not found'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/plugin.test.ts b/plugins/azure-devops/src/plugin.test.ts index f23639798f..d69fed6bab 100644 --- a/plugins/azure-devops/src/plugin.test.ts +++ b/plugins/azure-devops/src/plugin.test.ts @@ -13,10 +13,102 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { azureDevOpsPlugin } from './plugin'; +import { Entity } from '@backstage/catalog-model'; +import { azureDevOpsPlugin, isAzurePipelinesAvailable } from './plugin'; describe('azure-devops', () => { it('should export plugin', () => { expect(azureDevOpsPlugin).toBeDefined(); }); + + describe('isAzurePipelinesAvailable', () => { + it('should be true when project-repo annotation is present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + annotations: { + 'dev.azure.com/project-repo': 'projectName/repoName', + }, + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(true); + }); + + it('should be true when project and build-definition annotation is present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + annotations: { + 'dev.azure.com/project': 'projectName', + 'dev.azure.com/build-definition': 'buildDefinitionName', + }, + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(true); + }); + + it('should be true when project-repo and build-definition annotation is present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + annotations: { + 'dev.azure.com/project-repo': 'projectName/repoName', + 'dev.azure.com/build-definition': 'buildDefinitionName', + }, + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(true); + }); + + it('should be false when no annotations are present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(false); + }); + + it('should be false when only project annotation is present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + annotations: { + 'dev.azure.com/project': 'projectName', + }, + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(false); + }); + + it('should be false when only build-definition annotation is present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + annotations: { + 'dev.azure.com/build-definition': 'buildDefinitionName', + }, + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(false); + }); + }); }); diff --git a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts index c13dc526d8..9325a79039 100644 --- a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts +++ b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts @@ -18,6 +18,22 @@ import { Entity } from '@backstage/catalog-model'; import { getAnnotationValuesFromEntity } from './getAnnotationValuesFromEntity'; describe('getAnnotationValuesFromEntity', () => { + describe('without any annotations', () => { + it('should throw annotations not found', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'project-repo', + }, + }; + expect(() => getAnnotationValuesFromEntity(entity)).toThrow( + 'Expected "dev.azure.com" annotations were not found', + ); + }); + }); + describe('with valid project-repo annotation', () => { it('should return project and repo', () => { const entity: Entity = { @@ -140,7 +156,7 @@ describe('getAnnotationValuesFromEntity', () => { }); describe('with only project annotation', () => { - it('should should throw annotation not found error', () => { + it('should throw annotation not found error', () => { const entity: Entity = { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', @@ -163,7 +179,7 @@ describe('getAnnotationValuesFromEntity', () => { }); describe('with only build-definition annotation', () => { - it('should should throw annotation not found error', () => { + it('should throw annotation not found error', () => { const entity: Entity = { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', @@ -381,4 +397,55 @@ describe('getAnnotationValuesFromEntity', () => { ); }); }); + + describe('projectRepo and buildDefinition are provided', () => { + it('should return project, repo and buildDefinition', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'project-repo', + annotations: { + 'dev.azure.com/build-definition': 'buildDefinitionName', + 'dev.azure.com/project-repo': 'projectName/repoName', + }, + }, + }; + const values = getAnnotationValuesFromEntity(entity); + expect(values).toEqual({ + project: 'projectName', + repo: 'repoName', + definition: 'buildDefinitionName', + host: undefined, + org: undefined, + }); + }); + }); + + describe('project, projectRepo and buildDefinition are provided', () => { + it('should prefer project over project-repo.project and return no repo', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'project-repo', + annotations: { + 'dev.azure.com/project': 'projectName', + 'dev.azure.com/build-definition': 'buildDefinitionName', + 'dev.azure.com/project-repo': 'ignoredProject/repoName', + }, + }, + }; + const values = getAnnotationValuesFromEntity(entity); + expect(values).toEqual({ + project: 'projectName', + repo: undefined, + definition: 'buildDefinitionName', + host: undefined, + org: undefined, + }); + }); + }); }); diff --git a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts index 83091fb155..7533c473ed 100644 --- a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts +++ b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts @@ -29,34 +29,49 @@ export function getAnnotationValuesFromEntity(entity: Entity): { host?: string; org?: string; } { - const { host, org } = getHostOrg(entity.metadata.annotations); - - const projectRepoValues = getProjectRepo(entity.metadata.annotations); - if (projectRepoValues.project && projectRepoValues.repo) { - return { - project: projectRepoValues.project, - repo: projectRepoValues.repo, - host, - org, - }; - } - + const hostOrg = getHostOrg(entity.metadata.annotations); + const projectRepo = getProjectRepo(entity.metadata.annotations); const project = entity.metadata.annotations?.[AZURE_DEVOPS_PROJECT_ANNOTATION]; - if (!project) { + const definition = + entity.metadata.annotations?.[AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION]; + + if (definition) { + if (project) { + return { + project, + definition, + ...hostOrg, + }; + } + if (projectRepo.project) { + return { + project: projectRepo.project, + repo: projectRepo.repo, + definition, + ...hostOrg, + }; + } throw new Error( `Value for annotation "${AZURE_DEVOPS_PROJECT_ANNOTATION}" was not found`, ); + } else { + if (projectRepo.project) { + return { + project: projectRepo.project, + repo: projectRepo.repo, + ...hostOrg, + }; + } + + if (project) { + throw new Error( + `Value for annotation "${AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION}" was not found`, + ); + } } - const definition = - entity.metadata.annotations?.[AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION]; - if (!definition) { - throw new Error( - `Value for annotation "${AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION}" was not found`, - ); - } - return { project, definition, host, org }; + throw new Error('Expected "dev.azure.com" annotations were not found'); } function getProjectRepo(annotations?: Record): { diff --git a/plugins/catalog-backend/src/schema/openapi.generated.ts b/plugins/catalog-backend/src/schema/openapi.generated.ts index fe64c75373..c29dd78ec6 100644 --- a/plugins/catalog-backend/src/schema/openapi.generated.ts +++ b/plugins/catalog-backend/src/schema/openapi.generated.ts @@ -22,7 +22,7 @@ import { createValidatedOpenApiRouter } from '@backstage/backend-openapi-utils'; export const spec = { openapi: '3.0.3', info: { - title: '@backstage/plugin-catalog-backend', + title: 'catalog', version: '1', description: 'The Backstage backend plugin that provides the Backstage catalog', @@ -36,9 +36,6 @@ export const spec = { { url: '/', }, - { - url: 'catalog', - }, ], components: { examples: {}, diff --git a/plugins/catalog-backend/src/schema/openapi.yaml b/plugins/catalog-backend/src/schema/openapi.yaml index d3ef718286..51283d5fbc 100644 --- a/plugins/catalog-backend/src/schema/openapi.yaml +++ b/plugins/catalog-backend/src/schema/openapi.yaml @@ -1,6 +1,6 @@ openapi: 3.0.3 info: - title: '@backstage/plugin-catalog-backend' + title: catalog version: '1' description: The Backstage backend plugin that provides the Backstage catalog license: @@ -9,7 +9,6 @@ info: contact: {} servers: - url: / - - url: catalog components: examples: {} headers: {} diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx index ed22e126c5..5b5bd39310 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx @@ -26,6 +26,7 @@ import { TextField, Typography, makeStyles, + Tooltip, } from '@material-ui/core'; import CheckBoxIcon from '@material-ui/icons/CheckBox'; import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; @@ -39,6 +40,8 @@ import PersonIcon from '@material-ui/icons/Person'; import GroupIcon from '@material-ui/icons/Group'; import { humanizeEntity, humanizeEntityRef } from '../EntityRefLink/humanize'; import { useFetchEntities } from './useFetchEntities'; +import { withStyles } from '@material-ui/core/styles'; +import { useEntityPresentation } from '../../apis'; /** @public */ export type CatalogReactEntityOwnerPickerClassKey = 'input'; @@ -46,12 +49,30 @@ export type CatalogReactEntityOwnerPickerClassKey = 'input'; const useStyles = makeStyles( { input: {}, + fullWidth: { width: '100%' }, + boxLabel: { + width: '100%', + textOverflow: 'ellipsis', + overflow: 'hidden', + }, }, { name: 'CatalogReactEntityOwnerPicker', }, ); +const FixedWidthFormControlLabel = withStyles( + _theme => ({ + label: { + width: '100%', + }, + root: { + width: '90%', + }, + }), + { name: 'FixedWidthFormControlLabel' }, +)(FormControlLabel); + const icon = ; const checkedIcon = ; @@ -62,6 +83,42 @@ export type EntityOwnerPickerProps = { mode?: 'owners-only' | 'all'; }; +function RenderOptionLabel(props: { entity: Entity; isSelected: boolean }) { + const classes = useStyles(); + const isGroup = props.entity.kind.toLocaleLowerCase('en-US') === 'group'; + const { primaryTitle: title } = useEntityPresentation(props.entity); + return ( + + + } + onClick={event => event.preventDefault()} + label={ + + + {isGroup ? ( + + ) : ( + + )} +   + + {title} + + + + } + /> + + ); +} + /** @public */ export const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => { const classes = useStyles(); @@ -153,41 +210,13 @@ export const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => { if (typeof e !== 'string') { cache.setEntity(e); } - return entityRef; }), ); }} filterOptions={x => x} renderOption={(entity, { selected }) => { - const isGroup = entity.kind.toLocaleLowerCase('en-US') === 'group'; - - return ( - - } - onClick={event => event.preventDefault()} - label={ - - {isGroup ? ( - - ) : ( - - )} -   - {humanizeEntity( - entity, - humanizeEntityRef(entity, { defaultKind: entity.kind }), - )} - - } - /> - ); + return ; }} size="small" popupIcon={} diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md index bef24b50d8..feda3fd70d 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/api-report.md @@ -182,6 +182,7 @@ export const CatalogTable: { ): TableColumn; createNamespaceColumn(): TableColumn; }>; + defaultColumnsFunc: CatalogTableColumnsFunc; }; // @public diff --git a/plugins/catalog/src/alpha/plugin.tsx b/plugins/catalog/src/alpha/plugin.tsx index 99aacd27da..9a964c4e46 100644 --- a/plugins/catalog/src/alpha/plugin.tsx +++ b/plugins/catalog/src/alpha/plugin.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { convertLegacyRouteRef } from '@backstage/core-compat-api'; +import { convertLegacyRouteRefs } from '@backstage/core-compat-api'; import { createPlugin } from '@backstage/frontend-plugin-api'; import { entityRouteRef } from '@backstage/plugin-catalog-react'; @@ -38,16 +38,16 @@ import searchResultItems from './searchResultItems'; /** @alpha */ export default createPlugin({ id: 'catalog', - routes: { - catalogIndex: convertLegacyRouteRef(rootRouteRef), - catalogEntity: convertLegacyRouteRef(entityRouteRef), - }, - externalRoutes: { - viewTechDoc: convertLegacyRouteRef(viewTechDocRouteRef), - createComponent: convertLegacyRouteRef(createComponentRouteRef), - createFromTemplate: convertLegacyRouteRef(createFromTemplateRouteRef), - unregisterRedirect: convertLegacyRouteRef(unregisterRedirectRouteRef), - }, + routes: convertLegacyRouteRefs({ + catalogIndex: rootRouteRef, + catalogEntity: entityRouteRef, + }), + externalRoutes: convertLegacyRouteRefs({ + viewTechDoc: viewTechDocRouteRef, + createComponent: createComponentRouteRef, + createFromTemplate: createFromTemplateRouteRef, + unregisterRedirect: unregisterRedirectRouteRef, + }), extensions: [ ...apis, ...pages, diff --git a/plugins/catalog/src/apis/EntityPresentationApi/defaults.tsx b/plugins/catalog/src/apis/EntityPresentationApi/defaults.tsx index 84f04c6f83..813f2e3eb8 100644 --- a/plugins/catalog/src/apis/EntityPresentationApi/defaults.tsx +++ b/plugins/catalog/src/apis/EntityPresentationApi/defaults.tsx @@ -18,15 +18,15 @@ import { IconComponent } from '@backstage/core-plugin-api'; import { defaultEntityPresentation } from '@backstage/plugin-catalog-react'; import { HumanDuration } from '@backstage/types'; import ApartmentIcon from '@material-ui/icons/Apartment'; -import BusinessIcon from '@material-ui/icons/Business'; +import CategoryIcon from '@material-ui/icons/Category'; import ExtensionIcon from '@material-ui/icons/Extension'; import HelpIcon from '@material-ui/icons/Help'; -import LibraryAddIcon from '@material-ui/icons/LibraryAdd'; +import FeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList'; import LocationOnIcon from '@material-ui/icons/LocationOn'; import MemoryIcon from '@material-ui/icons/Memory'; import PeopleIcon from '@material-ui/icons/People'; import PersonIcon from '@material-ui/icons/Person'; -import WorkIcon from '@material-ui/icons/Work'; +import StorageIcon from '@material-ui/icons/Storage'; import { DefaultEntityPresentationApiRenderer } from './DefaultEntityPresentationApi'; export const DEFAULT_CACHE_TTL: HumanDuration = { seconds: 10 }; @@ -38,13 +38,13 @@ export const UNKNOWN_KIND_ICON: IconComponent = HelpIcon; export const DEFAULT_ICONS: Record = { api: ExtensionIcon, component: MemoryIcon, - system: BusinessIcon, - resource: WorkIcon, + system: CategoryIcon, + resource: StorageIcon, domain: ApartmentIcon, location: LocationOnIcon, user: PersonIcon, group: PeopleIcon, - template: LibraryAddIcon, + template: FeaturedPlayListIcon, }; export function createDefaultRenderer(options: { diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx index 006210bb1d..7da12d7138 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx @@ -47,6 +47,7 @@ import React, { ReactNode, useMemo } from 'react'; import { columnFactories } from './columns'; import { CatalogTableColumnsFunc, CatalogTableRow } from './types'; import { PaginatedCatalogTable } from './PaginatedCatalogTable'; +import { defaultCatalogTableColumnsFunc } from './defaultCatalogTableColumnsFunc'; /** * Props for {@link CatalogTable}. @@ -77,52 +78,10 @@ const refCompare = (a: Entity, b: Entity) => { return toRef(a).localeCompare(toRef(b)); }; -const defaultColumnsFunc: CatalogTableColumnsFunc = ({ filters, entities }) => { - const showTypeColumn = filters.type === undefined; - - return [ - columnFactories.createTitleColumn({ hidden: true }), - columnFactories.createNameColumn({ defaultKind: filters.kind?.value }), - ...createEntitySpecificColumns(), - columnFactories.createMetadataDescriptionColumn(), - columnFactories.createTagsColumn(), - ]; - - function createEntitySpecificColumns(): TableColumn[] { - const baseColumns = [ - columnFactories.createSystemColumn(), - columnFactories.createOwnerColumn(), - columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }), - columnFactories.createSpecLifecycleColumn(), - ]; - switch (filters.kind?.value) { - case 'user': - return []; - case 'domain': - case 'system': - return [columnFactories.createOwnerColumn()]; - case 'group': - case 'template': - return [ - columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }), - ]; - case 'location': - return [ - columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }), - columnFactories.createSpecTargetsColumn(), - ]; - default: - return entities.every(entity => entity.metadata.namespace === 'default') - ? baseColumns - : [...baseColumns, columnFactories.createNamespaceColumn()]; - } - } -}; - /** @public */ export const CatalogTable = (props: CatalogTableProps) => { const { - columns = defaultColumnsFunc, + columns = defaultCatalogTableColumnsFunc, tableOptions, subtitle, emptyContent, @@ -267,6 +226,7 @@ export const CatalogTable = (props: CatalogTableProps) => { }; CatalogTable.columns = columnFactories; +CatalogTable.defaultColumnsFunc = defaultCatalogTableColumnsFunc; function toEntityRow(entity: Entity) { const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, { diff --git a/plugins/catalog/src/components/CatalogTable/defaultCatalogTableColumnsFunc.tsx b/plugins/catalog/src/components/CatalogTable/defaultCatalogTableColumnsFunc.tsx new file mode 100644 index 0000000000..85f44d3f51 --- /dev/null +++ b/plugins/catalog/src/components/CatalogTable/defaultCatalogTableColumnsFunc.tsx @@ -0,0 +1,67 @@ +/* + * Copyright 2023 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 { TableColumn } from '@backstage/core-components'; +import { columnFactories } from './columns'; +import { CatalogTableColumnsFunc, CatalogTableRow } from './types'; + +// The defaultCatalogTableColumnsFunc symbol is not directly exported, but through the +// CatalogTable.defaultColumnsFunc field. +/** @public */ +export const defaultCatalogTableColumnsFunc: CatalogTableColumnsFunc = ({ + filters, + entities, +}) => { + const showTypeColumn = filters.type === undefined; + + return [ + columnFactories.createTitleColumn({ hidden: true }), + columnFactories.createNameColumn({ defaultKind: filters.kind?.value }), + ...createEntitySpecificColumns(), + columnFactories.createMetadataDescriptionColumn(), + columnFactories.createTagsColumn(), + ]; + + function createEntitySpecificColumns(): TableColumn[] { + const baseColumns = [ + columnFactories.createSystemColumn(), + columnFactories.createOwnerColumn(), + columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }), + columnFactories.createSpecLifecycleColumn(), + ]; + switch (filters.kind?.value) { + case 'user': + return []; + case 'domain': + case 'system': + return [columnFactories.createOwnerColumn()]; + case 'group': + case 'template': + return [ + columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }), + ]; + case 'location': + return [ + columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }), + columnFactories.createSpecTargetsColumn(), + ]; + default: + return entities.every(entity => entity.metadata.namespace === 'default') + ? baseColumns + : [...baseColumns, columnFactories.createNamespaceColumn()]; + } + } +}; diff --git a/plugins/cloudbuild/README.md b/plugins/cloudbuild/README.md index 07999c85a1..2677d02b13 100644 --- a/plugins/cloudbuild/README.md +++ b/plugins/cloudbuild/README.md @@ -1,4 +1,4 @@ -# Google Cloud Build +# Google Cloud Build Plugin ### Welcome to the Google Cloud Build plugin! @@ -47,7 +47,7 @@ const cicdContent = ( ##### OPTIONAL -If you don't use GitHub Actions, or don't want to show it on your CI/CD page, then you can remove the switch case for it +If you don't use GitHub Actions, or don't want to show it on your CI/CD page, then you can remove the switch case for it: ```diff // packages/app/src/components/catalog/EntityPage.tsx @@ -62,9 +62,9 @@ const cicdContent = ( - ``` -### Add annotation to your component-info.yaml file. +### Add annotation(s) to your component-info.yaml file -Any component, that you would like the Cloud Build Plugin to populate for, should include the following annotation: +Any component, that you would like the Cloud Build Plugin to populate for, should include the following `cloudbuild-project-slug` annotation. This annotation sets the GCP project name to be used for pulling the Cloud Build details from. ```diff // component-info.yaml @@ -79,3 +79,62 @@ spec: type: website lifecycle: development ``` + +By default, the cloud build results list is filtered by repository name equal to the name you have set in your component-info.yaml file. This is `metadata.name`. So if your metadata.name is `backstage` then it will only show builds matching the backstage repo name. + +Additionally, build results are pulled from the `global` region by default. + +#### Change Filtering + +If you need the page to be filtered on a different repository name, then you can use the following annotation: + +```diff +// component-info.yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage + description: Backstage application. + annotations: + google.com/cloudbuild-project-slug: your-project-name ++ google.com/cloudbuild-repo-name: my-backstage +spec: + type: website + lifecycle: development +``` + +You can also automatically filter the results based on trigger name instead of repository name. To do so, use the following annotation: + +```diff +// component-info.yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage + description: Backstage application. + annotations: + google.com/cloudbuild-project-slug: your-project-name ++ google.com/cloudbuild-trigger-name: my-trigger-name +spec: + type: website + lifecycle: development +``` + +`Note:` The `cloudbuild-repo-name` annotation takes precedence over the `cloudbuild-trigger-name` annotation. So if you happen to use both annotations, cloudbuild-repo-name will be used. It is recommended to use one or the other if required. + +If you need to pull Cloud Build results from a location or region other than the global scope, then use the following annotation: + +```diff +// component-info.yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage + description: Backstage application. + annotations: + google.com/cloudbuild-project-slug: your-project-name ++ google.com/cloudbuild-location: us-central1 +spec: + type: website + lifecycle: development +``` diff --git a/plugins/cloudbuild/api-report.md b/plugins/cloudbuild/api-report.md index 3fbb15000d..2ce42d5e34 100644 --- a/plugins/cloudbuild/api-report.md +++ b/plugins/cloudbuild/api-report.md @@ -58,17 +58,22 @@ export const CLOUDBUILD_ANNOTATION = 'google.com/cloudbuild-project-slug'; export type CloudbuildApi = { listWorkflowRuns: (options: { projectId: string; + location: string; + cloudBuildFilter: string; }) => Promise; getWorkflow: (options: { projectId: string; + location: string; id: string; }) => Promise; getWorkflowRun: (options: { projectId: string; + location: string; id: string; }) => Promise; reRunWorkflow: (options: { projectId: string; + location: string; runId: string; }) => Promise; }; @@ -84,19 +89,27 @@ export class CloudbuildClient implements CloudbuildApi { // (undocumented) getWorkflow(options: { projectId: string; + location: string; id: string; }): Promise; // (undocumented) getWorkflowRun(options: { projectId: string; + location: string; id: string; }): Promise; // (undocumented) listWorkflowRuns(options: { projectId: string; + location: string; + cloudBuildFilter: string; }): Promise; // (undocumented) - reRunWorkflow(options: { projectId: string; runId: string }): Promise; + reRunWorkflow(options: { + projectId: string; + location: string; + runId: string; + }): Promise; } // @public (undocumented) @@ -234,11 +247,11 @@ export interface StorageSource { // @public (undocumented) export interface Substitutions { - // (undocumented) - BRANCH_NAME: string; // (undocumented) COMMIT_SHA: string; // (undocumented) + REF_NAME: string; + // (undocumented) REPO_NAME: string; // (undocumented) REVISION_ID: string; diff --git a/plugins/cloudbuild/src/api/CloudbuildApi.ts b/plugins/cloudbuild/src/api/CloudbuildApi.ts index cb29b49fbf..9e2d63fc01 100644 --- a/plugins/cloudbuild/src/api/CloudbuildApi.ts +++ b/plugins/cloudbuild/src/api/CloudbuildApi.ts @@ -29,17 +29,22 @@ export const cloudbuildApiRef = createApiRef({ export type CloudbuildApi = { listWorkflowRuns: (options: { projectId: string; + location: string; + cloudBuildFilter: string; }) => Promise; getWorkflow: (options: { projectId: string; + location: string; id: string; }) => Promise; getWorkflowRun: (options: { projectId: string; + location: string; id: string; }) => Promise; reRunWorkflow: (options: { projectId: string; + location: string; runId: string; }) => Promise; }; diff --git a/plugins/cloudbuild/src/api/CloudbuildClient.ts b/plugins/cloudbuild/src/api/CloudbuildClient.ts index 06f393b433..256e702cda 100644 --- a/plugins/cloudbuild/src/api/CloudbuildClient.ts +++ b/plugins/cloudbuild/src/api/CloudbuildClient.ts @@ -28,11 +28,14 @@ export class CloudbuildClient implements CloudbuildApi { async reRunWorkflow(options: { projectId: string; + location: string; runId: string; }): Promise { await this.request( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( options.projectId, + )}/locations/${encodeURIComponent( + options.location, )}/builds/${encodeURIComponent(options.runId)}:retry`, 'POST', ); @@ -40,11 +43,15 @@ export class CloudbuildClient implements CloudbuildApi { async listWorkflowRuns(options: { projectId: string; + location: string; + cloudBuildFilter: string; }): Promise { const workflowRuns = await this.request( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( options.projectId, - )}/builds`, + )}/locations/${encodeURIComponent( + options.location, + )}/builds?filter=${encodeURIComponent(options.cloudBuildFilter)}`, ); const builds: ActionsListWorkflowRunsForRepoResponseData = @@ -55,11 +62,14 @@ export class CloudbuildClient implements CloudbuildApi { async getWorkflow(options: { projectId: string; + location: string; id: string; }): Promise { const workflow = await this.request( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( options.projectId, + )}/locations/${encodeURIComponent( + options.location, )}/builds/${encodeURIComponent(options.id)}`, ); @@ -70,11 +80,14 @@ export class CloudbuildClient implements CloudbuildApi { async getWorkflowRun(options: { projectId: string; + location: string; id: string; }): Promise { const workflow = await this.request( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( options.projectId, + )}/locations/${encodeURIComponent( + options.location, )}/builds/${encodeURIComponent(options.id)}`, ); const build: ActionsGetWorkflowResponseData = await workflow.json(); diff --git a/plugins/cloudbuild/src/api/types.ts b/plugins/cloudbuild/src/api/types.ts index 1dd03265bc..b721e8dca1 100644 --- a/plugins/cloudbuild/src/api/types.ts +++ b/plugins/cloudbuild/src/api/types.ts @@ -81,7 +81,7 @@ export interface Options { export interface Substitutions { COMMIT_SHA: string; SHORT_SHA: string; - BRANCH_NAME: string; + REF_NAME: string; REPO_NAME: string; REVISION_ID: string; } diff --git a/plugins/cloudbuild/src/components/Cards/Cards.tsx b/plugins/cloudbuild/src/components/Cards/Cards.tsx index 11efe520e0..5d837cce68 100644 --- a/plugins/cloudbuild/src/components/Cards/Cards.tsx +++ b/plugins/cloudbuild/src/components/Cards/Cards.tsx @@ -22,6 +22,8 @@ import { WorkflowRunStatus } from '../WorkflowRunStatus'; import { makeStyles, LinearProgress } from '@material-ui/core'; import ExternalLinkIcon from '@material-ui/icons/Launch'; import { CLOUDBUILD_ANNOTATION } from '../useProjectName'; +import { getLocation } from '../useLocation'; +import { getCloudbuildFilter } from '../useCloudBuildFilter'; import { InfoCard, @@ -79,9 +81,13 @@ export const LatestWorkflowRunCard = (props: { branch: string }) => { const { entity } = useEntity(); const errorApi = useApi(errorApiRef); const projectId = entity?.metadata.annotations?.[CLOUDBUILD_ANNOTATION] || ''; + const location = getLocation(entity); + const cloudBuildFilter = getCloudbuildFilter(entity); const [{ runs, loading, error }] = useWorkflowRuns({ projectId, + location, + cloudBuildFilter, }); const lastRun = runs?.[0] ?? ({} as WorkflowRun); useEffect(() => { diff --git a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx index f55d7957a3..1c9bdcbf5f 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx @@ -34,6 +34,7 @@ import { useProjectName } from '../useProjectName'; import { WorkflowRunStatus } from '../WorkflowRunStatus'; import { useWorkflowRunsDetails } from './useWorkflowRunsDetails'; import { Breadcrumbs, Link, WarningPanel } from '@backstage/core-components'; +import { getLocation } from '../useLocation'; const useStyles = makeStyles(theme => ({ root: { @@ -63,8 +64,9 @@ const useStyles = makeStyles(theme => ({ export const WorkflowRunDetails = (props: { entity: Entity }) => { const { value: projectName, loading, error } = useProjectName(props.entity); const [projectId] = (projectName ?? '/').split('/'); + const location = getLocation(props.entity); - const details = useWorkflowRunsDetails(projectId); + const details = useWorkflowRunsDetails(projectId, location); const classes = useStyles(); if (error) { @@ -96,9 +98,9 @@ export const WorkflowRunDetails = (props: { entity: Entity }) => { - Branch + Ref - {details.value?.substitutions.BRANCH_NAME} + {details.value?.substitutions.REF_NAME} diff --git a/plugins/cloudbuild/src/components/WorkflowRunDetails/useWorkflowRunsDetails.ts b/plugins/cloudbuild/src/components/WorkflowRunDetails/useWorkflowRunsDetails.ts index 549ab1eaf2..abc146fb6c 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunDetails/useWorkflowRunsDetails.ts +++ b/plugins/cloudbuild/src/components/WorkflowRunDetails/useWorkflowRunsDetails.ts @@ -18,13 +18,14 @@ import { cloudbuildApiRef } from '../../api'; import { useApi, useRouteRefParams } from '@backstage/core-plugin-api'; import { buildRouteRef } from '../../routes'; -export const useWorkflowRunsDetails = (projectId: string) => { +export const useWorkflowRunsDetails = (projectId: string, location: string) => { const api = useApi(cloudbuildApiRef); const { id } = useRouteRefParams(buildRouteRef); const details = useAsync(async () => { return projectId ? api.getWorkflowRun({ projectId, + location, id: id, }) : Promise.reject('No projectId provided'); diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx index 0152f9d964..92a806bee7 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx @@ -35,7 +35,7 @@ describe('', () => { substitutions: { COMMIT_SHA: 'e3adasd2e3adasd2e3adasd2', SHORT_SHA: 'f12j1231', - BRANCH_NAME: 'main', + REF_NAME: 'main', REPO_NAME: 'backstage', REVISION_ID: 'g123123', }, diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx index 294847a700..65b5ca149f 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx @@ -26,6 +26,8 @@ import { buildRouteRef } from '../../routes'; import { DateTime } from 'luxon'; import { Table, TableColumn, Link } from '@backstage/core-components'; import { useRouteRef } from '@backstage/core-plugin-api'; +import { getLocation } from '../useLocation'; +import { getCloudbuildFilter } from '../useCloudBuildFilter'; const generatedColumns: TableColumn[] = [ { @@ -71,7 +73,7 @@ const generatedColumns: TableColumn[] = [ title: 'Ref', render: (row: Partial) => ( - {row.substitutions?.BRANCH_NAME} + {row.substitutions?.REF_NAME} ), }, @@ -162,9 +164,12 @@ export const WorkflowRunsTableView = ({ export const WorkflowRunsTable = (props: { entity: Entity }) => { const { value: projectName, loading } = useProjectName(props.entity); const [projectId] = (projectName ?? '/').split('/'); - + const location = getLocation(props.entity); + const cloudBuildFilter = getCloudbuildFilter(props.entity); const [tableProps, { retry, setPage, setPageSize }] = useWorkflowRuns({ projectId, + location, + cloudBuildFilter, }); return ( diff --git a/plugins/cloudbuild/src/components/useCloudBuildFilter.ts b/plugins/cloudbuild/src/components/useCloudBuildFilter.ts new file mode 100644 index 0000000000..a71cc1e9b6 --- /dev/null +++ b/plugins/cloudbuild/src/components/useCloudBuildFilter.ts @@ -0,0 +1,43 @@ +/* + * 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 { Entity } from '@backstage/catalog-model'; + +const CLOUDBUILD_FILTER_REPO_STRING = 'substitutions.REPO_NAME='; +const CLOUDBUILD_FILTER_REPO_ANNOTATION = 'google.com/cloudbuild-repo-name'; +const CLOUDBUILD_FILTER_TRIGGER_STRING = 'substitutions.TRIGGER_NAME='; +const CLOUDBUILD_FILTER_TRIGGER_ANNOTATION = + 'google.com/cloudbuild-trigger-name'; + +/** @public */ + +export const getCloudbuildFilter = (entity: Entity) => { + const repoAnnotation = + entity?.metadata.annotations?.[CLOUDBUILD_FILTER_REPO_ANNOTATION] ?? ''; + const triggerAnnotation = + entity?.metadata.annotations?.[CLOUDBUILD_FILTER_TRIGGER_ANNOTATION] ?? ''; + if (repoAnnotation) { + const cloudbuildFilter = CLOUDBUILD_FILTER_REPO_STRING + repoAnnotation; + return cloudbuildFilter; + } else if (triggerAnnotation) { + const cloudbuildFilter = + CLOUDBUILD_FILTER_TRIGGER_STRING + triggerAnnotation; + return cloudbuildFilter; + } + const entityName = entity?.metadata.name ?? ''; + const cloudbuildFilter = CLOUDBUILD_FILTER_REPO_STRING + entityName; + return cloudbuildFilter; +}; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/index.ts b/plugins/cloudbuild/src/components/useLocation.ts similarity index 61% rename from plugins/scaffolder/src/legacy/MultistepJsonForm/index.ts rename to plugins/cloudbuild/src/components/useLocation.ts index b125e7c4c2..54a3c8f776 100644 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/index.ts +++ b/plugins/cloudbuild/src/components/useLocation.ts @@ -13,4 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { MultistepJsonForm } from './MultistepJsonForm'; + +import { Entity } from '@backstage/catalog-model'; + +const CLOUDBUILD_LOCATION_ANNOTATION = 'google.com/cloudbuild-location'; + +/** @public */ + +export const getLocation = (entity: Entity) => { + const locationAnnotation = + entity?.metadata.annotations?.[CLOUDBUILD_LOCATION_ANNOTATION] ?? ''; + if (locationAnnotation) { + return locationAnnotation; + } + return 'global'; +}; diff --git a/plugins/cloudbuild/src/components/useWorkflowRuns.ts b/plugins/cloudbuild/src/components/useWorkflowRuns.ts index 424f08e38d..7e3e148dd1 100644 --- a/plugins/cloudbuild/src/components/useWorkflowRuns.ts +++ b/plugins/cloudbuild/src/components/useWorkflowRuns.ts @@ -33,8 +33,12 @@ export type WorkflowRun = { rerun: () => void; }; -export function useWorkflowRuns(options: { projectId: string }) { - const { projectId } = options; +export function useWorkflowRuns(options: { + projectId: string; + location: string; + cloudBuildFilter: string; +}) { + const { projectId, location, cloudBuildFilter } = options; const api = useApi(cloudbuildApiRef); const errorApi = useApi(errorApiRef); @@ -51,6 +55,8 @@ export function useWorkflowRuns(options: { projectId: string }) { return api .listWorkflowRuns({ projectId, + location, + cloudBuildFilter, }) .then( ( @@ -65,6 +71,7 @@ export function useWorkflowRuns(options: { projectId: string }) { try { await api.reRunWorkflow({ projectId, + location, runId: run.id, }); } catch (e) { diff --git a/plugins/devtools/api-report-alpha.md b/plugins/devtools/api-report-alpha.md new file mode 100644 index 0000000000..59aefd3698 --- /dev/null +++ b/plugins/devtools/api-report-alpha.md @@ -0,0 +1,19 @@ +## API Report File for "@backstage/plugin-devtools" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackstagePlugin } from '@backstage/frontend-plugin-api'; +import { RouteRef } from '@backstage/frontend-plugin-api'; + +// @alpha (undocumented) +const _default: BackstagePlugin< + { + root: RouteRef; + }, + {} +>; +export default _default; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json index ece8fe89e3..e972242c82 100644 --- a/plugins/devtools/package.json +++ b/plugins/devtools/package.json @@ -5,9 +5,22 @@ "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.esm.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "frontend-plugin" @@ -29,9 +42,11 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { + "@backstage/core-compat-api": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", "@backstage/plugin-devtools-common": "workspace:^", "@backstage/plugin-permission-react": "workspace:^", "@material-ui/core": "^4.9.13", diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/index.ts b/plugins/devtools/src/alpha.ts similarity index 89% rename from plugins/scaffolder/src/legacy/TemplateEditorPage/index.ts rename to plugins/devtools/src/alpha.ts index 7de0d3c679..e80f131817 100644 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/index.ts +++ b/plugins/devtools/src/alpha.ts @@ -13,4 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { TemplateEditorPage } from './TemplateEditorPage'; + +export * from './alpha/index'; +export { default } from './alpha/index'; diff --git a/plugins/scaffolder-react/src/legacy/index.ts b/plugins/devtools/src/alpha/index.ts similarity index 94% rename from plugins/scaffolder-react/src/legacy/index.ts rename to plugins/devtools/src/alpha/index.ts index c539a8ba60..2f137f09ee 100644 --- a/plugins/scaffolder-react/src/legacy/index.ts +++ b/plugins/devtools/src/alpha/index.ts @@ -13,4 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export * from './extensions'; + +export { default } from './plugin'; diff --git a/plugins/devtools/src/alpha/plugin.tsx b/plugins/devtools/src/alpha/plugin.tsx new file mode 100644 index 0000000000..746b90a50f --- /dev/null +++ b/plugins/devtools/src/alpha/plugin.tsx @@ -0,0 +1,70 @@ +/* + * Copyright 2023 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 { + createApiExtension, + createApiFactory, + createNavItemExtension, + createPageExtension, + createPlugin, + discoveryApiRef, + identityApiRef, +} from '@backstage/frontend-plugin-api'; + +import { devToolsApiRef, DevToolsClient } from '../api'; +import { + compatWrapper, + convertLegacyRouteRef, +} from '@backstage/core-compat-api'; +import BuildIcon from '@material-ui/icons/Build'; +import { rootRouteRef } from '../routes'; + +/** @alpha */ +export const devToolsApi = createApiExtension({ + factory: createApiFactory({ + api: devToolsApiRef, + deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, + factory: ({ discoveryApi, identityApi }) => + new DevToolsClient({ discoveryApi, identityApi }), + }), +}); + +/** @alpha */ +export const devToolsPage = createPageExtension({ + defaultPath: '/devtools', + routeRef: convertLegacyRouteRef(rootRouteRef), + loader: () => + import('../components/DevToolsPage').then(m => + compatWrapper(), + ), +}); + +/** @alpha */ +export const devToolsNavItem = createNavItemExtension({ + title: 'DevTools', + routeRef: convertLegacyRouteRef(rootRouteRef), + icon: BuildIcon, +}); + +/** @alpha */ +export default createPlugin({ + id: 'devtools', + routes: { + root: convertLegacyRouteRef(rootRouteRef), + }, + extensions: [devToolsApi, devToolsPage, devToolsNavItem], +}); diff --git a/plugins/explore-backend/README.md b/plugins/explore-backend/README.md index 543e8e2fa2..aae3ff94b8 100644 --- a/plugins/explore-backend/README.md +++ b/plugins/explore-backend/README.md @@ -9,6 +9,36 @@ for these tools. ### Adding the plugin to your `packages/backend` +Install dependencies + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-explore-backend +``` + +Add feature + +```ts title="packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-explore-backend')); +``` + +Config: + +```yaml +explore: + tools: + - title: New Relic + description: new relic plugin + url: /newrelic + image: https://i.imgur.com/L37ikrX.jpg + tags: + - newrelic + - proxy + - nerdGraph +``` + +### Adding the plugin to your `packages/backend` (old) + #### Tools as Config Install dependencies diff --git a/plugins/explore-backend/api-report.md b/plugins/explore-backend/api-report.md index b652f5515b..05a057fa7b 100644 --- a/plugins/explore-backend/api-report.md +++ b/plugins/explore-backend/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 { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { ExploreTool } from '@backstage/plugin-explore-common'; import express from 'express'; @@ -16,6 +17,10 @@ import type { ToolDocumentCollatorFactoryOptions as ToolDocumentCollatorFactoryO // @public (undocumented) export function createRouter(options: RouterOptions): Promise; +// @public +const explorePlugin: () => BackendFeature; +export default explorePlugin; + // @public (undocumented) export interface ExploreToolProvider { getTools(request: GetExploreToolsRequest): Promise; diff --git a/plugins/explore-backend/package.json b/plugins/explore-backend/package.json index 5af891fb02..36d0c2b7af 100644 --- a/plugins/explore-backend/package.json +++ b/plugins/explore-backend/package.json @@ -29,6 +29,7 @@ }, "dependencies": { "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/plugin-explore-common": "workspace:^", "@backstage/plugin-search-backend-module-explore": "workspace:^", @@ -42,6 +43,7 @@ "yn": "^4.0.0" }, "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "supertest": "^6.2.4" diff --git a/plugins/explore-backend/src/index.ts b/plugins/explore-backend/src/index.ts index 15659d6ab6..ae3ffd182b 100644 --- a/plugins/explore-backend/src/index.ts +++ b/plugins/explore-backend/src/index.ts @@ -20,6 +20,7 @@ * @packageDocumentation */ +export { explorePlugin as default } from './plugin'; export * from './service'; export * from './tools'; diff --git a/plugins/explore-backend/src/plugin.test.ts b/plugins/explore-backend/src/plugin.test.ts new file mode 100644 index 0000000000..391c00ba88 --- /dev/null +++ b/plugins/explore-backend/src/plugin.test.ts @@ -0,0 +1,50 @@ +/* + * Copyright 2024 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 { mockServices, startTestBackend } from '@backstage/backend-test-utils'; +import { ExploreTool } from '@backstage/plugin-explore-common'; +import { explorePlugin } from './plugin'; + +describe('explorePlugin', () => { + it('should register explore plugin and its router', async () => { + const tool: ExploreTool = { + title: 'Tool Title', + image: 'https://example.com/image.png', + url: 'https://example.com', + lifecycle: 'production', + tags: ['tag1', 'tag2'], + }; + + const httpRouterMock = mockServices.httpRouter.mock(); + + await startTestBackend({ + extensionPoints: [], + features: [ + explorePlugin(), + httpRouterMock.factory, + mockServices.rootConfig.factory({ + data: { + explore: { + tools: [tool], + }, + }, + }), + ], + }); + + expect(httpRouterMock.use).toHaveBeenCalledTimes(1); + }); +}); diff --git a/plugins/explore-backend/src/plugin.ts b/plugins/explore-backend/src/plugin.ts new file mode 100644 index 0000000000..d81493c85a --- /dev/null +++ b/plugins/explore-backend/src/plugin.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2024 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 { loggerToWinstonLogger } from '@backstage/backend-common'; +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { createRouter } from './service'; +import { StaticExploreToolProvider } from './tools'; + +/** + * The explore backend plugin. + * + * @public + */ +export const explorePlugin = createBackendPlugin({ + pluginId: 'explore', + register(env) { + env.registerInit({ + deps: { + config: coreServices.rootConfig, + httpRouter: coreServices.httpRouter, + logger: coreServices.logger, + }, + async init({ config, httpRouter, logger }) { + httpRouter.use( + await createRouter({ + logger: loggerToWinstonLogger(logger), + toolProvider: StaticExploreToolProvider.fromConfig(config), + }), + ); + }, + }); + }, +}); diff --git a/plugins/graphiql/src/alpha.tsx b/plugins/graphiql/src/alpha.tsx index fdd343020d..086f397d7a 100644 --- a/plugins/graphiql/src/alpha.tsx +++ b/plugins/graphiql/src/alpha.tsx @@ -37,6 +37,7 @@ import { graphiQLRouteRef } from './route-refs'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; /** @alpha */ @@ -128,7 +129,7 @@ export default createPlugin({ graphiqlGitlabGraphiQLEndpointExtension, graphiqlNavItem, ], - routes: { - root: convertLegacyRouteRef(graphiQLRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: graphiQLRouteRef, + }), }); diff --git a/plugins/home/src/api/VisitsStorageApi.ts b/plugins/home/src/api/VisitsStorageApi.ts index c72d4c5d64..a7cd063455 100644 --- a/plugins/home/src/api/VisitsStorageApi.ts +++ b/plugins/home/src/api/VisitsStorageApi.ts @@ -130,16 +130,16 @@ export class VisitsStorageApi implements VisitsApi { } return new Promise((resolve, reject) => { - const subsription = this.storageApi + const subscription = this.storageApi .observe$(storageKey) .subscribe({ next: next => { const visits = next.value ?? []; - subsription.unsubscribe(); + subscription.unsubscribe(); resolve(visits); }, error: err => { - subsription.unsubscribe(); + subscription.unsubscribe(); reject(err); }, }); diff --git a/plugins/scaffolder-backend-module-rails/Rails.dockerfile b/plugins/scaffolder-backend-module-rails/Rails.dockerfile index 921faa601d..8ea3fc370a 100644 --- a/plugins/scaffolder-backend-module-rails/Rails.dockerfile +++ b/plugins/scaffolder-backend-module-rails/Rails.dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.2 +FROM ruby:3.3 RUN apt-get update -qq && \ apt-get install -y nodejs postgresql-client git && \ diff --git a/plugins/scaffolder-react/api-report-alpha.md b/plugins/scaffolder-react/api-report-alpha.md index 615b54df84..6976951670 100644 --- a/plugins/scaffolder-react/api-report-alpha.md +++ b/plugins/scaffolder-react/api-report-alpha.md @@ -7,11 +7,8 @@ import { ApiHolder } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; -import { CustomFieldExtensionSchema } from '@backstage/plugin-scaffolder-react'; import { CustomFieldValidator } from '@backstage/plugin-scaffolder-react'; import { Dispatch } from 'react'; -import { Extension } from '@backstage/core-plugin-api'; -import { FieldExtensionComponent } from '@backstage/plugin-scaffolder-react'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; import { FieldValidation } from '@rjsf/utils'; import { FormProps } from '@backstage/plugin-scaffolder-react'; @@ -24,7 +21,6 @@ import { default as React_2 } from 'react'; import { ReactElement } from 'react'; import { ReactNode } from 'react'; import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; -import { ScaffolderRJSFFieldProps } from '@backstage/plugin-scaffolder-react'; import { ScaffolderRJSFFormProps } from '@backstage/plugin-scaffolder-react'; import { ScaffolderStep } from '@backstage/plugin-scaffolder-react'; import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; @@ -51,14 +47,6 @@ export const createAsyncValidators: ( // @alpha export const createFieldValidation: () => FieldValidation; -// @alpha -export function createLegacyScaffolderFieldExtension< - TReturnValue = unknown, - TInputProps = unknown, ->( - options: LegacyFieldExtensionOptions, -): Extension>; - // @alpha export const DefaultTemplateOutputs: (props: { output?: ScaffolderTaskOutput; @@ -83,39 +71,6 @@ export type FormValidation = { [name: string]: FieldValidation | FormValidation; }; -// @alpha -export type LegacyCustomFieldValidator = ( - data: TFieldReturnValue, - field: FieldValidation, - context: { - apiHolder: ApiHolder; - }, -) => void | Promise; - -// @alpha -export interface LegacyFieldExtensionComponentProps< - TFieldReturnValue, - TUiOptions = unknown, -> extends ScaffolderRJSFFieldProps { - // (undocumented) - uiSchema: ScaffolderRJSFFieldProps['uiSchema'] & { - 'ui:options'?: TUiOptions; - }; -} - -// @alpha -export type LegacyFieldExtensionOptions< - TFieldReturnValue = unknown, - TInputProps = unknown, -> = { - name: string; - component: ( - props: LegacyFieldExtensionComponentProps, - ) => JSX.Element | null; - validation?: LegacyCustomFieldValidator; - schema?: CustomFieldExtensionSchema; -}; - // @alpha export interface ParsedTemplateSchema { // (undocumented) diff --git a/plugins/scaffolder-react/src/alpha.ts b/plugins/scaffolder-react/src/alpha.ts index 224ee97c06..36c3fcf264 100644 --- a/plugins/scaffolder-react/src/alpha.ts +++ b/plugins/scaffolder-react/src/alpha.ts @@ -15,4 +15,3 @@ */ export * from './next'; -export * from './legacy'; diff --git a/plugins/scaffolder-react/src/legacy/extensions/index.tsx b/plugins/scaffolder-react/src/legacy/extensions/index.tsx deleted file mode 100644 index 870d797fc4..0000000000 --- a/plugins/scaffolder-react/src/legacy/extensions/index.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 { - LegacyCustomFieldValidator, - LegacyFieldExtensionOptions, - LegacyFieldExtensionComponentProps, -} from './types'; -import { Extension, attachComponentData } from '@backstage/core-plugin-api'; -import { FIELD_EXTENSION_KEY } from '../../extensions/keys'; -import { FieldExtensionComponent } from '@backstage/plugin-scaffolder-react'; - -/** - * Method for creating field extensions that can be used in the scaffolder - * frontend form. - * @alpha - */ -export function createLegacyScaffolderFieldExtension< - TReturnValue = unknown, - TInputProps = unknown, ->( - options: LegacyFieldExtensionOptions, -): Extension> { - return { - expose() { - const FieldExtensionDataHolder: any = () => null; - - attachComponentData( - FieldExtensionDataHolder, - FIELD_EXTENSION_KEY, - options, - ); - - return FieldExtensionDataHolder; - }, - }; -} - -export type { - LegacyCustomFieldValidator, - LegacyFieldExtensionOptions, - LegacyFieldExtensionComponentProps, -}; diff --git a/plugins/scaffolder-react/src/legacy/extensions/types.ts b/plugins/scaffolder-react/src/legacy/extensions/types.ts deleted file mode 100644 index 54c38ad2cd..0000000000 --- a/plugins/scaffolder-react/src/legacy/extensions/types.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 { ApiHolder } from '@backstage/core-plugin-api'; -import { FieldValidation } from '@rjsf/utils'; -import { - CustomFieldExtensionSchema, - ScaffolderRJSFFieldProps, -} from '@backstage/plugin-scaffolder-react'; - -/** - * Field validation type for Custom Field Extensions. - * - * @alpha - */ -export type LegacyCustomFieldValidator = ( - data: TFieldReturnValue, - field: FieldValidation, - context: { apiHolder: ApiHolder }, -) => void | Promise; - -/** - * Type for the Custom Field Extension with the - * name and components and validation function. - * - * @alpha - */ -export type LegacyFieldExtensionOptions< - TFieldReturnValue = unknown, - TInputProps = unknown, -> = { - name: string; - component: ( - props: LegacyFieldExtensionComponentProps, - ) => JSX.Element | null; - validation?: LegacyCustomFieldValidator; - schema?: CustomFieldExtensionSchema; -}; - -/** - * Type for field extensions and being able to type - * incoming props easier. - * - * @alpha - */ -export interface LegacyFieldExtensionComponentProps< - TFieldReturnValue, - TUiOptions = unknown, -> extends ScaffolderRJSFFieldProps { - uiSchema: ScaffolderRJSFFieldProps['uiSchema'] & { - 'ui:options'?: TUiOptions; - }; -} diff --git a/plugins/scaffolder/api-report-alpha.md b/plugins/scaffolder/api-report-alpha.md index c8824d42da..3f0b60cd95 100644 --- a/plugins/scaffolder/api-report-alpha.md +++ b/plugins/scaffolder/api-report-alpha.md @@ -3,19 +3,13 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -/// - import { BackstagePlugin } from '@backstage/frontend-plugin-api'; -import { ComponentType } from 'react'; -import { Entity } from '@backstage/catalog-model'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; import type { FormProps as FormProps_2 } from '@rjsf/core'; import { FormProps as FormProps_3 } from '@backstage/plugin-scaffolder-react'; -import { JSX as JSX_2 } from 'react'; import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; import { PathParams } from '@backstage/core-plugin-api'; -import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; import { RouteRef } from '@backstage/frontend-plugin-api'; @@ -55,40 +49,6 @@ export type FormProps = Pick< 'transformErrors' | 'noHtml5Validate' >; -// @alpha -export const LegacyRouter: (props: LegacyRouterProps) => React_2.JSX.Element; - -// @alpha -export type LegacyRouterProps = { - components?: { - ReviewStepComponent?: ComponentType; - TemplateCardComponent?: - | ComponentType<{ - template: TemplateEntityV1beta3; - }> - | undefined; - TaskPageComponent?: ComponentType>; - }; - groups?: Array<{ - title?: React_2.ReactNode; - filter: (entity: Entity) => boolean; - }>; - templateFilter?: (entity: TemplateEntityV1beta3) => boolean; - defaultPreviewTemplate?: string; - headerOptions?: { - pageTitleOverride?: string; - title?: string; - subtitle?: string; - }; - contextMenu?: { - editor?: boolean; - actions?: boolean; - }; -}; - -// @alpha -export const LegacyScaffolderPage: (props: LegacyRouterProps) => JSX_2.Element; - // @alpha (undocumented) export type TemplateListPageProps = { TemplateCardComponent?: React_2.ComponentType<{ diff --git a/plugins/scaffolder/dev/index.tsx b/plugins/scaffolder/dev/index.tsx index b683345ff5..e4425b04bf 100644 --- a/plugins/scaffolder/dev/index.tsx +++ b/plugins/scaffolder/dev/index.tsx @@ -24,7 +24,7 @@ import { } from '@backstage/plugin-catalog-react'; import React from 'react'; import { scaffolderApiRef, ScaffolderClient } from '../src'; -import { ScaffolderPage, LegacyScaffolderPage } from '../src/plugin'; +import { ScaffolderPage } from '../src/plugin'; import { discoveryApiRef, fetchApiRef, @@ -68,11 +68,6 @@ createDevApp() title: 'Create', element: , }) - .addPage({ - path: '/legacy-create', - title: 'Create (next)', - element: , - }) .addPage({ path: '/create-groups', title: 'Groups', @@ -91,22 +86,4 @@ createDevApp() /> ), }) - .addPage({ - path: '/legacy-create-groups', - title: 'Groups (next)', - element: ( - e.metadata.tags?.includes('techdocs') || false, - title: 'Techdocs', - }, - { - filter: e => e.metadata.tags?.includes('react') || false, - title: 'React', - }, - ]} - /> - ), - }) .render(); diff --git a/plugins/scaffolder/src/alpha.tsx b/plugins/scaffolder/src/alpha.tsx index 152745eec1..37e2978802 100644 --- a/plugins/scaffolder/src/alpha.tsx +++ b/plugins/scaffolder/src/alpha.tsx @@ -29,6 +29,7 @@ import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; import { scmIntegrationsApiRef } from '@backstage/integration-react'; import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; @@ -50,8 +51,6 @@ export { type TemplateWizardPageProps, } from './next'; -export * from './legacy'; - const scaffolderApi = createApiExtension({ factory: createApiFactory({ api: scaffolderApiRef, @@ -87,17 +86,17 @@ const scaffolderNavItem = createNavItemExtension({ /** @alpha */ export default createPlugin({ id: 'scaffolder', - routes: { - root: convertLegacyRouteRef(rootRouteRef), - selectedTemplate: convertLegacyRouteRef(selectedTemplateRouteRef), - ongoingTask: convertLegacyRouteRef(scaffolderTaskRouteRef), - actions: convertLegacyRouteRef(actionsRouteRef), - listTasks: convertLegacyRouteRef(scaffolderListTaskRouteRef), - edit: convertLegacyRouteRef(editRouteRef), - }, - externalRoutes: { - registerComponent: convertLegacyRouteRef(registerComponentRouteRef), - viewTechDoc: convertLegacyRouteRef(viewTechDocRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + selectedTemplate: selectedTemplateRouteRef, + ongoingTask: scaffolderTaskRouteRef, + actions: actionsRouteRef, + listTasks: scaffolderListTaskRouteRef, + edit: editRouteRef, + }), + externalRoutes: convertLegacyRouteRefs({ + registerComponent: registerComponentRouteRef, + viewTechDoc: viewTechDocRouteRef, + }), extensions: [scaffolderApi, scaffolderPage, scaffolderNavItem], }); diff --git a/plugins/scaffolder/src/components/ListTasksPage/ListTasksPage.tsx b/plugins/scaffolder/src/components/ListTasksPage/ListTasksPage.tsx index 1edac508d8..aac0ed5c79 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/ListTasksPage.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/ListTasksPage.tsx @@ -18,7 +18,6 @@ import { EmptyState, ErrorPanel, Header, - Lifecycle, Link, Page, Progress, @@ -139,11 +138,7 @@ export const ListTasksPage = (props: MyTaskPageProps) => {
- List template tasks - - } + title="List template tasks" subtitle="All tasks that have been started" /> diff --git a/plugins/scaffolder/src/components/index.ts b/plugins/scaffolder/src/components/index.ts index fd8c11e2da..552a75c99b 100644 --- a/plugins/scaffolder/src/components/index.ts +++ b/plugins/scaffolder/src/components/index.ts @@ -22,5 +22,3 @@ export type { RouterProps } from './Router'; export { OngoingTask as TaskPage } from './OngoingTask'; export type { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; - -export type { TaskPageProps } from '../legacy/TaskPage'; diff --git a/plugins/scaffolder/src/components/types.ts b/plugins/scaffolder/src/components/types.ts deleted file mode 100644 index b1e99a84e6..0000000000 --- a/plugins/scaffolder/src/components/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * 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. - */ diff --git a/plugins/scaffolder/src/deprecated.ts b/plugins/scaffolder/src/deprecated.ts index f08a83c594..907871946c 100644 --- a/plugins/scaffolder/src/deprecated.ts +++ b/plugins/scaffolder/src/deprecated.ts @@ -212,3 +212,13 @@ export type LayoutTemplate = LayoutTemplateTemp; * @deprecated use import from {@link @backstage/plugin-scaffolder-react#LayoutOptions} instead as this has now been moved. */ export type LayoutOptions = LayoutOptionsTemp; + +/** + * TaskPageProps for constructing a TaskPage + * @public + * @deprecated - this is a useless type that is no longer used. + */ +export type TaskPageProps = { + // Optional loading text shown before a task begins executing. + loadingText?: string; +}; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/index.ts b/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/index.ts deleted file mode 100644 index d6d0bf3499..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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. - */ -export { DescriptionField } from './DescriptionField'; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.test.tsx b/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.test.tsx deleted file mode 100644 index 3f8e153b65..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.test.tsx +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 { getReviewData, getUiSchemasFromSteps } from './ReviewStep'; - -describe('MultistepJsonForm', () => { - const formDataMock = { - password: 'password', - masked: 'Some info to mask', - open: 'Some open info', - hidden: 'Some info to hide', - 'other-open': 'Other open info', - }; - - const stepsMock = [ - { - title: 'The test template', - schema: { - title: 'The test template', - properties: { - password: { - title: 'Password', - type: 'string', - 'ui:widget': 'password', - }, - masked: { - title: 'Masked', - type: 'string', - 'ui:backstage': { - review: { - mask: '******', - }, - }, - }, - open: { - title: 'Open info', - type: 'string', - }, - }, - }, - }, - { - title: 'Other fields', - schema: { - title: 'Other fields', - properties: { - hidden: { - title: 'Hidden', - type: 'string', - 'ui:backstage': { - review: { - show: false, - }, - }, - }, - 'other-open': { - title: 'Other Open Info', - type: 'string', - }, - }, - }, - }, - ]; - - test('Fields are defined to be hidden or masked', () => { - const schemas = getUiSchemasFromSteps(stepsMock); - const reviewData = getReviewData(formDataMock, schemas); - - expect(reviewData.password).toBe('******'); - expect(reviewData.masked).toBe('******'); - expect(reviewData.open).toBe('Some open info'); - expect(reviewData.hidden).toBeUndefined(); - expect(reviewData['other-open']).toBe('Other open info'); - }); -}); diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx b/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx deleted file mode 100644 index 68b25d97d2..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx +++ /dev/null @@ -1,225 +0,0 @@ -/* - * 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 { - Button, - Step as StepUI, - StepContent, - StepLabel, - Stepper, - Typography, -} from '@material-ui/core'; -import { JsonObject } from '@backstage/types'; -import { - errorApiRef, - featureFlagsApiRef, - useAnalytics, - useRouteRefParams, - useApi, -} from '@backstage/core-plugin-api'; -import { FormProps, IChangeEvent, withTheme } from '@rjsf/core'; -import { Theme as MuiTheme } from '@rjsf/material-ui'; -import React, { ComponentType, useState } from 'react'; -import { transformSchemaToProps } from './schema'; -import cloneDeep from 'lodash/cloneDeep'; -import * as fieldOverrides from './FieldOverrides'; -import { ReviewStep } from './ReviewStep'; -import validator from '@rjsf/validator-ajv8'; -import { extractSchemaFromStep } from '@backstage/plugin-scaffolder-react/alpha'; -import { selectedTemplateRouteRef } from '../../routes'; -import { - LayoutOptions, - ReviewStepProps, -} from '@backstage/plugin-scaffolder-react'; - -const Form = withTheme(MuiTheme); - -type Step = { - schema: JsonObject; - title: string; -} & Partial, 'schema'>>; - -/** - * The props for a dynamic form of a scaffolder template. - */ -export type MultistepJsonFormProps = { - /** - * Steps for the form, each contains title and form schema - */ - steps: Step[]; - formData: Record; - onChange: (e: IChangeEvent) => void; - onReset: () => void; - onFinish?: () => Promise; - widgets?: FormProps['widgets']; - fields?: FormProps['fields']; - finishButtonLabel?: string; - layouts: LayoutOptions[]; - ReviewStepComponent?: ComponentType; -}; - -export function getSchemasFromSteps(steps: Step[]) { - return steps.map(({ schema }) => ({ - mergedSchema: schema, - ...extractSchemaFromStep(schema), - })); -} - -/** - * Creates the dynamic form for a scaffolder template. - */ -export const MultistepJsonForm = (props: MultistepJsonFormProps) => { - const { - formData, - onChange, - onReset, - onFinish, - fields, - widgets, - layouts, - ReviewStepComponent, - } = props; - const { templateName } = useRouteRefParams(selectedTemplateRouteRef); - const analytics = useAnalytics(); - const [activeStep, setActiveStep] = useState(0); - const [disableButtons, setDisableButtons] = useState(false); - const errorApi = useApi(errorApiRef); - const featureFlagApi = useApi(featureFlagsApiRef); - const featureFlagKey = 'backstage:featureFlag'; - const filterOutProperties = (step: Step): Step => { - const filteredStep = cloneDeep(step); - const removedPropertyKeys: Array = []; - if (filteredStep.schema.properties) { - filteredStep.schema.properties = Object.fromEntries( - Object.entries(filteredStep.schema.properties).filter( - ([key, value]) => { - if (value[featureFlagKey]) { - if (featureFlagApi.isActive(value[featureFlagKey])) { - return true; - } - removedPropertyKeys.push(key); - return false; - } - return true; - }, - ), - ); - - // remove the feature flag property key from required if they are not active - filteredStep.schema.required = Array.isArray(filteredStep.schema.required) - ? filteredStep.schema.required?.filter( - r => !removedPropertyKeys.includes(r as string), - ) - : filteredStep.schema.required; - } - return filteredStep; - }; - - const steps = props.steps - .filter(step => { - const featureFlag = step.schema[featureFlagKey]; - return ( - typeof featureFlag !== 'string' || featureFlagApi.isActive(featureFlag) - ); - }) - .map(filterOutProperties); - - const handleReset = () => { - setActiveStep(0); - onReset(); - }; - const handleNext = () => { - const stepNum = Math.min(activeStep + 1, steps.length); - setActiveStep(stepNum); - analytics.captureEvent('click', `Next Step (${stepNum})`); - }; - const handleBack = () => setActiveStep(Math.max(activeStep - 1, 0)); - const handleCreate = async () => { - if (!onFinish) { - return; - } - - setDisableButtons(true); - try { - await onFinish(); - analytics.captureEvent('create', formData.name || `new ${templateName}`); - } catch (err) { - errorApi.post(err); - } finally { - setDisableButtons(false); - } - }; - - const ReviewStepElement = ReviewStepComponent ?? ReviewStep; - - return ( - <> - - {steps.map(({ title, schema, ...formProps }, index) => { - return ( - - - - {title} - - - -
) => { - if (e.errors.length === 0) handleNext(); - }} - experimental_defaultFormStateBehavior={{ - allOf: 'populateDefaults', - }} - {...formProps} - {...transformSchemaToProps(schema, layouts)} - > - - -
-
-
- ); - })} -
- {activeStep === steps.length && ( - - )} - - ); -}; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/ReviewStep.tsx b/plugins/scaffolder/src/legacy/MultistepJsonForm/ReviewStep.tsx deleted file mode 100644 index c3b244e921..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/ReviewStep.tsx +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 { Box, Button, Paper, Typography } from '@material-ui/core'; -import React from 'react'; -import { Content, StructuredMetadataTable } from '@backstage/core-components'; -import { UiSchema } from '@rjsf/utils'; -import { JsonObject } from '@backstage/types'; -import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; - -export function getReviewData( - formData: Record, - uiSchemas: UiSchema[], -) { - const reviewData: Record = {}; - const orderedReviewProperties = new Set( - uiSchemas.map(us => us.name).concat(Object.getOwnPropertyNames(formData)), - ); - - for (const key of orderedReviewProperties) { - const uiSchema = uiSchemas.find(us => us.name === key); - - if (!uiSchema) { - reviewData[key] = formData[key]; - continue; - } - - if (uiSchema['ui:widget'] === 'password') { - reviewData[key] = '******'; - continue; - } - - if (!uiSchema['ui:backstage'] || !uiSchema['ui:backstage'].review) { - reviewData[key] = formData[key]; - continue; - } - - const review = uiSchema['ui:backstage'].review as JsonObject; - if (review.mask) { - reviewData[key] = review.mask; - continue; - } - - if (!review.show) { - continue; - } - reviewData[key] = formData[key]; - } - - return reviewData; -} - -export function getUiSchemasFromSteps( - steps: { - schema: JsonObject; - }[], -): UiSchema[] { - const uiSchemas: Array = []; - steps.forEach(step => { - const schemaProps = step.schema.properties as JsonObject; - for (const key in schemaProps) { - if (schemaProps.hasOwnProperty(key)) { - const uiSchema = schemaProps[key] as UiSchema; - uiSchema.name = key; - uiSchemas.push(uiSchema); - } - } - }); - return uiSchemas; -} - -/** - * The component displaying the Last Step in scaffolder template form. - * Which represents the summary of the input provided by the end user. - */ -export const ReviewStep = (props: ReviewStepProps) => { - const { - disableButtons, - formData, - handleBack, - handleCreate, - handleReset, - steps, - } = props; - return ( - - - Review and create - ({ schema: mergedSchema })), - ), - )} - /> - - - - - - - ); -}; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.test.ts b/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.test.ts deleted file mode 100644 index af5bb7fac5..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.test.ts +++ /dev/null @@ -1,535 +0,0 @@ -/* - * 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 { transformSchemaToProps } from './schema'; - -describe('transformSchemaToProps', () => { - it('transforms deep schema', () => { - const inputSchema = { - type: 'object', - 'ui:welp': 'warp', - properties: { - field1: { - type: 'string', - 'ui:derp': 'herp', - }, - field2: { - type: 'object', - properties: { - fieldX: { - type: 'string', - 'ui:derp': 'xerp', - }, - }, - }, - }, - }; - const expectedSchema = { - type: 'object', - properties: { - field1: { - type: 'string', - }, - field2: { - type: 'object', - properties: { - fieldX: { - type: 'string', - }, - }, - }, - }, - }; - const expectedUiSchema = { - 'ui:welp': 'warp', - field1: { - 'ui:derp': 'herp', - }, - field2: { - fieldX: { - 'ui:derp': 'xerp', - }, - }, - }; - - expect(transformSchemaToProps(inputSchema)).toEqual({ - schema: expectedSchema, - uiSchema: expectedUiSchema, - }); - }); - - it('transforms schema with anyOf fields', () => { - const inputSchema = { - type: 'object', - anyOf: [ - { - properties: { - field3: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - { - properties: { - field3: { - type: 'string', - default: 'Value 2', - 'ui:readonly': true, - }, - }, - }, - ], - oneOf: [ - { - properties: { - field4: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - ], - allOf: [ - { - properties: { - field5: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - ], - properties: { - field1: { - type: 'object', - anyOf: [ - { - properties: { - field3: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - { - properties: { - field3: { - type: 'string', - default: 'Value 2', - 'ui:readonly': true, - }, - }, - }, - ], - oneOf: [ - { - properties: { - field4: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - ], - allOf: [ - { - properties: { - field5: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - ], - }, - field2: { - type: 'string', - 'ui:derp': 'xerp', - }, - }, - }; - const expectedSchema = { - type: 'object', - anyOf: [ - { - properties: { - field3: { - type: 'string', - default: 'Value 1', - }, - }, - }, - { - properties: { - field3: { - type: 'string', - default: 'Value 2', - }, - }, - }, - ], - oneOf: [ - { - properties: { - field4: { - type: 'string', - default: 'Value 1', - }, - }, - }, - ], - allOf: [ - { - properties: { - field5: { - type: 'string', - default: 'Value 1', - }, - }, - }, - ], - properties: { - field1: { - type: 'object', - anyOf: [ - { - properties: { - field3: { - type: 'string', - default: 'Value 1', - }, - }, - }, - { - properties: { - field3: { - type: 'string', - default: 'Value 2', - }, - }, - }, - ], - oneOf: [ - { - properties: { - field4: { - type: 'string', - default: 'Value 1', - }, - }, - }, - ], - allOf: [ - { - properties: { - field5: { - type: 'string', - default: 'Value 1', - }, - }, - }, - ], - }, - field2: { - type: 'string', - }, - }, - }; - const expectedUiSchema = { - field3: { - 'ui:readonly': true, - }, - field4: { - 'ui:readonly': true, - }, - field5: { - 'ui:readonly': true, - }, - field1: { - field3: { - 'ui:readonly': true, - }, - field4: { - 'ui:readonly': true, - }, - field5: { - 'ui:readonly': true, - }, - }, - field2: { - 'ui:derp': 'xerp', - }, - }; - - expect(transformSchemaToProps(inputSchema)).toEqual({ - schema: expectedSchema, - uiSchema: expectedUiSchema, - }); - }); - - it('transforms schema with dependencies', () => { - const inputSchema = { - type: 'object', - properties: { - name: { - type: 'string', - }, - credit_card: { - type: 'number', - }, - }, - required: ['name'], - dependencies: { - credit_card: { - properties: { - billing_address: { - type: 'string', - 'ui:widget': 'textarea', - }, - }, - required: ['billing_address'], - }, - }, - }; - const expectedSchema = { - type: 'object', - properties: { - name: { - type: 'string', - }, - credit_card: { - type: 'number', - }, - }, - required: ['name'], - dependencies: { - credit_card: { - properties: { - billing_address: { - type: 'string', - }, - }, - required: ['billing_address'], - }, - }, - }; - const expectedUiSchema = { - billing_address: { - 'ui:widget': 'textarea', - }, - credit_card: {}, - name: {}, - }; - - expect(transformSchemaToProps(inputSchema)).toEqual({ - schema: expectedSchema, - uiSchema: expectedUiSchema, - }); - }); - - it('transforms schema with complex dependencies', () => { - const inputSchema = { - type: 'object', - properties: { - conditional: { - title: 'Person', - type: 'object', - properties: { - 'Do you have any pets?': { - type: 'string', - enum: ['No', 'Yes: One', 'Yes: More than one'], - default: 'No', - 'ui:widget': 'radio', - }, - }, - required: ['Do you have any pets?'], - dependencies: { - 'Do you have any pets?': { - oneOf: [ - { - properties: { - 'Do you have any pets?': { - enum: ['No'], - }, - }, - }, - { - properties: { - 'Do you have any pets?': { - enum: ['Yes: One'], - }, - 'How old is your pet?': { - type: 'number', - }, - }, - required: ['How old is your pet?'], - }, - { - properties: { - 'Do you have any pets?': { - enum: ['Yes: More than one'], - }, - 'Do you want to get rid of any?': { - type: 'boolean', - }, - }, - required: ['Do you want to get rid of any?'], - }, - ], - }, - }, - }, - }, - }; - const expectedSchema = { - type: 'object', - properties: { - conditional: { - title: 'Person', - type: 'object', - properties: { - 'Do you have any pets?': { - type: 'string', - enum: ['No', 'Yes: One', 'Yes: More than one'], - default: 'No', - }, - }, - required: ['Do you have any pets?'], - dependencies: { - 'Do you have any pets?': { - oneOf: [ - { - properties: { - 'Do you have any pets?': { - enum: ['No'], - }, - }, - }, - { - properties: { - 'Do you have any pets?': { - enum: ['Yes: One'], - }, - 'How old is your pet?': { - type: 'number', - }, - }, - required: ['How old is your pet?'], - }, - { - properties: { - 'Do you have any pets?': { - enum: ['Yes: More than one'], - }, - 'Do you want to get rid of any?': { - type: 'boolean', - }, - }, - required: ['Do you want to get rid of any?'], - }, - ], - }, - }, - }, - }, - }; - const expectedUiSchema = { - conditional: { - 'Do you have any pets?': { - 'ui:widget': 'radio', - }, - 'Do you want to get rid of any?': {}, - 'How old is your pet?': {}, - }, - }; - - expect(transformSchemaToProps(inputSchema)).toEqual({ - schema: expectedSchema, - uiSchema: expectedUiSchema, - }); - }); - - it('transforms schema with array items', () => { - const inputSchema = { - type: 'object', - properties: { - person: { - type: 'array', - items: { - type: 'object', - properties: { - name: { - type: 'string', - }, - address: { - type: 'string', - 'ui:widget': 'textarea', - }, - }, - }, - }, - accountNumber: { - type: 'number', - }, - }, - }; - const expectedSchema = { - type: 'object', - properties: { - person: { - type: 'array', - items: { - type: 'object', - properties: { - name: { - type: 'string', - }, - address: { - type: 'string', - }, - }, - }, - }, - accountNumber: { - type: 'number', - }, - }, - }; - const expectedUiSchema = { - accountNumber: {}, - person: { - items: { - name: {}, - address: { - 'ui:widget': 'textarea', - }, - }, - }, - }; - - expect(transformSchemaToProps(inputSchema)).toEqual({ - schema: expectedSchema, - uiSchema: expectedUiSchema, - }); - }); -}); diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.ts b/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.ts deleted file mode 100644 index e6221cb8d5..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.ts +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 { JsonObject } from '@backstage/types'; -import { UiSchema } from '@rjsf/utils'; -import type { LayoutOptions } from '@backstage/plugin-scaffolder-react'; -import { FormProps } from '@rjsf/core'; - -function isObject(value: unknown): value is JsonObject { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - -function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) { - if (!isObject(schema)) { - return; - } - - const { properties, items, anyOf, oneOf, allOf, dependencies } = schema; - - for (const propName in schema) { - if (!schema.hasOwnProperty(propName)) { - continue; - } - - if (propName.startsWith('ui:')) { - uiSchema[propName] = schema[propName]; - delete schema[propName]; - } - } - - if (isObject(properties)) { - for (const propName in properties) { - if (!properties.hasOwnProperty(propName)) { - continue; - } - - const schemaNode = properties[propName]; - if (!isObject(schemaNode)) { - continue; - } - const innerUiSchema = {}; - uiSchema[propName] = uiSchema[propName] || innerUiSchema; - extractUiSchema(schemaNode, innerUiSchema); - } - } - - if (isObject(items)) { - const innerUiSchema = {}; - uiSchema.items = innerUiSchema; - extractUiSchema(items, innerUiSchema); - } - - if (Array.isArray(anyOf)) { - for (const schemaNode of anyOf) { - if (!isObject(schemaNode)) { - continue; - } - extractUiSchema(schemaNode, uiSchema); - } - } - - if (Array.isArray(oneOf)) { - for (const schemaNode of oneOf) { - if (!isObject(schemaNode)) { - continue; - } - extractUiSchema(schemaNode, uiSchema); - } - } - - if (Array.isArray(allOf)) { - for (const schemaNode of allOf) { - if (!isObject(schemaNode)) { - continue; - } - extractUiSchema(schemaNode, uiSchema); - } - } - - if (isObject(dependencies)) { - for (const depName of Object.keys(dependencies)) { - const schemaNode = dependencies[depName]; - if (!isObject(schemaNode)) { - continue; - } - extractUiSchema(schemaNode, uiSchema); - } - } -} - -export function transformSchemaToProps( - inputSchema: JsonObject, - layouts: LayoutOptions[] = [], -): { - schema: FormProps['schema']; - uiSchema: FormProps['uiSchema']; -} { - const customLayoutName = inputSchema['ui:ObjectFieldTemplate']; - inputSchema.type = inputSchema.type || 'object'; - const schema = JSON.parse(JSON.stringify(inputSchema)); - delete schema.title; // Rendered separately - const uiSchema: UiSchema = {}; - extractUiSchema(schema, uiSchema); - - if (customLayoutName) { - const Layout = layouts.find( - layout => layout.name === customLayoutName, - )?.component; - - if (Layout) { - uiSchema['ui:ObjectFieldTemplate'] = Layout; - } - } - - return { schema, uiSchema }; -} diff --git a/plugins/scaffolder/src/legacy/Router.tsx b/plugins/scaffolder/src/legacy/Router.tsx deleted file mode 100644 index ac183b9470..0000000000 --- a/plugins/scaffolder/src/legacy/Router.tsx +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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 React, { ComponentType, useEffect, PropsWithChildren } from 'react'; -import { Navigate, Route, Routes, useOutlet } from 'react-router-dom'; -import { Entity } from '@backstage/catalog-model'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { ScaffolderPage } from './ScaffolderPage'; -import { TemplatePage } from './TemplatePage'; -import { TaskPage } from './TaskPage'; -import { ActionsPage } from '../components/ActionsPage'; -import { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../extensions/default'; -import { useRouteRef, useRouteRefParams } from '@backstage/core-plugin-api'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; -import { - ReviewStepProps, - SecretsContextProvider, - useCustomFieldExtensions, - useCustomLayouts, -} from '@backstage/plugin-scaffolder-react'; -import { ListTasksPage } from '../components/ListTasksPage'; -import { - actionsRouteRef, - editRouteRef, - legacySelectedTemplateRouteRef, - scaffolderListTaskRouteRef, - scaffolderTaskRouteRef, - selectedTemplateRouteRef, -} from '../routes'; -import { TemplateEditorPage } from './TemplateEditorPage'; - -/** - * The props for the entrypoint `ScaffolderPage` component the plugin. - * @alpha - */ -export type LegacyRouterProps = { - components?: { - ReviewStepComponent?: ComponentType; - TemplateCardComponent?: - | ComponentType<{ template: TemplateEntityV1beta3 }> - | undefined; - TaskPageComponent?: ComponentType>; - }; - groups?: Array<{ - title?: React.ReactNode; - filter: (entity: Entity) => boolean; - }>; - templateFilter?: (entity: TemplateEntityV1beta3) => boolean; - defaultPreviewTemplate?: string; - headerOptions?: { - pageTitleOverride?: string; - title?: string; - subtitle?: string; - }; - /** - * Options for the context menu on the scaffolder page. - */ - contextMenu?: { - /** Whether to show a link to the template editor */ - editor?: boolean; - /** Whether to show a link to the actions documentation */ - actions?: boolean; - }; -}; - -/** - * The legacy router - * - * @alpha - */ -export const LegacyRouter = (props: LegacyRouterProps) => { - const { - groups, - templateFilter, - components = {}, - defaultPreviewTemplate, - } = props; - - const { ReviewStepComponent, TemplateCardComponent, TaskPageComponent } = - components; - - const outlet = useOutlet(); - const TaskPageElement = TaskPageComponent ?? TaskPage; - - const customFieldExtensions = - useCustomFieldExtensions(outlet); - - const fieldExtensions = [ - ...customFieldExtensions, - ...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter( - ({ name }) => - !customFieldExtensions.some( - customFieldExtension => customFieldExtension.name === name, - ), - ), - ] as LegacyFieldExtensionOptions[]; - - const customLayouts = useCustomLayouts(outlet); - - /** - * This component can be deleted once the older routes have been deprecated. - */ - const RedirectingComponent = () => { - const { templateName } = useRouteRefParams(legacySelectedTemplateRouteRef); - const newLink = useRouteRef(selectedTemplateRouteRef); - useEffect( - () => - // eslint-disable-next-line no-console - console.warn( - 'The route /template/:templateName is deprecated, please use the new /template/:namespace/:templateName route instead', - ), - [], - ); - return ; - }; - - return ( - - - } - /> - } - /> - - - - } - /> - } - /> - } /> - } /> - - - - } - /> - - } /> - - ); -}; diff --git a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPage.tsx b/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPage.tsx deleted file mode 100644 index 54122eddf0..0000000000 --- a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPage.tsx +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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 { - Content, - ContentHeader, - CreateButton, - Header, - Page, - SupportButton, -} from '@backstage/core-components'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { useRouteRef } from '@backstage/core-plugin-api'; -import { - CatalogFilterLayout, - EntityKindPicker, - EntityListProvider, - EntitySearchBar, - EntityTagPicker, - UserListPicker, -} from '@backstage/plugin-catalog-react'; -import React, { ComponentType } from 'react'; -import { TemplateList } from '../TemplateList'; -import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; -import { usePermission } from '@backstage/plugin-permission-react'; -import { ScaffolderPageContextMenu } from './ScaffolderPageContextMenu'; -import { registerComponentRouteRef } from '../../routes'; -import { TemplateTypePicker } from '../../components'; - -export type ScaffolderPageProps = { - TemplateCardComponent?: - | ComponentType<{ template: TemplateEntityV1beta3 }> - | undefined; - groups?: Array<{ - title?: React.ReactNode; - filter: (entity: TemplateEntityV1beta3) => boolean; - }>; - templateFilter?: (entity: TemplateEntityV1beta3) => boolean; - contextMenu?: { - editor?: boolean; - actions?: boolean; - tasks?: boolean; - }; - headerOptions?: { - pageTitleOverride?: string; - title?: string; - subtitle?: string; - }; -}; - -export const ScaffolderPageContents = ({ - TemplateCardComponent, - groups, - templateFilter, - contextMenu, - headerOptions, -}: ScaffolderPageProps) => { - const registerComponentLink = useRouteRef(registerComponentRouteRef); - const otherTemplatesGroup = { - title: groups ? 'Other Templates' : 'Templates', - filter: (entity: TemplateEntityV1beta3) => { - const filtered = (groups ?? []).map(group => group.filter(entity)); - return !filtered.some(result => result === true); - }, - }; - - const { allowed } = usePermission({ - permission: catalogEntityCreatePermission, - }); - - return ( - -
- -
- - - {allowed && ( - - )} - - Create new software components using standard templates. Different - templates create different kinds of components (services, websites, - documentation, ...). - - - - - - - - - {groups && - groups.map((group, index) => ( - - ))} - - - - -
- ); -}; - -export const ScaffolderPage = ({ - TemplateCardComponent, - groups, - templateFilter, - contextMenu, - headerOptions, -}: ScaffolderPageProps) => ( - - - -); diff --git a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.test.tsx b/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.test.tsx deleted file mode 100644 index 66513591d0..0000000000 --- a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.test.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 userEvent from '@testing-library/user-event'; -import { renderInTestApp } from '@backstage/test-utils'; -import { screen } from '@testing-library/react'; -import React from 'react'; -import { ScaffolderPageContextMenu } from './ScaffolderPageContextMenu'; -import { rootRouteRef } from '../../routes'; - -describe('ScaffolderPageContextMenu', () => { - it('does not render anything if fully disabled', async () => { - await renderInTestApp( -
- -
, - { mountedRoutes: { '/': rootRouteRef } }, - ); - - expect(screen.getByTestId('container')).toBeEmptyDOMElement(); - }); - - it('renders the editor option', async () => { - await renderInTestApp( -
- -
, - { - mountedRoutes: { '/': rootRouteRef }, - }, - ); - - await userEvent.click(screen.getByTestId('container').firstElementChild!); - - expect(screen.getByText('Template Editor')).toBeInTheDocument(); - expect(screen.queryByText('Installed Actions')).not.toBeInTheDocument(); - }); - - it('renders the actions option', async () => { - await renderInTestApp( -
- -
, - { - mountedRoutes: { '/': rootRouteRef }, - }, - ); - - await userEvent.click(screen.getByTestId('container').firstElementChild!); - - expect(screen.queryByText('Template Editor')).not.toBeInTheDocument(); - expect(screen.getByText('Installed Actions')).toBeInTheDocument(); - }); - - it('renders all options', async () => { - await renderInTestApp( -
- -
, - { - mountedRoutes: { '/': rootRouteRef }, - }, - ); - - await userEvent.click(screen.getByTestId('container').firstElementChild!); - - expect(screen.getByText('Template Editor')).toBeInTheDocument(); - expect(screen.getByText('Installed Actions')).toBeInTheDocument(); - }); -}); diff --git a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.tsx b/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.tsx deleted file mode 100644 index f6151c227b..0000000000 --- a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.tsx +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 { useRouteRef } from '@backstage/core-plugin-api'; -import IconButton from '@material-ui/core/IconButton'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import MenuItem from '@material-ui/core/MenuItem'; -import MenuList from '@material-ui/core/MenuList'; -import Popover from '@material-ui/core/Popover'; -import { makeStyles } from '@material-ui/core/styles'; -import Description from '@material-ui/icons/Description'; -import Edit from '@material-ui/icons/Edit'; -import List from '@material-ui/icons/List'; -import MoreVert from '@material-ui/icons/MoreVert'; -import React, { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { - actionsRouteRef, - editRouteRef, - scaffolderListTaskRouteRef, -} from '../../routes'; - -const useStyles = makeStyles(theme => ({ - button: { - color: theme.page.fontColor, - }, -})); - -export type ScaffolderPageContextMenuProps = { - editor?: boolean; - actions?: boolean; - tasks?: boolean; -}; - -export function ScaffolderPageContextMenu( - props: ScaffolderPageContextMenuProps, -) { - const classes = useStyles(); - const [anchorEl, setAnchorEl] = useState(); - const editLink = useRouteRef(editRouteRef); - const actionsLink = useRouteRef(actionsRouteRef); - const tasksLink = useRouteRef(scaffolderListTaskRouteRef); - - const navigate = useNavigate(); - - const showEditor = props.editor !== false; - const showActions = props.actions !== false; - const showTasks = props.tasks !== false; - - if (!showEditor && !showActions) { - return null; - } - - const onOpen = (event: React.SyntheticEvent) => { - setAnchorEl(event.currentTarget); - }; - - const onClose = () => { - setAnchorEl(undefined); - }; - - return ( - <> - - - - - - {showEditor && ( - navigate(editLink())}> - - - - - - )} - {showActions && ( - navigate(actionsLink())}> - - - - - - )} - {showTasks && ( - navigate(tasksLink())}> - - - - - - )} - - - - ); -} diff --git a/plugins/scaffolder/src/legacy/ScaffolderPage/index.ts b/plugins/scaffolder/src/legacy/ScaffolderPage/index.ts deleted file mode 100644 index 433e39723f..0000000000 --- a/plugins/scaffolder/src/legacy/ScaffolderPage/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 { ScaffolderPage } from './ScaffolderPage'; diff --git a/plugins/scaffolder/src/legacy/TaskPage/TaskErrors.tsx b/plugins/scaffolder/src/legacy/TaskPage/TaskErrors.tsx deleted file mode 100644 index 4f8ce974c8..0000000000 --- a/plugins/scaffolder/src/legacy/TaskPage/TaskErrors.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 { Box } from '@material-ui/core'; -import React, { useEffect, useRef } from 'react'; -import { DismissableBanner } from '@backstage/core-components'; - -type TaskErrorsProps = { - error?: Error; -}; - -export const TaskErrors = ({ error }: TaskErrorsProps) => { - const id = useRef(''); - - useEffect(() => { - id.current = String(Math.random()); - }, [error]); - return error ? ( - - - - ) : null; -}; diff --git a/plugins/scaffolder/src/legacy/TaskPage/TaskPage.tsx b/plugins/scaffolder/src/legacy/TaskPage/TaskPage.tsx deleted file mode 100644 index affb9a31b7..0000000000 --- a/plugins/scaffolder/src/legacy/TaskPage/TaskPage.tsx +++ /dev/null @@ -1,393 +0,0 @@ -/* - * 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 { parseEntityRef } from '@backstage/catalog-model'; -import { - Content, - ErrorPage, - Header, - LogViewer, - Page, - Progress, -} from '@backstage/core-components'; -import { - useApi, - useRouteRef, - useRouteRefParams, -} from '@backstage/core-plugin-api'; -import { - Button, - CircularProgress, - Paper, - StepButton, - StepIconProps, -} from '@material-ui/core'; -import Grid from '@material-ui/core/Grid'; -import Step from '@material-ui/core/Step'; -import StepLabel from '@material-ui/core/StepLabel'; -import Stepper from '@material-ui/core/Stepper'; -import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; -import Typography from '@material-ui/core/Typography'; -import Cancel from '@material-ui/icons/Cancel'; -import Check from '@material-ui/icons/Check'; -import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord'; -import classNames from 'classnames'; -import { DateTime, Interval } from 'luxon'; -import qs from 'qs'; -import React, { memo, useEffect, useMemo, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import useInterval from 'react-use/lib/useInterval'; -import { - ScaffolderTaskStatus, - ScaffolderTaskOutput, - useTaskEventStream, -} from '@backstage/plugin-scaffolder-react'; -import { TaskErrors } from './TaskErrors'; -import { TaskPageLinks } from './TaskPageLinks'; -import { - rootRouteRef, - scaffolderTaskRouteRef, - selectedTemplateRouteRef, -} from '../../routes'; -import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; -import humanizeDuration from 'humanize-duration'; - -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - width: '100%', - }, - button: { - marginBottom: theme.spacing(2), - marginLeft: theme.spacing(2), - }, - actionsContainer: { - marginBottom: theme.spacing(2), - }, - resetContainer: { - padding: theme.spacing(3), - }, - labelWrapper: { - display: 'flex', - flex: 1, - flexDirection: 'row', - justifyContent: 'space-between', - }, - stepWrapper: { - width: '100%', - }, - }), -); - -type TaskStep = { - id: string; - name: string; - status: ScaffolderTaskStatus; - startedAt?: string; - endedAt?: string; -}; - -const StepTimeTicker = ({ step }: { step: TaskStep }) => { - const [time, setTime] = useState(''); - - useInterval(() => { - if (!step.startedAt) { - setTime(''); - return; - } - - const end = step.endedAt - ? DateTime.fromISO(step.endedAt) - : DateTime.local(); - - const startedAt = DateTime.fromISO(step.startedAt); - const formatted = Interval.fromDateTimes(startedAt, end) - .toDuration() - .valueOf(); - - setTime(humanizeDuration(formatted, { round: true })); - }, 1000); - - return {time}; -}; - -const useStepIconStyles = makeStyles(theme => - createStyles({ - root: { - color: theme.palette.text.disabled, - display: 'flex', - height: 22, - alignItems: 'center', - }, - completed: { - color: theme.palette.status.ok, - }, - error: { - color: theme.palette.status.error, - }, - }), -); - -function TaskStepIconComponent(props: StepIconProps) { - const classes = useStepIconStyles(); - const { active, completed, error } = props; - - const getMiddle = () => { - if (active) { - return ; - } - if (completed) { - return ; - } - if (error) { - return ; - } - return ; - }; - - return ( -
- {getMiddle()} -
- ); -} - -export const TaskStatusStepper = memo( - (props: { - steps: TaskStep[]; - currentStepId: string | undefined; - onUserStepChange: (id: string) => void; - classes?: { - root?: string; - }; - }) => { - const { steps, currentStepId, onUserStepChange } = props; - const classes = useStyles(props); - - return ( -
- s.id === currentStepId)} - orientation="vertical" - nonLinear - > - {steps.map((step, index) => { - const isCancelled = step.status === 'cancelled'; - const isActive = step.status === 'processing'; - const isCompleted = step.status === 'completed'; - const isFailed = step.status === 'failed'; - const isSkipped = step.status === 'skipped'; - - return ( - - onUserStepChange(step.id)}> - -
- {step.name} - {isSkipped ? ( - Skipped - ) : ( - - )} -
-
-
-
- ); - })} -
-
- ); - }, -); - -const hasLinks = ({ links = [] }: ScaffolderTaskOutput): boolean => - links.length > 0; - -/** - * TaskPageProps for constructing a TaskPage - * @param loadingText - Optional loading text shown before a task begins executing. - * @public - * @deprecated - this is a useless type that is no longer used. - */ -export type TaskPageProps = { - loadingText?: string; -}; - -/** - * TaskPage for showing the status of the taskId provided as a param - * - * @alpha - */ -export const TaskPage = (props: TaskPageProps) => { - const { loadingText } = props; - const classes = useStyles(); - const navigate = useNavigate(); - const rootPath = useRouteRef(rootRouteRef); - const scaffolderApi = useApi(scaffolderApiRef); - const templateRoute = useRouteRef(selectedTemplateRouteRef); - const [userSelectedStepId, setUserSelectedStepId] = useState< - string | undefined - >(undefined); - const [clickedToCancel, setClickedToCancel] = useState(false); - const [lastActiveStepId, setLastActiveStepId] = useState( - undefined, - ); - const { taskId } = useRouteRefParams(scaffolderTaskRouteRef); - const taskStream = useTaskEventStream(taskId); - const completed = taskStream.completed; - const taskCancelled = taskStream.cancelled; - const steps = useMemo( - () => - taskStream.task?.spec.steps.map(step => ({ - ...step, - ...taskStream?.steps?.[step.id], - })) ?? [], - [taskStream], - ); - - useEffect(() => { - const mostRecentFailedOrActiveStep = steps.find(step => - ['failed', 'processing'].includes(step.status), - ); - if (completed && !mostRecentFailedOrActiveStep) { - setLastActiveStepId(steps[steps.length - 1]?.id); - return; - } - - setLastActiveStepId(mostRecentFailedOrActiveStep?.id); - }, [steps, completed]); - - const currentStepId = userSelectedStepId ?? lastActiveStepId; - - const logAsString = useMemo(() => { - if (!currentStepId) { - return loadingText ? loadingText : 'Loading...'; - } - const log = taskStream.stepLogs[currentStepId]; - - if (!log?.length) { - return 'Waiting for logs...'; - } - return log.join('\n'); - }, [taskStream.stepLogs, currentStepId, loadingText]); - - const taskNotFound = - taskStream.completed && !taskStream.loading && !taskStream.task; - - const { output } = taskStream; - - const handleStartOver = () => { - if (!taskStream.task || !taskStream.task?.spec.templateInfo?.entityRef) { - navigate(rootPath()); - return; - } - - const formData = taskStream.task!.spec.parameters; - - const { name, namespace } = parseEntityRef( - taskStream.task!.spec.templateInfo?.entityRef, - ); - - navigate( - `${templateRoute({ templateName: name, namespace })}?${qs.stringify({ - formData: JSON.stringify(formData), - })}`, - ); - }; - - const handleCancel = async () => { - setClickedToCancel(true); - await scaffolderApi.cancelTask(taskId); - }; - - return ( - -
- - {taskNotFound ? ( - - ) : ( -
- - - - - {output && hasLinks(output) && ( - - )} - - - - - - {!currentStepId && } - -
- - -
-
-
-
- )} -
- - ); -}; diff --git a/plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.test.tsx b/plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.test.tsx deleted file mode 100644 index 2f5d015f8d..0000000000 --- a/plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.test.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 { entityRouteRef } from '@backstage/plugin-catalog-react'; -import { renderInTestApp } from '@backstage/test-utils'; -import React from 'react'; -import { TaskPageLinks } from './TaskPageLinks'; - -describe('TaskPageLinks', () => { - beforeEach(() => {}); - - afterEach(() => { - jest.resetAllMocks(); - }); - - it('renders further links', async () => { - const output = { - links: [ - { url: 'https://first.url', title: 'Cool link 1' }, - { url: 'https://second.url', title: 'Cool link 2' }, - { entityRef: 'Component:default/my-app', title: 'Open in catalog' }, - { title: 'Skipped' }, - ], - }; - const { findByText, queryByText } = await renderInTestApp( - , - { - mountedRoutes: { - '/catalog/:namespace/:kind/:name/*': entityRouteRef, - }, - }, - ); - - let element = await findByText('Cool link 1'); - - expect(element).toBeInTheDocument(); - expect(element).toHaveAttribute('href', 'https://first.url'); - - element = await findByText('Cool link 2'); - - expect(element).toBeInTheDocument(); - expect(element).toHaveAttribute('href', 'https://second.url'); - - element = await findByText('Open in catalog'); - - expect(element).toBeInTheDocument(); - expect(element).toHaveAttribute( - 'href', - '/catalog/default/Component/my-app', - ); - - expect(queryByText('Skipped')).not.toBeInTheDocument(); - }); -}); diff --git a/plugins/scaffolder/src/legacy/TaskPage/index.ts b/plugins/scaffolder/src/legacy/TaskPage/index.ts deleted file mode 100644 index f7876888f9..0000000000 --- a/plugins/scaffolder/src/legacy/TaskPage/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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. - */ -export { TaskPage } from './TaskPage'; -export type { TaskPageProps } from './TaskPage'; diff --git a/plugins/scaffolder/src/legacy/TemplateCard/TemplateCard.tsx b/plugins/scaffolder/src/legacy/TemplateCard/TemplateCard.tsx deleted file mode 100644 index 80f719bd36..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateCard/TemplateCard.tsx +++ /dev/null @@ -1,316 +0,0 @@ -/* - * 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 { - DEFAULT_NAMESPACE, - Entity, - EntityLink, - parseEntityRef, - RELATION_OWNED_BY, - stringifyEntityRef, -} from '@backstage/catalog-model'; -import { - ItemCardHeader, - Link, - LinkButton, - MarkdownContent, -} from '@backstage/core-components'; -import { - IconComponent, - useApi, - useApp, - useRouteRef, -} from '@backstage/core-plugin-api'; -import { - ScmIntegrationIcon, - scmIntegrationsApiRef, -} from '@backstage/integration-react'; -import { - EntityRefLinks, - FavoriteEntity, - getEntityRelations, - getEntitySourceLocation, -} from '@backstage/plugin-catalog-react'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { - Box, - Card, - CardActions, - CardContent, - CardMedia, - Chip, - IconButton, - makeStyles, - Theme, - Tooltip, - Typography, - useTheme, -} from '@material-ui/core'; -import LanguageIcon from '@material-ui/icons/Language'; -import WarningIcon from '@material-ui/icons/Warning'; -import React from 'react'; -import { selectedTemplateRouteRef, viewTechDocRouteRef } from '../../routes'; - -const useStyles = makeStyles< - Theme, - { fontColor: string; backgroundImage: string } ->(theme => ({ - cardHeader: { - position: 'relative', - }, - title: { - backgroundImage: ({ backgroundImage }) => backgroundImage, - color: ({ fontColor }) => fontColor, - }, - box: { - overflow: 'hidden', - textOverflow: 'ellipsis', - display: '-webkit-box', - '-webkit-line-clamp': 10, - '-webkit-box-orient': 'vertical', - }, - label: { - color: theme.palette.text.secondary, - textTransform: 'uppercase', - fontSize: '0.65rem', - fontWeight: 'bold', - letterSpacing: 0.5, - lineHeight: 1, - paddingBottom: '0.2rem', - }, - linksLabel: { - padding: '0 16px', - }, - description: { - '& p': { - margin: '0px', - }, - }, - leftButton: { - marginRight: 'auto', - }, - starButton: { - position: 'absolute', - top: theme.spacing(0.5), - right: theme.spacing(0.5), - padding: '0.25rem', - color: ({ fontColor }) => fontColor, - }, -})); - -const MuiIcon = ({ icon: Icon }: { icon: IconComponent }) => ; - -const useDeprecationStyles = makeStyles(theme => ({ - deprecationIcon: { - position: 'absolute', - top: theme.spacing(0.5), - right: theme.spacing(3.5), - padding: '0.25rem', - }, - link: { - color: theme.palette.warning.light, - }, -})); - -export type TemplateCardProps = { - template: TemplateEntityV1beta3; - deprecated?: boolean; -}; - -type TemplateProps = { - description: string; - tags: string[]; - title: string; - type: string; - name: string; - links: EntityLink[]; -}; - -const getTemplateCardProps = ( - template: TemplateEntityV1beta3, -): TemplateProps & { key: string } => { - return { - key: template.metadata.uid!, - name: template.metadata.name, - title: `${(template.metadata.title || template.metadata.name) ?? ''}`, - type: template.spec.type ?? '', - description: template.metadata.description ?? '-', - tags: (template.metadata?.tags as string[]) ?? [], - links: template.metadata.links ?? [], - }; -}; - -const DeprecationWarning = () => { - const styles = useDeprecationStyles(); - - const Title = ( - - This template uses a syntax that has been deprecated, and should be - migrated to a newer syntax. Click for more info. - - ); - - return ( -
- - - - - -
- ); -}; - -export const TemplateCard = ({ template, deprecated }: TemplateCardProps) => { - const app = useApp(); - const backstageTheme = useTheme(); - const templateRoute = useRouteRef(selectedTemplateRouteRef); - const templateProps = getTemplateCardProps(template); - const ownedByRelations = getEntityRelations( - template as Entity, - RELATION_OWNED_BY, - ); - const themeId = backstageTheme.getPageTheme({ themeId: templateProps.type }) - ? templateProps.type - : 'other'; - const theme = backstageTheme.getPageTheme({ themeId }); - const classes = useStyles({ - fontColor: theme.fontColor, - backgroundImage: theme.backgroundImage, - }); - const { name, namespace } = parseEntityRef(stringifyEntityRef(template)); - const href = templateRoute({ templateName: name, namespace }); - - // TechDocs Link - const viewTechDoc = useRouteRef(viewTechDocRouteRef); - const viewTechDocsAnnotation = - template.metadata.annotations?.['backstage.io/techdocs-ref']; - const viewTechDocsLink = - !!viewTechDocsAnnotation && - !!viewTechDoc && - viewTechDoc({ - namespace: template.metadata.namespace || DEFAULT_NAMESPACE, - kind: template.kind, - name: template.metadata.name, - }); - - const iconResolver = (key?: string): IconComponent => - key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon; - - const scmIntegrationsApi = useApi(scmIntegrationsApiRef); - const sourceLocation = getEntitySourceLocation(template, scmIntegrationsApi); - - return ( - - - - {deprecated && } - - - - - - Description - - - - - - Owner - - - - - - Tags - - {templateProps.tags?.map(tag => ( - - ))} - - - - Links - - -
- {sourceLocation && ( - - - - - - )} - {viewTechDocsLink && ( - - - - - - )} - {templateProps.links?.map((link, i) => ( - - - - - - ))} -
- - Choose - -
-
- ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplateCard/index.ts b/plugins/scaffolder/src/legacy/TemplateCard/index.ts deleted file mode 100644 index 291a06ed69..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateCard/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 { TemplateCard } from './TemplateCard'; -export type { TemplateCardProps } from './TemplateCard'; diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx deleted file mode 100644 index def3bf1796..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx +++ /dev/null @@ -1,205 +0,0 @@ -/* - * 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 { StreamLanguage } from '@codemirror/language'; -import { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml'; -import { - Button, - Card, - CardContent, - CardHeader, - FormControl, - IconButton, - InputLabel, - makeStyles, - MenuItem, - Select, -} from '@material-ui/core'; -import CloseIcon from '@material-ui/icons/Close'; -import CodeMirror from '@uiw/react-codemirror'; -import React, { useCallback, useMemo, useState } from 'react'; -import yaml from 'yaml'; -import { Form } from '@backstage/plugin-scaffolder-react/alpha'; -import { TemplateEditorForm } from './TemplateEditorForm'; -import validator from '@rjsf/validator-ajv8'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; - -const useStyles = makeStyles(theme => ({ - root: { - gridArea: 'pageContent', - display: 'grid', - gridTemplateAreas: ` - "controls controls" - "fieldForm preview" - `, - gridTemplateRows: 'auto 1fr', - gridTemplateColumns: '1fr 1fr', - }, - controls: { - gridArea: 'controls', - display: 'flex', - flexFlow: 'row nowrap', - alignItems: 'center', - margin: theme.spacing(1), - }, - fieldForm: { - gridArea: 'fieldForm', - }, - preview: { - gridArea: 'preview', - }, -})); - -export const CustomFieldExplorer = ({ - customFieldExtensions = [], - onClose, -}: { - customFieldExtensions?: LegacyFieldExtensionOptions[]; - onClose?: () => void; -}) => { - const classes = useStyles(); - const fieldOptions = customFieldExtensions.filter(field => !!field.schema); - const [selectedField, setSelectedField] = useState(fieldOptions[0]); - const [fieldFormState, setFieldFormState] = useState({}); - const [refreshKey, setRefreshKey] = useState(Date.now()); - const [formState, setFormState] = useState({}); - const sampleFieldTemplate = useMemo( - () => - yaml.stringify({ - parameters: [ - { - title: `${selectedField.name} Example`, - properties: { - [selectedField.name]: { - type: selectedField.schema?.returnValue?.type, - 'ui:field': selectedField.name, - 'ui:options': fieldFormState, - }, - }, - }, - ], - }), - [fieldFormState, selectedField], - ); - - const fieldComponents = useMemo(() => { - return Object.fromEntries( - customFieldExtensions.map(({ name, component }) => [name, component]), - ); - }, [customFieldExtensions]); - - const handleSelectionChange = useCallback( - (selection: LegacyFieldExtensionOptions) => { - setSelectedField(selection); - setFieldFormState({}); - setFormState({}); - }, - [setFieldFormState, setSelectedField, setFormState], - ); - - const handleFieldConfigChange = useCallback( - (state: {}) => { - setFieldFormState(state); - // Force TemplateEditorForm to re-render since some fields - // may not be responsive to ui:option changes - setRefreshKey(Date.now()); - }, - [setFieldFormState, setRefreshKey], - ); - - return ( -
-
- - - Choose Custom Field Extension - - - - - - - -
-
- - - -
handleFieldConfigChange(e.formData)} - validator={validator} - schema={selectedField.schema?.uiOptions || {}} - experimental_defaultFormStateBehavior={{ - allOf: 'populateDefaults', - }} - > - -
-
-
-
-
- - - - - - - null} - /> -
-
- ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditor.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditor.tsx deleted file mode 100644 index f6e7b38d7d..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditor.tsx +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 { makeStyles } from '@material-ui/core'; -import React, { useState } from 'react'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; -import { TemplateDirectoryAccess } from '../../lib/filesystem'; -import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; -import { DirectoryEditorProvider } from '../../next/TemplateEditorPage/DirectoryEditorContext'; -import { DryRunProvider } from '../../next/TemplateEditorPage/DryRunContext'; -import { TemplateEditorBrowser } from '../../next/TemplateEditorPage/TemplateEditorBrowser'; -import { TemplateEditorTextArea } from '../../next/TemplateEditorPage/TemplateEditorTextArea'; -import { TemplateEditorForm } from './TemplateEditorForm'; -import { DryRunResults } from '../../next/TemplateEditorPage/DryRunResults'; - -const useStyles = makeStyles({ - // Reset and fix sizing to make sure scrolling behaves correctly - root: { - gridArea: 'pageContent', - - display: 'grid', - gridTemplateAreas: ` - "browser editor preview" - "results results results" - `, - gridTemplateColumns: '1fr 3fr 2fr', - gridTemplateRows: '1fr auto', - }, - browser: { - gridArea: 'browser', - overflow: 'auto', - }, - editor: { - gridArea: 'editor', - overflow: 'auto', - }, - preview: { - gridArea: 'preview', - overflow: 'auto', - }, - results: { - gridArea: 'results', - }, -}); - -export const TemplateEditor = (props: { - directory: TemplateDirectoryAccess; - fieldExtensions?: LegacyFieldExtensionOptions[]; - layouts?: LayoutOptions[]; - onClose?: () => void; -}) => { - const classes = useStyles(); - - const [errorText, setErrorText] = useState(); - - return ( - - -
-
- -
-
- -
-
- -
-
- -
-
-
-
- ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorForm.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorForm.tsx deleted file mode 100644 index df05efc921..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorForm.tsx +++ /dev/null @@ -1,261 +0,0 @@ -/* - * 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 { useApiHolder } from '@backstage/core-plugin-api'; -import { JsonObject, JsonValue } from '@backstage/types'; -import { makeStyles } from '@material-ui/core/styles'; -import React, { Component, ReactNode, useMemo, useState } from 'react'; -import useDebounce from 'react-use/lib/useDebounce'; -import yaml from 'yaml'; -import { - LayoutOptions, - TemplateParameterSchema, -} from '@backstage/plugin-scaffolder-react'; - -import { useDryRun } from '../../next/TemplateEditorPage/DryRunContext'; -import { useDirectoryEditor } from '../../next/TemplateEditorPage/DirectoryEditorContext'; -import { MultistepJsonForm } from '../MultistepJsonForm'; -import { createValidator } from '../TemplatePage'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; - -const useStyles = makeStyles({ - containerWrapper: { - position: 'relative', - width: '100%', - height: '100%', - }, - container: { - position: 'absolute', - top: 0, - bottom: 0, - left: 0, - right: 0, - overflow: 'auto', - }, -}); - -interface ErrorBoundaryProps { - invalidator: unknown; - setErrorText(errorText: string | undefined): void; - children: ReactNode; -} - -interface ErrorBoundaryState { - shouldRender: boolean; -} - -class ErrorBoundary extends Component { - state = { - shouldRender: true, - }; - - componentDidUpdate(prevProps: { invalidator: unknown }) { - if (prevProps.invalidator !== this.props.invalidator) { - this.setState({ shouldRender: true }); - } - } - - componentDidCatch(error: Error) { - this.props.setErrorText(error.message); - this.setState({ shouldRender: false }); - } - - render() { - return this.state.shouldRender ? this.props.children : null; - } -} - -interface TemplateEditorFormProps { - content?: string; - /** Setting this to true will cause the content to be parsed as if it is the template entity spec */ - contentIsSpec?: boolean; - data: JsonObject; - onUpdate: (data: JsonObject) => void; - setErrorText: (errorText?: string) => void; - - onDryRun?: (data: JsonObject) => Promise; - fieldExtensions?: LegacyFieldExtensionOptions[]; - layouts?: LayoutOptions[]; -} - -function isJsonObject(value: JsonValue | undefined): value is JsonObject { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - -/** Shows the a template form that is parsed from the provided content */ -export function TemplateEditorForm(props: TemplateEditorFormProps) { - const { - content, - contentIsSpec, - data, - onUpdate, - onDryRun, - setErrorText, - fieldExtensions = [], - layouts = [], - } = props; - const classes = useStyles(); - const apiHolder = useApiHolder(); - - const [steps, setSteps] = useState(); - - const fields = useMemo(() => { - return Object.fromEntries( - fieldExtensions.map(({ name, component }) => [name, component]), - ); - }, [fieldExtensions]); - - useDebounce( - () => { - try { - if (!content) { - setSteps(undefined); - return; - } - const parsed: JsonValue = yaml - .parseAllDocuments(content) - .filter(c => c) - .map(c => c.toJSON())[0]; - - if (!isJsonObject(parsed)) { - setSteps(undefined); - return; - } - - let rootObj = parsed; - if (!contentIsSpec) { - const isTemplate = - String(parsed.kind).toLocaleLowerCase('en-US') === 'template'; - if (!isTemplate) { - setSteps(undefined); - return; - } - - rootObj = isJsonObject(parsed.spec) ? parsed.spec : {}; - } - - const { parameters } = rootObj; - - if (!Array.isArray(parameters)) { - setErrorText('Template parameters must be an array'); - setSteps(undefined); - return; - } - - const fieldValidators = Object.fromEntries( - fieldExtensions.map(({ name, validation }) => [name, validation]), - ); - - setErrorText(); - setSteps( - parameters.flatMap(param => - isJsonObject(param) - ? [ - { - title: String(param.title), - schema: param, - validate: createValidator(param, fieldValidators, { - apiHolder, - }), - }, - ] - : [], - ), - ); - } catch (e) { - setErrorText(e.message); - } - }, - 250, - [contentIsSpec, content, apiHolder], - ); - - if (!steps) { - return null; - } - - return ( -
-
- - onUpdate(e.formData)} - onReset={() => onUpdate({})} - finishButtonLabel={onDryRun && 'Try It'} - onFinish={onDryRun && (() => onDryRun(data))} - layouts={layouts} - /> - -
-
- ); -} - -/** A version of the TemplateEditorForm that is connected to the DirectoryEditor and DryRun contexts */ -export function TemplateEditorFormDirectoryEditorDryRun( - props: Pick< - TemplateEditorFormProps, - 'setErrorText' | 'fieldExtensions' | 'layouts' - >, -) { - const { setErrorText, fieldExtensions = [], layouts } = props; - const dryRun = useDryRun(); - - const directoryEditor = useDirectoryEditor(); - const { selectedFile } = directoryEditor; - - const [data, setData] = useState({}); - - const handleDryRun = async () => { - if (!selectedFile) { - return; - } - - try { - await dryRun.execute({ - templateContent: selectedFile.content, - values: data, - files: directoryEditor.files, - }); - setErrorText(); - } catch (e) { - setErrorText(String(e.cause || e)); - throw e; - } - }; - - const content = - selectedFile && selectedFile.path.match(/\.ya?ml$/) - ? selectedFile.content - : undefined; - - return ( - - ); -} - -TemplateEditorForm.DirectoryEditorDryRun = - TemplateEditorFormDirectoryEditorDryRun; diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorPage.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorPage.tsx deleted file mode 100644 index 127c73dcf5..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorPage.tsx +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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, { useState } from 'react'; -import { Content, Header, Page } from '@backstage/core-components'; -import { - TemplateDirectoryAccess, - WebFileSystemAccess, -} from '../../lib/filesystem'; -import { type LayoutOptions } from '@backstage/plugin-scaffolder-react'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; -import { TemplateEditorIntro } from '../../next/TemplateEditorPage/TemplateEditorIntro'; -import { TemplateEditor } from './TemplateEditor'; -import { TemplateFormPreviewer } from './TemplateFormPreviewer'; -import { CustomFieldExplorer } from './CustomFieldExplorer'; - -type Selection = - | { - type: 'local'; - directory: TemplateDirectoryAccess; - } - | { - type: 'form'; - } - | { - type: 'field-explorer'; - }; - -interface TemplateEditorPageProps { - defaultPreviewTemplate?: string; - customFieldExtensions?: LegacyFieldExtensionOptions[]; - layouts?: LayoutOptions[]; -} - -export function TemplateEditorPage(props: TemplateEditorPageProps) { - const [selection, setSelection] = useState(); - - let content: JSX.Element | null = null; - if (selection?.type === 'local') { - content = ( - setSelection(undefined)} - layouts={props.layouts} - /> - ); - } else if (selection?.type === 'form') { - content = ( - setSelection(undefined)} - layouts={props.layouts} - /> - ); - } else if (selection?.type === 'field-explorer') { - content = ( - setSelection(undefined)} - /> - ); - } else { - content = ( - - { - if (option === 'local') { - WebFileSystemAccess.requestDirectoryAccess() - .then(directory => setSelection({ type: 'local', directory })) - .catch(() => {}); - } else if (option === 'form') { - setSelection({ type: 'form' }); - } else if (option === 'field-explorer') { - setSelection({ type: 'field-explorer' }); - } - }} - /> - - ); - } - - return ( - -
- {content} - - ); -} diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateFormPreviewer.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateFormPreviewer.tsx deleted file mode 100644 index 9e92d12d93..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateFormPreviewer.tsx +++ /dev/null @@ -1,221 +0,0 @@ -/* - * 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 } from '@backstage/catalog-model'; -import { alertApiRef, useApi } from '@backstage/core-plugin-api'; -import { - catalogApiRef, - humanizeEntityRef, -} from '@backstage/plugin-catalog-react'; -import { - FormControl, - IconButton, - InputLabel, - LinearProgress, - makeStyles, - MenuItem, - Select, -} from '@material-ui/core'; -import CloseIcon from '@material-ui/icons/Close'; -import React, { useCallback, useState } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import yaml from 'yaml'; -import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; -import { TemplateEditorTextArea } from '../../next/TemplateEditorPage/TemplateEditorTextArea'; -import { TemplateEditorForm } from './TemplateEditorForm'; - -const EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI -parameters: - - title: Fill in some steps - required: - - name - properties: - name: - title: Name - type: string - description: Unique name of the component - owner: - title: Owner - type: string - description: Owner of the component - ui:field: OwnerPicker - ui:options: - catalogFilter: - kind: Group - - title: Choose a location - required: - - repoUrl - properties: - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com -steps: - - id: fetch-base - name: Fetch Base - action: fetch:template - input: - url: ./template - values: - name: \${{parameters.name}} -`; - -type TemplateOption = { - label: string; - value: Entity; -}; - -const useStyles = makeStyles(theme => ({ - root: { - gridArea: 'pageContent', - display: 'grid', - gridTemplateAreas: ` - "controls controls" - "textArea preview" - `, - gridTemplateRows: 'auto 1fr', - gridTemplateColumns: '1fr 1fr', - }, - controls: { - gridArea: 'controls', - display: 'flex', - flexFlow: 'row nowrap', - alignItems: 'center', - margin: theme.spacing(1), - }, - textArea: { - gridArea: 'textArea', - }, - preview: { - gridArea: 'preview', - }, -})); - -export const TemplateFormPreviewer = ({ - defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML, - customFieldExtensions = [], - onClose, - layouts = [], -}: { - defaultPreviewTemplate?: string; - customFieldExtensions?: LegacyFieldExtensionOptions[]; - onClose?: () => void; - layouts?: LayoutOptions[]; -}) => { - const classes = useStyles(); - const alertApi = useApi(alertApiRef); - const catalogApi = useApi(catalogApiRef); - const [selectedTemplate, setSelectedTemplate] = useState(''); - const [errorText, setErrorText] = useState(); - const [templateOptions, setTemplateOptions] = useState([]); - const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate); - const [formState, setFormState] = useState({}); - - const { loading } = useAsync( - () => - catalogApi - .getEntities({ - filter: { kind: 'template' }, - fields: [ - 'kind', - 'metadata.namespace', - 'metadata.name', - 'metadata.title', - 'spec.parameters', - 'spec.steps', - 'spec.output', - ], - }) - .then(({ items }) => - setTemplateOptions( - items.map(template => ({ - label: - template.metadata.title ?? - humanizeEntityRef(template, { defaultKind: 'template' }), - value: template, - })), - ), - ) - .catch(e => - alertApi.post({ - message: `Error loading exisiting templates: ${e.message}`, - severity: 'error', - }), - ), - [catalogApi], - ); - - const handleSelectChange = useCallback( - // TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types - (selected: any) => { - setSelectedTemplate(selected); - setTemplateYaml(yaml.stringify(selected.spec)); - }, - [setTemplateYaml], - ); - - return ( - <> - {loading && } -
-
- - - Load Existing Template - - - - - - - -
-
- -
-
- -
-
- - ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplateList/TemplateList.test.tsx b/plugins/scaffolder/src/legacy/TemplateList/TemplateList.test.tsx deleted file mode 100644 index c65613d2f5..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateList/TemplateList.test.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 { screen } from '@testing-library/react'; -import React from 'react'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { TemplateList } from './TemplateList'; -import { rootRouteRef } from '../../routes'; -import { - ScmIntegrationsApi, - scmIntegrationsApiRef, -} from '@backstage/integration-react'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; - -jest.mock('@backstage/plugin-catalog-react', () => ({ - useEntityList: jest.fn().mockReturnValue({ - loading: false, - entities: [ - { - apiVersion: 'scaffolder.backstage.io/v1beta3', - kind: 'Template', - metadata: { - name: 't1', - }, - spec: {}, - }, - { - apiVersion: 'scaffolder.backstage.io/v1beta3', - kind: 'Template', - metadata: { - name: 't2', - }, - spec: {}, - }, - ], - }), - getEntityRelations: jest.fn().mockImplementation(() => []), - getEntitySourceLocation: jest.fn().mockImplementation(() => ({})), -})); - -describe('TemplateList', () => { - const mockIntegrationsApi: Partial = { - byHost: () => ({ type: 'github' }), - }; - - it('should filter out templates based on provided filter condition', async () => { - const TemplateCardComponent = ({ - template, - }: { - template: TemplateEntityV1beta3; - }) => ( -
{template.metadata.name}
- ); - - await renderInTestApp( - -
- e.metadata.name === 't1'} - TemplateCardComponent={TemplateCardComponent} - /> -
-
, - { mountedRoutes: { '/': rootRouteRef } }, - ); - - expect(() => screen.getByTestId('t2')).toThrow(); - expect(screen.getByTestId('t1')).toBeDefined(); - }); -}); diff --git a/plugins/scaffolder/src/legacy/TemplateList/TemplateList.tsx b/plugins/scaffolder/src/legacy/TemplateList/TemplateList.tsx deleted file mode 100644 index c925cdf6ef..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateList/TemplateList.tsx +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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 React, { ComponentType } from 'react'; -import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; -import { - isTemplateEntityV1beta3, - TemplateEntityV1beta3, -} from '@backstage/plugin-scaffolder-common'; -import { - Content, - ContentHeader, - ItemCardGrid, - Link, - Progress, - WarningPanel, -} from '@backstage/core-components'; -import { useEntityList } from '@backstage/plugin-catalog-react'; -import { Typography } from '@material-ui/core'; -import { TemplateCard } from '../TemplateCard'; - -/** - * @internal - */ -export type TemplateListProps = { - TemplateCardComponent?: - | ComponentType<{ template: TemplateEntityV1beta3 }> - | undefined; - group?: { - title?: React.ReactNode; - filter: (entity: TemplateEntityV1beta3) => boolean; - }; - templateFilter?: (entity: TemplateEntityV1beta3) => boolean; -}; - -/** - * @internal - */ -export const TemplateList = ({ - TemplateCardComponent, - group, - templateFilter, -}: TemplateListProps) => { - const { loading, error, entities } = useEntityList(); - const Card = TemplateCardComponent || TemplateCard; - const templateEntities = entities.filter(isTemplateEntityV1beta3); - const maybeFilteredEntities = ( - group ? templateEntities.filter(group.filter) : templateEntities - ).filter(e => (templateFilter ? templateFilter(e) : true)); - - const titleComponent: React.ReactNode = (() => { - if (group && group.title) { - if (typeof group.title === 'string') { - return ; - } - return group.title; - } - - return ; - })(); - - if (group && maybeFilteredEntities.length === 0) { - return null; - } - return ( - <> - {loading && } - - {error && ( - - {error.message} - - )} - - {!error && !loading && !entities.length && ( - - No templates found that match your filter. Learn more about{' '} - - adding templates - - . - - )} - - - {titleComponent} - - {maybeFilteredEntities && - maybeFilteredEntities?.length > 0 && - maybeFilteredEntities.map((template: Entity) => ( - - ))} - - - - ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplateList/index.ts b/plugins/scaffolder/src/legacy/TemplateList/index.ts deleted file mode 100644 index 0b62f9cbb1..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateList/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 { TemplateList } from './TemplateList'; -export type { TemplateListProps } from './TemplateList'; diff --git a/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.test.tsx b/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.test.tsx deleted file mode 100644 index 344929fa43..0000000000 --- a/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.test.tsx +++ /dev/null @@ -1,366 +0,0 @@ -/* - * 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 { - MockAnalyticsApi, - renderInTestApp, - TestApiRegistry, -} from '@backstage/test-utils'; -import { act, fireEvent, screen, within } from '@testing-library/react'; -import React from 'react'; -import { Route, Routes } from 'react-router-dom'; -import { - scaffolderApiRef, - ScaffolderApi, - SecretsContextProvider, -} from '@backstage/plugin-scaffolder-react'; -import { TemplatePage } from './TemplatePage'; -import { - featureFlagsApiRef, - FeatureFlagsApi, - analyticsApiRef, -} from '@backstage/core-plugin-api'; -import { ApiProvider } from '@backstage/core-app-api'; -import { errorApiRef } from '@backstage/core-plugin-api'; -import { rootRouteRef } from '../../routes'; - -jest.mock('react-router-dom', () => { - return { - ...(jest.requireActual('react-router-dom') as any), - useParams: () => ({ - templateName: 'test', - }), - }; -}); - -const scaffolderApiMock: jest.Mocked = { - cancelTask: jest.fn(), - scaffold: jest.fn(), - getTemplateParameterSchema: jest.fn(), - getIntegrationsList: jest.fn(), - getTask: jest.fn(), - streamLogs: jest.fn(), - listActions: jest.fn(), - listTasks: jest.fn(), -}; - -const featureFlagsApiMock: jest.Mocked = { - isActive: jest.fn(), - registerFlag: jest.fn(), - getRegisteredFlags: jest.fn(), - save: jest.fn(), -}; - -const errorApiMock = { post: jest.fn(), error$: jest.fn() }; - -const analyticsMock = new MockAnalyticsApi(); - -const schemaMockValue = { - title: 'my-schema', - steps: [ - { - title: 'Fill in some steps', - schema: { - title: 'Fill in some steps', - 'backstage:featureFlag': 'experimental-feature', - properties: { - name: { - title: 'Name', - type: 'string', - 'backstage:featureFlag': 'should-show-some-stuff-first-option', - }, - description: { - title: 'Description', - type: 'string', - description: 'A description for the component', - }, - owner: { - title: 'Owner', - type: 'string', - description: 'Owner of the component', - }, - }, - type: 'object', - }, - }, - { - title: 'Send data', - schema: { - title: 'Send data', - properties: { - user: { - title: 'User', - type: 'string', - }, - }, - type: 'object', - }, - }, - ], -}; - -const apis = TestApiRegistry.from( - [scaffolderApiRef, scaffolderApiMock], - [errorApiRef, errorApiMock], - [featureFlagsApiRef, featureFlagsApiMock], - [analyticsApiRef, analyticsMock], -); - -describe('TemplatePage', () => { - beforeEach(() => jest.resetAllMocks()); - - it('renders correctly', async () => { - scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ - title: 'React SSR Template', - steps: [], - }); - const rendered = await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/create': rootRouteRef, - }, - }, - ); - - expect(rendered.getByText('Create a New Component')).toBeInTheDocument(); - expect(rendered.getByText('React SSR Template')).toBeInTheDocument(); - }); - - it('renders spinner while loading', async () => { - let resolve: Function; - const promise = new Promise(res => { - resolve = res; - }); - scaffolderApiMock.getTemplateParameterSchema.mockReturnValueOnce(promise); - const rendered = await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/create': rootRouteRef, - }, - }, - ); - - expect(rendered.getByText('Create a New Component')).toBeInTheDocument(); - expect(rendered.getByTestId('loading-progress')).toBeInTheDocument(); - - await act(async () => { - resolve!({ - title: 'React SSR Template', - steps: [], - }); - }); - }); - - it('captures expected analytics events', async () => { - scaffolderApiMock.scaffold.mockResolvedValue({ taskId: 'xyz' }); - scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ - title: 'schema-4-analytics', - steps: [ - { - title: 'Fill in some steps', - schema: { - properties: { - name: { - title: 'Name', - type: 'string', - }, - }, - required: ['name'], - }, - }, - ], - }); - const { findByLabelText, findByText } = await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/create': rootRouteRef, - }, - }, - ); - - // Fill out the name field - expect(await findByText('Fill in some steps')).toBeInTheDocument(); - fireEvent.change(await findByLabelText('Name', { exact: false }), { - target: { value: 'expected-name' }, - }); - - // Go to the final page - fireEvent.click(await findByText('Next step')); - expect(await findByText('Reset')).toBeInTheDocument(); - - // Create the software - await act(async () => { - fireEvent.click(await findByText('Create')); - }); - - // The "Next Step" button should have fired an event - expect(analyticsMock.getEvents()[0]).toMatchObject({ - action: 'click', - subject: 'Next Step (1)', - context: { entityRef: 'template:default/test' }, - }); - - // And the "Create" button should have fired an event - expect(analyticsMock.getEvents()[1]).toMatchObject({ - action: 'create', - subject: 'expected-name', - context: { entityRef: 'template:default/test' }, - }); - }); - - it('navigates away if no template was loaded', async () => { - scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue( - undefined as any, - ); - - const rendered = await renderInTestApp( - - - - - - } - /> - This is root} /> - - , - { - routeEntries: ['/create'], - mountedRoutes: { '/create': rootRouteRef }, - }, - ); - - expect( - rendered.queryByText('Create a New Component'), - ).not.toBeInTheDocument(); - expect(rendered.getByText('This is root')).toBeInTheDocument(); - }); - - it('display template with oneOf', async () => { - scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ - title: 'my-schema', - steps: [ - { - title: 'Fill in some steps', - schema: { - oneOf: [ - { - title: 'First', - properties: { - name: { - title: 'Name', - type: 'string', - }, - }, - required: ['name'], - }, - { - title: 'Second', - properties: { - something: { - title: 'Something', - type: 'string', - }, - }, - required: ['something'], - }, - ], - }, - }, - ], - }); - - const { findByText, findByLabelText, findAllByRole, findByRole } = - await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/create/actions': rootRouteRef, - }, - }, - ); - - expect(await findByText('Fill in some steps')).toBeInTheDocument(); - - // Fill the first option - fireEvent.change(await findByLabelText('Name', { exact: false }), { - target: { value: 'my-name' }, - }); - - // Switch to second option - fireEvent.mouseDown((await findAllByRole('button'))[0]); - const listbox = within(await findByRole('listbox')); - fireEvent.click(listbox.getByText(/Second/i)); - - // Fill the second option - fireEvent.change(await findByLabelText('Something', { exact: false }), { - target: { value: 'my-something' }, - }); - - // Go to the final page - fireEvent.click(await findByText('Next step')); - expect(await findByText('Reset')).toBeInTheDocument(); - }); - - it('should display a section or property based on a feature flag', async () => { - featureFlagsApiMock.isActive.mockImplementation(flag => { - return flag === 'experimental-feature'; - }); - scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue( - schemaMockValue, - ); - - await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/create/actions': rootRouteRef, - }, - }, - ); - - expect(screen.queryByText('Name')).not.toBeInTheDocument(); - expect(screen.getByText('Description')).toBeInTheDocument(); - expect(screen.getByText('Owner')).toBeInTheDocument(); - expect(screen.getByText('Send data')).toBeInTheDocument(); - }); -}); diff --git a/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.tsx b/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.tsx deleted file mode 100644 index ffb754bae3..0000000000 --- a/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.tsx +++ /dev/null @@ -1,187 +0,0 @@ -/* - * 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 { LinearProgress } from '@material-ui/core'; -import { IChangeEvent } from '@rjsf/core'; -import qs from 'qs'; -import React, { ComponentType, useCallback, useState } from 'react'; -import { Navigate, useNavigate } from 'react-router-dom'; -import useAsync from 'react-use/lib/useAsync'; -import { - type LayoutOptions, - scaffolderApiRef, - useTemplateSecrets, - ReviewStepProps, -} from '@backstage/plugin-scaffolder-react'; -import { MultistepJsonForm } from '../MultistepJsonForm'; -import { createValidator } from './createValidator'; - -import { Content, Header, InfoCard, Page } from '@backstage/core-components'; -import { - AnalyticsContext, - errorApiRef, - useApi, - useApiHolder, - useRouteRef, - useRouteRefParams, -} from '@backstage/core-plugin-api'; -import { stringifyEntityRef } from '@backstage/catalog-model'; -import { - rootRouteRef, - scaffolderTaskRouteRef, - selectedTemplateRouteRef, -} from '../../routes'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; - -const useTemplateParameterSchema = (templateRef: string) => { - const scaffolderApi = useApi(scaffolderApiRef); - const { value, loading, error } = useAsync( - () => scaffolderApi.getTemplateParameterSchema(templateRef), - [scaffolderApi, templateRef], - ); - return { schema: value, loading, error }; -}; - -type Props = { - ReviewStepComponent?: ComponentType; - customFieldExtensions?: LegacyFieldExtensionOptions[]; - layouts?: LayoutOptions[]; - headerOptions?: { - pageTitleOverride?: string; - title?: string; - subtitle?: string; - }; -}; - -export const TemplatePage = ({ - ReviewStepComponent, - customFieldExtensions = [], - layouts = [], - headerOptions, -}: Props) => { - const apiHolder = useApiHolder(); - const secretsContext = useTemplateSecrets(); - const errorApi = useApi(errorApiRef); - const scaffolderApi = useApi(scaffolderApiRef); - const { templateName, namespace } = useRouteRefParams( - selectedTemplateRouteRef, - ); - const templateRef = stringifyEntityRef({ - name: templateName, - kind: 'template', - namespace, - }); - const navigate = useNavigate(); - const scaffolderTaskRoute = useRouteRef(scaffolderTaskRouteRef); - const rootRoute = useRouteRef(rootRouteRef); - const { schema, loading, error } = useTemplateParameterSchema(templateRef); - const [formState, setFormState] = useState>(() => { - const query = qs.parse(window.location.search, { - ignoreQueryPrefix: true, - }); - - try { - return JSON.parse(query.formData as string); - } catch (e) { - return query.formData ?? {}; - } - }); - const handleFormReset = () => setFormState({}); - const handleChange = useCallback( - (e: IChangeEvent) => setFormState(e.formData), - [setFormState], - ); - - const handleCreate = async () => { - const { taskId } = await scaffolderApi.scaffold({ - templateRef, - values: formState, - secrets: secretsContext?.secrets, - }); - - const formParams = qs.stringify( - { formData: formState }, - { addQueryPrefix: true }, - ); - const newUrl = `${window.location.pathname}${formParams}`; - // We use direct history manipulation since useSearchParams and - // useNavigate in react-router-dom cause unnecessary extra rerenders. - // Also make sure to replace the state rather than pushing to avoid - // extra back/forward slots. - window.history?.replaceState(null, document.title, newUrl); - - navigate(scaffolderTaskRoute({ taskId })); - }; - - if (error) { - errorApi.post(new Error(`Failed to load template, ${error}`)); - return ; - } - if (!loading && !schema) { - errorApi.post(new Error('Template was not found.')); - return ; - } - - const customFieldComponents = Object.fromEntries( - customFieldExtensions.map(({ name, component }) => [name, component]), - ); - - const customFieldValidators = Object.fromEntries( - customFieldExtensions.map(({ name, validation }) => [name, validation]), - ); - - return ( - - -
- - {loading && } - {schema && ( - - { - return { - ...step, - validate: createValidator( - step.schema, - customFieldValidators, - { apiHolder }, - ), - }; - })} - /> - - )} - - - - ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplatePage/createValidator.test.ts b/plugins/scaffolder/src/legacy/TemplatePage/createValidator.test.ts deleted file mode 100644 index d6a5cd7499..0000000000 --- a/plugins/scaffolder/src/legacy/TemplatePage/createValidator.test.ts +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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 { createValidator } from './createValidator'; -import { LegacyCustomFieldValidator } from '@backstage/plugin-scaffolder-react/alpha'; -import { ApiHolder } from '@backstage/core-plugin-api'; -import { FieldValidation, FormValidation } from '@rjsf/utils'; - -type CustomLinkType = { - url: string; - title: string; - icon: string; -}; - -describe('createValidator', () => { - const validators: Record< - string, - undefined | LegacyCustomFieldValidator - > = { - CustomPicker: ( - value: unknown, - fieldValidation: FieldValidation, - _context: { apiHolder: ApiHolder }, - ) => { - if (!value || !(value as { value?: unknown }).value) { - fieldValidation.addError('Error !'); - } - }, - CustomLink: ( - values: unknown, - fieldValidation: FieldValidation, - _context: { apiHolder: ApiHolder }, - ) => { - const input = values as CustomLinkType[]; - for (const item of input) { - const validGitlabUrlRegex = - /gitlab\.(?:stg\.)?spotify\.com\?owner=.*&repo=.*/; - - if (!item || !validGitlabUrlRegex.test(item.url)) { - fieldValidation.addError( - `Make sure to put in a valid gitlab clone url.`, - ); - } - } - }, - TagPicker: ( - values: unknown, - fieldValidation: FieldValidation, - _context: { apiHolder: ApiHolder }, - ) => { - const input = values as string[]; - for (const item of input) { - if (!/^[a-z0-9-]+$/.test(item)) { - fieldValidation.addError( - 'A tag name can only contain lowercase letters, numeric characters or dashes', - ); - } - } - }, - }; - - const apiHolderMock: jest.Mocked = { - get: jest.fn().mockImplementation(() => { - return null; - }), - }; - - const context = { - apiHolder: apiHolderMock, - }; - - it('should call validator for object property from a custom field extension', () => { - /* GIVEN */ - const rootSchema = { - title: 'Title', - properties: { - p1: { - title: 'PropertyOn', - type: 'object', - 'ui:field': 'CustomPicker', - }, - }, - }; - const validator = createValidator(rootSchema, validators, context); - - const formData = { - p1: {}, - }; - const errors = { - addError: jest.fn(), - p1: { - addError: jest.fn(), - } as unknown as FormValidation, - } as unknown as FormValidation; - - /* WHEN */ - const result = validator(formData, errors); - - /* THEN */ - expect(result).not.toBeNull(); - expect(result.p1?.addError).toHaveBeenCalledTimes(1); - }); - - it('should call validator for array property from a custom field extension', () => { - /* GIVEN */ - const rootSchema = { - title: 'My form', - properties: { - tags: { - title: 'Tags', - type: 'array', - items: { - type: 'string', - 'ui:field': 'TagPicker', - }, - }, - }, - }; - const validator = createValidator(rootSchema, validators, context); - - const formData = { - tags: ['invalid-tag$$'], - }; - const errors = { - addError: jest.fn(), - tags: { - addError: jest.fn(), - } as unknown as FormValidation, - } as unknown as FormValidation; - - /* WHEN */ - const result = validator(formData, errors); - - /* THEN */ - expect(result).not.toBeNull(); - expect(result.tags?.addError).toHaveBeenCalledTimes(1); - }); - - it('should call validator for array object property from a custom field extension', () => { - /* GIVEN */ - const rootSchema = { - title: 'My links', - properties: { - links: { - title: 'Links', - type: 'array', - items: { - type: 'object', - required: ['url', 'title', 'icon'], - properties: { - url: { - title: 'url', - description: 'url', - type: 'object', - 'ui:field': 'CustomLink', - }, - }, - }, - }, - }, - }; - const validator = createValidator(rootSchema, validators, context); - - const formData = { - links: [ - { - url: 'http://gitlab.spotify.nl/owener=me&repo=test', - icon: 'subject', - title: 'My repository for testing features', - } as CustomLinkType, - ], - }; - const errors = { - addError: jest.fn(), - links: { - addError: jest.fn(), - } as unknown as FormValidation, - } as unknown as FormValidation; - - /* WHEN */ - const result = validator(formData, errors); - - /* THEN */ - expect(result).not.toBeNull(); - expect(result.links?.addError).toHaveBeenCalledTimes(1); - }); -}); diff --git a/plugins/scaffolder/src/legacy/TemplatePage/createValidator.ts b/plugins/scaffolder/src/legacy/TemplatePage/createValidator.ts deleted file mode 100644 index ae0b834fe9..0000000000 --- a/plugins/scaffolder/src/legacy/TemplatePage/createValidator.ts +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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 { LegacyCustomFieldValidator } from '@backstage/plugin-scaffolder-react/alpha'; -import { FieldValidation, FormValidation } from '@rjsf/utils'; -import { JsonObject, JsonValue } from '@backstage/types'; -import { ApiHolder } from '@backstage/core-plugin-api'; - -function isObject(obj: unknown): obj is JsonObject { - return typeof obj === 'object' && obj !== null && !Array.isArray(obj); -} - -function isArray(obj: unknown): obj is JsonObject { - return typeof obj === 'object' && obj !== null && Array.isArray(obj); -} - -export const createValidator = ( - rootSchema: JsonObject, - validators: Record>, - context: { - apiHolder: ApiHolder; - }, -) => { - function validate( - schema: JsonObject, - formData: JsonObject, - errors: FormValidation, - ) { - const schemaProps = schema.properties; - const customObject = schema.type === 'object' && schemaProps === undefined; - - if (!isObject(schemaProps) && !customObject) { - return; - } - - if (schemaProps) { - for (const [key, propData] of Object.entries(formData)) { - const propValidation = errors[key]; - - const doValidate = (item: JsonValue | undefined) => { - if (item && isObject(item)) { - const fieldName = item['ui:field'] as string; - if (fieldName && typeof validators[fieldName] === 'function') { - validators[fieldName]!( - propData as JsonObject[], - propValidation as FieldValidation, - context, - ); - } - } - }; - - const propSchemaProps = schemaProps[key]; - if (isObject(propData) && isObject(propSchemaProps)) { - validate( - propSchemaProps, - propData as JsonObject, - propValidation as FormValidation, - ); - } else if (isArray(propData)) { - if (isObject(propSchemaProps)) { - const { items } = propSchemaProps; - if (isObject(items)) { - if (items.type === 'object') { - const properties = (items?.properties ?? []) as JsonObject[]; - for (const [, value] of Object.entries(properties)) { - doValidate(value); - } - } else { - doValidate(items); - } - } - } - } else { - doValidate(propSchemaProps); - } - } - } else if (customObject) { - const fieldName = schema['ui:field'] as string; - if (fieldName && typeof validators[fieldName] === 'function') { - validators[fieldName]!(formData, errors, context); - } - } - } - - return (formData: JsonObject, errors: FormValidation) => { - validate(rootSchema, formData, errors); - return errors; - }; -}; diff --git a/plugins/scaffolder/src/legacy/TemplatePage/index.ts b/plugins/scaffolder/src/legacy/TemplatePage/index.ts deleted file mode 100644 index d3ae24504b..0000000000 --- a/plugins/scaffolder/src/legacy/TemplatePage/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 { TemplatePage } from './TemplatePage'; -export { createValidator } from './createValidator'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx index 68ed6f906f..fb69dabe13 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx @@ -27,8 +27,8 @@ import React, { useEffect, useMemo, useState } from 'react'; import { useDryRun } from '../DryRunContext'; import { DryRunResultsSplitView } from './DryRunResultsSplitView'; import { FileBrowser } from '../../../components/FileBrowser'; -import { TaskPageLinks } from '../../../legacy/TaskPage/TaskPageLinks'; -import { TaskStatusStepper } from '../../../legacy/TaskPage/TaskPage'; +import { TaskPageLinks } from './TaskPageLinks'; +import { TaskStatusStepper } from './TaskStatusStepper'; const useStyles = makeStyles({ root: { diff --git a/plugins/scaffolder/src/legacy/TaskPage/IconLink.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx similarity index 97% rename from plugins/scaffolder/src/legacy/TaskPage/IconLink.tsx rename to plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx index dd0b3da876..6676c622fa 100644 --- a/plugins/scaffolder/src/legacy/TaskPage/IconLink.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * Copyright 2024 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - import React from 'react'; import { Grid, LinkProps, makeStyles, Typography } from '@material-ui/core'; import LanguageIcon from '@material-ui/icons/Language'; diff --git a/plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx similarity index 100% rename from plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.tsx rename to plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx new file mode 100644 index 0000000000..f776d133e0 --- /dev/null +++ b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx @@ -0,0 +1,199 @@ +/* + * Copyright 2024 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, { useState } from 'react'; +import { memo } from 'react'; +import Step from '@material-ui/core/Step'; +import StepLabel from '@material-ui/core/StepLabel'; +import Stepper from '@material-ui/core/Stepper'; +import { ScaffolderTaskStatus } from '@backstage/plugin-scaffolder-react'; +import { + StepButton, + StepIconProps, + Theme, + createStyles, + makeStyles, + CircularProgress, +} from '@material-ui/core'; +import Cancel from '@material-ui/icons/Cancel'; +import Check from '@material-ui/icons/Check'; +import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord'; +import Typography from '@material-ui/core/Typography'; +import { DateTime, Interval } from 'luxon'; +import useInterval from 'react-use/lib/useInterval'; +import humanizeDuration from 'humanize-duration'; +import classNames from 'classnames'; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + root: { + width: '100%', + }, + button: { + marginBottom: theme.spacing(2), + marginLeft: theme.spacing(2), + }, + actionsContainer: { + marginBottom: theme.spacing(2), + }, + resetContainer: { + padding: theme.spacing(3), + }, + labelWrapper: { + display: 'flex', + flex: 1, + flexDirection: 'row', + justifyContent: 'space-between', + }, + stepWrapper: { + width: '100%', + }, + }), +); + +type TaskStep = { + id: string; + name: string; + status: ScaffolderTaskStatus; + startedAt?: string; + endedAt?: string; +}; + +const useStepIconStyles = makeStyles(theme => + createStyles({ + root: { + color: theme.palette.text.disabled, + display: 'flex', + height: 22, + alignItems: 'center', + }, + completed: { + color: theme.palette.status.ok, + }, + error: { + color: theme.palette.status.error, + }, + }), +); + +const StepTimeTicker = ({ step }: { step: TaskStep }) => { + const [time, setTime] = useState(''); + + useInterval(() => { + if (!step.startedAt) { + setTime(''); + return; + } + + const end = step.endedAt + ? DateTime.fromISO(step.endedAt) + : DateTime.local(); + + const startedAt = DateTime.fromISO(step.startedAt); + const formatted = Interval.fromDateTimes(startedAt, end) + .toDuration() + .valueOf(); + + setTime(humanizeDuration(formatted, { round: true })); + }, 1000); + + return {time}; +}; + +function TaskStepIconComponent(props: StepIconProps) { + const classes = useStepIconStyles(); + const { active, completed, error } = props; + + const getMiddle = () => { + if (active) { + return ; + } + if (completed) { + return ; + } + if (error) { + return ; + } + return ; + }; + + return ( +
+ {getMiddle()} +
+ ); +} + +export const TaskStatusStepper = memo( + (props: { + steps: TaskStep[]; + currentStepId: string | undefined; + onUserStepChange: (id: string) => void; + classes?: { + root?: string; + }; + }) => { + const { steps, currentStepId, onUserStepChange } = props; + const classes = useStyles(props); + + return ( +
+ s.id === currentStepId)} + orientation="vertical" + nonLinear + > + {steps.map((step, index) => { + const isCancelled = step.status === 'cancelled'; + const isActive = step.status === 'processing'; + const isCompleted = step.status === 'completed'; + const isFailed = step.status === 'failed'; + const isSkipped = step.status === 'skipped'; + + return ( + + onUserStepChange(step.id)}> + +
+ {step.name} + {isSkipped ? ( + Skipped + ) : ( + + )} +
+
+
+
+ ); + })} +
+
+ ); + }, +); diff --git a/plugins/scaffolder/src/plugin.tsx b/plugins/scaffolder/src/plugin.tsx index fdde81695d..7fa7dc1521 100644 --- a/plugins/scaffolder/src/plugin.tsx +++ b/plugins/scaffolder/src/plugin.tsx @@ -212,15 +212,3 @@ export const EntityTagsPickerFieldExtension = scaffolderPlugin.provide( schema: EntityTagsPickerSchema, }), ); - -/** - * @alpha - * The Router and main entrypoint to the Alpha Scaffolder plugin. - */ -export const LegacyScaffolderPage = scaffolderPlugin.provide( - createRoutableExtension({ - name: 'LegacyScaffolderPage', - component: () => import('./legacy/Router').then(m => m.LegacyRouter), - mountPoint: rootRouteRef, - }), -); diff --git a/plugins/search-backend/src/schema/openapi.generated.ts b/plugins/search-backend/src/schema/openapi.generated.ts index 2586b7a5bf..06b576ba70 100644 --- a/plugins/search-backend/src/schema/openapi.generated.ts +++ b/plugins/search-backend/src/schema/openapi.generated.ts @@ -22,7 +22,7 @@ import { createValidatedOpenApiRouter } from '@backstage/backend-openapi-utils'; export const spec = { openapi: '3.0.3', info: { - title: '@backstage/plugin-search-backend', + title: 'search', version: '1', description: 'The Backstage backend plugin that provides search functionality.', diff --git a/plugins/search-backend/src/schema/openapi.yaml b/plugins/search-backend/src/schema/openapi.yaml index 79bb84dfe0..47f7e0a1e5 100644 --- a/plugins/search-backend/src/schema/openapi.yaml +++ b/plugins/search-backend/src/schema/openapi.yaml @@ -1,6 +1,6 @@ openapi: 3.0.3 info: - title: '@backstage/plugin-search-backend' + title: search version: '1' description: The Backstage backend plugin that provides search functionality. license: diff --git a/plugins/search/src/alpha.tsx b/plugins/search/src/alpha.tsx index a3a5023693..4f654548f5 100644 --- a/plugins/search/src/alpha.tsx +++ b/plugins/search/src/alpha.tsx @@ -70,6 +70,7 @@ import { UrlUpdater } from './components/SearchPage/SearchPage'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; /** @alpha */ @@ -248,7 +249,7 @@ export const searchNavItem = createNavItemExtension({ export default createPlugin({ id: 'search', extensions: [searchApi, searchPage, searchNavItem], - routes: { - root: convertLegacyRouteRef(rootRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + }), }); diff --git a/plugins/tech-radar/src/alpha.tsx b/plugins/tech-radar/src/alpha.tsx index 1fb5fa06f3..54e209fae3 100644 --- a/plugins/tech-radar/src/alpha.tsx +++ b/plugins/tech-radar/src/alpha.tsx @@ -27,6 +27,7 @@ import { SampleTechRadarApi } from './sample'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; import { rootRouteRef } from './plugin'; @@ -61,7 +62,7 @@ export const techRadarApi = createApiExtension({ export default createPlugin({ id: 'tech-radar', extensions: [techRadarPage, techRadarApi], - routes: { - root: convertLegacyRouteRef(rootRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + }), }); diff --git a/plugins/techdocs-module-addons-contrib/src/ReportIssue/ReportIssue.tsx b/plugins/techdocs-module-addons-contrib/src/ReportIssue/ReportIssue.tsx index c81eacb1ee..a6d8021b9d 100644 --- a/plugins/techdocs-module-addons-contrib/src/ReportIssue/ReportIssue.tsx +++ b/plugins/techdocs-module-addons-contrib/src/ReportIssue/ReportIssue.tsx @@ -111,8 +111,25 @@ export const ReportIssueAddon = ({ const mainContentPosition = mainContent!.getBoundingClientRect(); const selectionPosition = selection.getRangeAt(0).getBoundingClientRect(); + // Calculating the distance between the selection's top and the main content's top + const distanceFromTop = selectionPosition.top - mainContentPosition.top; + const minDistanceFromTop = 50; + + // Defining a base value for 'top' + let top = distanceFromTop < minDistanceFromTop ? 101 : distanceFromTop - 16; + + // Checking if the main content is off-screen towards the top + if (mainContentPosition.top < 0) { + const absMainContentTop = Math.abs(mainContentPosition.top); + + // Adjusting 'top' if the selection is close to the top edge and the main content is off-screen + if (distanceFromTop - absMainContentTop < minDistanceFromTop) { + top += 89; + } + } + setStyle({ - top: `${selectionPosition.top - mainContentPosition.top - 16}px`, + top: `${top}px`, left: `${selectionPosition.left + selectionPosition.width / 2}px`, }); // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/plugins/techdocs/src/alpha.tsx b/plugins/techdocs/src/alpha.tsx index ef564d469a..88dce3b48e 100644 --- a/plugins/techdocs/src/alpha.tsx +++ b/plugins/techdocs/src/alpha.tsx @@ -34,6 +34,7 @@ import { import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; import { techdocsApiRef, @@ -168,9 +169,9 @@ export default createPlugin({ techDocsEntityContent, techDocsSearchResultListItemExtension, ], - routes: { - root: convertLegacyRouteRef(rootRouteRef), - docRoot: convertLegacyRouteRef(rootDocsRouteRef), - entityContent: convertLegacyRouteRef(rootCatalogDocsRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + docRoot: rootDocsRouteRef, + entityContent: rootCatalogDocsRouteRef, + }), }); diff --git a/plugins/todo-backend/src/schema/openapi.generated.ts b/plugins/todo-backend/src/schema/openapi.generated.ts index effe851790..238be2fe5b 100644 --- a/plugins/todo-backend/src/schema/openapi.generated.ts +++ b/plugins/todo-backend/src/schema/openapi.generated.ts @@ -22,7 +22,7 @@ import { createValidatedOpenApiRouter } from '@backstage/backend-openapi-utils'; export const spec = { openapi: '3.0.3', info: { - title: '@backstage/plugin-todo-backend', + title: 'todo', version: '1', description: 'The Backstage backend plugin that provides source code todo comment browsing.', diff --git a/plugins/todo-backend/src/schema/openapi.yaml b/plugins/todo-backend/src/schema/openapi.yaml index 8023144f48..7408927b99 100644 --- a/plugins/todo-backend/src/schema/openapi.yaml +++ b/plugins/todo-backend/src/schema/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: - title: '@backstage/plugin-todo-backend' + title: todo version: '1' description: The Backstage backend plugin that provides source code todo comment browsing. license: diff --git a/plugins/user-settings/src/alpha.tsx b/plugins/user-settings/src/alpha.tsx index 5dabd70739..f14db7233d 100644 --- a/plugins/user-settings/src/alpha.tsx +++ b/plugins/user-settings/src/alpha.tsx @@ -22,6 +22,7 @@ import { } from '@backstage/frontend-plugin-api'; import { convertLegacyRouteRef, + convertLegacyRouteRefs, compatWrapper, } from '@backstage/core-compat-api'; import SettingsIcon from '@material-ui/icons/Settings'; @@ -65,7 +66,7 @@ export const settingsNavItem = createNavItemExtension({ export default createPlugin({ id: 'user-settings', extensions: [userSettingsPage, settingsNavItem], - routes: { - root: convertLegacyRouteRef(settingsRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: settingsRouteRef, + }), }); diff --git a/yarn.lock b/yarn.lock index 39042b78e8..b556638d4b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -363,515 +363,515 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.490.0" +"@aws-sdk/client-cognito-identity@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-signing": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-signing": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 4b131c722d611242c8d5eb961115fb60f40bd228ecb2f6ce4851d30bae7b3b39b68cfd6ca363f901e8c16571539d37c7a617dae6681aa0bcfeec189a6b5afcea + checksum: 078c17e6f6fed15ee320a4d94e9925ff7ccb537416552492b3e66179998a8259c1d68c2f1523243c497c7bc64d613f33acc92b9f9c2c9238eee41be26aebcaf9 languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/client-eks@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/client-eks@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-signing": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 - "@smithy/util-waiter": ^2.0.16 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-signing": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 + "@smithy/util-waiter": ^2.1.0 tslib: ^2.5.0 uuid: ^8.3.2 - checksum: 367e3c987f644b0b4a6c5fba1ef1e6caa52594205ac9efe095960e00dcf4b0191f143080cfbdbb3807b91140cda14973f734e536104b355908d9c7ed3ba9fa64 + checksum: f4d9ce87c23c1d117e4046c97ac974131e54b878eb0aed9457739ca0d202f8d36c9b2ba3718120de531fdb200ccab123a4d1f848ef8c3858b1ca5d81dcd9c789 languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/client-organizations@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/client-organizations@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-signing": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-signing": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 073bc5ecc31e7c0cb0fd195e868f17946e7f60e12cdab3402fd1752374939915affb8f15fb55697f1a626736d7b05e35e65d466a5dddfd6e091eb0e16803f8a8 + checksum: 3c7deae27a0549ff97551d577df701f21823ca6f3fc965b35add491642faf3ddb060183752687264727e10cc80addb1a3c263af81f2a35d15fe0c3edb02a5da2 languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/client-s3@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/client-s3@npm:3.495.0" dependencies: "@aws-crypto/sha1-browser": 3.0.0 "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-bucket-endpoint": 3.489.0 - "@aws-sdk/middleware-expect-continue": 3.489.0 - "@aws-sdk/middleware-flexible-checksums": 3.489.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-location-constraint": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-sdk-s3": 3.489.0 - "@aws-sdk/middleware-signing": 3.489.0 - "@aws-sdk/middleware-ssec": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/signature-v4-multi-region": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@aws-sdk/xml-builder": 3.485.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/eventstream-serde-browser": ^2.0.16 - "@smithy/eventstream-serde-config-resolver": ^2.0.16 - "@smithy/eventstream-serde-node": ^2.0.16 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-blob-browser": ^2.0.17 - "@smithy/hash-node": ^2.0.18 - "@smithy/hash-stream-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/md5-js": ^2.0.18 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-stream": ^2.0.24 - "@smithy/util-utf8": ^2.0.2 - "@smithy/util-waiter": ^2.0.16 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-bucket-endpoint": 3.495.0 + "@aws-sdk/middleware-expect-continue": 3.495.0 + "@aws-sdk/middleware-flexible-checksums": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-location-constraint": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-sdk-s3": 3.495.0 + "@aws-sdk/middleware-signing": 3.495.0 + "@aws-sdk/middleware-ssec": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/signature-v4-multi-region": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@aws-sdk/xml-builder": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/eventstream-serde-browser": ^2.1.0 + "@smithy/eventstream-serde-config-resolver": ^2.1.0 + "@smithy/eventstream-serde-node": ^2.1.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-blob-browser": ^2.1.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/hash-stream-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/md5-js": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-stream": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 + "@smithy/util-waiter": ^2.1.0 fast-xml-parser: 4.2.5 tslib: ^2.5.0 - checksum: 28fc1c384bdba8c374ac8f150350feb5b6e8afaef76aaba2705d8d06d60dec9a209869888a3e91e75c88454084940916b1bc6070cc422d50712af7dd20a66ccf + checksum: 2add0f58189bfc394a6b3963ef4295b9997f3ea544d8a92ba2d16b9051f4fd07fb9f184e9ad6ca6ce665cbec496abd5e0e69a91a97213117dc20aafd3bed2840 languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/client-sqs@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/client-sqs@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-sdk-sqs": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/md5-js": ^2.0.18 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-middleware": ^2.0.9 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-sdk-sqs": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/md5-js": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-middleware": ^2.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 394f351ca8feff09b631eab6e285068379384a592832ec8ae502a15f60a475f2aa43e29d74b0dd5c2732610a9f7f122148ee442550975ecded53368b8d01a6b1 + checksum: 4dcbf031c1902149d8fa82f7c555eb416d904c1e197ad2deae927856748719c03b025bb122a131df34435269039a6b0538635826e0bcab204b86ef24fe4595b8 languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/client-sso@npm:3.490.0" +"@aws-sdk/client-sso@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/client-sso@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: f09172f7af1de8371dc4bd03ef18f2a260bd9868db9460912d392d0f2bcf4101e8f78eed440db6bd99437a3b8d1c1a107fb3bc904f20f4a99eb0a262c0644b14 + checksum: a4672a8a2c454be634cb7e97a3cc075df55ad7ab8eb494bda3e4d16831f110212069668ab4fe6085f4b09920d1a04f3bd2cca0caf3a395d874cbcf5d71c6ffe7 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.490.0, @aws-sdk/client-sts@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/client-sts@npm:3.490.0" +"@aws-sdk/client-sts@npm:3.495.0, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.495.0 + resolution: "@aws-sdk/client-sts@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-middleware": ^2.0.9 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-middleware": ^2.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 fast-xml-parser: 4.2.5 tslib: ^2.5.0 - checksum: 0fffd52bfae00c2e1beacf2cc58924131097efb7022a72f2d8c00e93e9c00ceb584d085b92160a2798d761726c7ca8492da5a7e8665d103a658ad96f9633e04e + checksum: 33c5ef3fc87a2fb8cb5dc6bc855c5756712110d1c0be713543ffd657fcae4062e10ce9a1501bb9bc7a9f821a542f6e52c3bd9d88add89af67a116f3f5ab486fd languageName: node linkType: hard -"@aws-sdk/core@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/core@npm:3.490.0" +"@aws-sdk/core@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/core@npm:3.495.0" dependencies: - "@smithy/core": ^1.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/signature-v4": ^2.0.0 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 + "@smithy/core": ^1.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/signature-v4": ^2.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 8d711ba4373b4ee074f5a225642cb91cd0052daf1e2880da1f5bd1b38197ea5c7888a4181710f715393f83618aacc4465262f9a80de8f4faf2644d5832e455b5 + checksum: 2038b283ab62a0a10880a7193cef8b3673298ff9b7ba3005e3a47df43c588d3a3a9dfdbe607b99183932675a74ec17a88a90f9a5c5f5896292a9e6cbc888cf13 languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.490.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.495.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.490.0 - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/client-cognito-identity": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: c1ee2aa0c1d6c9bd61f17550c9381b05e790f23afc5dd757a242e2a9f8ee0c03c49f8b29452258b86c5f68b9e87fba3eb5b299ceb6414f1db6919de32aacba17 + checksum: 8bd8841d5d2e5316c271f6e5585216f906d60a42b221d5afdd52d49b6318faa6776cdc956704a22b675c5dd41fd164a2cf512f069a99738660eeea24c3316234 languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.489.0" +"@aws-sdk/credential-provider-env@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: ef1c3fb9e12cb3b62be41d87ce168b704d462b6fb27d08eab58b003940e3b24b043f122efab42cdc41d0bd632074114f39b474c480705dc61ed6e879690fa93f + checksum: 5454a770638e2122877679897acb422871e0381c7e8a2a848c1837f16115bea7d3abaf56e2282b9986885de186538868f90c62292348251bbbd84c872c4a5eb0 languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.489.0" +"@aws-sdk/credential-provider-http@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/property-provider": ^2.0.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/util-stream": ^2.0.24 + "@aws-sdk/types": 3.495.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/util-stream": ^2.1.0 tslib: ^2.5.0 - checksum: 601580c4299b1b0d7a696a94643b78c12491261f975275c5ae544ca5eee1f08fb4d21af1935257f2972b1f8ed8c0246275963e9c97cc53484f6d501ad6dbd4c6 + checksum: 367563058b01bc681523de85f4753bb53c53b0975c9258d6b4583222a28543ca2b2e3b5f75c1f1f6fb25a25baeb053d8d46c86b6997c4243bfc062a03093bae8 languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.490.0" +"@aws-sdk/credential-provider-ini@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.495.0" dependencies: - "@aws-sdk/credential-provider-env": 3.489.0 - "@aws-sdk/credential-provider-process": 3.489.0 - "@aws-sdk/credential-provider-sso": 3.490.0 - "@aws-sdk/credential-provider-web-identity": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@smithy/credential-provider-imds": ^2.0.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.8.0 + "@aws-sdk/credential-provider-env": 3.495.0 + "@aws-sdk/credential-provider-process": 3.495.0 + "@aws-sdk/credential-provider-sso": 3.495.0 + "@aws-sdk/credential-provider-web-identity": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/credential-provider-imds": ^2.2.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 5dd24af06b3a2977c1ebd47621619b18b8d9f9bed04e8ac5daae9faedabe66d6c6792a62da54513d668f0b11315cab4fd41a85637e35646cec46588742e36b1f + checksum: fcd401dcc8a71a601888a9abd5e915ae8bdf19501ed0f497478d8844a7e11769314488b2b3a1995c33a954ab499ab118911decdfaf8151e47c4768d6e090a429 languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.490.0, @aws-sdk/credential-provider-node@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.490.0" +"@aws-sdk/credential-provider-node@npm:3.495.0, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.495.0" dependencies: - "@aws-sdk/credential-provider-env": 3.489.0 - "@aws-sdk/credential-provider-ini": 3.490.0 - "@aws-sdk/credential-provider-process": 3.489.0 - "@aws-sdk/credential-provider-sso": 3.490.0 - "@aws-sdk/credential-provider-web-identity": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@smithy/credential-provider-imds": ^2.0.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.8.0 + "@aws-sdk/credential-provider-env": 3.495.0 + "@aws-sdk/credential-provider-ini": 3.495.0 + "@aws-sdk/credential-provider-process": 3.495.0 + "@aws-sdk/credential-provider-sso": 3.495.0 + "@aws-sdk/credential-provider-web-identity": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/credential-provider-imds": ^2.2.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 52820573a6aff0ea8c7ca0699fb374ba9a94a9e9eb777c2b1225d3565fdde7a65c70fcbe9ec887cf555c2df73cdc341641791f1358a102e052869d0f4978d4d0 + checksum: c661de3423fb106d1f3347e24287d0fd9208e02a2fe4159300ec7c1df90196f09df25aab06428f64d3cfcae2a28482737d8cd9ad6d8adca0aa0cfa810276b0ac languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.489.0" +"@aws-sdk/credential-provider-process@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 19eb75f0222176f33ad5fbeb5a02b312a37a48966b73ff5c1af9974d439dc4c6faeffe745c2a23b0abb67ab876f9e10099b4a22c2ee9d15be5290556331a7a9a + checksum: e19812756fb578cf5e7845db1fc2df77fadb427efaefe7ce23effa20f5f7e1661cea05179ab425e3cbef08966b1821a4ccfbd00343f68f65b0564c0b06510b9a languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.490.0" +"@aws-sdk/credential-provider-sso@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.495.0" dependencies: - "@aws-sdk/client-sso": 3.490.0 - "@aws-sdk/token-providers": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.8.0 + "@aws-sdk/client-sso": 3.495.0 + "@aws-sdk/token-providers": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: ea3c9d180f13f676b7717a8e0aabdca33b36f2dbf27128dfa6f8172040aa895437ef03e08802b9d6b104a783b8606b8af923193ff54f79e92118aa54babaa311 + checksum: 2f96aba1921612026e8dcd7d7f58988c63efdf270a8688adb0704f2e442778700d7160c890cf926a89eb79a2471ee9084329bd8463998bbb416b0f5ebfe8f7e3 languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.489.0" +"@aws-sdk/credential-provider-web-identity@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 6da681688c9a61b6e100c71983a1ba19ef34bcbd8d1e4e85e3399d86e74cdc8d81f57b6da1983319596c87ef1600471e82c5243fb909f9752eff99a6ef26a8ea + checksum: d22fda65683d0558dd03e710c8ef4762c4c500d8527cf951b3597a716a56ffbd1d9bf22089e4714325f4043a5e9eb9f6b27e2e3f217eef06de3cc3364e5a8a0f languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/credential-providers@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/credential-providers@npm:3.495.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.490.0 - "@aws-sdk/client-sso": 3.490.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/credential-provider-cognito-identity": 3.490.0 - "@aws-sdk/credential-provider-env": 3.489.0 - "@aws-sdk/credential-provider-http": 3.489.0 - "@aws-sdk/credential-provider-ini": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/credential-provider-process": 3.489.0 - "@aws-sdk/credential-provider-sso": 3.490.0 - "@aws-sdk/credential-provider-web-identity": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@smithy/credential-provider-imds": ^2.0.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/client-cognito-identity": 3.495.0 + "@aws-sdk/client-sso": 3.495.0 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/credential-provider-cognito-identity": 3.495.0 + "@aws-sdk/credential-provider-env": 3.495.0 + "@aws-sdk/credential-provider-http": 3.495.0 + "@aws-sdk/credential-provider-ini": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/credential-provider-process": 3.495.0 + "@aws-sdk/credential-provider-sso": 3.495.0 + "@aws-sdk/credential-provider-web-identity": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/credential-provider-imds": ^2.2.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 470f752cdf07861b6d5d7aff18e0541400bb211fcda7037347593f67d3882be9f5bd66b334915dc6549b96c554e1334e1dfec3286210eb9e18628a8bc2f19052 + checksum: 1cb201bc9fe2f2f5edd277416962e32e6f99ecc98b5d386bfcac91d6db1719d66b57b1e690d660a6fe1ac198648d5df906397ac5e2d9d5a35d345bcc3230324a languageName: node linkType: hard @@ -897,34 +897,34 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/lib-storage@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/lib-storage@npm:3.495.0" dependencies: - "@smithy/abort-controller": ^2.0.1 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/smithy-client": ^2.2.1 + "@smithy/abort-controller": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/smithy-client": ^2.3.0 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: ^2.5.0 peerDependencies: "@aws-sdk/client-s3": ^3.0.0 - checksum: 253dc2e4fd33efcf5ee8d3ad76bb3f2ed1d4573e27fa8be23dc3b9b60bcf22e769684f3ab639c3551a66282e160e4b1693527ac49062c6a42b55716e7aadc6df + checksum: 6d7a1576f30ff2432f0907a8357604de5a6d338c706e34c8e85ef6fbb4e2a878c84ce41978c79844757454b0e90914c83b4c983a428a7ea0ba67b6ce7d15c9a8 languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.489.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-arn-parser": 3.465.0 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 - "@smithy/util-config-provider": ^2.1.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-arn-parser": 3.495.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 + "@smithy/util-config-provider": ^2.2.0 tslib: ^2.5.0 - checksum: 209278da47bf7e3b0e3cd6bc0f80d56bd6fc06400c12041474d1fdef7d227b8120bd7ac0b471fd15e03433e8c9e5e8c7a20d4f5f057dc23edfecaf4b61ad1378 + checksum: d75288d8d290b0749a9f17bf893dfb2d334a08707dbda2d24d187f53096c58f190e102a789310045b03792fe6d145a23af7dbac07994b27473f386328cc2bb5c languageName: node linkType: hard @@ -941,107 +941,107 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.489.0" +"@aws-sdk/middleware-expect-continue@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 2e4bc714e5c410d2362ec274e2f36ffbb35dc826030ac64ec2d34bf9a89b1defa3c8cd1e0d92c4f41ddb64035039ddfac927069152ea70437061f2f078d43cc1 + checksum: d9e49bd36994cc5a0114d51fb050efecf5f9ae46bd5718b5acb98d486a864d33ced0d1a0afc96f22192a23f4a9acf8c784db3d97243b25452c55fd4e3491aec8 languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.489.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.495.0" dependencies: "@aws-crypto/crc32": 3.0.0 "@aws-crypto/crc32c": 3.0.0 - "@aws-sdk/types": 3.489.0 - "@smithy/is-array-buffer": ^2.0.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/types": 3.495.0 + "@smithy/is-array-buffer": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 522f234ba9fdf5fe1476c72b7480158723a52e15db0560a4d79fa00dd43935633104648a4be2d0d741afa90f5b4f5ced3e99ffdece9b1aa75f4c08389dbe5f10 + checksum: 5ec9e6543222349ee4cc1560ebd0ec3fc076e62bb6a6f2fcfb55cb2b7b6d7f944dd3801869bc3a0367975bf7efbc587c1acb19fc9de07faf389aa966e8eeb15f languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.489.0" +"@aws-sdk/middleware-host-header@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 15072d8409066de23ae815ce84c9ab9ce509e368654a3438b398e0f1bec5e215a52a59388ede1fe4c7a40cb639759c50aab3a3562ffe17352a24e6f92f2ddd1e + checksum: 4b4f64827f2f75df045229987625560c1ee35a30e48044f3b60292dbb0599760459097a79e805e2982e1a1150def39758aaf5637e8696b8d21101c03988499ff languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.489.0" +"@aws-sdk/middleware-location-constraint@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: d9499c897ef1f89afafdc2b4ebaa32cb31396cd7412ddaab545427820c33ef90e6f3e9f16b82607cc7a0d402994034b0c51255c06e2bd15f30d618d10f8bcbc6 + checksum: 8315ea52cff810e8c19176e24528bee4a29af7f2631b1508e04a8936396dd020535e507300df9e5d8b98d4b8c1c5fd78b9e868f0500b7a66e0743394fd2313a5 languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-logger@npm:3.489.0" +"@aws-sdk/middleware-logger@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-logger@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 10fa2538663512158f7a5889da693b0351f1f464457e45bc02199540adf6985ddfda81fe36dbdddabe1fe12709118fa106a365988e691fab834c9d93bf34329e + checksum: d36ee788bdcfc19bd73525c7b0dc476e63b26f4a798a43626fdc76776c0b46f905867bd86c8792aaa7736cbfb18b1fe36c22ef86af4cd8dacdc10e34feee0caf languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.489.0" +"@aws-sdk/middleware-recursion-detection@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: bf1592f0577e8a5be5857100c288c0de0895b98b00d1947403d9ff99936d366cd3e8ae4838560ee68ff0d5fb74f26c2f139f23fee8b72ce8f753a742b467bb02 + checksum: eaa7921de46d6d2389b56eb36417a32bd1af41c4ed24f6e2956fa4fd1bb14141253368d96882402df4f6498eaee081c67c170ce74f042d74b0ec431cd1219df7 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.489.0" +"@aws-sdk/middleware-sdk-s3@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-arn-parser": 3.465.0 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/protocol-http": ^3.0.12 - "@smithy/signature-v4": ^2.0.0 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/util-config-provider": ^2.1.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-arn-parser": 3.495.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/signature-v4": ^2.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/util-config-provider": ^2.2.0 tslib: ^2.5.0 - checksum: 4a1541d7e21172a270cf3965171abcfd1dcb1fc98eac982fb2d3f8dbc10cfecec5ea13bfb27ada66c1a40a6446d027399818edabf1180b340e496eb6826fa8d7 + checksum: b3c6e8fda75ca696a1ba8b2327c1cf3ec941d19af5927614949f4ba317934db2733c22fa011f614651a093a3374d7be1fa5c3f834517a48a6884060ff6cfd625 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.489.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 - "@smithy/util-hex-encoding": ^2.0.0 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 + "@smithy/util-hex-encoding": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: a87d0f4c4dd0afd67b37cd5b4de4daa2505c7a51faa2c6aeef6eac0d6a74e68aa3457ec30bc6c174418899899de252ccda1ce53afe8380db2183c8620a4fa84f + checksum: 78c2b4a59fe5fe6797b5a31c486b7169aba57c4c070db1e691c1049d03a6952a406cd88d0d612bbb252a8d06855437022f505934f137e8244db93d33572545ea languageName: node linkType: hard @@ -1055,42 +1055,42 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-signing@npm:3.489.0" +"@aws-sdk/middleware-signing@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-signing@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/signature-v4": ^2.0.0 - "@smithy/types": ^2.8.0 - "@smithy/util-middleware": ^2.0.9 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/signature-v4": ^2.1.0 + "@smithy/types": ^2.9.0 + "@smithy/util-middleware": ^2.1.0 tslib: ^2.5.0 - checksum: bf50942d8ca7baf2d27b0a6d8fb06219971da9863ee0fa7a2ab56c85d344b0374724f608cec371b75a2ea2a0cd4da6d7d431f8bf1f3d9fe5f1797a4d15272962 + checksum: ca717e5c2bc03157f4ee6f3c05d8c815ecf7bab83f5f86c8751a3106d4f5459630258d945d8840650bfb367b881ff3be1fc0c9037162f717380c2a76dec938db languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.489.0" +"@aws-sdk/middleware-ssec@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: c3666f606bcdcbe2c36a21e0460fd9514ea6f7a3faf09fb392457ca7fc9f41da81351a50f4432ce748a24daad5715736eddf7e59694f0fbbcc530b395c2bf12c + checksum: 5f92ae6ac0b7a869203650c343eb0f42375b8784b20abed88f2075db4413935469c988c5daee6b520aea63a2208ca412a9a78c6fbb0b14fc7719c9dbc9ffdc65 languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.489.0" +"@aws-sdk/middleware-user-agent@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: b5254863f2203b598199ad65ca87a5a3b92a3ecb51cabbb910819b0f03f61b26b553364e047b9b3329463f8dd4324a650d045deaf548cb5e7de2c08ed2f5dfd6 + checksum: a36dcd5252b001786a8d970143855e80242fa1d88252693a8c2a244114fcfae02eb4ae958a37efa92aeff5cc792506f9199961c346fd943949141a3e078c3123 languageName: node linkType: hard @@ -1138,31 +1138,31 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.489.0" +"@aws-sdk/region-config-resolver@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/types": ^2.8.0 - "@smithy/util-config-provider": ^2.1.0 - "@smithy/util-middleware": ^2.0.9 + "@aws-sdk/types": 3.495.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/types": ^2.9.0 + "@smithy/util-config-provider": ^2.2.0 + "@smithy/util-middleware": ^2.1.0 tslib: ^2.5.0 - checksum: 2352d0b3409e6d5225fd3f6f5da81164fcb93bb528579eacefea75ef8760f8626434e377eb3c7785046ce996732209f300de70958905124acbd1eb45a192e24b + checksum: f0f723dbd46761246dd771d975cb60c60afcbb10a94138183b7b00cad633ce92fdd7f2ee9ae60fcfc369d4aadd653d56562f5a14652dc8974816fbaf2c924182 languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.489.0" +"@aws-sdk/signature-v4-multi-region@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.495.0" dependencies: - "@aws-sdk/middleware-sdk-s3": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/signature-v4": ^2.0.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/middleware-sdk-s3": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/signature-v4": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 613ab4f64682844dd9a6c6675f7db218185d3415a40b255e1346a0217576bad431156324739d148542421c67036462476b95ac801ea8c7f24f5abac96514ee23 + checksum: 93559456f5d4cae2fde06f49c41275d411bc9c4625cb73b6fc88f165c960d7a9a5e1432ae95ad6243430e6c0d07b6710e94aaf0ca39c7514e7c9f0240a466507 languageName: node linkType: hard @@ -1182,48 +1182,48 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/token-providers@npm:3.489.0" +"@aws-sdk/token-providers@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/token-providers@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/property-provider": ^2.0.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: cf2e14a09ead031e9ac3426fd0e5bc71656f1ce9ba470c860af26d8935dce65b28365973388175f982dd2d8fb6c470520dee426045b26174663a5adc6ac5928c + checksum: 76b8dacaf9d0d9c608866d10bb8d0d42070e88872688f9dae3cd2cce2cd573bb6937ffd4e4ef3ca94763ac4f549faaf6f7d1e1bea714d7ec37b5a7ca533f5599 languageName: node linkType: hard @@ -1237,13 +1237,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.489.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": - version: 3.489.0 - resolution: "@aws-sdk/types@npm:3.489.0" +"@aws-sdk/types@npm:3.495.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": + version: 3.495.0 + resolution: "@aws-sdk/types@npm:3.495.0" dependencies: - "@smithy/types": ^2.8.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: e4692f04daee278e4fc7faeadb8fee077aee5b1210a6c237c203b4688b714d1efc96c9f4574b71e264f71d8f4aad06b5728bcba13d12242c92f93dec81e3d3da + checksum: 786d7d860cd8c22a631d48e5a2a0570b941f43927d3bee1da36d4749f71fbdc2e7908f15f73582d0572c74f9f0e6b411a33f94facf27aec93d9f2920b9a662f4 languageName: node linkType: hard @@ -1258,12 +1258,12 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-arn-parser@npm:3.465.0, @aws-sdk/util-arn-parser@npm:^3.310.0": - version: 3.465.0 - resolution: "@aws-sdk/util-arn-parser@npm:3.465.0" +"@aws-sdk/util-arn-parser@npm:3.495.0, @aws-sdk/util-arn-parser@npm:^3.310.0": + version: 3.495.0 + resolution: "@aws-sdk/util-arn-parser@npm:3.495.0" dependencies: tslib: ^2.5.0 - checksum: ce2dd638e9b8ef3260ce1c1ae299a4e44cbaa28a07cda9f1033b763cea8b1d901b7a963338e8a172af17074d06811f09605f3f903318c4bd2bbf102e92d02546 + checksum: 130f1b1c0d2b9917782049693aa4ab6aec98858d6e2b46c14a3a6c4979e65073f731aec96aa0e1c04e927d0b32ad2d4a6a701e2a6d5d416c6ea35e670e4eb987 languageName: node linkType: hard @@ -1277,15 +1277,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/util-endpoints@npm:3.489.0" +"@aws-sdk/util-endpoints@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/util-endpoints@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 - "@smithy/util-endpoints": ^1.0.8 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 + "@smithy/util-endpoints": ^1.1.0 tslib: ^2.5.0 - checksum: 5c225b12ce5c18ecd64079d2e4133374244728ac7c8055efb07ca5b274266cb0e2d6c88ce5ae4385d45d67b2999fcd5bbe5e8dd4299792542683682ac05950e8 + checksum: a479feeea6b136c9a07f885373e859a37f19b4d55cf6f9ecd89017c13349f55d239aa5a083465b1d945ff6bf13809efd27133340bdecaef875e72bd60d534c76 languageName: node linkType: hard @@ -1337,32 +1337,32 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.489.0" +"@aws-sdk/util-user-agent-browser@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 bowser: ^2.11.0 tslib: ^2.5.0 - checksum: b24009655bd5a7755575d6ed5c955d6fcfa3a70248e1a9c9d4a58cc7ed4bb25936a276917a0ab60b6e11e7ed915d5dcfdd5e9112e373bd23b24d24963324e516 + checksum: 47071d5d514e08ef2818e42b437798238df771bff320256eef4589a24dae3f84ac064897c941919e1b571aaf95345282a7e8e43729f787526b70e80dfba8dead languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.489.0" +"@aws-sdk/util-user-agent-node@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: 755845ce1cebdc78d3bb2bab058cf8e966658373daa7c62ae808fc0fc733248ed019042b1eed4ad3274ae08f23506cc000e1b0d41b6f01fd29cccad4275b3f8e + checksum: e4c188c91b78b33d8da77984f3513a61ece3454d02d16605ec985b8481d309d12ad7544d2233d1396aaffd0758b4d0d1c4c143b9edd68d66e2681a4fd32eac34 languageName: node linkType: hard @@ -1385,13 +1385,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.485.0": - version: 3.485.0 - resolution: "@aws-sdk/xml-builder@npm:3.485.0" +"@aws-sdk/xml-builder@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/xml-builder@npm:3.495.0" dependencies: - "@smithy/types": ^2.8.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 97eacc7fff1161876cb672051905156d6aec8116f76b35d5f2ca87b676b5b270fc6de0b9bed53792272a7712d835077ac64b4135fed7ea81c3e4cbf070f1be58 + checksum: f2c695268c887e1f0e39991867ceca861f3242a0c12689ccfe582bce4f3543cf241a7ea4873a4a1c8b3637a5592a29c8f9266040f375a3eaaa9aebce6d697ecd languageName: node linkType: hard @@ -3110,13 +3110,13 @@ __metadata: languageName: node linkType: hard -"@babel/runtime-corejs3@npm:^7.20.7, @babel/runtime-corejs3@npm:^7.22.15, @babel/runtime-corejs3@npm:^7.23.5": - version: 7.23.6 - resolution: "@babel/runtime-corejs3@npm:7.23.6" +"@babel/runtime-corejs3@npm:^7.20.7, @babel/runtime-corejs3@npm:^7.22.15, @babel/runtime-corejs3@npm:^7.23.7": + version: 7.23.8 + resolution: "@babel/runtime-corejs3@npm:7.23.8" dependencies: core-js-pure: ^3.30.2 regenerator-runtime: ^0.14.0 - checksum: 92576ea17ff674025aa3cd208bfb8301e4bde432cfa404b56f94242948cbd40125c1a4c9c54a99134e08ded8bcde305633a22b1f4c676687c3b868557d23b762 + checksum: e786b79bcb3031bd7433fb4523e43f0acbd386cd7bb5b0a6df6e627c7965706b3d5612211ea3d729ce4459ba1d1b654ccdd8aefe791c6413f70882ee1be903b9 languageName: node linkType: hard @@ -4622,7 +4622,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-auth-backend-module-microsoft-provider@workspace:plugins/auth-backend-module-microsoft-provider": +"@backstage/plugin-auth-backend-module-microsoft-provider@workspace:^, @backstage/plugin-auth-backend-module-microsoft-provider@workspace:plugins/auth-backend-module-microsoft-provider": version: 0.0.0-use.local resolution: "@backstage/plugin-auth-backend-module-microsoft-provider@workspace:plugins/auth-backend-module-microsoft-provider" dependencies: @@ -4636,6 +4636,7 @@ __metadata: "@types/passport-microsoft": ^1.0.0 express: ^4.18.2 jose: ^4.6.0 + lodash: ^4.17.21 msw: ^1.0.0 node-fetch: ^2.6.7 passport: ^0.7.0 @@ -4673,6 +4674,30 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-auth-backend-module-oidc-provider@workspace:^, @backstage/plugin-auth-backend-module-oidc-provider@workspace:plugins/auth-backend-module-oidc-provider": + version: 0.0.0-use.local + resolution: "@backstage/plugin-auth-backend-module-oidc-provider@workspace:plugins/auth-backend-module-oidc-provider" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-defaults": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + cookie-parser: ^1.4.6 + express: ^4.18.2 + express-promise-router: ^4.1.1 + express-session: ^1.17.3 + jose: ^4.14.6 + msw: ^1.3.1 + openid-client: ^5.5.0 + passport: ^0.6.0 + supertest: ^6.3.3 + languageName: unknown + linkType: soft + "@backstage/plugin-auth-backend-module-okta-provider@workspace:^, @backstage/plugin-auth-backend-module-okta-provider@workspace:plugins/auth-backend-module-okta-provider": version: 0.0.0-use.local resolution: "@backstage/plugin-auth-backend-module-okta-provider@workspace:plugins/auth-backend-module-okta-provider" @@ -4752,8 +4777,10 @@ __metadata: "@backstage/plugin-auth-backend-module-github-provider": "workspace:^" "@backstage/plugin-auth-backend-module-gitlab-provider": "workspace:^" "@backstage/plugin-auth-backend-module-google-provider": "workspace:^" + "@backstage/plugin-auth-backend-module-microsoft-provider": "workspace:^" "@backstage/plugin-auth-backend-module-oauth2-provider": "workspace:^" "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "workspace:^" + "@backstage/plugin-auth-backend-module-oidc-provider": "workspace:^" "@backstage/plugin-auth-backend-module-okta-provider": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" @@ -4795,7 +4822,6 @@ __metadata: passport-auth0: ^1.4.3 passport-bitbucket-oauth2: ^0.1.2 passport-github2: ^0.1.12 - passport-gitlab2: ^5.0.0 passport-google-oauth20: ^2.0.0 passport-microsoft: ^1.0.0 passport-oauth2: ^1.6.1 @@ -6141,10 +6167,12 @@ __metadata: resolution: "@backstage/plugin-devtools@workspace:plugins/devtools" dependencies: "@backstage/cli": "workspace:^" + "@backstage/core-compat-api": "workspace:^" "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" "@backstage/plugin-devtools-common": "workspace:^" "@backstage/plugin-permission-react": "workspace:^" "@material-ui/core": ^4.9.13 @@ -6415,6 +6443,8 @@ __metadata: resolution: "@backstage/plugin-explore-backend@workspace:plugins/explore-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/plugin-explore-common": "workspace:^" @@ -9692,10 +9722,10 @@ __metadata: languageName: node linkType: hard -"@braintree/sanitize-url@npm:=6.0.4": - version: 6.0.4 - resolution: "@braintree/sanitize-url@npm:6.0.4" - checksum: f5ec6048973722ea1c46ae555d2e9eb848d7fa258994f8ea7d6db9514ee754ea3ef344ef71b3696d486776bcb839f3124e79f67c6b5b2814ed2da220b340627c +"@braintree/sanitize-url@npm:=7.0.0": + version: 7.0.0 + resolution: "@braintree/sanitize-url@npm:7.0.0" + checksum: 2ca9c617343d00c668486f5382cd6ef7d0bd54ba6c8d40deb0f3e7843390a056cf0c590f1d06d38a49b7d8b3f63c006f89873944996742835f2b523b707913a0 languageName: node linkType: hard @@ -11018,14 +11048,14 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/core@npm:^39.25.0": - version: 39.25.0 - resolution: "@gitbeaker/core@npm:39.25.0" +"@gitbeaker/core@npm:^39.30.0": + version: 39.30.0 + resolution: "@gitbeaker/core@npm:39.30.0" dependencies: - "@gitbeaker/requester-utils": ^39.25.0 + "@gitbeaker/requester-utils": ^39.30.0 qs: ^6.11.2 xcase: ^2.0.1 - checksum: 56ebe3c6ba1078c47a6cae0abcd5ae4fd928dc73c9eb7dc462894d497d6fa5373c0d09a7a7a0583097cffa641eeb0b28b1764d33a085a7b95f0115399240bc7e + checksum: 4724659bab57cde13b63bba7ffad52651ebb726c444bb1d6c1c69c70efb89ed3d319abf12c117f9a8ab6741cc26e6a19c23e237bebd07d13b2f8c970171dc069 languageName: node linkType: hard @@ -11053,25 +11083,25 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/requester-utils@npm:^39.25.0": - version: 39.25.0 - resolution: "@gitbeaker/requester-utils@npm:39.25.0" +"@gitbeaker/requester-utils@npm:^39.30.0": + version: 39.30.0 + resolution: "@gitbeaker/requester-utils@npm:39.30.0" dependencies: - async-sema: ^3.1.1 - micromatch: ^4.0.5 + picomatch-browser: ^2.2.6 qs: ^6.11.2 + rate-limiter-flexible: ^4.0.0 xcase: ^2.0.1 - checksum: 1ca90f5ac705d5ef9df682b3051106326bc660427b9b2a88762992690981ce0b6bed4b22bc08af0ba97043766f9898605ba58ed6c1a08b6711af34032f013ed2 + checksum: 05a60b027736edd165341c88ddbe095c78e77616f60033a9c9b419b657cd7d9998a9a801470a88d25d96be44b3a5233e3f1a4042aee075872f2882d10122db69 languageName: node linkType: hard "@gitbeaker/rest@npm:^39.25.0": - version: 39.25.0 - resolution: "@gitbeaker/rest@npm:39.25.0" + version: 39.30.0 + resolution: "@gitbeaker/rest@npm:39.30.0" dependencies: - "@gitbeaker/core": ^39.25.0 - "@gitbeaker/requester-utils": ^39.25.0 - checksum: 5732a34fe3f2fe0a048963baf90b237fde7a1be61fa327e2c7aa69266649394b5b48cd99a6c6abaf1cf8b32b84a293800af33eef49c011b252d6e061f7fe1af9 + "@gitbeaker/core": ^39.30.0 + "@gitbeaker/requester-utils": ^39.30.0 + checksum: 2b04dbb28c1a5f47c067c376ff0b4664278d72dcdef7696646a6d9331a400d9dfe75382e041a0a683fdc5ac1805abdb2919455fea786fd97f0eb65a5473d3fb5 languageName: node linkType: hard @@ -13966,8 +13996,8 @@ __metadata: linkType: hard "@openapitools/openapi-generator-cli@npm:^2.4.26, @openapitools/openapi-generator-cli@npm:^2.7.0": - version: 2.8.0 - resolution: "@openapitools/openapi-generator-cli@npm:2.8.0" + version: 2.9.0 + resolution: "@openapitools/openapi-generator-cli@npm:2.9.0" dependencies: "@nestjs/axios": 3.0.1 "@nestjs/common": 10.3.0 @@ -13981,14 +14011,14 @@ __metadata: console.table: 0.10.0 fs-extra: 10.1.0 glob: 7.2.3 - inquirer: 8.2.5 + inquirer: 8.2.6 lodash: 4.17.21 reflect-metadata: 0.1.13 - rxjs: 7.8.0 + rxjs: 7.8.1 tslib: 2.6.2 bin: openapi-generator-cli: main.js - checksum: 76a43d3087b2a4eb521814369ce99ade622fc146bb2414f52c01a7565f81fa94a6d42f2bf6889a4b25814744f0462613853a609d97c12a608c5717aed2e3898a + checksum: 102040381b42edbab4fa34aa49c3cf8188fdb892c3e251bcb5bdf7c599597f3572d52d44fed7bead5fcaec24d624491c20dc96d2f164fa44e7fc232c7d787f69 languageName: node linkType: hard @@ -14012,59 +14042,59 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/core@npm:1.18.1": - version: 1.18.1 - resolution: "@opentelemetry/core@npm:1.18.1" +"@opentelemetry/core@npm:1.20.0": + version: 1.20.0 + resolution: "@opentelemetry/core@npm:1.20.0" dependencies: - "@opentelemetry/semantic-conventions": 1.18.1 + "@opentelemetry/semantic-conventions": 1.20.0 peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.8.0" - checksum: dfb3181836ce04d2e983c0e8382e4bd0228ec42280e0a3f5330e2742903c0fb1db0efc2792479d27f928533a386f163c2e0fce2a2f45b05e66b2809d268915dc + checksum: 90a01430902926894a3d7ac6a5bd68b3bcb59aede568d08ca09abdd6d9cc46e9423f2fc65a496c7a8c13a2d3df259586f1a0d500fac6271524f189247e97d8fa languageName: node linkType: hard -"@opentelemetry/exporter-prometheus@npm:^0.45.0": - version: 0.45.1 - resolution: "@opentelemetry/exporter-prometheus@npm:0.45.1" +"@opentelemetry/exporter-prometheus@npm:^0.47.0": + version: 0.47.0 + resolution: "@opentelemetry/exporter-prometheus@npm:0.47.0" dependencies: - "@opentelemetry/core": 1.18.1 - "@opentelemetry/resources": 1.18.1 - "@opentelemetry/sdk-metrics": 1.18.1 + "@opentelemetry/core": 1.20.0 + "@opentelemetry/resources": 1.20.0 + "@opentelemetry/sdk-metrics": 1.20.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 033fda6759610350d7f11c91d66a2c0e3cc7ac1182267e6ed4aba2fb90add66e344925e6ab89db76ff91c7fa67c82c0c4099657c5a9b68c4140ca4d0a3c1abac + checksum: 7b9af3e1912f4ef796f29d34e6a7a35cc51c6c4bef1252678c58180ff4e90a121663acbaf5c4ff90a197258e2ab596f7b873364ca80ea3096bc675e97df5bead languageName: node linkType: hard -"@opentelemetry/resources@npm:1.18.1": - version: 1.18.1 - resolution: "@opentelemetry/resources@npm:1.18.1" +"@opentelemetry/resources@npm:1.20.0": + version: 1.20.0 + resolution: "@opentelemetry/resources@npm:1.20.0" dependencies: - "@opentelemetry/core": 1.18.1 - "@opentelemetry/semantic-conventions": 1.18.1 + "@opentelemetry/core": 1.20.0 + "@opentelemetry/semantic-conventions": 1.20.0 peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.8.0" - checksum: b3311734802dca77eb379331ae7c409867ffe82cf17bca0e362de49e2d28313441a0177f62fc8c6c1f605bfc82c50e80ac065f17d81fc4fa131afff146db6432 + checksum: 22b851789bccd778901ea095f51006b57b0059ddeb0ff153ce548c92cd83202af5739fc9dd5c1d2e4640c8eacf7a08ffd24d5ae30f2ebae60855b026ecb87d33 languageName: node linkType: hard -"@opentelemetry/sdk-metrics@npm:1.18.1, @opentelemetry/sdk-metrics@npm:^1.13.0": - version: 1.18.1 - resolution: "@opentelemetry/sdk-metrics@npm:1.18.1" +"@opentelemetry/sdk-metrics@npm:1.20.0, @opentelemetry/sdk-metrics@npm:^1.13.0": + version: 1.20.0 + resolution: "@opentelemetry/sdk-metrics@npm:1.20.0" dependencies: - "@opentelemetry/core": 1.18.1 - "@opentelemetry/resources": 1.18.1 + "@opentelemetry/core": 1.20.0 + "@opentelemetry/resources": 1.20.0 lodash.merge: ^4.6.2 peerDependencies: "@opentelemetry/api": ">=1.3.0 <1.8.0" - checksum: ed2b87ea6380adc04bf50955cf7ae65220c6f35292b7d0535562c2e83d8b672306103c48fd45f3cc03ab3d640a8d2c6e367b265f5f4b0cbe03b0f51eb85759c7 + checksum: 6bd2d77ee14d85d9894ba08715969bc18d75582a53d9d31e2fed6a77f46c32e5fbae6daf6f1c32446a3cc5169620b7f29da27ca006d7c16750f9d83966fd864e languageName: node linkType: hard -"@opentelemetry/semantic-conventions@npm:1.18.1": - version: 1.18.1 - resolution: "@opentelemetry/semantic-conventions@npm:1.18.1" - checksum: b60c008c01067c0e8f130ab5d61f5207c85b6db08fa926f629c854ab9917ca93fbabd7ae8d1586f9f82e3b29706b0444ded9d6781f7fb7a003eeb27d89af468f +"@opentelemetry/semantic-conventions@npm:1.20.0": + version: 1.20.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.20.0" + checksum: c71d466ab37158c57ff15a8fcb55682c812993b9d0d8e05114094abbe70f5ce2735909d70b749fddbc0621e5cdae19fecbb4e087034f606bce98e3bf9c74613e languageName: node linkType: hard @@ -14100,13 +14130,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.32.3": - version: 1.41.0 - resolution: "@playwright/test@npm:1.41.0" + version: 1.41.1 + resolution: "@playwright/test@npm:1.41.1" dependencies: - playwright: 1.41.0 + playwright: 1.41.1 bin: playwright: cli.js - checksum: 3a7039f8cd14dd242154255417c100a99c3254a3c1fd26df2a11be24c10b06ef77d2736336d7743dedc5e1a6a52748e58ced730b6048f8bd75d8867ce81661e0 + checksum: d9877e777a1a7f60f097df57b6abc2478e2ae342930a409c8546c8aa40d6e206cbc16bf1c71b23414ac3fbad36dcae1ad79635d7f4eb705ab54d3c705e82ea04 languageName: node linkType: hard @@ -15048,16 +15078,16 @@ __metadata: linkType: hard "@rollup/plugin-json@npm:^6.0.0": - version: 6.0.1 - resolution: "@rollup/plugin-json@npm:6.0.1" + version: 6.1.0 + resolution: "@rollup/plugin-json@npm:6.1.0" dependencies: - "@rollup/pluginutils": ^5.0.1 + "@rollup/pluginutils": ^5.1.0 peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - checksum: 86995e3ceec0205bd0b5ae3075f4592e0ab3e6e6327a5dcfc825b44113eaae5819d26d5403d29b177ac59299e0b08c641c8d030e0c72805b92805ededc9cac44 + checksum: cc018d20c80242a2b8b44fae61a968049cf31bb8406218187cc7cda35747616594e79452dd65722e7da6dd825b392e90d4599d43cd4461a02fefa2865945164e languageName: node linkType: hard @@ -15106,19 +15136,19 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^5.0.1": - version: 5.0.4 - resolution: "@rollup/pluginutils@npm:5.0.4" +"@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.1.0": + version: 5.1.0 + resolution: "@rollup/pluginutils@npm:5.1.0" dependencies: "@types/estree": ^1.0.0 estree-walker: ^2.0.2 picomatch: ^2.3.1 peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - checksum: 893d5805ac4121fc704926963a0ae4e79e9e2bc8d736c3b28499ab69a404cce5119ca3a4e0c3d3a81d62f1beb3966f35285c36935d94b061794f26e94fed4cd1 + checksum: 3cc5a6d91452a6eabbfd1ae79b4dd1f1e809d2eecda6e175deb784e75b0911f47e9ecce73f8dd315d6a8b3f362582c91d3c0f66908b6ced69345b3cbe28f8ce8 languageName: node linkType: hard @@ -15347,13 +15377,13 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^2.0.1, @smithy/abort-controller@npm:^2.1.0": - version: 2.1.0 - resolution: "@smithy/abort-controller@npm:2.1.0" +"@smithy/abort-controller@npm:^2.1.0, @smithy/abort-controller@npm:^2.1.1": + version: 2.1.1 + resolution: "@smithy/abort-controller@npm:2.1.1" dependencies: - "@smithy/types": ^2.9.0 + "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 52ad57706997dd1fabeb5b4d1f43d65403f31f8c7bf2fd6addb84b8132b406763574911499ab757be1c0c7329c06c574174750f17383507cfb05e1df05b26882 + checksum: 4bfad0d6b3a75bd1e6f997aa41cc9d8ba8bfdf548cfe703553ad7b42f0bf3e06b595d584be7b9ab90d2e3b22aacad94c02c32e21bea96e46933443f09c59523a languageName: node linkType: hard @@ -15376,7 +15406,7 @@ __metadata: languageName: node linkType: hard -"@smithy/config-resolver@npm:^2.0.23, @smithy/config-resolver@npm:^2.1.0": +"@smithy/config-resolver@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/config-resolver@npm:2.1.0" dependencies: @@ -15389,7 +15419,7 @@ __metadata: languageName: node linkType: hard -"@smithy/core@npm:^1.2.2": +"@smithy/core@npm:^1.3.0": version: 1.3.0 resolution: "@smithy/core@npm:1.3.0" dependencies: @@ -15405,7 +15435,7 @@ __metadata: languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^2.0.0, @smithy/credential-provider-imds@npm:^2.2.0": +"@smithy/credential-provider-imds@npm:^2.2.0": version: 2.2.0 resolution: "@smithy/credential-provider-imds@npm:2.2.0" dependencies: @@ -15418,7 +15448,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-codec@npm:^2.0.1, @smithy/eventstream-codec@npm:^2.1.0": +"@smithy/eventstream-codec@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/eventstream-codec@npm:2.1.0" dependencies: @@ -15430,7 +15460,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^2.0.16": +"@smithy/eventstream-serde-browser@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/eventstream-serde-browser@npm:2.1.0" dependencies: @@ -15441,7 +15471,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^2.0.16": +"@smithy/eventstream-serde-config-resolver@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/eventstream-serde-config-resolver@npm:2.1.0" dependencies: @@ -15451,7 +15481,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^2.0.16": +"@smithy/eventstream-serde-node@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/eventstream-serde-node@npm:2.1.0" dependencies: @@ -15473,7 +15503,7 @@ __metadata: languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^2.3.2, @smithy/fetch-http-handler@npm:^2.4.0": +"@smithy/fetch-http-handler@npm:^2.4.0": version: 2.4.0 resolution: "@smithy/fetch-http-handler@npm:2.4.0" dependencies: @@ -15486,7 +15516,7 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^2.0.17": +"@smithy/hash-blob-browser@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/hash-blob-browser@npm:2.1.0" dependencies: @@ -15498,7 +15528,7 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-node@npm:^2.0.18": +"@smithy/hash-node@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/hash-node@npm:2.1.0" dependencies: @@ -15510,7 +15540,7 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^2.0.18": +"@smithy/hash-stream-node@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/hash-stream-node@npm:2.1.0" dependencies: @@ -15521,7 +15551,7 @@ __metadata: languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^2.0.16": +"@smithy/invalid-dependency@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/invalid-dependency@npm:2.1.0" dependencies: @@ -15531,7 +15561,7 @@ __metadata: languageName: node linkType: hard -"@smithy/is-array-buffer@npm:^2.0.0, @smithy/is-array-buffer@npm:^2.1.0": +"@smithy/is-array-buffer@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/is-array-buffer@npm:2.1.0" dependencies: @@ -15540,7 +15570,7 @@ __metadata: languageName: node linkType: hard -"@smithy/md5-js@npm:^2.0.18": +"@smithy/md5-js@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/md5-js@npm:2.1.0" dependencies: @@ -15551,7 +15581,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^2.0.18": +"@smithy/middleware-content-length@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/middleware-content-length@npm:2.1.0" dependencies: @@ -15562,7 +15592,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^2.3.0, @smithy/middleware-endpoint@npm:^2.4.0": +"@smithy/middleware-endpoint@npm:^2.4.0": version: 2.4.0 resolution: "@smithy/middleware-endpoint@npm:2.4.0" dependencies: @@ -15577,7 +15607,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-retry@npm:^2.0.26, @smithy/middleware-retry@npm:^2.1.0": +"@smithy/middleware-retry@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/middleware-retry@npm:2.1.0" dependencies: @@ -15594,7 +15624,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-serde@npm:^2.0.16, @smithy/middleware-serde@npm:^2.1.0": +"@smithy/middleware-serde@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/middleware-serde@npm:2.1.0" dependencies: @@ -15604,7 +15634,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-stack@npm:^2.0.10, @smithy/middleware-stack@npm:^2.1.0": +"@smithy/middleware-stack@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/middleware-stack@npm:2.1.0" dependencies: @@ -15614,7 +15644,7 @@ __metadata: languageName: node linkType: hard -"@smithy/node-config-provider@npm:^2.1.9, @smithy/node-config-provider@npm:^2.2.0": +"@smithy/node-config-provider@npm:^2.2.0": version: 2.2.0 resolution: "@smithy/node-config-provider@npm:2.2.0" dependencies: @@ -15626,20 +15656,20 @@ __metadata: languageName: node linkType: hard -"@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.2.2, @smithy/node-http-handler@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/node-http-handler@npm:2.3.0" +"@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.3.0": + version: 2.3.1 + resolution: "@smithy/node-http-handler@npm:2.3.1" dependencies: - "@smithy/abort-controller": ^2.1.0 - "@smithy/protocol-http": ^3.1.0 - "@smithy/querystring-builder": ^2.1.0 - "@smithy/types": ^2.9.0 + "@smithy/abort-controller": ^2.1.1 + "@smithy/protocol-http": ^3.1.1 + "@smithy/querystring-builder": ^2.1.1 + "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 8f431d7fa4e07908ecfd58d13721b5adc41519415e9ea58d104ab44da008c0244fd551a6fddc27e9bac1ca8ba98d3f117b37c379c096e5038ff70b723466dce6 + checksum: e6a514098f44cfc962318b15df79bb5e9de7fffe883fe073965879b2cf2436726709b5be14262871794104272e8506f793f8e77b8bf5b36398714a3a51512516 languageName: node linkType: hard -"@smithy/property-provider@npm:^2.0.0, @smithy/property-provider@npm:^2.1.0": +"@smithy/property-provider@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/property-provider@npm:2.1.0" dependencies: @@ -15649,24 +15679,24 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^3.0.12, @smithy/protocol-http@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/protocol-http@npm:3.1.0" +"@smithy/protocol-http@npm:^3.1.0, @smithy/protocol-http@npm:^3.1.1": + version: 3.1.1 + resolution: "@smithy/protocol-http@npm:3.1.1" dependencies: - "@smithy/types": ^2.9.0 + "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 3aae910192708bfd5cc3de85dc28c2eb7f6b425d6edc2b930f769330bc4912f8e7ff2a5dc8b9dd98614d1f9fa8d4f64a9f9eb45e54c4da94e29612accc3218fc + checksum: a5be1c5b5bff18c5a35c23870e1ffa38da33e56f93bdd8f26c615f4c0d2d3e1effffe441e756c0b0ba3aad2dd0845332f634702bf8455ed865a04eebfef1329b languageName: node linkType: hard -"@smithy/querystring-builder@npm:^2.1.0": - version: 2.1.0 - resolution: "@smithy/querystring-builder@npm:2.1.0" +"@smithy/querystring-builder@npm:^2.1.0, @smithy/querystring-builder@npm:^2.1.1": + version: 2.1.1 + resolution: "@smithy/querystring-builder@npm:2.1.1" dependencies: - "@smithy/types": ^2.9.0 - "@smithy/util-uri-escape": ^2.1.0 + "@smithy/types": ^2.9.1 + "@smithy/util-uri-escape": ^2.1.1 tslib: ^2.5.0 - checksum: 307cfec9c5765b9aca10318913cd91513d323895d9cfb863309b49fe634dfdb3ebf74ef3dc17e3d4aa60d1c4e8f48a63cfd11c2b2099b36cd4d9f53198e933a0 + checksum: b8623c7ef6d19fb21c41bfda29cce9c673ac501914085b39642ff5a72cf5742b19cd9de1a1851d13f2e1bbfc2e9522070b5ca32ed906aacf93f732a56e76098a languageName: node linkType: hard @@ -15689,7 +15719,7 @@ __metadata: languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^2.0.6, @smithy/shared-ini-file-loader@npm:^2.3.0": +"@smithy/shared-ini-file-loader@npm:^2.3.0": version: 2.3.0 resolution: "@smithy/shared-ini-file-loader@npm:2.3.0" dependencies: @@ -15699,23 +15729,23 @@ __metadata: languageName: node linkType: hard -"@smithy/signature-v4@npm:^2.0.0": - version: 2.0.1 - resolution: "@smithy/signature-v4@npm:2.0.1" +"@smithy/signature-v4@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/signature-v4@npm:2.1.0" dependencies: - "@smithy/eventstream-codec": ^2.0.1 - "@smithy/is-array-buffer": ^2.0.0 - "@smithy/types": ^2.0.2 - "@smithy/util-hex-encoding": ^2.0.0 - "@smithy/util-middleware": ^2.0.0 - "@smithy/util-uri-escape": ^2.0.0 - "@smithy/util-utf8": ^2.0.0 + "@smithy/eventstream-codec": ^2.1.0 + "@smithy/is-array-buffer": ^2.1.0 + "@smithy/types": ^2.9.0 + "@smithy/util-hex-encoding": ^2.1.0 + "@smithy/util-middleware": ^2.1.0 + "@smithy/util-uri-escape": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 2c4bc499251dfbdbea0359fc5196002ac805df7f6f87d7cba36164d8fcd16a749a3c1a52259569134628511dc496724d5e76744c1c39fee3a3f42c5fbfe3749b + checksum: 3e2fa005930f8228b9480087f4eeacbf36200e268c760890182e21ae4035b5e02e9d10bc6d9f9ae0bc257b02cadadb522afdf1f3bddf3c2d61c3e3796f90e8ca languageName: node linkType: hard -"@smithy/smithy-client@npm:^2.2.1, @smithy/smithy-client@npm:^2.3.0": +"@smithy/smithy-client@npm:^2.3.0": version: 2.3.0 resolution: "@smithy/smithy-client@npm:2.3.0" dependencies: @@ -15738,16 +15768,16 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^2.0.2, @smithy/types@npm:^2.8.0, @smithy/types@npm:^2.9.0": - version: 2.9.0 - resolution: "@smithy/types@npm:2.9.0" +"@smithy/types@npm:^2.9.0, @smithy/types@npm:^2.9.1": + version: 2.9.1 + resolution: "@smithy/types@npm:2.9.1" dependencies: tslib: ^2.5.0 - checksum: 74d59ddcc2eca419c493b99d09f912e72511d088df0c6b6548df876dd49407b3cbb68550c9d6fa1d03d65f96bb099c450bdad1b4724d52144ca65f547850a4bb + checksum: 8570affb4abb5d0ead57293977fc915d44be481120defcabb87a3fb1c7b5d2501b117835eca357b5d54ea4bbee08032f9dc3d909ecbf0abb0cec2ca9678ae7bd languageName: node linkType: hard -"@smithy/url-parser@npm:^2.0.16, @smithy/url-parser@npm:^2.1.0": +"@smithy/url-parser@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/url-parser@npm:2.1.0" dependencies: @@ -15758,7 +15788,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-base64@npm:^2.0.1, @smithy/util-base64@npm:^2.1.0": +"@smithy/util-base64@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-base64@npm:2.1.0" dependencies: @@ -15768,7 +15798,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-browser@npm:^2.0.1": +"@smithy/util-body-length-browser@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-body-length-browser@npm:2.1.0" dependencies: @@ -15777,12 +15807,12 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^2.1.0": - version: 2.1.0 - resolution: "@smithy/util-body-length-node@npm:2.1.0" +"@smithy/util-body-length-node@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-body-length-node@npm:2.2.0" dependencies: tslib: ^2.5.0 - checksum: e4635251898f12e1825f2848e0b7cc9d01ec6635b3f1f71b790734bb702b88e795f6c539d42d95472dad00e50e9ff13fcf396791092b131e5834069cb8f52ed0 + checksum: a2ada7daeb31147675b66f0a95cd24ed10ee800211ddde34b1bbbd0a2bfbfdc82efbc8fe2c9bf4e18a67e7112aaf432f381a32e19be06735c8f4e0c3eec1a4a5 languageName: node linkType: hard @@ -15796,7 +15826,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-config-provider@npm:^2.1.0, @smithy/util-config-provider@npm:^2.2.0": +"@smithy/util-config-provider@npm:^2.2.0": version: 2.2.0 resolution: "@smithy/util-config-provider@npm:2.2.0" dependencies: @@ -15805,7 +15835,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^2.0.24": +"@smithy/util-defaults-mode-browser@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-defaults-mode-browser@npm:2.1.0" dependencies: @@ -15818,7 +15848,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^2.0.32": +"@smithy/util-defaults-mode-node@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-defaults-mode-node@npm:2.1.0" dependencies: @@ -15833,7 +15863,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-endpoints@npm:^1.0.8": +"@smithy/util-endpoints@npm:^1.1.0": version: 1.1.0 resolution: "@smithy/util-endpoints@npm:1.1.0" dependencies: @@ -15844,7 +15874,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-hex-encoding@npm:^2.0.0, @smithy/util-hex-encoding@npm:^2.1.0": +"@smithy/util-hex-encoding@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-hex-encoding@npm:2.1.0" dependencies: @@ -15853,7 +15883,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-middleware@npm:^2.0.0, @smithy/util-middleware@npm:^2.0.9, @smithy/util-middleware@npm:^2.1.0": +"@smithy/util-middleware@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-middleware@npm:2.1.0" dependencies: @@ -15863,7 +15893,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-retry@npm:^2.0.9, @smithy/util-retry@npm:^2.1.0": +"@smithy/util-retry@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-retry@npm:2.1.0" dependencies: @@ -15874,7 +15904,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-stream@npm:^2.0.24, @smithy/util-stream@npm:^2.1.0": +"@smithy/util-stream@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-stream@npm:2.1.0" dependencies: @@ -15890,16 +15920,16 @@ __metadata: languageName: node linkType: hard -"@smithy/util-uri-escape@npm:^2.0.0, @smithy/util-uri-escape@npm:^2.1.0": - version: 2.1.0 - resolution: "@smithy/util-uri-escape@npm:2.1.0" +"@smithy/util-uri-escape@npm:^2.1.0, @smithy/util-uri-escape@npm:^2.1.1": + version: 2.1.1 + resolution: "@smithy/util-uri-escape@npm:2.1.1" dependencies: tslib: ^2.5.0 - checksum: 11aca3e04a57428266fdb09f408f21bb51d5fa0b6b31ceb5769a63c670ad8f24c95bcbc1d6046d625b7992293e86f46207d1018233130e9f4c4e97d236ff9cd8 + checksum: 822ed7390e28d5c7b8dab5e5c5a8de998e0778220137962a71b47b2d8900289d48a3a2c9945e68e1cac921d43f61660045e7fdffe8df9e63004575fcf2aa99b2 languageName: node linkType: hard -"@smithy/util-utf8@npm:^2.0.0, @smithy/util-utf8@npm:^2.0.2, @smithy/util-utf8@npm:^2.1.0": +"@smithy/util-utf8@npm:^2.0.0, @smithy/util-utf8@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-utf8@npm:2.1.0" dependencies: @@ -15909,7 +15939,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-waiter@npm:^2.0.16": +"@smithy/util-waiter@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-waiter@npm:2.1.0" dependencies: @@ -16201,12 +16231,12 @@ __metadata: linkType: hard "@stoplight/types@npm:^14.0.0": - version: 14.0.0 - resolution: "@stoplight/types@npm:14.0.0" + version: 14.1.1 + resolution: "@stoplight/types@npm:14.1.1" dependencies: "@types/json-schema": ^7.0.4 utility-types: ^3.10.0 - checksum: 462fb6c718a2679927421ca1fffb5e31be2d150130e95a2771ffba04f68fc0e0f8ef3d4ae050e63fd4044bc4103e2ea82c98e1f5c7ff192a78914838eb250e5e + checksum: 1da2e683e88afe2f72c3b3af341537bc9bac153d224f65744ca60d44eade93609ce91172064ae27093e1ebfa7bcbf05fb232a1910d83b2aee5b1eed4bb726200 languageName: node linkType: hard @@ -16423,406 +16453,452 @@ __metadata: languageName: node linkType: hard -"@swagger-api/apidom-ast@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ast@npm:0.83.0" +"@swagger-api/apidom-ast@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ast@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-error": ^0.83.0 + "@swagger-api/apidom-error": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 unraw: ^3.0.0 - checksum: 7449e1c3eb316920e277d773a3504af9379ade513836342a55817888c73ad65bf08c6c11222fbd9f6862108ab3fad3d2ce2dfa7ab4f9acf48a3134f27f057f87 + checksum: 11770246944b3bb5964a88e71a7e32e37691b7a3b6ec9ae6acf58cd580571ca75c079d749bb952cd08c86be2155cbef3ed418ad6194681e1e2fea643a2128af2 languageName: node linkType: hard -"@swagger-api/apidom-core@npm:>=0.83.0 <1.0.0, @swagger-api/apidom-core@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-core@npm:0.83.0" +"@swagger-api/apidom-core@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-core@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-core@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 + "@swagger-api/apidom-ast": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 "@types/ramda": ~0.29.6 minim: ~0.23.8 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 short-unique-id: ^5.0.2 stampit: ^4.3.2 - checksum: acbdd94eabb7ad44ba5c7c1e69a831bd5b53aca6f4e66abb66ad5e8d53717cb453a5885c51008b6a7b5f7e16de8660a1b5652a4498883c84d37cb62b093e3e91 + checksum: e02f1a838ab1d811960a48f98922c66bb306f1a5a1a154b8fe4c6445fb0a20c671409fee14a2e49051387bc7b5c28e218161bcc1519c6ad9cbc767bf432ee05d languageName: node linkType: hard -"@swagger-api/apidom-error@npm:>=0.83.0 <1.0.0, @swagger-api/apidom-error@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-error@npm:0.83.0" +"@swagger-api/apidom-error@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-error@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-error@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - checksum: 94fee6b4ee4a60a7d121d17c92808bec452bd7c638c3ecceda6fc427f47a0297e78a2366a37c7216b84b4a95aead825eb421356fa17dc67dd44da86e27660d1c + checksum: bdd3051a47f4300344c0f1f2a55c4bb3dbe147ba8ebd27c94a77db2c90e8cc371bca63b72dfb49d0034794b82929edbf70d20ab33f59ba9f8c2d2fc8dc0430db languageName: node linkType: hard -"@swagger-api/apidom-json-pointer@npm:>=0.83.0 <1.0.0, @swagger-api/apidom-json-pointer@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-json-pointer@npm:0.83.0" +"@swagger-api/apidom-json-pointer@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-json-pointer@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-json-pointer@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: b48d784f18a8d8e948292c1126a0b768a0df347d31b6b1e4fa28df64ceb83cbb5d465a80fc87e127529e339000eb97d28f7c4d632af47db3dbe7eeb92f9477c1 + checksum: 89d748fd1f52fce381d4e07710244d94c4d9f8a20411ca8bcfb33e7ec515432c7766660b296a9c603fa6b861b39eca4917151f98f3688f1bdcf10f25f9d90134 languageName: node linkType: hard -"@swagger-api/apidom-ns-api-design-systems@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-api-design-systems@npm:0.83.0" +"@swagger-api/apidom-ns-api-design-systems@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-api-design-systems@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 711a533d1a386e296525bbb131948e24ca548ee0d4de67acd8ae9f37097fef5801d82887eecdb9a45f954fb10c30666634fa78edb2e09d061beaab8dde47da35 + checksum: 8e993f6b8cd37cb9857a34437e2b16e087ccce524373726a167bf98ab622c44a03c47c81e218ff4b00aa7bd973a25bd696e2437c5fd018ace09ba2ad0fcda9de languageName: node linkType: hard -"@swagger-api/apidom-ns-asyncapi-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-asyncapi-2@npm:0.83.0" +"@swagger-api/apidom-ns-asyncapi-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-asyncapi-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-json-schema-draft-7": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-json-schema-draft-7": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 0c7e6bc35c2b5e46bd08922309cd494133302ce3b6b8d0cbfbfb99106ea7c1e160ca4ab11f21161598c532c86fafa9127320e5b561560a01e51ceef9d545e767 + checksum: bef3de2c2a854590c8bb1cd892a5b170b65e14119a97528652457bf1e3e19f4a05d7da41ddb697f64de9972c8fad8afc7e6ccfa97ce8809fc9eba8c1305d509c languageName: node linkType: hard -"@swagger-api/apidom-ns-json-schema-draft-4@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-json-schema-draft-4@npm:0.83.0" +"@swagger-api/apidom-ns-json-schema-draft-4@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-json-schema-draft-4@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.83.0 - "@swagger-api/apidom-core": ^0.83.0 + "@swagger-api/apidom-ast": ^0.92.0 + "@swagger-api/apidom-core": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 7fb5db60a95d3531b9fb38693a0b758a8bb3e946f7e7f4e202eaef093cdd53c6289031c8b8977e8548c6376b8e41a627827b64e2c9f5de2f63fc3a427e2f670b + checksum: 6b0d57acf1c34df314c401ab25d0feb3ad5638fc8c848f6b84c76691fef177a39a9e8ebfa16309d22c764d9bfb292ed5ad39943b2cece67dde746a6e9d5fdc12 languageName: node linkType: hard -"@swagger-api/apidom-ns-json-schema-draft-6@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-json-schema-draft-6@npm:0.83.0" +"@swagger-api/apidom-ns-json-schema-draft-6@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-json-schema-draft-6@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-ns-json-schema-draft-4": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ns-json-schema-draft-4": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 60d3d359bf0e8054bad013fb2d7bd4c020d4fb0ce6819538b47986ea7f89269af5f1c3b65c7ddb864bc502a7c41e6069c042a9be753cd9d47dc13b9d0572d216 + checksum: 5660459753ff1359527e61820db59a6465ecc8b51cc5a6c14e155b2144b67570c6fc2c7c41d97617470d1478b85e26879fadc3f1ff4460c6309411c13db209e6 languageName: node linkType: hard -"@swagger-api/apidom-ns-json-schema-draft-7@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-json-schema-draft-7@npm:0.83.0" +"@swagger-api/apidom-ns-json-schema-draft-7@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-json-schema-draft-7@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-ns-json-schema-draft-6": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ns-json-schema-draft-6": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 01623f0c65795d1022e903d39858caac018f9fe338049247ea668805e1926d05713faae9f8ea43188e465a1e2f6783a5e3b38036965b56859036a16d8deb3b86 + checksum: 838d2b9917b4086880156e895d67adfd6400236e97b2a75814356dc55b0d45afd3e458bfe97b52af39aeea4c3483fc40f7a1551af14285977009513a168fb87c languageName: node linkType: hard -"@swagger-api/apidom-ns-openapi-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-openapi-2@npm:0.83.0" +"@swagger-api/apidom-ns-openapi-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-openapi-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-ns-json-schema-draft-4": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ns-json-schema-draft-4": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 078b138517b0c0dffa67186f2a23938ba87c98c9dd98d431ff812a8be45b3b711e22749b62e22ccd70d4615a92c0ca442b793386fe201583aa8c52556260b082 + checksum: 154de0b299a3ff0fcac40cf995dafb8c173cb4e294c75f952a9fa9cd5452eaab7783a9e5abb425fbc6e7135466155645e9b96fa9495f3effa7aec18f3152e6c3 languageName: node linkType: hard -"@swagger-api/apidom-ns-openapi-3-0@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-openapi-3-0@npm:0.83.0" +"@swagger-api/apidom-ns-openapi-3-0@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-openapi-3-0@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-ns-json-schema-draft-4": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ns-json-schema-draft-4": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: dabe0745da3c4a3e719f1d9d7d3fbcd177c3735ec00ad762414ed6d9d82eed43b0897896d48e3b8690186029b952146b8bfcab2406d91797e6a9f81f451c51f3 + checksum: 9ae883feea63c06f2514ba834b637bd00d6a56c35fe9b875507698d991199202d307a90bd06ebeaeb5642e3e42fe54238249858568c8a61a1797792fa5fff259 languageName: node linkType: hard -"@swagger-api/apidom-ns-openapi-3-1@npm:>=0.83.0 <1.0.0, @swagger-api/apidom-ns-openapi-3-1@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-openapi-3-1@npm:0.83.0" +"@swagger-api/apidom-ns-openapi-3-1@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-ns-openapi-3-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-openapi-3-1@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.83.0 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.83.0 + "@swagger-api/apidom-ast": ^0.92.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 499818a4e437017f7a7ca8861dc1b8e90ba8bb8c300a1f2754bb7b2b05f95e0e897f6305bec1aa5c5af0f03c94e541660a412da25467091bcf35847cc2ee6a4c + checksum: 316861ccd563d28c46039fa4202337f2266e0b99bf803bc71f64d307d824a74dcf7e4cdf7fc4ac25d6cf3521aebc74938c2001eb74ef0c364bc02470a1ffc723 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:0.83.0" +"@swagger-api/apidom-ns-workflows-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-workflows-1@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-api-design-systems": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 + ramda-adjunct: ^4.1.1 + stampit: ^4.3.2 + checksum: 684804790b58b52a28ae10ffc7fc2fa5bf6b99d8cb3e5d9409e28325c4d4b9ce5b5cc10e0cc401fb21788753ea65287e33db79337388afccd54f6902f60d9159 + languageName: node + linkType: hard + +"@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:0.92.0" + dependencies: + "@babel/runtime-corejs3": ^7.20.7 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-api-design-systems": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@types/ramda": ~0.29.6 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 5a0ccf6158f4d9582002c3df4c30136ad8e0f7ee8e75a32f000d638e9b1906e1c42d9137fc4093532bbdbc7ebb3b23eb9fe2819690ae7643e9dde301710b264f + checksum: d9c361b8bb7b8a056acc2c52ef70a2d7304c511efc836cfebc315558ced7e93fe4e958dd554030a3315702d49ace30082ff7f2f91e9a76aaa2fff944a19fe39e languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-api-design-systems": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-api-design-systems": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: add8a138f379eddf4ce0fa78ffaf91d65c66b073d7304e11ed9db7f6262e2a981e8c9cb5cd36bb2471f573a37179c0f5414be9934714cc9166a98bfb6766931e + checksum: 248e61ed6e202eeab048c7c5e3eff0e0f2b6bfea958a02cbc6d8b831693a015d063db118af25c2e7380a4828ab84bf991764d200409a8eb99ffadb0dc6db65c0 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-asyncapi-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-asyncapi-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 0f510d2fb6b69daaebbc55cb186820394584941495ca2d7ae3ad608cc78f48f7b49d8dbf7299ac3fde2c553c8b0244bf265037e435e1e79176afc30029f127ca + checksum: 0fc981bc839758af1b3a8dfa0695376919a515a11ae71e6f9f1e0c91dd1530aa659fa7405cb73109db28fd95f594f09b5ee941611cc4ce4f3d1817335b12ec4b languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-asyncapi-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-asyncapi-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 46c4fff48263ec0bb40698ded08018c2d6bb653da1e88b1a50ea1b433b83a922a65029d09a77b0febaed6b26822ac520222a8495eafc5f86d81be003b8d0f418 + checksum: a1554f73cc20b75df71296322f6bdf5b5a0f1d775bd9bff89d7798843606e1a383c48960ddc2b1f879c962d2d56962e6096c3000ec2ad6091d49627aa2992b2e languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-json@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-json@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-json@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-json@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.83.0 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 + "@swagger-api/apidom-ast": ^0.92.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 "@types/ramda": ~0.29.6 node-gyp: latest - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 tree-sitter: =0.20.4 tree-sitter-json: =0.20.1 web-tree-sitter: =0.20.3 - checksum: be94a40fb8d342fe6394f01a803f0403612a796017bd6169dd52c201b26d60ed36cf6b7363faf2c8203fa67b65349d74c99b685c589ffbad30c26df29a3a53db + checksum: ca66dd9fffaa84249398420b9cf2301721d2b173340e0f07097348b73654f54698a370a94d814d7f51b7e662f968054b7fc745607074dbd71892c53714a18b62 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-json-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-json-2@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-json-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-json-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: e65c17bc9809af2b4c240c7f128258602bb8bdb440ad508ef08f5829b3347cc053624d117a4297c806a621ed61d9a53158a4aa4ed5cb3487a38935c32226d57d + checksum: 383827eec8fbc2bb36c095c8db4f8dce5264e5ffdfa7aca9a938d603294d99f0a552d57947222c160fbbbc1b79be7d08a7091348f3b373bbe25bd52a34bee529 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 3a0df777ad9dfdc6e9f6fb4984dfd3e3299a3ceff430719dc26eda9526e2102f786c89a08705cd780602eab5e85344ebe82dca1043741ecbf3ebd7b1961c109c + checksum: 592c1149d901a3c21594aca5c96a997382648ff559fb67cd6b75630440248a52f26df91ad96fa762e585e297725e20eb6f5623f91a6b6a5e2c950f57df4de760 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 5cec1f6237871f479233d75b862ccf774ffe5c6d63c9f08734fa6c0067e53ec9091683e5d309bf94cf080bd570bd4cc2496c85988ec0d52cdc378219033a8bdc + checksum: feaa0b825921ea9defde642b65a07049a8539905142baa113b3b5e90c76630a58ef2557a6f770740e32e5cfa46486fc9f7d3c468b8ec29aaa53cb507c4ad3469 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: bee0a9f82ddd02c1cbcf2b90896b70c2607a3ff53ca4431d176639878e0da0173946d6e303bab69d4d794dde178fcbd3c815428123f73eca2095ca89e828330d + checksum: efd8dbd705592accadce53b25fc293ee48d1d11ec191f618df4243e6fdfea1add502ef3a5d433051883092dd29bf0a9f2026f2314a0cced1b8f04af59e63e995 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: d6b3db2b4bf6280a14a76c29b9b6998380a1af09c0726bf736c7b64b30999268c2360776a284c76c2ec45d19f7c106816c98b2f399ec6225cfc9222dee3fb6ff + checksum: 47a034efae971b56d13e96bc64d0973a2015ca303bf63334117ebbcfb2b2676d50a0b68aa24ea5a3b669786a524035762d52ae1cc795f3c3dc65249297a23068 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 6bd8cf74b04d7f8fbf0cb0202253db349c7ce1ace7ccc9cff72ae36035a3dac5606e73fc5a829f0ac02af2369aff81ad3991701674091e692ffefb4ffed9499d + checksum: c565913065e401109e7e4494f1024d24958959c742e5f842247a56eca6b75dcc9c3495a4c550912a62d62db896b2803bd317642336b4b18c851adc141fa38b61 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-yaml-1-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-yaml-1-2@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-workflows-json-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-workflows-json-1@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.83.0 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-workflows-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@types/ramda": ~0.29.6 + ramda: ~0.29.1 + ramda-adjunct: ^4.0.0 + checksum: 570f8323aaa5c67da3b5421d6ca6a9f0c3bf486a602584fa5969476e6a4943abe9a7f8f2bd7dfc1a7019286746e65cc76b050cadfabab276e0d452fbad4db59f + languageName: node + linkType: hard + +"@swagger-api/apidom-parser-adapter-workflows-yaml-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-workflows-yaml-1@npm:0.92.0" + dependencies: + "@babel/runtime-corejs3": ^7.20.7 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-workflows-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 + "@types/ramda": ~0.29.6 + ramda: ~0.29.1 + ramda-adjunct: ^4.0.0 + checksum: 020ecd34fb45ba57977377f71dc0b28ebba95b950bb873e1f6222eb6b544f91243dfb6b1f7555fe5f279d7bee044089337216a3f4b8e58612fb7066530938f32 + languageName: node + linkType: hard + +"@swagger-api/apidom-parser-adapter-yaml-1-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-yaml-1-2@npm:0.92.0" + dependencies: + "@babel/runtime-corejs3": ^7.20.7 + "@swagger-api/apidom-ast": ^0.92.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 "@types/ramda": ~0.29.6 node-gyp: latest - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 tree-sitter: =0.20.4 tree-sitter-yaml: =0.5.0 web-tree-sitter: =0.20.3 - checksum: df777f06199a82b8ccfb3ea53def7bbd08d06f3e3f4b5083526661bc86dd920ac83ca5b34dcaa26c0194d1dd7e104b6f324454790504b6934eb684011f6a5749 + checksum: 1ee0bf2c2f7fed54ff194917034f31080ad4ad36e14dc2018c80d8bda38f8b6574ace974eca1a65aa336a86df375dabd0661215909551031e796dcee9d0d1a14 languageName: node linkType: hard -"@swagger-api/apidom-reference@npm:>=0.83.0 <1.0.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-reference@npm:0.83.0" +"@swagger-api/apidom-reference@npm:>=0.90.0 <1.0.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-reference@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-json-pointer": ^0.83.0 - "@swagger-api/apidom-ns-asyncapi-2": ^0.83.0 - "@swagger-api/apidom-ns-openapi-2": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.83.0 - "@swagger-api/apidom-parser-adapter-api-design-systems-json": ^0.83.0 - "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": ^0.83.0 - "@swagger-api/apidom-parser-adapter-asyncapi-json-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-json-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-json-3-0": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-json-3-1": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-yaml-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-json-pointer": ^0.92.0 + "@swagger-api/apidom-ns-asyncapi-2": ^0.92.0 + "@swagger-api/apidom-ns-openapi-2": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 + "@swagger-api/apidom-ns-workflows-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-api-design-systems-json": ^0.92.0 + "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": ^0.92.0 + "@swagger-api/apidom-parser-adapter-asyncapi-json-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-json-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-json-3-0": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-json-3-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-yaml-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-workflows-json-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-workflows-yaml-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 axios: ^1.4.0 minimatch: ^7.4.3 process: ^0.11.10 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 dependenciesMeta: @@ -16838,6 +16914,8 @@ __metadata: optional: true "@swagger-api/apidom-ns-openapi-3-1": optional: true + "@swagger-api/apidom-ns-workflows-1": + optional: true "@swagger-api/apidom-parser-adapter-api-design-systems-json": optional: true "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": @@ -16860,9 +16938,13 @@ __metadata: optional: true "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": optional: true + "@swagger-api/apidom-parser-adapter-workflows-json-1": + optional: true + "@swagger-api/apidom-parser-adapter-workflows-yaml-1": + optional: true "@swagger-api/apidom-parser-adapter-yaml-1-2": optional: true - checksum: b19c9c98cda575b139b1556327809c2367cca9e169ac50ea64049f6cc64148630709e5cc11573124460bcd5f5fc834c0c4434b8564fac4488e16de3cef65a16f + checksum: 05b2c97233f2f60879d2dc62a811a4b31520acb7b3c730d47e60e5927f861c1bf1376e790648b773b242ccb1e24596c567014c570d123655dc59fc2c590668c7 languageName: node linkType: hard @@ -17096,8 +17178,8 @@ __metadata: linkType: soft "@testing-library/dom@npm:^9.0.0": - version: 9.3.3 - resolution: "@testing-library/dom@npm:9.3.3" + version: 9.3.4 + resolution: "@testing-library/dom@npm:9.3.4" dependencies: "@babel/code-frame": ^7.10.4 "@babel/runtime": ^7.12.5 @@ -17107,7 +17189,7 @@ __metadata: dom-accessibility-api: ^0.5.9 lz-string: ^1.5.0 pretty-format: ^27.0.2 - checksum: 34e0a564da7beb92aa9cc44a9080221e2412b1a132eb37be3d513fe6c58027674868deb9f86195756d98d15ba969a30fe00632a4e26e25df2a5a4f6ac0686e37 + checksum: dfd6fb0d6c7b4dd716ba3c47309bc9541b4a55772cb61758b4f396b3785efe2dbc75dc63423545c039078c7ffcc5e4b8c67c2db1b6af4799580466036f70026f languageName: node linkType: hard @@ -17940,7 +18022,7 @@ __metadata: languageName: node linkType: hard -"@types/hoist-non-react-statics@npm:^3.3.0, @types/hoist-non-react-statics@npm:^3.3.1": +"@types/hoist-non-react-statics@npm:^3.3.0": version: 3.3.1 resolution: "@types/hoist-non-react-statics@npm:3.3.1" dependencies: @@ -18370,9 +18452,9 @@ __metadata: linkType: hard "@types/node@npm:^16.11.26, @types/node@npm:^16.7.10, @types/node@npm:^16.9.2": - version: 16.18.71 - resolution: "@types/node@npm:16.18.71" - checksum: 7b61ec0abd2a298518b562618ddbcc1704a6427c666c9512a0b12700a2b26cad151ccfd3c147c9ab77ac5e0bcb62bfbf67c48fa0ef812a00859a1e33368e8802 + version: 16.18.74 + resolution: "@types/node@npm:16.18.74" + checksum: 33d8f157b51cb2f6907a7019e0bef0733f6ebd025f208863e6e6ea4721348902f2c7ac9eeaadff9f1e138927921e620c7f0a655475a298569d7551f2d28e35f3 languageName: node linkType: hard @@ -20719,13 +20801,6 @@ __metadata: languageName: node linkType: hard -"async-sema@npm:^3.1.1": - version: 3.1.1 - resolution: "async-sema@npm:3.1.1" - checksum: 07b8c51f6cab107417ecdd8126b7a9fe5a75151b7f69fdd420dcc8ee08f9e37c473a217247e894b56e999b088b32e902dbe41637e4e9b594d3f8dfcdddfadc5e - languageName: node - linkType: hard - "async@npm:^2.6.2, async@npm:^2.6.4": version: 2.6.4 resolution: "async@npm:2.6.4" @@ -20926,12 +21001,12 @@ __metadata: linkType: hard "azure-devops-node-api@npm:^12.0.0": - version: 12.1.0 - resolution: "azure-devops-node-api@npm:12.1.0" + version: 12.3.0 + resolution: "azure-devops-node-api@npm:12.3.0" dependencies: tunnel: 0.0.6 typed-rest-client: ^1.8.4 - checksum: aa3c3f3eff89485a44ea31843749c5abf5ddfb0d2f059a3f5623d75d5eddbab5b839a5458c158e7941b9c8a2adfde2ecfea128ed076f730c309c869e8a318a78 + checksum: 4f76f4633f57b92267b9f841591ee2c9548bc51421d3d5b0072c854f6a3f3bc77b3a334863a22f1b903c620492a8be877ee16ff5af05e6d131b281a683a7f695 languageName: node linkType: hard @@ -22241,10 +22316,10 @@ __metadata: languageName: node linkType: hard -"classnames@npm:*, classnames@npm:^2.2.5, classnames@npm:^2.2.6, classnames@npm:^2.3.1": - version: 2.3.3 - resolution: "classnames@npm:2.3.3" - checksum: 0cb4db9cc3b8d2363c81f857f85b30351605fe683c89d140939aed4e06895a9570be737494ef3907e7069e2b98ed25ba3960fbf087b33309a18707fc38565e95 +"classnames@npm:*, classnames@npm:^2.2.5, classnames@npm:^2.2.6, classnames@npm:^2.3.1, classnames@npm:^2.5.1": + version: 2.5.1 + resolution: "classnames@npm:2.5.1" + checksum: da424a8a6f3a96a2e87d01a432ba19315503294ac7e025f9fece656db6b6a0f7b5003bb1fbb51cbb0d9624d964f1b9bb35a51c73af9b2434c7b292c42231c1e5 languageName: node linkType: hard @@ -23234,9 +23309,9 @@ __metadata: linkType: hard "core-js@npm:^3.26.0, core-js@npm:^3.6.5": - version: 3.33.3 - resolution: "core-js@npm:3.33.3" - checksum: 070b9c696f5a9b22bab0208daf9fcdffbc3b4f4c89ed2be512b7d99d4be363accfbb26fa6eec7261055d89e8ea0a5bcfccad5923fe43f1f2eafca9f568cc5596 + version: 3.35.1 + resolution: "core-js@npm:3.35.1" + checksum: e246af6b634be3763ffe3ce6ac4601b4dc5b928006fb6c95e5d08ecd82a2413bf36f00ffe178b89c9a8e94000288933a78a9881b2c9498e6cf312b031013b952 languageName: node linkType: hard @@ -23600,20 +23675,20 @@ __metadata: linkType: hard "css-loader@npm:^6.5.1": - version: 6.8.1 - resolution: "css-loader@npm:6.8.1" + version: 6.9.1 + resolution: "css-loader@npm:6.9.1" dependencies: icss-utils: ^5.1.0 - postcss: ^8.4.21 + postcss: ^8.4.33 postcss-modules-extract-imports: ^3.0.0 - postcss-modules-local-by-default: ^4.0.3 - postcss-modules-scope: ^3.0.0 + postcss-modules-local-by-default: ^4.0.4 + postcss-modules-scope: ^3.1.1 postcss-modules-values: ^4.0.0 postcss-value-parser: ^4.2.0 - semver: ^7.3.8 + semver: ^7.5.4 peerDependencies: webpack: ^5.0.0 - checksum: 7c1784247bdbe76dc5c55fb1ac84f1d4177a74c47259942c9cfdb7a8e6baef11967a0bc85ac285f26bd26d5059decb848af8154a03fdb4f4894f41212f45eef3 + checksum: b0c1776f9c46474219eb471eeb8f4c8986a7735dc8356e578a63303cf292a7c8cb868fa74bf94a1a174e948fcb6523c63fca081cac6bbf246be8275b3cc384f0 languageName: node linkType: hard @@ -25041,8 +25116,8 @@ __metadata: linkType: hard "elastic-builder@npm:^2.16.0": - version: 2.23.0 - resolution: "elastic-builder@npm:2.23.0" + version: 2.24.0 + resolution: "elastic-builder@npm:2.24.0" dependencies: lodash.has: ^4.5.2 lodash.hasin: ^4.5.2 @@ -25052,7 +25127,7 @@ __metadata: lodash.isobject: ^3.0.2 lodash.isstring: ^4.0.1 lodash.omit: ^4.5.0 - checksum: 6cd3d6fd3ea20adb2f48a21d3bd25fd89dd9f692feab95357356b8a814f5a36579c7a8326e818127fc5ec50774c1818c4f8e5d0aeea00cccd0aeda5563e17123 + checksum: 4bbfa66a179b78dbd90a0a3ee19cf7fc2105deca195c65d3047cf2ef2e6fa4925049038ed1f28d46a3ce96daa47f2cf8d924ea2e2fc0c585569a5a7acd09f2ed languageName: node linkType: hard @@ -25541,7 +25616,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.18.10, esbuild@npm:~0.18.20": +"esbuild@npm:^0.18.10": version: 0.18.20 resolution: "esbuild@npm:0.18.20" dependencies: @@ -25618,7 +25693,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.19.0": +"esbuild@npm:^0.19.0, esbuild@npm:~0.19.10": version: 0.19.11 resolution: "esbuild@npm:0.19.11" dependencies: @@ -26588,7 +26663,7 @@ __metadata: "@gitbeaker/node": ^35.1.0 "@octokit/rest": ^19.0.3 "@opentelemetry/api": ^1.4.1 - "@opentelemetry/exporter-prometheus": ^0.45.0 + "@opentelemetry/exporter-prometheus": ^0.47.0 "@opentelemetry/sdk-metrics": ^1.13.0 "@types/dockerode": ^3.3.0 "@types/express": ^4.17.6 @@ -28113,20 +28188,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:7.1.6": - version: 7.1.6 - resolution: "glob@npm:7.1.6" - dependencies: - fs.realpath: ^1.0.0 - inflight: ^1.0.4 - inherits: 2 - minimatch: ^3.0.4 - once: ^1.3.0 - path-is-absolute: ^1.0.0 - checksum: 351d549dd90553b87c2d3f90ce11aed9e1093c74130440e7ae0592e11bbcd2ce7f0ebb8ba6bfe63aaf9b62166a7f4c80cb84490ae5d78408bb2572bf7d4ee0a6 - languageName: node - linkType: hard - "glob@npm:7.2.3, glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7, glob@npm:^7.2.0": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -28409,7 +28470,7 @@ __metadata: languageName: node linkType: hard -"graphiql@npm:3.0.10, graphiql@npm:^3.0.6": +"graphiql@npm:3.0.10": version: 3.0.10 resolution: "graphiql@npm:3.0.10" dependencies: @@ -28425,6 +28486,22 @@ __metadata: languageName: node linkType: hard +"graphiql@npm:^3.0.6": + version: 3.1.0 + resolution: "graphiql@npm:3.1.0" + dependencies: + "@graphiql/react": ^0.20.2 + "@graphiql/toolkit": ^0.9.1 + graphql-language-service: ^5.2.0 + markdown-it: ^12.2.0 + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 + react: ^16.8.0 || ^17 || ^18 + react-dom: ^16.8.0 || ^17 || ^18 + checksum: a8969ea299561fe627ba566fb72dd90eda31b195e9983af87c4079bf807f5b356d116ece133e46d5098d6809a88b8f3b64b04a9e95dfe34cd84eb8fd109e2b8a + languageName: node + linkType: hard + "graphlib@npm:^2.1.8": version: 2.1.8 resolution: "graphlib@npm:2.1.8" @@ -28990,8 +29067,8 @@ __metadata: linkType: hard "html-webpack-plugin@npm:^5.3.1": - version: 5.5.4 - resolution: "html-webpack-plugin@npm:5.5.4" + version: 5.6.0 + resolution: "html-webpack-plugin@npm:5.6.0" dependencies: "@types/html-minifier-terser": ^6.0.0 html-minifier-terser: ^6.0.2 @@ -28999,8 +29076,14 @@ __metadata: pretty-error: ^4.0.0 tapable: ^2.0.0 peerDependencies: + "@rspack/core": 0.x || 1.x webpack: ^5.20.0 - checksum: b49befb73d67a3716fd0e6f7776b108d2b0b7050fb8221f05cd114cbae13c03150a13b7cdf5e76170be040ce7936a1cf76f7a4bfd9ebe1552b72d7889a74c374 + peerDependenciesMeta: + "@rspack/core": + optional: true + webpack: + optional: true + checksum: 32a6e41da538e798fd0be476637d7611a5e8a98a3508f031996e9eb27804dcdc282cb01f847cf5d066f21b49cfb8e21627fcf977ffd0c9bea81cf80e5a65070d languageName: node linkType: hard @@ -29536,30 +29619,7 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:8.2.5": - version: 8.2.5 - resolution: "inquirer@npm:8.2.5" - dependencies: - ansi-escapes: ^4.2.1 - chalk: ^4.1.1 - cli-cursor: ^3.1.0 - cli-width: ^3.0.0 - external-editor: ^3.0.3 - figures: ^3.0.0 - lodash: ^4.17.21 - mute-stream: 0.0.8 - ora: ^5.4.1 - run-async: ^2.4.0 - rxjs: ^7.5.5 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - through: ^2.3.6 - wrap-ansi: ^7.0.0 - checksum: f13ee4c444187786fb393609dedf6b30870115a57b603f2e6424f29a99abc13446fd45ee22461c33c9c40a92a60a8df62d0d6b25d74fc6676fa4cb211de55b55 - languageName: node - linkType: hard - -"inquirer@npm:^8.0.0, inquirer@npm:^8.2.0": +"inquirer@npm:8.2.6, inquirer@npm:^8.0.0, inquirer@npm:^8.2.0": version: 8.2.6 resolution: "inquirer@npm:8.2.6" dependencies: @@ -31617,13 +31677,13 @@ __metadata: linkType: hard "json-schema-to-ts@npm:^2.6.2": - version: 2.9.2 - resolution: "json-schema-to-ts@npm:2.9.2" + version: 2.12.0 + resolution: "json-schema-to-ts@npm:2.12.0" dependencies: "@babel/runtime": ^7.18.3 "@types/json-schema": ^7.0.9 - ts-algebra: ^1.2.0 - checksum: 64bf7226511a3719075d28e715fbd203576088b6ebcf494d6c5ee2bcf5b24d6081fa0cfce22ce254ad8798b7044603db4e4d19779c6f5765285fb9ddaa0756ef + ts-algebra: ^1.2.2 + checksum: 6dc4bc836591d888beb20e8bf45dfa3b75df4a331f18675bd2e39a2262e105e0dc86012031fff0be408499a07ae8bc30f5a879c24696189b2c30a34edd5fa72f languageName: node linkType: hard @@ -32142,8 +32202,8 @@ __metadata: linkType: hard "knex@npm:3, knex@npm:^3.0.0": - version: 3.0.1 - resolution: "knex@npm:3.0.1" + version: 3.1.0 + resolution: "knex@npm:3.1.0" dependencies: colorette: 2.0.19 commander: ^10.0.0 @@ -32154,7 +32214,7 @@ __metadata: getopts: 2.3.0 interpret: ^2.2.0 lodash: ^4.17.21 - pg-connection-string: 2.6.1 + pg-connection-string: 2.6.2 rechoir: ^0.8.0 resolve-from: ^5.0.0 tarn: ^3.0.2 @@ -32176,7 +32236,7 @@ __metadata: optional: true bin: knex: bin/cli.js - checksum: bcfc3f8da9a7e898a873d2a122856ac9355f5ee1c0ab39534d6cac9ea69388da2fe0fa607b20d65298e191a4377af72f8ff7f4430f8b8c4abc144010b7e9796c + checksum: 3905f8d27960975f7f57f3f488d1ef3ccf47784acc8eb627e8a28cbbe1f296c6879c8ef0cbd9e17e867be80117d305cd948545f3fbd4c74b24c90d2413bbc021 languageName: node linkType: hard @@ -35665,7 +35725,7 @@ __metadata: languageName: node linkType: hard -"openid-client@npm:^5.2.1, openid-client@npm:^5.3.0, openid-client@npm:^5.4.3": +"openid-client@npm:^5.2.1, openid-client@npm:^5.3.0, openid-client@npm:^5.4.3, openid-client@npm:^5.5.0": version: 5.6.4 resolution: "openid-client@npm:5.6.4" dependencies: @@ -36314,6 +36374,17 @@ __metadata: languageName: node linkType: hard +"passport@npm:^0.6.0": + version: 0.6.0 + resolution: "passport@npm:0.6.0" + dependencies: + passport-strategy: 1.x.x + pause: 0.0.1 + utils-merge: ^1.0.1 + checksum: ef932ad671d50de34765c7a53cd1e058d8331a82a6df09265a9c6c1168911aee4a7b5215803d0101110ab7f317e096b4954ca7e18fb2c33b9929f0bd17dbe159 + languageName: node + linkType: hard + "passport@npm:^0.7.0": version: 0.7.0 resolution: "passport@npm:0.7.0" @@ -36543,14 +36614,7 @@ __metadata: languageName: node linkType: hard -"pg-connection-string@npm:2.6.1": - version: 2.6.1 - resolution: "pg-connection-string@npm:2.6.1" - checksum: 882344a47e1ecf3a91383e0809bf2ac48facea97fcec0358d6e060e1cbcb8737acde419b4c86f05da4ce4a16634ee50fff1d2bb787d73b52ccbfde697243ad8a - languageName: node - linkType: hard - -"pg-connection-string@npm:^2.3.0, pg-connection-string@npm:^2.5.0, pg-connection-string@npm:^2.6.2": +"pg-connection-string@npm:2.6.2, pg-connection-string@npm:^2.3.0, pg-connection-string@npm:^2.5.0, pg-connection-string@npm:^2.6.2": version: 2.6.2 resolution: "pg-connection-string@npm:2.6.2" checksum: 22265882c3b6f2320785378d0760b051294a684989163d5a1cde4009e64e84448d7bf67d9a7b9e7f69440c3ee9e2212f9aa10dd17ad6773f6143c6020cebbcb5 @@ -36676,6 +36740,13 @@ __metadata: languageName: node linkType: hard +"picomatch-browser@npm:^2.2.6": + version: 2.2.6 + resolution: "picomatch-browser@npm:2.2.6" + checksum: 946c50a8654da43167a0f9a90dd0b50f3d4e830ee71c0926ee9052d7e6f40d8907deaafba19cea71b97207b4aaa52c245335e4cd5bbaf78fe2ba567cd0c341fa + languageName: node + linkType: hard + "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.2.3, picomatch@npm:^2.3.0, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -36819,27 +36890,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.41.0": - version: 1.41.0 - resolution: "playwright-core@npm:1.41.0" +"playwright-core@npm:1.41.1": + version: 1.41.1 + resolution: "playwright-core@npm:1.41.1" bin: playwright-core: cli.js - checksum: 14671265916a1fd0c71d94640de19c48bcce3f7dec35530f10e349e97030ea44ffa8ee518cbf811501e3ab2b74874aecf917e46bf40fea0570db1d4bea1fe7ac + checksum: c83446a560c6bd85f6f0cd586ff8c643b77e2005567386e12f85890936cc370673114b94cd883246018797cc1580e93b0296ade7d07275bb611b8962f5bb9693 languageName: node linkType: hard -"playwright@npm:1.41.0": - version: 1.41.0 - resolution: "playwright@npm:1.41.0" +"playwright@npm:1.41.1": + version: 1.41.1 + resolution: "playwright@npm:1.41.1" dependencies: fsevents: 2.3.2 - playwright-core: 1.41.0 + playwright-core: 1.41.1 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: e7c32136911c58e06b964fe7d33f8b3d8f6a067ae5218662a0811dd6c90e007db1774eb7e161f4aa748d760f404f4c066b7b7303c2b617f7448b6ee4b86c9999 + checksum: 3da7fb929abdec6adbdd8829f840580f5f210713214a8d230b130127f2270403eb2113c6c1418012221149707250fff896794c7c22c260dd09a92bf800227f31 languageName: node linkType: hard @@ -37073,27 +37144,27 @@ __metadata: languageName: node linkType: hard -"postcss-modules-local-by-default@npm:^4.0.0, postcss-modules-local-by-default@npm:^4.0.3": - version: 4.0.3 - resolution: "postcss-modules-local-by-default@npm:4.0.3" +"postcss-modules-local-by-default@npm:^4.0.0, postcss-modules-local-by-default@npm:^4.0.4": + version: 4.0.4 + resolution: "postcss-modules-local-by-default@npm:4.0.4" dependencies: icss-utils: ^5.0.0 postcss-selector-parser: ^6.0.2 postcss-value-parser: ^4.1.0 peerDependencies: postcss: ^8.1.0 - checksum: 2f8083687f3d6067885f8863dd32dbbb4f779cfcc7e52c17abede9311d84faf6d3ed8760e7c54c6380281732ae1f78e5e56a28baf3c271b33f450a11c9e30485 + checksum: 578b955b0773147890caa88c30b10dfc849c5b1412a47ad51751890dba16fca9528c3ab00a19b186a8c2c150c2d08e2ce64d3d907800afee1f37c6d38252e365 languageName: node linkType: hard -"postcss-modules-scope@npm:^3.0.0": - version: 3.0.0 - resolution: "postcss-modules-scope@npm:3.0.0" +"postcss-modules-scope@npm:^3.0.0, postcss-modules-scope@npm:^3.1.1": + version: 3.1.1 + resolution: "postcss-modules-scope@npm:3.1.1" dependencies: postcss-selector-parser: ^6.0.4 peerDependencies: postcss: ^8.1.0 - checksum: 330b9398dbd44c992c92b0dc612c0626135e2cc840fee41841eb61247a6cfed95af2bd6f67ead9dd9d0bb41f5b0367129d93c6e434fa3e9c58ade391d9a5a138 + checksum: 9e9d23abb0babc7fa243be65704d72a5a9ceb2bded4dbaef96a88210d468b03c8c3158c197f4e22300c851f08c6fdddd6ebe65f44e4c34448b45b8a2e063a16d languageName: node linkType: hard @@ -37306,7 +37377,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.1.0, postcss@npm:^8.4.21, postcss@npm:^8.4.27": +"postcss@npm:^8.1.0, postcss@npm:^8.4.27, postcss@npm:^8.4.33": version: 8.4.33 resolution: "postcss@npm:8.4.33" dependencies: @@ -37945,10 +38016,10 @@ __metadata: languageName: node linkType: hard -"ramda@npm:~0.29.0": - version: 0.29.0 - resolution: "ramda@npm:0.29.0" - checksum: 9ab26c06eb7545cbb7eebcf75526d6ee2fcaae19e338f165b2bf32772121e7b28192d6664d1ba222ff76188ba26ab307342d66e805dbb02c860560adc4d5dd57 +"ramda@npm:~0.29.1": + version: 0.29.1 + resolution: "ramda@npm:0.29.1" + checksum: df7c627597a66d5f317f6ba77ad17d7ba818efc9c2c4a638440bc23f2c651e823970ea05b05a28895738c0e4b738fadbdc17b2c97b3ad922826febc09c859c44 languageName: node linkType: hard @@ -38012,6 +38083,13 @@ __metadata: languageName: node linkType: hard +"rate-limiter-flexible@npm:^4.0.0": + version: 4.0.0 + resolution: "rate-limiter-flexible@npm:4.0.0" + checksum: defaa10e35d77399c4bbdeaa0e3f0028bcc5f6d678118d54496d5c01a4c9d5d56e16885e2ea339e7dd1ea056a3594bba24a18b5da236965f1d186fd52bdbe9fe + languageName: node + linkType: hard + "raw-body@npm:2.5.1": version: 2.5.1 resolution: "raw-body@npm:2.5.1" @@ -38312,11 +38390,11 @@ __metadata: linkType: hard "react-hook-form@npm:^7.12.2, react-hook-form@npm:^7.13.0": - version: 7.48.2 - resolution: "react-hook-form@npm:7.48.2" + version: 7.49.3 + resolution: "react-hook-form@npm:7.49.3" peerDependencies: react: ^16.8.0 || ^17 || ^18 - checksum: 39652d08f78f16e5234049ceeb794d8bcd4d146772aca99c6db8c5aea8926cd4a230d02098886a441074deefbc24ffcb5ed57bc7cb0009d950115f5b3e627f12 + checksum: 9769845e2749f5c9d1d033be3819bc572ffa67f19ec2e567c61a58d0d060107facdf8425aab253c2e667c00853b7706a50bd6739fca6228c284c9313420ca26f languageName: node linkType: hard @@ -38451,35 +38529,25 @@ __metadata: languageName: node linkType: hard -"react-redux@npm:^8.1.3": - version: 8.1.3 - resolution: "react-redux@npm:8.1.3" +"react-redux@npm:^9.0.4": + version: 9.1.0 + resolution: "react-redux@npm:9.1.0" dependencies: - "@babel/runtime": ^7.12.1 - "@types/hoist-non-react-statics": ^3.3.1 "@types/use-sync-external-store": ^0.0.3 - hoist-non-react-statics: ^3.3.2 - react-is: ^18.0.0 use-sync-external-store: ^1.0.0 peerDependencies: - "@types/react": ^16.8 || ^17.0 || ^18.0 - "@types/react-dom": ^16.8 || ^17.0 || ^18.0 - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - react-native: ">=0.59" - redux: ^4 || ^5.0.0-beta.0 + "@types/react": ^18.2.25 + react: ^18.0 + react-native: ">=0.69" + redux: ^5.0.0 peerDependenciesMeta: "@types/react": optional: true - "@types/react-dom": - optional: true - react-dom: - optional: true react-native: optional: true redux: optional: true - checksum: 192ea6f6053148ec80a4148ec607bc259403b937e515f616a1104ca5ab357e97e98b8245ed505a17afee67a72341d4a559eaca9607968b4a422aa9b44ba7eb89 + checksum: 1b07714379ff0087b4fb43ffd138cc84efb7608c874d632a4e2162e1874f3e0f6b69a0a9b0f24f93cbf122c694ac9cfd315770676d4cabb167d159f1ef419560 languageName: node linkType: hard @@ -39085,7 +39153,7 @@ __metadata: languageName: node linkType: hard -"redux@npm:^4.0.0, redux@npm:^4.0.4, redux@npm:^4.1.2": +"redux@npm:^4.0.0, redux@npm:^4.0.4": version: 4.1.2 resolution: "redux@npm:4.1.2" dependencies: @@ -39094,6 +39162,13 @@ __metadata: languageName: node linkType: hard +"redux@npm:^5.0.0": + version: 5.0.1 + resolution: "redux@npm:5.0.1" + checksum: e74affa9009dd5d994878b9a1ce30d6569d986117175056edb003de2651c05b10fe7819d6fa94aea1a94de9a82f252f986547f007a2fbeb35c317a2e5f5ecf2c + languageName: node + linkType: hard + "reflect-metadata@npm:0.1.13": version: 0.1.13 resolution: "reflect-metadata@npm:0.1.13" @@ -39397,10 +39472,10 @@ __metadata: languageName: node linkType: hard -"reselect@npm:^4.1.8": - version: 4.1.8 - resolution: "reselect@npm:4.1.8" - checksum: a4ac87cedab198769a29be92bc221c32da76cfdad6911eda67b4d3e7136dca86208c3b210e31632eae31ebd2cded18596f0dd230d3ccc9e978df22f233b5583e +"reselect@npm:^5.0.1": + version: 5.1.0 + resolution: "reselect@npm:5.1.0" + checksum: 5bc9c5d03d7caea00d0c0e24330bf23d91801227346fec1cef6a60988ab8d3dd7cee76e6994ca0915bc1c20845bb2bd929b95753763e0a9db74c0f9dff5cb845 languageName: node linkType: hard @@ -39930,12 +40005,12 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:7.8.0": - version: 7.8.0 - resolution: "rxjs@npm:7.8.0" +"rxjs@npm:7.8.1, rxjs@npm:^7.2.0, rxjs@npm:^7.5.5, rxjs@npm:^7.8.1": + version: 7.8.1 + resolution: "rxjs@npm:7.8.1" dependencies: tslib: ^2.1.0 - checksum: 61b4d4fd323c1043d8d6ceb91f24183b28bcf5def4f01ca111511d5c6b66755bc5578587fe714ef5d67cf4c9f2e26f4490d4e1d8cabf9bd5967687835e9866a2 + checksum: de4b53db1063e618ec2eca0f7965d9137cabe98cf6be9272efe6c86b47c17b987383df8574861bcced18ebd590764125a901d5506082be84a8b8e364bf05f119 languageName: node linkType: hard @@ -39948,15 +40023,6 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.2.0, rxjs@npm:^7.5.5, rxjs@npm:^7.8.1": - version: 7.8.1 - resolution: "rxjs@npm:7.8.1" - dependencies: - tslib: ^2.1.0 - checksum: de4b53db1063e618ec2eca0f7965d9137cabe98cf6be9272efe6c86b47c17b987383df8574861bcced18ebd590764125a901d5506082be84a8b8e364bf05f119 - languageName: node - linkType: hard - "sade@npm:^1.7.3": version: 1.8.1 resolution: "sade@npm:1.8.1" @@ -41679,12 +41745,12 @@ __metadata: linkType: hard "sucrase@npm:^3.20.2": - version: 3.34.0 - resolution: "sucrase@npm:3.34.0" + version: 3.35.0 + resolution: "sucrase@npm:3.35.0" dependencies: "@jridgewell/gen-mapping": ^0.3.2 commander: ^4.0.0 - glob: 7.1.6 + glob: ^10.3.10 lines-and-columns: ^1.1.6 mz: ^2.7.0 pirates: ^4.0.1 @@ -41692,7 +41758,7 @@ __metadata: bin: sucrase: bin/sucrase sucrase-node: bin/sucrase-node - checksum: 61860063bdf6103413698e13247a3074d25843e91170825a9752e4af7668ffadd331b6e99e92fc32ee5b3c484ee134936f926fa9039d5711fafff29d017a2110 + checksum: 9fc5792a9ab8a14dcf9c47dcb704431d35c1cdff1d17d55d382a31c2e8e3063870ad32ce120a80915498486246d612e30cda44f1624d9d9a10423e1a43487ad1 languageName: node linkType: hard @@ -41798,16 +41864,16 @@ __metadata: languageName: node linkType: hard -"swagger-client@npm:^3.24.6": - version: 3.24.6 - resolution: "swagger-client@npm:3.24.6" +"swagger-client@npm:^3.25.0": + version: 3.25.0 + resolution: "swagger-client@npm:3.25.0" dependencies: "@babel/runtime-corejs3": ^7.22.15 - "@swagger-api/apidom-core": ">=0.83.0 <1.0.0" - "@swagger-api/apidom-error": ">=0.83.0 <1.0.0" - "@swagger-api/apidom-json-pointer": ">=0.83.0 <1.0.0" - "@swagger-api/apidom-ns-openapi-3-1": ">=0.83.0 <1.0.0" - "@swagger-api/apidom-reference": ">=0.83.0 <1.0.0" + "@swagger-api/apidom-core": ">=0.90.0 <1.0.0" + "@swagger-api/apidom-error": ">=0.90.0 <1.0.0" + "@swagger-api/apidom-json-pointer": ">=0.90.0 <1.0.0" + "@swagger-api/apidom-ns-openapi-3-1": ">=0.90.0 <1.0.0" + "@swagger-api/apidom-reference": ">=0.90.0 <1.0.0" cookie: ~0.6.0 deepmerge: ~4.3.0 fast-json-patch: ^3.0.0-1 @@ -41818,18 +41884,18 @@ __metadata: qs: ^6.10.2 traverse: ~0.6.6 undici: ^5.24.0 - checksum: 8bb1aeea4576fdd88543c4e011b1f087c52b34e5a069d560937a5c32a6e1e6c7eda243810886f8b09e4e12062e8f2768edaa5e6193140a28f9604bac42b18104 + checksum: 2e989059b4edeab26b148993cea8a68c4ad34927d4058479f2722c01d8bd0f67bfb1f69dc93ce24a5adb5a8e0f45e4438ad38f8bfb70f8d0b1a8d66650abe060 languageName: node linkType: hard "swagger-ui-react@npm:^5.0.0": - version: 5.10.5 - resolution: "swagger-ui-react@npm:5.10.5" + version: 5.11.0 + resolution: "swagger-ui-react@npm:5.11.0" dependencies: - "@babel/runtime-corejs3": ^7.23.5 - "@braintree/sanitize-url": =6.0.4 + "@babel/runtime-corejs3": ^7.23.7 + "@braintree/sanitize-url": =7.0.0 base64-js: ^1.5.1 - classnames: ^2.3.1 + classnames: ^2.5.1 css.escape: 1.5.1 deep-extend: 0.6.0 dompurify: =3.0.6 @@ -41847,23 +41913,23 @@ __metadata: react-immutable-proptypes: 2.2.0 react-immutable-pure-component: ^2.2.0 react-inspector: ^6.0.1 - react-redux: ^8.1.3 + react-redux: ^9.0.4 react-syntax-highlighter: ^15.5.0 - redux: ^4.1.2 + redux: ^5.0.0 redux-immutable: ^4.0.0 remarkable: ^2.0.1 - reselect: ^4.1.8 + reselect: ^5.0.1 serialize-error: ^8.1.0 sha.js: ^2.4.11 - swagger-client: ^3.24.6 + swagger-client: ^3.25.0 url-parse: ^1.5.10 xml: =1.0.1 xml-but-prettier: ^1.0.1 zenscroll: ^4.0.2 peerDependencies: - react: ">=17.0.0" - react-dom: ">=17.0.0" - checksum: 79256d68d56389d089a953f7d6c3a95a67c0b4e2794ae3992ba60adc0312aeb4446d8ba1e20687fcd7708d562e7c15fa733dbcb54cd8f99948ebf4c4513fa042 + react: ">=16.8.0 <19" + react-dom: ">=16.8.0 <19" + checksum: f46acfe503f80566f5a28c5a7a27091f80a764d4602e81ef2dc59466097bdf0e6f6568b866a0a90ab23db39a88fe6f5e4d96b3d5367d05b8ecedb256477fb1cb languageName: node linkType: hard @@ -42485,10 +42551,10 @@ __metadata: languageName: node linkType: hard -"ts-algebra@npm:^1.2.0": - version: 1.2.0 - resolution: "ts-algebra@npm:1.2.0" - checksum: 471d3a049dbceadf2355f980e4d0a4cba413b50e66f0c8fb5eece876c238f7d2a270e1c85aa9ebd04349ae70335715f8e6d87338fd8cf755d12e285e884b3d91 +"ts-algebra@npm:^1.2.2": + version: 1.2.2 + resolution: "ts-algebra@npm:1.2.2" + checksum: eea0c08fba10c4a758086079c575a32c4c050f50087e06fcc1ccd53b045bdf7bdb0ab9597a52a241a714f058ff047cedbddcb1539de5e66bb424aa5b33c677a1 languageName: node linkType: hard @@ -42631,10 +42697,10 @@ __metadata: linkType: hard "tsx@npm:^4.0.0": - version: 4.6.2 - resolution: "tsx@npm:4.6.2" + version: 4.7.0 + resolution: "tsx@npm:4.7.0" dependencies: - esbuild: ~0.18.20 + esbuild: ~0.19.10 fsevents: ~2.3.3 get-tsconfig: ^4.7.2 dependenciesMeta: @@ -42642,7 +42708,7 @@ __metadata: optional: true bin: tsx: dist/cli.mjs - checksum: a9f13bdb67bfb316bbfc92303d8464323ab1b673aa93ea97271c211a8ba7c59274d4b32eeec5ad8fbd0b04260a092a3ad2116abeb6913254ba456010ff685743 + checksum: a3a17fa8a40dbe0aff26fb2bc71a069e568152e0685b0bd9a31ea1091806274ba14882551433ed01efa7eae16f1aa965e2e47f3075ec1e914c42cf5dfce1f924 languageName: node linkType: hard @@ -43900,8 +43966,8 @@ __metadata: linkType: hard "vite@npm:^4.4.9": - version: 4.5.1 - resolution: "vite@npm:4.5.1" + version: 4.5.2 + resolution: "vite@npm:4.5.2" dependencies: esbuild: ^0.18.10 fsevents: ~2.3.2 @@ -43935,7 +44001,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 72b3584b3d3b8d14e8a37f0248e47fb8b4d02ab35de5b5a8e5ca8ae55c3be2aab73760dc36edac4fa722de182f78cc492eb44888fcb4a9a0712c4605dad644f9 + checksum: 9d1f84f703c2660aced34deee7f309278ed368880f66e9570ac115c793d91f7fffb80ab19c602b3c8bc1341fe23437d86a3fcca2a9ef82f7ef0cdac5a40d0c86 languageName: node linkType: hard